OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "render_int.h" | 7 #include "render_int.h" |
8 | 8 |
9 #include "core/include/fpdfapi/fpdf_pageobj.h" | 9 #include "core/include/fpdfapi/fpdf_pageobj.h" |
10 #include "core/include/fpdfapi/fpdf_render.h" | 10 #include "core/include/fpdfapi/fpdf_render.h" |
11 #include "core/include/fxge/fx_ge.h" | 11 #include "core/include/fxge/fx_ge.h" |
12 #include "core/src/fpdfapi/fpdf_page/pageint.h" | 12 #include "core/src/fpdfapi/fpdf_page/pageint.h" |
13 | 13 |
14 CPDF_Type3Cache::~CPDF_Type3Cache() { | 14 CPDF_Type3Cache::~CPDF_Type3Cache() { |
15 for (const auto& pair : m_SizeMap) { | 15 for (const auto& pair : m_SizeMap) { |
16 delete pair.second; | 16 delete pair.second; |
17 } | 17 } |
18 m_SizeMap.clear(); | 18 m_SizeMap.clear(); |
19 } | 19 } |
20 CFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(FX_DWORD charcode, | 20 CFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(FX_DWORD charcode, |
21 const CFX_AffineMatrix* pMatrix, | 21 const CFX_Matrix* pMatrix, |
22 FX_FLOAT retinaScaleX, | 22 FX_FLOAT retinaScaleX, |
23 FX_FLOAT retinaScaleY) { | 23 FX_FLOAT retinaScaleY) { |
24 _CPDF_UniqueKeyGen keygen; | 24 _CPDF_UniqueKeyGen keygen; |
25 keygen.Generate( | 25 keygen.Generate( |
26 4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000), | 26 4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000), |
27 FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000)); | 27 FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000)); |
28 CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); | 28 CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); |
29 CPDF_Type3Glyphs* pSizeCache; | 29 CPDF_Type3Glyphs* pSizeCache; |
30 auto it = m_SizeMap.find(FaceGlyphsKey); | 30 auto it = m_SizeMap.find(FaceGlyphsKey); |
31 if (it == m_SizeMap.end()) { | 31 if (it == m_SizeMap.end()) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 if (_IsScanLine8bpp(pBuf + line * pitch, width)) { | 119 if (_IsScanLine8bpp(pBuf + line * pitch, width)) { |
120 return line; | 120 return line; |
121 } | 121 } |
122 } | 122 } |
123 line += line_step; | 123 line += line_step; |
124 } | 124 } |
125 return -1; | 125 return -1; |
126 } | 126 } |
127 CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize, | 127 CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize, |
128 FX_DWORD charcode, | 128 FX_DWORD charcode, |
129 const CFX_AffineMatrix* pMatrix, | 129 const CFX_Matrix* pMatrix, |
130 FX_FLOAT retinaScaleX, | 130 FX_FLOAT retinaScaleX, |
131 FX_FLOAT retinaScaleY) { | 131 FX_FLOAT retinaScaleY) { |
132 const CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode); | 132 const CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode); |
133 if (!pChar || !pChar->m_pBitmap) | 133 if (!pChar || !pChar->m_pBitmap) |
134 return nullptr; | 134 return nullptr; |
135 | 135 |
136 CFX_DIBitmap* pBitmap = pChar->m_pBitmap; | 136 CFX_DIBitmap* pBitmap = pChar->m_pBitmap; |
137 CFX_AffineMatrix image_matrix, text_matrix; | 137 CFX_Matrix image_matrix, text_matrix; |
138 image_matrix = pChar->m_ImageMatrix; | 138 image_matrix = pChar->m_ImageMatrix; |
139 text_matrix.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0); | 139 text_matrix.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0); |
140 image_matrix.Concat(text_matrix); | 140 image_matrix.Concat(text_matrix); |
141 CFX_DIBitmap* pResBitmap = NULL; | 141 CFX_DIBitmap* pResBitmap = NULL; |
142 int left, top; | 142 int left, top; |
143 if (FXSYS_fabs(image_matrix.b) < FXSYS_fabs(image_matrix.a) / 100 && | 143 if (FXSYS_fabs(image_matrix.b) < FXSYS_fabs(image_matrix.a) / 100 && |
144 FXSYS_fabs(image_matrix.c) < FXSYS_fabs(image_matrix.d) / 100) { | 144 FXSYS_fabs(image_matrix.c) < FXSYS_fabs(image_matrix.d) / 100) { |
145 int top_line, bottom_line; | 145 int top_line, bottom_line; |
146 top_line = _DetectFirstLastScan(pBitmap, TRUE); | 146 top_line = _DetectFirstLastScan(pBitmap, TRUE); |
147 bottom_line = _DetectFirstLastScan(pBitmap, FALSE); | 147 bottom_line = _DetectFirstLastScan(pBitmap, FALSE); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 va_list argList; | 187 va_list argList; |
188 va_start(argList, count); | 188 va_start(argList, count); |
189 for (int i = 0; i < count; i++) { | 189 for (int i = 0; i < count; i++) { |
190 int p = va_arg(argList, int); | 190 int p = va_arg(argList, int); |
191 ((FX_DWORD*)m_Key)[i] = p; | 191 ((FX_DWORD*)m_Key)[i] = p; |
192 } | 192 } |
193 va_end(argList); | 193 va_end(argList); |
194 m_KeyLen = count * sizeof(FX_DWORD); | 194 m_KeyLen = count * sizeof(FX_DWORD); |
195 } | 195 } |
196 FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, | 196 FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, |
197 const CFX_AffineMatrix* pObj2Device, | 197 const CFX_Matrix* pObj2Device, |
198 CFX_PathData* pClippingPath) { | 198 CFX_PathData* pClippingPath) { |
199 if (textobj->m_nChars == 0) { | 199 if (textobj->m_nChars == 0) { |
200 return TRUE; | 200 return TRUE; |
201 } | 201 } |
202 int text_render_mode = textobj->m_TextState.GetObject()->m_TextMode; | 202 int text_render_mode = textobj->m_TextState.GetObject()->m_TextMode; |
203 if (text_render_mode == 3) { | 203 if (text_render_mode == 3) { |
204 return TRUE; | 204 return TRUE; |
205 } | 205 } |
206 CPDF_Font* pFont = textobj->m_TextState.GetFont(); | 206 CPDF_Font* pFont = textobj->m_TextState.GetFont(); |
207 if (pFont->GetFontType() == PDFFONT_TYPE3) { | 207 if (pFont->GetFontType() == PDFFONT_TYPE3) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 stroke_argb = GetStrokeArgb(textobj); | 250 stroke_argb = GetStrokeArgb(textobj); |
251 } | 251 } |
252 } | 252 } |
253 if (bFill) { | 253 if (bFill) { |
254 if (textobj->m_ColorState.GetFillColor()->IsPattern()) { | 254 if (textobj->m_ColorState.GetFillColor()->IsPattern()) { |
255 bPattern = TRUE; | 255 bPattern = TRUE; |
256 } else { | 256 } else { |
257 fill_argb = GetFillArgb(textobj); | 257 fill_argb = GetFillArgb(textobj); |
258 } | 258 } |
259 } | 259 } |
260 CFX_AffineMatrix text_matrix; | 260 CFX_Matrix text_matrix; |
261 textobj->GetTextMatrix(&text_matrix); | 261 textobj->GetTextMatrix(&text_matrix); |
262 if (IsAvailableMatrix(text_matrix) == FALSE) { | 262 if (IsAvailableMatrix(text_matrix) == FALSE) { |
263 return TRUE; | 263 return TRUE; |
264 } | 264 } |
265 FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); | 265 FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); |
266 if (bPattern) { | 266 if (bPattern) { |
267 DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, | 267 DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, |
268 &text_matrix, bFill, bStroke); | 268 &text_matrix, bFill, bStroke); |
269 return TRUE; | 269 return TRUE; |
270 } | 270 } |
271 if (bClip || bStroke) { | 271 if (bClip || bStroke) { |
272 const CFX_AffineMatrix* pDeviceMatrix = pObj2Device; | 272 const CFX_Matrix* pDeviceMatrix = pObj2Device; |
273 CFX_AffineMatrix device_matrix; | 273 CFX_Matrix device_matrix; |
274 if (bStroke) { | 274 if (bStroke) { |
275 const FX_FLOAT* pCTM = textobj->m_TextState.GetObject()->m_CTM; | 275 const FX_FLOAT* pCTM = textobj->m_TextState.GetObject()->m_CTM; |
276 if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) { | 276 if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) { |
277 CFX_AffineMatrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0); | 277 CFX_Matrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0); |
278 text_matrix.ConcatInverse(ctm); | 278 text_matrix.ConcatInverse(ctm); |
279 device_matrix.Copy(ctm); | 279 device_matrix.Copy(ctm); |
280 device_matrix.Concat(*pObj2Device); | 280 device_matrix.Concat(*pObj2Device); |
281 pDeviceMatrix = &device_matrix; | 281 pDeviceMatrix = &device_matrix; |
282 } | 282 } |
283 } | 283 } |
284 int flag = 0; | 284 int flag = 0; |
285 if (bStroke && bFill) { | 285 if (bStroke && bFill) { |
286 flag |= FX_FILL_STROKE; | 286 flag |= FX_FILL_STROKE; |
287 flag |= FX_STROKE_TEXT_MODE; | 287 flag |= FX_STROKE_TEXT_MODE; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 m_pType3Font = pType3Font; | 347 m_pType3Font = pType3Font; |
348 } | 348 } |
349 ~CPDF_RefType3Cache() { | 349 ~CPDF_RefType3Cache() { |
350 while (m_dwCount--) { | 350 while (m_dwCount--) { |
351 ReleaseCachedType3(m_pType3Font); | 351 ReleaseCachedType3(m_pType3Font); |
352 } | 352 } |
353 } | 353 } |
354 FX_DWORD m_dwCount; | 354 FX_DWORD m_dwCount; |
355 CPDF_Type3Font* m_pType3Font; | 355 CPDF_Type3Font* m_pType3Font; |
356 }; | 356 }; |
357 FX_BOOL CPDF_RenderStatus::ProcessType3Text( | 357 FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, |
358 const CPDF_TextObject* textobj, | 358 const CFX_Matrix* pObj2Device) { |
359 const CFX_AffineMatrix* pObj2Device) { | |
360 CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->GetType3Font(); | 359 CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->GetType3Font(); |
361 for (int j = 0; j < m_Type3FontCache.GetSize(); j++) { | 360 for (int j = 0; j < m_Type3FontCache.GetSize(); j++) { |
362 if (m_Type3FontCache.GetAt(j) == pType3Font) | 361 if (m_Type3FontCache.GetAt(j) == pType3Font) |
363 return TRUE; | 362 return TRUE; |
364 } | 363 } |
365 CFX_Matrix dCTM = m_pDevice->GetCTM(); | 364 CFX_Matrix dCTM = m_pDevice->GetCTM(); |
366 FX_FLOAT sa = FXSYS_fabs(dCTM.a); | 365 FX_FLOAT sa = FXSYS_fabs(dCTM.a); |
367 FX_FLOAT sd = FXSYS_fabs(dCTM.d); | 366 FX_FLOAT sd = FXSYS_fabs(dCTM.d); |
368 CFX_AffineMatrix text_matrix; | 367 CFX_Matrix text_matrix; |
369 textobj->GetTextMatrix(&text_matrix); | 368 textobj->GetTextMatrix(&text_matrix); |
370 CFX_AffineMatrix char_matrix = pType3Font->GetFontMatrix(); | 369 CFX_Matrix char_matrix = pType3Font->GetFontMatrix(); |
371 FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); | 370 FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); |
372 char_matrix.Scale(font_size, font_size); | 371 char_matrix.Scale(font_size, font_size); |
373 FX_ARGB fill_argb = GetFillArgb(textobj, TRUE); | 372 FX_ARGB fill_argb = GetFillArgb(textobj, TRUE); |
374 int fill_alpha = FXARGB_A(fill_argb); | 373 int fill_alpha = FXARGB_A(fill_argb); |
375 int device_class = m_pDevice->GetDeviceClass(); | 374 int device_class = m_pDevice->GetDeviceClass(); |
376 FXTEXT_GLYPHPOS* pGlyphAndPos = NULL; | 375 FXTEXT_GLYPHPOS* pGlyphAndPos = NULL; |
377 if (device_class == FXDC_DISPLAY) { | 376 if (device_class == FXDC_DISPLAY) { |
378 pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, textobj->m_nChars); | 377 pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, textobj->m_nChars); |
379 } else if (fill_alpha < 255) { | 378 } else if (fill_alpha < 255) { |
380 return FALSE; | 379 return FALSE; |
381 } | 380 } |
382 CPDF_RefType3Cache refTypeCache(pType3Font); | 381 CPDF_RefType3Cache refTypeCache(pType3Font); |
383 FX_DWORD* pChars = textobj->m_pCharCodes; | 382 FX_DWORD* pChars = textobj->m_pCharCodes; |
384 if (textobj->m_nChars == 1) { | 383 if (textobj->m_nChars == 1) { |
385 pChars = (FX_DWORD*)(&textobj->m_pCharCodes); | 384 pChars = (FX_DWORD*)(&textobj->m_pCharCodes); |
386 } | 385 } |
387 for (int iChar = 0; iChar < textobj->m_nChars; iChar++) { | 386 for (int iChar = 0; iChar < textobj->m_nChars; iChar++) { |
388 FX_DWORD charcode = pChars[iChar]; | 387 FX_DWORD charcode = pChars[iChar]; |
389 if (charcode == (FX_DWORD)-1) { | 388 if (charcode == (FX_DWORD)-1) { |
390 continue; | 389 continue; |
391 } | 390 } |
392 CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode); | 391 CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode); |
393 if (pType3Char == NULL) { | 392 if (pType3Char == NULL) { |
394 continue; | 393 continue; |
395 } | 394 } |
396 CFX_AffineMatrix matrix = char_matrix; | 395 CFX_Matrix matrix = char_matrix; |
397 matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0; | 396 matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0; |
398 matrix.Concat(text_matrix); | 397 matrix.Concat(text_matrix); |
399 matrix.Concat(*pObj2Device); | 398 matrix.Concat(*pObj2Device); |
400 if (!pType3Char->LoadBitmap(m_pContext)) { | 399 if (!pType3Char->LoadBitmap(m_pContext)) { |
401 if (pGlyphAndPos) { | 400 if (pGlyphAndPos) { |
402 for (int i = 0; i < iChar; i++) { | 401 for (int i = 0; i < iChar; i++) { |
403 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[i]; | 402 FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[i]; |
404 if (glyph.m_pGlyph == NULL) { | 403 if (glyph.m_pGlyph == NULL) { |
405 continue; | 404 continue; |
406 } | 405 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 int origin_y = FXSYS_round(matrix.f); | 466 int origin_y = FXSYS_round(matrix.f); |
468 if (pGlyphAndPos) { | 467 if (pGlyphAndPos) { |
469 pGlyphAndPos[iChar].m_pGlyph = pBitmap; | 468 pGlyphAndPos[iChar].m_pGlyph = pBitmap; |
470 pGlyphAndPos[iChar].m_OriginX = origin_x; | 469 pGlyphAndPos[iChar].m_OriginX = origin_x; |
471 pGlyphAndPos[iChar].m_OriginY = origin_y; | 470 pGlyphAndPos[iChar].m_OriginY = origin_y; |
472 } else { | 471 } else { |
473 m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left, | 472 m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left, |
474 origin_y - pBitmap->m_Top, fill_argb); | 473 origin_y - pBitmap->m_Top, fill_argb); |
475 } | 474 } |
476 } else { | 475 } else { |
477 CFX_AffineMatrix image_matrix = pType3Char->m_ImageMatrix; | 476 CFX_Matrix image_matrix = pType3Char->m_ImageMatrix; |
478 image_matrix.Concat(matrix); | 477 image_matrix.Concat(matrix); |
479 CPDF_ImageRenderer renderer; | 478 CPDF_ImageRenderer renderer; |
480 if (renderer.Start(this, pType3Char->m_pBitmap, fill_argb, 255, | 479 if (renderer.Start(this, pType3Char->m_pBitmap, fill_argb, 255, |
481 &image_matrix, 0, FALSE)) { | 480 &image_matrix, 0, FALSE)) { |
482 renderer.Continue(NULL); | 481 renderer.Continue(NULL); |
483 } | 482 } |
484 if (!renderer.m_Result) { | 483 if (!renderer.m_Result) { |
485 return FALSE; | 484 return FALSE; |
486 } | 485 } |
487 } | 486 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 charpos.m_bGlyphAdjust = TRUE; | 589 charpos.m_bGlyphAdjust = TRUE; |
591 } | 590 } |
592 } | 591 } |
593 } | 592 } |
594 FX_BOOL CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, | 593 FX_BOOL CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, |
595 int nChars, | 594 int nChars, |
596 FX_DWORD* pCharCodes, | 595 FX_DWORD* pCharCodes, |
597 FX_FLOAT* pCharPos, | 596 FX_FLOAT* pCharPos, |
598 CPDF_Font* pFont, | 597 CPDF_Font* pFont, |
599 FX_FLOAT font_size, | 598 FX_FLOAT font_size, |
600 const CFX_AffineMatrix* pText2User, | 599 const CFX_Matrix* pText2User, |
601 const CFX_AffineMatrix* pUser2Device, | 600 const CFX_Matrix* pUser2Device, |
602 const CFX_GraphStateData* pGraphState, | 601 const CFX_GraphStateData* pGraphState, |
603 FX_ARGB fill_argb, | 602 FX_ARGB fill_argb, |
604 FX_ARGB stroke_argb, | 603 FX_ARGB stroke_argb, |
605 CFX_PathData* pClippingPath, | 604 CFX_PathData* pClippingPath, |
606 int nFlag) { | 605 int nFlag) { |
607 CFX_FontCache* pCache = | 606 CFX_FontCache* pCache = |
608 pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() | 607 pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() |
609 : NULL; | 608 : NULL; |
610 CPDF_CharPosList CharPosList; | 609 CPDF_CharPosList CharPosList; |
611 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); | 610 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); |
612 return pDevice->DrawTextPath(CharPosList.m_nChars, CharPosList.m_pCharPos, | 611 return pDevice->DrawTextPath(CharPosList.m_nChars, CharPosList.m_pCharPos, |
613 &pFont->m_Font, pCache, font_size, pText2User, | 612 &pFont->m_Font, pCache, font_size, pText2User, |
614 pUser2Device, pGraphState, fill_argb, | 613 pUser2Device, pGraphState, fill_argb, |
615 stroke_argb, pClippingPath, nFlag); | 614 stroke_argb, pClippingPath, nFlag); |
616 } | 615 } |
617 void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, | 616 void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, |
618 int left, | 617 int left, |
619 int top, | 618 int top, |
620 CPDF_Font* pFont, | 619 CPDF_Font* pFont, |
621 int height, | 620 int height, |
622 const CFX_ByteString& str, | 621 const CFX_ByteString& str, |
623 FX_ARGB argb) { | 622 FX_ARGB argb) { |
624 FX_RECT font_bbox; | 623 FX_RECT font_bbox; |
625 pFont->GetFontBBox(font_bbox); | 624 pFont->GetFontBBox(font_bbox); |
626 FX_FLOAT font_size = | 625 FX_FLOAT font_size = |
627 (FX_FLOAT)height * 1000.0f / (FX_FLOAT)(font_bbox.top - font_bbox.bottom); | 626 (FX_FLOAT)height * 1000.0f / (FX_FLOAT)(font_bbox.top - font_bbox.bottom); |
628 FX_FLOAT origin_x = (FX_FLOAT)left; | 627 FX_FLOAT origin_x = (FX_FLOAT)left; |
629 FX_FLOAT origin_y = | 628 FX_FLOAT origin_y = |
630 (FX_FLOAT)top + font_size * (FX_FLOAT)font_bbox.top / 1000.0f; | 629 (FX_FLOAT)top + font_size * (FX_FLOAT)font_bbox.top / 1000.0f; |
631 CFX_AffineMatrix matrix(1.0f, 0, 0, -1.0f, 0, 0); | 630 CFX_Matrix matrix(1.0f, 0, 0, -1.0f, 0, 0); |
632 DrawTextString(pDevice, origin_x, origin_y, pFont, font_size, &matrix, str, | 631 DrawTextString(pDevice, origin_x, origin_y, pFont, font_size, &matrix, str, |
633 argb); | 632 argb); |
634 } | 633 } |
635 void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, | 634 void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, |
636 FX_FLOAT origin_x, | 635 FX_FLOAT origin_x, |
637 FX_FLOAT origin_y, | 636 FX_FLOAT origin_y, |
638 CPDF_Font* pFont, | 637 CPDF_Font* pFont, |
639 FX_FLOAT font_size, | 638 FX_FLOAT font_size, |
640 const CFX_AffineMatrix* pMatrix, | 639 const CFX_Matrix* pMatrix, |
641 const CFX_ByteString& str, | 640 const CFX_ByteString& str, |
642 FX_ARGB fill_argb, | 641 FX_ARGB fill_argb, |
643 FX_ARGB stroke_argb, | 642 FX_ARGB stroke_argb, |
644 const CFX_GraphStateData* pGraphState, | 643 const CFX_GraphStateData* pGraphState, |
645 const CPDF_RenderOptions* pOptions) { | 644 const CPDF_RenderOptions* pOptions) { |
646 int nChars = pFont->CountChar(str, str.GetLength()); | 645 int nChars = pFont->CountChar(str, str.GetLength()); |
647 if (nChars == 0) { | 646 if (nChars == 0) { |
648 return; | 647 return; |
649 } | 648 } |
650 FX_DWORD charcode; | 649 FX_DWORD charcode; |
651 int offset = 0; | 650 int offset = 0; |
652 FX_DWORD* pCharCodes; | 651 FX_DWORD* pCharCodes; |
653 FX_FLOAT* pCharPos; | 652 FX_FLOAT* pCharPos; |
654 if (nChars == 1) { | 653 if (nChars == 1) { |
655 charcode = pFont->GetNextChar(str, str.GetLength(), offset); | 654 charcode = pFont->GetNextChar(str, str.GetLength(), offset); |
656 pCharCodes = (FX_DWORD*)(uintptr_t)charcode; | 655 pCharCodes = (FX_DWORD*)(uintptr_t)charcode; |
657 pCharPos = NULL; | 656 pCharPos = NULL; |
658 } else { | 657 } else { |
659 pCharCodes = FX_Alloc(FX_DWORD, nChars); | 658 pCharCodes = FX_Alloc(FX_DWORD, nChars); |
660 pCharPos = FX_Alloc(FX_FLOAT, nChars - 1); | 659 pCharPos = FX_Alloc(FX_FLOAT, nChars - 1); |
661 FX_FLOAT cur_pos = 0; | 660 FX_FLOAT cur_pos = 0; |
662 for (int i = 0; i < nChars; i++) { | 661 for (int i = 0; i < nChars; i++) { |
663 pCharCodes[i] = pFont->GetNextChar(str, str.GetLength(), offset); | 662 pCharCodes[i] = pFont->GetNextChar(str, str.GetLength(), offset); |
664 if (i) { | 663 if (i) { |
665 pCharPos[i - 1] = cur_pos; | 664 pCharPos[i - 1] = cur_pos; |
666 } | 665 } |
667 cur_pos += pFont->GetCharWidthF(pCharCodes[i]) * font_size / 1000; | 666 cur_pos += pFont->GetCharWidthF(pCharCodes[i]) * font_size / 1000; |
668 } | 667 } |
669 } | 668 } |
670 CFX_AffineMatrix matrix; | 669 CFX_Matrix matrix; |
671 if (pMatrix) { | 670 if (pMatrix) { |
672 matrix = *pMatrix; | 671 matrix = *pMatrix; |
673 } | 672 } |
674 matrix.e = origin_x; | 673 matrix.e = origin_x; |
675 matrix.f = origin_y; | 674 matrix.f = origin_y; |
676 if (pFont->GetFontType() == PDFFONT_TYPE3) | 675 if (pFont->GetFontType() == PDFFONT_TYPE3) |
677 ; | 676 ; |
678 else if (stroke_argb == 0) { | 677 else if (stroke_argb == 0) { |
679 DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, | 678 DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, |
680 &matrix, fill_argb, pOptions); | 679 &matrix, fill_argb, pOptions); |
681 } else | 680 } else |
682 DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, | 681 DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, |
683 &matrix, NULL, pGraphState, fill_argb, stroke_argb, NULL); | 682 &matrix, NULL, pGraphState, fill_argb, stroke_argb, NULL); |
684 if (nChars > 1) { | 683 if (nChars > 1) { |
685 FX_Free(pCharCodes); | 684 FX_Free(pCharCodes); |
686 FX_Free(pCharPos); | 685 FX_Free(pCharPos); |
687 } | 686 } |
688 } | 687 } |
689 FX_BOOL CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, | 688 FX_BOOL CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, |
690 int nChars, | 689 int nChars, |
691 FX_DWORD* pCharCodes, | 690 FX_DWORD* pCharCodes, |
692 FX_FLOAT* pCharPos, | 691 FX_FLOAT* pCharPos, |
693 CPDF_Font* pFont, | 692 CPDF_Font* pFont, |
694 FX_FLOAT font_size, | 693 FX_FLOAT font_size, |
695 const CFX_AffineMatrix* pText2Device, | 694 const CFX_Matrix* pText2Device, |
696 FX_ARGB fill_argb, | 695 FX_ARGB fill_argb, |
697 const CPDF_RenderOptions* pOptions) { | 696 const CPDF_RenderOptions* pOptions) { |
698 CFX_FontCache* pCache = | 697 CFX_FontCache* pCache = |
699 pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() | 698 pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() |
700 : NULL; | 699 : NULL; |
701 CPDF_CharPosList CharPosList; | 700 CPDF_CharPosList CharPosList; |
702 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); | 701 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); |
703 int FXGE_flags = 0; | 702 int FXGE_flags = 0; |
704 if (pOptions) { | 703 if (pOptions) { |
705 FX_DWORD dwFlags = pOptions->m_Flags; | 704 FX_DWORD dwFlags = pOptions->m_Flags; |
(...skipping 18 matching lines...) Expand all Loading... |
724 } else { | 723 } else { |
725 FXGE_flags = FXTEXT_CLEARTYPE; | 724 FXGE_flags = FXTEXT_CLEARTYPE; |
726 } | 725 } |
727 if (pFont->GetFontType() & PDFFONT_CIDFONT) { | 726 if (pFont->GetFontType() & PDFFONT_CIDFONT) { |
728 FXGE_flags |= FXFONT_CIDFONT; | 727 FXGE_flags |= FXFONT_CIDFONT; |
729 } | 728 } |
730 return pDevice->DrawNormalText(CharPosList.m_nChars, CharPosList.m_pCharPos, | 729 return pDevice->DrawNormalText(CharPosList.m_nChars, CharPosList.m_pCharPos, |
731 &pFont->m_Font, pCache, font_size, | 730 &pFont->m_Font, pCache, font_size, |
732 pText2Device, fill_argb, FXGE_flags); | 731 pText2Device, fill_argb, FXGE_flags); |
733 } | 732 } |
734 void CPDF_RenderStatus::DrawTextPathWithPattern( | 733 void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, |
735 const CPDF_TextObject* textobj, | 734 const CFX_Matrix* pObj2Device, |
736 const CFX_AffineMatrix* pObj2Device, | 735 CPDF_Font* pFont, |
737 CPDF_Font* pFont, | 736 FX_FLOAT font_size, |
738 FX_FLOAT font_size, | 737 const CFX_Matrix* pTextMatrix, |
739 const CFX_AffineMatrix* pTextMatrix, | 738 FX_BOOL bFill, |
740 FX_BOOL bFill, | 739 FX_BOOL bStroke) { |
741 FX_BOOL bStroke) { | |
742 if (!bStroke) { | 740 if (!bStroke) { |
743 CPDF_PathObject path; | 741 CPDF_PathObject path; |
744 CPDF_TextObject* pCopy = new CPDF_TextObject; | 742 CPDF_TextObject* pCopy = new CPDF_TextObject; |
745 pCopy->Copy(textobj); | 743 pCopy->Copy(textobj); |
746 path.m_bStroke = FALSE; | 744 path.m_bStroke = FALSE; |
747 path.m_FillType = FXFILL_WINDING; | 745 path.m_FillType = FXFILL_WINDING; |
748 path.m_ClipPath.AppendTexts(&pCopy, 1); | 746 path.m_ClipPath.AppendTexts(&pCopy, 1); |
749 path.m_ColorState = textobj->m_ColorState; | 747 path.m_ColorState = textobj->m_ColorState; |
750 path.m_Path.New()->AppendRect(textobj->m_Left, textobj->m_Bottom, | 748 path.m_Path.New()->AppendRect(textobj->m_Left, textobj->m_Bottom, |
751 textobj->m_Right, textobj->m_Top); | 749 textobj->m_Right, textobj->m_Top); |
(...skipping 18 matching lines...) Expand all Loading... |
770 for (FX_DWORD i = 0; i < CharPosList.m_nChars; i++) { | 768 for (FX_DWORD i = 0; i < CharPosList.m_nChars; i++) { |
771 FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i]; | 769 FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i]; |
772 const CFX_PathData* pPath = pFaceCache->LoadGlyphPath( | 770 const CFX_PathData* pPath = pFaceCache->LoadGlyphPath( |
773 &pFont->m_Font, charpos.m_GlyphIndex, charpos.m_FontCharWidth); | 771 &pFont->m_Font, charpos.m_GlyphIndex, charpos.m_FontCharWidth); |
774 if (pPath == NULL) { | 772 if (pPath == NULL) { |
775 continue; | 773 continue; |
776 } | 774 } |
777 CPDF_PathObject path; | 775 CPDF_PathObject path; |
778 path.m_GraphState = textobj->m_GraphState; | 776 path.m_GraphState = textobj->m_GraphState; |
779 path.m_ColorState = textobj->m_ColorState; | 777 path.m_ColorState = textobj->m_ColorState; |
780 CFX_AffineMatrix matrix; | 778 CFX_Matrix matrix; |
781 if (charpos.m_bGlyphAdjust) | 779 if (charpos.m_bGlyphAdjust) |
782 matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], | 780 matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], |
783 charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); | 781 charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); |
784 matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, | 782 matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, |
785 charpos.m_OriginY); | 783 charpos.m_OriginY); |
786 path.m_Path.New()->Append(pPath, &matrix); | 784 path.m_Path.New()->Append(pPath, &matrix); |
787 path.m_Matrix = *pTextMatrix; | 785 path.m_Matrix = *pTextMatrix; |
788 path.m_bStroke = bStroke; | 786 path.m_bStroke = bStroke; |
789 path.m_FillType = bFill ? FXFILL_WINDING : 0; | 787 path.m_FillType = bFill ? FXFILL_WINDING : 0; |
790 path.CalcBoundingBox(); | 788 path.CalcBoundingBox(); |
791 ProcessPath(&path, pObj2Device); | 789 ProcessPath(&path, pObj2Device); |
792 } | 790 } |
793 } | 791 } |
794 | 792 |
795 CFX_PathData* CPDF_Font::LoadGlyphPath(FX_DWORD charcode, int dest_width) { | 793 CFX_PathData* CPDF_Font::LoadGlyphPath(FX_DWORD charcode, int dest_width) { |
796 int glyph_index = GlyphFromCharCode(charcode); | 794 int glyph_index = GlyphFromCharCode(charcode); |
797 if (!m_Font.GetFace()) | 795 if (!m_Font.GetFace()) |
798 return nullptr; | 796 return nullptr; |
799 return m_Font.LoadGlyphPath(glyph_index, dest_width); | 797 return m_Font.LoadGlyphPath(glyph_index, dest_width); |
800 } | 798 } |
OLD | NEW |