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 "core/fpdfapi/render/render_int.h" | 7 #include "core/fpdfapi/render/render_int.h" |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "core/fpdfapi/render/cpdf_textrenderer.h" | 24 #include "core/fpdfapi/render/cpdf_textrenderer.h" |
25 #include "core/fpdfapi/render/cpdf_type3cache.h" | 25 #include "core/fpdfapi/render/cpdf_type3cache.h" |
26 #include "core/fxge/cfx_facecache.h" | 26 #include "core/fxge/cfx_facecache.h" |
27 #include "core/fxge/cfx_fxgedevice.h" | 27 #include "core/fxge/cfx_fxgedevice.h" |
28 #include "core/fxge/cfx_gemodule.h" | 28 #include "core/fxge/cfx_gemodule.h" |
29 #include "core/fxge/cfx_graphstatedata.h" | 29 #include "core/fxge/cfx_graphstatedata.h" |
30 #include "core/fxge/cfx_pathdata.h" | 30 #include "core/fxge/cfx_pathdata.h" |
31 #include "core/fxge/cfx_renderdevice.h" | 31 #include "core/fxge/cfx_renderdevice.h" |
32 #include "third_party/base/numerics/safe_math.h" | 32 #include "third_party/base/numerics/safe_math.h" |
33 | 33 |
34 FX_BOOL CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj, | 34 bool CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj, |
35 const CFX_Matrix* pObj2Device, | 35 const CFX_Matrix* pObj2Device, |
36 CFX_PathData* pClippingPath) { | 36 CFX_PathData* pClippingPath) { |
37 if (textobj->m_nChars == 0) | 37 if (textobj->m_nChars == 0) |
38 return TRUE; | 38 return true; |
39 | 39 |
40 const TextRenderingMode text_render_mode = textobj->m_TextState.GetTextMode(); | 40 const TextRenderingMode text_render_mode = textobj->m_TextState.GetTextMode(); |
41 if (text_render_mode == TextRenderingMode::MODE_INVISIBLE) | 41 if (text_render_mode == TextRenderingMode::MODE_INVISIBLE) |
42 return TRUE; | 42 return true; |
43 | 43 |
44 CPDF_Font* pFont = textobj->m_TextState.GetFont(); | 44 CPDF_Font* pFont = textobj->m_TextState.GetFont(); |
45 if (pFont->IsType3Font()) | 45 if (pFont->IsType3Font()) |
46 return ProcessType3Text(textobj, pObj2Device); | 46 return ProcessType3Text(textobj, pObj2Device); |
47 | 47 |
48 bool bFill = false; | 48 bool bFill = false; |
49 bool bStroke = false; | 49 bool bStroke = false; |
50 bool bClip = false; | 50 bool bClip = false; |
51 if (pClippingPath) { | 51 if (pClippingPath) { |
52 bClip = true; | 52 bClip = true; |
(...skipping 14 matching lines...) Expand all Loading... |
67 case TextRenderingMode::MODE_FILL_STROKE_CLIP: | 67 case TextRenderingMode::MODE_FILL_STROKE_CLIP: |
68 bFill = true; | 68 bFill = true; |
69 if (pFont->GetFace()) | 69 if (pFont->GetFace()) |
70 bStroke = true; | 70 bStroke = true; |
71 break; | 71 break; |
72 case TextRenderingMode::MODE_INVISIBLE: | 72 case TextRenderingMode::MODE_INVISIBLE: |
73 // Already handled above, but the compiler is not smart enough to | 73 // Already handled above, but the compiler is not smart enough to |
74 // realize it. Fall through. | 74 // realize it. Fall through. |
75 ASSERT(false); | 75 ASSERT(false); |
76 case TextRenderingMode::MODE_CLIP: | 76 case TextRenderingMode::MODE_CLIP: |
77 return TRUE; | 77 return true; |
78 } | 78 } |
79 } | 79 } |
80 FX_ARGB stroke_argb = 0; | 80 FX_ARGB stroke_argb = 0; |
81 FX_ARGB fill_argb = 0; | 81 FX_ARGB fill_argb = 0; |
82 bool bPattern = false; | 82 bool bPattern = false; |
83 if (bStroke) { | 83 if (bStroke) { |
84 if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) { | 84 if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) { |
85 bPattern = true; | 85 bPattern = true; |
86 } else { | 86 } else { |
87 stroke_argb = GetStrokeArgb(textobj); | 87 stroke_argb = GetStrokeArgb(textobj); |
88 } | 88 } |
89 } | 89 } |
90 if (bFill) { | 90 if (bFill) { |
91 if (textobj->m_ColorState.GetFillColor()->IsPattern()) { | 91 if (textobj->m_ColorState.GetFillColor()->IsPattern()) { |
92 bPattern = true; | 92 bPattern = true; |
93 } else { | 93 } else { |
94 fill_argb = GetFillArgb(textobj); | 94 fill_argb = GetFillArgb(textobj); |
95 } | 95 } |
96 } | 96 } |
97 CFX_Matrix text_matrix; | 97 CFX_Matrix text_matrix; |
98 textobj->GetTextMatrix(&text_matrix); | 98 textobj->GetTextMatrix(&text_matrix); |
99 if (!IsAvailableMatrix(text_matrix)) | 99 if (!IsAvailableMatrix(text_matrix)) |
100 return TRUE; | 100 return true; |
101 | 101 |
102 FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); | 102 FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); |
103 if (bPattern) { | 103 if (bPattern) { |
104 DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, | 104 DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, |
105 &text_matrix, bFill, bStroke); | 105 &text_matrix, bFill, bStroke); |
106 return TRUE; | 106 return true; |
107 } | 107 } |
108 if (bClip || bStroke) { | 108 if (bClip || bStroke) { |
109 const CFX_Matrix* pDeviceMatrix = pObj2Device; | 109 const CFX_Matrix* pDeviceMatrix = pObj2Device; |
110 CFX_Matrix device_matrix; | 110 CFX_Matrix device_matrix; |
111 if (bStroke) { | 111 if (bStroke) { |
112 const FX_FLOAT* pCTM = textobj->m_TextState.GetCTM(); | 112 const FX_FLOAT* pCTM = textobj->m_TextState.GetCTM(); |
113 if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) { | 113 if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) { |
114 CFX_Matrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0); | 114 CFX_Matrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0); |
115 text_matrix.ConcatInverse(ctm); | 115 text_matrix.ConcatInverse(ctm); |
116 device_matrix = ctm; | 116 device_matrix = ctm; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 ~CPDF_RefType3Cache() { | 161 ~CPDF_RefType3Cache() { |
162 while (m_dwCount--) { | 162 while (m_dwCount--) { |
163 ReleaseCachedType3(m_pType3Font); | 163 ReleaseCachedType3(m_pType3Font); |
164 } | 164 } |
165 } | 165 } |
166 uint32_t m_dwCount; | 166 uint32_t m_dwCount; |
167 CPDF_Type3Font* const m_pType3Font; | 167 CPDF_Type3Font* const m_pType3Font; |
168 }; | 168 }; |
169 | 169 |
170 // TODO(npm): Font fallback for type 3 fonts? (Completely separate code!!) | 170 // TODO(npm): Font fallback for type 3 fonts? (Completely separate code!!) |
171 FX_BOOL CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, | 171 bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, |
172 const CFX_Matrix* pObj2Device) { | 172 const CFX_Matrix* pObj2Device) { |
173 CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->AsType3Font(); | 173 CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->AsType3Font(); |
174 for (int i = 0; i < m_Type3FontCache.GetSize(); ++i) { | 174 for (int i = 0; i < m_Type3FontCache.GetSize(); ++i) { |
175 if (m_Type3FontCache.GetAt(i) == pType3Font) | 175 if (m_Type3FontCache.GetAt(i) == pType3Font) |
176 return TRUE; | 176 return true; |
177 } | 177 } |
178 | 178 |
179 CFX_Matrix dCTM = m_pDevice->GetCTM(); | 179 CFX_Matrix dCTM = m_pDevice->GetCTM(); |
180 FX_FLOAT sa = FXSYS_fabs(dCTM.a); | 180 FX_FLOAT sa = FXSYS_fabs(dCTM.a); |
181 FX_FLOAT sd = FXSYS_fabs(dCTM.d); | 181 FX_FLOAT sd = FXSYS_fabs(dCTM.d); |
182 CFX_Matrix text_matrix; | 182 CFX_Matrix text_matrix; |
183 textobj->GetTextMatrix(&text_matrix); | 183 textobj->GetTextMatrix(&text_matrix); |
184 CFX_Matrix char_matrix = pType3Font->GetFontMatrix(); | 184 CFX_Matrix char_matrix = pType3Font->GetFontMatrix(); |
185 FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); | 185 FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); |
186 char_matrix.Scale(font_size, font_size); | 186 char_matrix.Scale(font_size, font_size); |
187 FX_ARGB fill_argb = GetFillArgb(textobj, TRUE); | 187 FX_ARGB fill_argb = GetFillArgb(textobj, true); |
188 int fill_alpha = FXARGB_A(fill_argb); | 188 int fill_alpha = FXARGB_A(fill_argb); |
189 int device_class = m_pDevice->GetDeviceClass(); | 189 int device_class = m_pDevice->GetDeviceClass(); |
190 std::vector<FXTEXT_GLYPHPOS> glyphs; | 190 std::vector<FXTEXT_GLYPHPOS> glyphs; |
191 if (device_class == FXDC_DISPLAY) | 191 if (device_class == FXDC_DISPLAY) |
192 glyphs.resize(textobj->m_nChars); | 192 glyphs.resize(textobj->m_nChars); |
193 else if (fill_alpha < 255) | 193 else if (fill_alpha < 255) |
194 return FALSE; | 194 return false; |
195 | 195 |
196 CPDF_RefType3Cache refTypeCache(pType3Font); | 196 CPDF_RefType3Cache refTypeCache(pType3Font); |
197 uint32_t* pChars = textobj->m_pCharCodes; | 197 uint32_t* pChars = textobj->m_pCharCodes; |
198 if (textobj->m_nChars == 1) | 198 if (textobj->m_nChars == 1) |
199 pChars = (uint32_t*)(&textobj->m_pCharCodes); | 199 pChars = (uint32_t*)(&textobj->m_pCharCodes); |
200 | 200 |
201 for (int iChar = 0; iChar < textobj->m_nChars; iChar++) { | 201 for (int iChar = 0; iChar < textobj->m_nChars; iChar++) { |
202 uint32_t charcode = pChars[iChar]; | 202 uint32_t charcode = pChars[iChar]; |
203 if (charcode == (uint32_t)-1) | 203 if (charcode == (uint32_t)-1) |
204 continue; | 204 continue; |
(...skipping 13 matching lines...) Expand all Loading... |
218 if (!glyph.m_pGlyph) | 218 if (!glyph.m_pGlyph) |
219 continue; | 219 continue; |
220 | 220 |
221 m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap, | 221 m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap, |
222 glyph.m_OriginX + glyph.m_pGlyph->m_Left, | 222 glyph.m_OriginX + glyph.m_pGlyph->m_Left, |
223 glyph.m_OriginY - glyph.m_pGlyph->m_Top, | 223 glyph.m_OriginY - glyph.m_pGlyph->m_Top, |
224 fill_argb); | 224 fill_argb); |
225 } | 225 } |
226 glyphs.clear(); | 226 glyphs.clear(); |
227 } | 227 } |
228 CPDF_GraphicStates* pStates = CloneObjStates(textobj, FALSE); | 228 CPDF_GraphicStates* pStates = CloneObjStates(textobj, false); |
229 CPDF_RenderOptions Options = m_Options; | 229 CPDF_RenderOptions Options = m_Options; |
230 Options.m_Flags |= RENDER_FORCE_HALFTONE | RENDER_RECT_AA; | 230 Options.m_Flags |= RENDER_FORCE_HALFTONE | RENDER_RECT_AA; |
231 Options.m_Flags &= ~RENDER_FORCE_DOWNSAMPLE; | 231 Options.m_Flags &= ~RENDER_FORCE_DOWNSAMPLE; |
232 CPDF_Dictionary* pFormResource = nullptr; | 232 CPDF_Dictionary* pFormResource = nullptr; |
233 if (pType3Char->m_pForm && pType3Char->m_pForm->m_pFormDict) { | 233 if (pType3Char->m_pForm && pType3Char->m_pForm->m_pFormDict) { |
234 pFormResource = | 234 pFormResource = |
235 pType3Char->m_pForm->m_pFormDict->GetDictFor("Resources"); | 235 pType3Char->m_pForm->m_pFormDict->GetDictFor("Resources"); |
236 } | 236 } |
237 if (fill_alpha == 255) { | 237 if (fill_alpha == 255) { |
238 CPDF_RenderStatus status; | 238 CPDF_RenderStatus status; |
239 status.Initialize(m_pContext, m_pDevice, nullptr, nullptr, this, | 239 status.Initialize(m_pContext, m_pDevice, nullptr, nullptr, this, |
240 pStates, &Options, | 240 pStates, &Options, |
241 pType3Char->m_pForm->m_Transparency, m_bDropObjects, | 241 pType3Char->m_pForm->m_Transparency, m_bDropObjects, |
242 pFormResource, FALSE, pType3Char, fill_argb); | 242 pFormResource, false, pType3Char, fill_argb); |
243 status.m_Type3FontCache.Append(m_Type3FontCache); | 243 status.m_Type3FontCache.Append(m_Type3FontCache); |
244 status.m_Type3FontCache.Add(pType3Font); | 244 status.m_Type3FontCache.Add(pType3Font); |
245 m_pDevice->SaveState(); | 245 m_pDevice->SaveState(); |
246 status.RenderObjectList(pType3Char->m_pForm.get(), &matrix); | 246 status.RenderObjectList(pType3Char->m_pForm.get(), &matrix); |
247 m_pDevice->RestoreState(false); | 247 m_pDevice->RestoreState(false); |
248 } else { | 248 } else { |
249 CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox(); | 249 CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox(); |
250 rect_f.Transform(&matrix); | 250 rect_f.Transform(&matrix); |
251 FX_RECT rect = rect_f.GetOuterRect(); | 251 FX_RECT rect = rect_f.GetOuterRect(); |
252 CFX_FxgeDevice bitmap_device; | 252 CFX_FxgeDevice bitmap_device; |
253 if (!bitmap_device.Create((int)(rect.Width() * sa), | 253 if (!bitmap_device.Create((int)(rect.Width() * sa), |
254 (int)(rect.Height() * sd), FXDIB_Argb, | 254 (int)(rect.Height() * sd), FXDIB_Argb, |
255 nullptr)) { | 255 nullptr)) { |
256 return TRUE; | 256 return true; |
257 } | 257 } |
258 bitmap_device.GetBitmap()->Clear(0); | 258 bitmap_device.GetBitmap()->Clear(0); |
259 CPDF_RenderStatus status; | 259 CPDF_RenderStatus status; |
260 status.Initialize(m_pContext, &bitmap_device, nullptr, nullptr, this, | 260 status.Initialize(m_pContext, &bitmap_device, nullptr, nullptr, this, |
261 pStates, &Options, | 261 pStates, &Options, |
262 pType3Char->m_pForm->m_Transparency, m_bDropObjects, | 262 pType3Char->m_pForm->m_Transparency, m_bDropObjects, |
263 pFormResource, FALSE, pType3Char, fill_argb); | 263 pFormResource, false, pType3Char, fill_argb); |
264 status.m_Type3FontCache.Append(m_Type3FontCache); | 264 status.m_Type3FontCache.Append(m_Type3FontCache); |
265 status.m_Type3FontCache.Add(pType3Font); | 265 status.m_Type3FontCache.Add(pType3Font); |
266 matrix.TranslateI(-rect.left, -rect.top); | 266 matrix.TranslateI(-rect.left, -rect.top); |
267 matrix.Scale(sa, sd); | 267 matrix.Scale(sa, sd); |
268 status.RenderObjectList(pType3Char->m_pForm.get(), &matrix); | 268 status.RenderObjectList(pType3Char->m_pForm.get(), &matrix); |
269 m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top); | 269 m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top); |
270 } | 270 } |
271 delete pStates; | 271 delete pStates; |
272 } else if (pType3Char->m_pBitmap) { | 272 } else if (pType3Char->m_pBitmap) { |
273 if (device_class == FXDC_DISPLAY) { | 273 if (device_class == FXDC_DISPLAY) { |
(...skipping 11 matching lines...) Expand all Loading... |
285 } else { | 285 } else { |
286 glyphs[iChar].m_pGlyph = pBitmap; | 286 glyphs[iChar].m_pGlyph = pBitmap; |
287 glyphs[iChar].m_OriginX = origin_x; | 287 glyphs[iChar].m_OriginX = origin_x; |
288 glyphs[iChar].m_OriginY = origin_y; | 288 glyphs[iChar].m_OriginY = origin_y; |
289 } | 289 } |
290 } else { | 290 } else { |
291 CFX_Matrix image_matrix = pType3Char->m_ImageMatrix; | 291 CFX_Matrix image_matrix = pType3Char->m_ImageMatrix; |
292 image_matrix.Concat(matrix); | 292 image_matrix.Concat(matrix); |
293 CPDF_ImageRenderer renderer; | 293 CPDF_ImageRenderer renderer; |
294 if (renderer.Start(this, pType3Char->m_pBitmap.get(), fill_argb, 255, | 294 if (renderer.Start(this, pType3Char->m_pBitmap.get(), fill_argb, 255, |
295 &image_matrix, 0, FALSE)) { | 295 &image_matrix, 0, false)) { |
296 renderer.Continue(nullptr); | 296 renderer.Continue(nullptr); |
297 } | 297 } |
298 if (!renderer.m_Result) | 298 if (!renderer.m_Result) |
299 return FALSE; | 299 return false; |
300 } | 300 } |
301 } | 301 } |
302 } | 302 } |
303 | 303 |
304 if (glyphs.empty()) | 304 if (glyphs.empty()) |
305 return TRUE; | 305 return true; |
306 | 306 |
307 FX_RECT rect = FXGE_GetGlyphsBBox(glyphs, 0, sa, sd); | 307 FX_RECT rect = FXGE_GetGlyphsBBox(glyphs, 0, sa, sd); |
308 CFX_DIBitmap bitmap; | 308 CFX_DIBitmap bitmap; |
309 if (!bitmap.Create(static_cast<int>(rect.Width() * sa), | 309 if (!bitmap.Create(static_cast<int>(rect.Width() * sa), |
310 static_cast<int>(rect.Height() * sd), FXDIB_8bppMask)) { | 310 static_cast<int>(rect.Height() * sd), FXDIB_8bppMask)) { |
311 return TRUE; | 311 return true; |
312 } | 312 } |
313 bitmap.Clear(0); | 313 bitmap.Clear(0); |
314 for (const FXTEXT_GLYPHPOS& glyph : glyphs) { | 314 for (const FXTEXT_GLYPHPOS& glyph : glyphs) { |
315 if (!glyph.m_pGlyph) | 315 if (!glyph.m_pGlyph) |
316 continue; | 316 continue; |
317 | 317 |
318 pdfium::base::CheckedNumeric<int> left = glyph.m_OriginX; | 318 pdfium::base::CheckedNumeric<int> left = glyph.m_OriginX; |
319 left += glyph.m_pGlyph->m_Left; | 319 left += glyph.m_pGlyph->m_Left; |
320 left -= rect.left; | 320 left -= rect.left; |
321 left *= sa; | 321 left *= sa; |
322 if (!left.IsValid()) | 322 if (!left.IsValid()) |
323 continue; | 323 continue; |
324 | 324 |
325 pdfium::base::CheckedNumeric<int> top = glyph.m_OriginY; | 325 pdfium::base::CheckedNumeric<int> top = glyph.m_OriginY; |
326 top -= glyph.m_pGlyph->m_Top; | 326 top -= glyph.m_pGlyph->m_Top; |
327 top -= rect.top; | 327 top -= rect.top; |
328 top *= sd; | 328 top *= sd; |
329 if (!top.IsValid()) | 329 if (!top.IsValid()) |
330 continue; | 330 continue; |
331 | 331 |
332 bitmap.CompositeMask(left.ValueOrDie(), top.ValueOrDie(), | 332 bitmap.CompositeMask(left.ValueOrDie(), top.ValueOrDie(), |
333 glyph.m_pGlyph->m_Bitmap.GetWidth(), | 333 glyph.m_pGlyph->m_Bitmap.GetWidth(), |
334 glyph.m_pGlyph->m_Bitmap.GetHeight(), | 334 glyph.m_pGlyph->m_Bitmap.GetHeight(), |
335 &glyph.m_pGlyph->m_Bitmap, fill_argb, 0, 0, | 335 &glyph.m_pGlyph->m_Bitmap, fill_argb, 0, 0, |
336 FXDIB_BLEND_NORMAL, nullptr, FALSE, 0, nullptr); | 336 FXDIB_BLEND_NORMAL, nullptr, false, 0, nullptr); |
337 } | 337 } |
338 m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb); | 338 m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb); |
339 return TRUE; | 339 return true; |
340 } | 340 } |
341 | 341 |
342 class CPDF_CharPosList { | 342 class CPDF_CharPosList { |
343 public: | 343 public: |
344 CPDF_CharPosList(); | 344 CPDF_CharPosList(); |
345 ~CPDF_CharPosList(); | 345 ~CPDF_CharPosList(); |
346 void Load(int nChars, | 346 void Load(int nChars, |
347 uint32_t* pCharCodes, | 347 uint32_t* pCharCodes, |
348 FX_FLOAT* pCharPos, | 348 FX_FLOAT* pCharPos, |
349 CPDF_Font* pFont, | 349 CPDF_Font* pFont, |
(...skipping 11 matching lines...) Expand all Loading... |
361 } | 361 } |
362 | 362 |
363 void CPDF_CharPosList::Load(int nChars, | 363 void CPDF_CharPosList::Load(int nChars, |
364 uint32_t* pCharCodes, | 364 uint32_t* pCharCodes, |
365 FX_FLOAT* pCharPos, | 365 FX_FLOAT* pCharPos, |
366 CPDF_Font* pFont, | 366 CPDF_Font* pFont, |
367 FX_FLOAT FontSize) { | 367 FX_FLOAT FontSize) { |
368 m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars); | 368 m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars); |
369 m_nChars = 0; | 369 m_nChars = 0; |
370 CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); | 370 CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); |
371 FX_BOOL bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); | 371 bool bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); |
372 for (int iChar = 0; iChar < nChars; iChar++) { | 372 for (int iChar = 0; iChar < nChars; iChar++) { |
373 uint32_t CharCode = | 373 uint32_t CharCode = |
374 nChars == 1 ? (uint32_t)(uintptr_t)pCharCodes : pCharCodes[iChar]; | 374 nChars == 1 ? (uint32_t)(uintptr_t)pCharCodes : pCharCodes[iChar]; |
375 if (CharCode == (uint32_t)-1) { | 375 if (CharCode == (uint32_t)-1) { |
376 continue; | 376 continue; |
377 } | 377 } |
378 bool bVert = false; | 378 bool bVert = false; |
379 FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; | 379 FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; |
380 if (pCIDFont) { | 380 if (pCIDFont) { |
381 charpos.m_bFontStyle = true; | 381 charpos.m_bFontStyle = true; |
(...skipping 11 matching lines...) Expand all Loading... |
393 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 393 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
394 charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); | 394 charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); |
395 #endif | 395 #endif |
396 if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) { | 396 if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) { |
397 charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); | 397 charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); |
398 } else { | 398 } else { |
399 charpos.m_FontCharWidth = 0; | 399 charpos.m_FontCharWidth = 0; |
400 } | 400 } |
401 charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0; | 401 charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0; |
402 charpos.m_OriginY = 0; | 402 charpos.m_OriginY = 0; |
403 charpos.m_bGlyphAdjust = FALSE; | 403 charpos.m_bGlyphAdjust = false; |
404 if (!pCIDFont) { | 404 if (!pCIDFont) { |
405 continue; | 405 continue; |
406 } | 406 } |
407 uint16_t CID = pCIDFont->CIDFromCharCode(CharCode); | 407 uint16_t CID = pCIDFont->CIDFromCharCode(CharCode); |
408 if (bVertWriting) { | 408 if (bVertWriting) { |
409 charpos.m_OriginY = charpos.m_OriginX; | 409 charpos.m_OriginY = charpos.m_OriginX; |
410 charpos.m_OriginX = 0; | 410 charpos.m_OriginX = 0; |
411 short vx, vy; | 411 short vx, vy; |
412 pCIDFont->GetVertOrigin(CID, vx, vy); | 412 pCIDFont->GetVertOrigin(CID, vx, vy); |
413 charpos.m_OriginX -= FontSize * vx / 1000; | 413 charpos.m_OriginX -= FontSize * vx / 1000; |
414 charpos.m_OriginY -= FontSize * vy / 1000; | 414 charpos.m_OriginY -= FontSize * vy / 1000; |
415 } | 415 } |
416 const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID); | 416 const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID); |
417 if (pTransform && !bVert) { | 417 if (pTransform && !bVert) { |
418 charpos.m_AdjustMatrix[0] = pCIDFont->CIDTransformToFloat(pTransform[0]); | 418 charpos.m_AdjustMatrix[0] = pCIDFont->CIDTransformToFloat(pTransform[0]); |
419 charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]); | 419 charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]); |
420 charpos.m_AdjustMatrix[1] = pCIDFont->CIDTransformToFloat(pTransform[1]); | 420 charpos.m_AdjustMatrix[1] = pCIDFont->CIDTransformToFloat(pTransform[1]); |
421 charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]); | 421 charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]); |
422 charpos.m_OriginX += | 422 charpos.m_OriginX += |
423 pCIDFont->CIDTransformToFloat(pTransform[4]) * FontSize; | 423 pCIDFont->CIDTransformToFloat(pTransform[4]) * FontSize; |
424 charpos.m_OriginY += | 424 charpos.m_OriginY += |
425 pCIDFont->CIDTransformToFloat(pTransform[5]) * FontSize; | 425 pCIDFont->CIDTransformToFloat(pTransform[5]) * FontSize; |
426 charpos.m_bGlyphAdjust = TRUE; | 426 charpos.m_bGlyphAdjust = true; |
427 } | 427 } |
428 } | 428 } |
429 } | 429 } |
430 | 430 |
431 // static | 431 // static |
432 FX_BOOL CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, | 432 bool CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, |
433 int nChars, | 433 int nChars, |
434 uint32_t* pCharCodes, | 434 uint32_t* pCharCodes, |
435 FX_FLOAT* pCharPos, | 435 FX_FLOAT* pCharPos, |
436 CPDF_Font* pFont, | 436 CPDF_Font* pFont, |
437 FX_FLOAT font_size, | 437 FX_FLOAT font_size, |
438 const CFX_Matrix* pText2User, | 438 const CFX_Matrix* pText2User, |
439 const CFX_Matrix* pUser2Device, | 439 const CFX_Matrix* pUser2Device, |
440 const CFX_GraphStateData* pGraphState, | 440 const CFX_GraphStateData* pGraphState, |
441 FX_ARGB fill_argb, | 441 FX_ARGB fill_argb, |
442 FX_ARGB stroke_argb, | 442 FX_ARGB stroke_argb, |
443 CFX_PathData* pClippingPath, | 443 CFX_PathData* pClippingPath, |
444 int nFlag) { | 444 int nFlag) { |
445 CPDF_CharPosList CharPosList; | 445 CPDF_CharPosList CharPosList; |
446 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); | 446 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); |
447 if (CharPosList.m_nChars == 0) | 447 if (CharPosList.m_nChars == 0) |
448 return TRUE; | 448 return true; |
449 bool bDraw = true; | 449 bool bDraw = true; |
450 int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition; | 450 int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition; |
451 uint32_t startIndex = 0; | 451 uint32_t startIndex = 0; |
452 for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { | 452 for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { |
453 int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition; | 453 int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition; |
454 if (fontPosition == curFontPosition) | 454 if (fontPosition == curFontPosition) |
455 continue; | 455 continue; |
456 auto* font = fontPosition == -1 | 456 auto* font = fontPosition == -1 |
457 ? &pFont->m_Font | 457 ? &pFont->m_Font |
458 : pFont->m_FontFallbacks[fontPosition].get(); | 458 : pFont->m_FontFallbacks[fontPosition].get(); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, | 528 DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, |
529 &matrix, fill_argb, pOptions); | 529 &matrix, fill_argb, pOptions); |
530 } else { | 530 } else { |
531 DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, | 531 DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, |
532 &matrix, nullptr, pGraphState, fill_argb, stroke_argb, nullptr, | 532 &matrix, nullptr, pGraphState, fill_argb, stroke_argb, nullptr, |
533 0); | 533 0); |
534 } | 534 } |
535 } | 535 } |
536 | 536 |
537 // static | 537 // static |
538 FX_BOOL CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, | 538 bool CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, |
539 int nChars, | 539 int nChars, |
540 uint32_t* pCharCodes, | 540 uint32_t* pCharCodes, |
541 FX_FLOAT* pCharPos, | 541 FX_FLOAT* pCharPos, |
542 CPDF_Font* pFont, | 542 CPDF_Font* pFont, |
543 FX_FLOAT font_size, | 543 FX_FLOAT font_size, |
544 const CFX_Matrix* pText2Device, | 544 const CFX_Matrix* pText2Device, |
545 FX_ARGB fill_argb, | 545 FX_ARGB fill_argb, |
546 const CPDF_RenderOptions* pOptions) { | 546 const CPDF_RenderOptions* pOptions) { |
547 CPDF_CharPosList CharPosList; | 547 CPDF_CharPosList CharPosList; |
548 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); | 548 CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); |
549 if (CharPosList.m_nChars == 0) | 549 if (CharPosList.m_nChars == 0) |
550 return TRUE; | 550 return true; |
551 int FXGE_flags = 0; | 551 int FXGE_flags = 0; |
552 if (pOptions) { | 552 if (pOptions) { |
553 uint32_t dwFlags = pOptions->m_Flags; | 553 uint32_t dwFlags = pOptions->m_Flags; |
554 if (dwFlags & RENDER_CLEARTYPE) { | 554 if (dwFlags & RENDER_CLEARTYPE) { |
555 FXGE_flags |= FXTEXT_CLEARTYPE; | 555 FXGE_flags |= FXTEXT_CLEARTYPE; |
556 if (dwFlags & RENDER_BGR_STRIPE) { | 556 if (dwFlags & RENDER_BGR_STRIPE) { |
557 FXGE_flags |= FXTEXT_BGR_STRIPE; | 557 FXGE_flags |= FXTEXT_BGR_STRIPE; |
558 } | 558 } |
559 } | 559 } |
560 if (dwFlags & RENDER_NOTEXTSMOOTH) { | 560 if (dwFlags & RENDER_NOTEXTSMOOTH) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 bDraw = false; | 602 bDraw = false; |
603 } | 603 } |
604 return bDraw; | 604 return bDraw; |
605 } | 605 } |
606 | 606 |
607 void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, | 607 void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, |
608 const CFX_Matrix* pObj2Device, | 608 const CFX_Matrix* pObj2Device, |
609 CPDF_Font* pFont, | 609 CPDF_Font* pFont, |
610 FX_FLOAT font_size, | 610 FX_FLOAT font_size, |
611 const CFX_Matrix* pTextMatrix, | 611 const CFX_Matrix* pTextMatrix, |
612 FX_BOOL bFill, | 612 bool bFill, |
613 FX_BOOL bStroke) { | 613 bool bStroke) { |
614 if (!bStroke) { | 614 if (!bStroke) { |
615 CPDF_PathObject path; | 615 CPDF_PathObject path; |
616 std::vector<std::unique_ptr<CPDF_TextObject>> pCopy; | 616 std::vector<std::unique_ptr<CPDF_TextObject>> pCopy; |
617 pCopy.push_back(std::unique_ptr<CPDF_TextObject>(textobj->Clone())); | 617 pCopy.push_back(std::unique_ptr<CPDF_TextObject>(textobj->Clone())); |
618 path.m_bStroke = FALSE; | 618 path.m_bStroke = false; |
619 path.m_FillType = FXFILL_WINDING; | 619 path.m_FillType = FXFILL_WINDING; |
620 path.m_ClipPath.AppendTexts(&pCopy); | 620 path.m_ClipPath.AppendTexts(&pCopy); |
621 path.m_ColorState = textobj->m_ColorState; | 621 path.m_ColorState = textobj->m_ColorState; |
622 path.m_Path.AppendRect(textobj->m_Left, textobj->m_Bottom, textobj->m_Right, | 622 path.m_Path.AppendRect(textobj->m_Left, textobj->m_Bottom, textobj->m_Right, |
623 textobj->m_Top); | 623 textobj->m_Top); |
624 path.m_Left = textobj->m_Left; | 624 path.m_Left = textobj->m_Left; |
625 path.m_Bottom = textobj->m_Bottom; | 625 path.m_Bottom = textobj->m_Bottom; |
626 path.m_Right = textobj->m_Right; | 626 path.m_Right = textobj->m_Right; |
627 path.m_Top = textobj->m_Top; | 627 path.m_Top = textobj->m_Top; |
628 RenderSingleObject(&path, pObj2Device); | 628 RenderSingleObject(&path, pObj2Device); |
(...skipping 23 matching lines...) Expand all Loading... |
652 matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, | 652 matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, |
653 charpos.m_OriginY); | 653 charpos.m_OriginY); |
654 path.m_Path.Append(pPath, &matrix); | 654 path.m_Path.Append(pPath, &matrix); |
655 path.m_Matrix = *pTextMatrix; | 655 path.m_Matrix = *pTextMatrix; |
656 path.m_bStroke = bStroke; | 656 path.m_bStroke = bStroke; |
657 path.m_FillType = bFill ? FXFILL_WINDING : 0; | 657 path.m_FillType = bFill ? FXFILL_WINDING : 0; |
658 path.CalcBoundingBox(); | 658 path.CalcBoundingBox(); |
659 ProcessPath(&path, pObj2Device); | 659 ProcessPath(&path, pObj2Device); |
660 } | 660 } |
661 } | 661 } |
OLD | NEW |