| 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 |