Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: core/fpdfapi/fpdf_font/fpdf_font.cpp

Issue 1824033002: Split core/include/fpdfapi/fpdf_resource.h (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fpdfapi/fpdf_font/font_int.h ('k') | core/fpdfapi/fpdf_font/fpdf_font_charset.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/fpdf_font/font_int.h" 7 #include "core/fpdfapi/fpdf_font/font_int.h"
8 8
9 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" 9 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
10 #include "core/fpdfapi/fpdf_page/pageint.h" 10 #include "core/fpdfapi/fpdf_page/pageint.h"
11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" 11 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
14 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h"
15 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h"
16 #include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h" 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
17 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
17 #include "core/fpdfapi/include/cpdf_modulemgr.h" 18 #include "core/fpdfapi/include/cpdf_modulemgr.h"
18 #include "core/fxcrt/include/fx_ext.h" 19 #include "core/fxcrt/include/fx_ext.h"
19 #include "core/include/fpdfapi/fpdf_resource.h"
20 #include "core/include/fxge/fx_freetype.h" 20 #include "core/include/fxge/fx_freetype.h"
21 #include "third_party/base/stl_util.h" 21 #include "third_party/base/stl_util.h"
22 22
23 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
24 #include "core/fxge/apple/apple_int.h"
25 #endif
26
27 namespace {
28
29 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
30 struct GlyphNameMap {
31 const FX_CHAR* m_pStrAdobe;
32 const FX_CHAR* m_pStrUnicode;
33 };
34
35 const GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"},
36 {"fi", "uniFB01"},
37 {"fl", "uniFB02"},
38 {"ffi", "uniFB03"},
39 {"ffl", "uniFB04"}};
40
41 int compareString(const void* key, const void* element) {
42 return FXSYS_stricmp((const FX_CHAR*)key,
43 ((GlyphNameMap*)element)->m_pStrAdobe);
44 }
45
46 const FX_CHAR* GlyphNameRemap(const FX_CHAR* pStrAdobe) {
47 GlyphNameMap* found = (GlyphNameMap*)FXSYS_bsearch(
48 pStrAdobe, g_GlyphNameSubsts,
49 sizeof(g_GlyphNameSubsts) / sizeof(GlyphNameMap), sizeof(GlyphNameMap),
50 compareString);
51 if (found)
52 return found->m_pStrUnicode;
53 return NULL;
54 }
55 #endif
56
57 const uint8_t ChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00},
58 {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
59 {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
60 {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
61 {0xD0, 0xC2, 0xCB, 0xCE, 0x00}};
62
63 FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) {
64 if (value == "WinAnsiEncoding") {
65 basemap = PDFFONT_ENCODING_WINANSI;
66 } else if (value == "MacRomanEncoding") {
67 basemap = PDFFONT_ENCODING_MACROMAN;
68 } else if (value == "MacExpertEncoding") {
69 basemap = PDFFONT_ENCODING_MACEXPERT;
70 } else if (value == "PDFDocEncoding") {
71 basemap = PDFFONT_ENCODING_PDFDOC;
72 } else {
73 return FALSE;
74 }
75 return TRUE;
76 }
77
78 FX_BOOL FT_UseType1Charmap(FXFT_Face face) {
79 if (FXFT_Get_Face_CharmapCount(face) == 0) {
80 return FALSE;
81 }
82 if (FXFT_Get_Face_CharmapCount(face) == 1 &&
83 FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
84 FXFT_ENCODING_UNICODE) {
85 return FALSE;
86 }
87 if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
88 FXFT_ENCODING_UNICODE) {
89 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);
90 } else {
91 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
92 }
93 return TRUE;
94 }
95
96 } // namespace
97
98 FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) { 23 FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) {
99 for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) { 24 for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
100 if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) == 25 if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) ==
101 platform_id && 26 platform_id &&
102 FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) == 27 FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) ==
103 encoding_id) { 28 encoding_id) {
104 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]); 29 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
105 return TRUE; 30 return TRUE;
106 } 31 }
107 } 32 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 void CPDF_FontGlobals::Set(CPDF_Document* pDoc, int index, CPDF_Font* pFont) { 74 void CPDF_FontGlobals::Set(CPDF_Document* pDoc, int index, CPDF_Font* pFont) {
150 if (!pdfium::ContainsKey(m_StockMap, pDoc)) 75 if (!pdfium::ContainsKey(m_StockMap, pDoc))
151 m_StockMap[pDoc].reset(new CFX_StockFontArray); 76 m_StockMap[pDoc].reset(new CFX_StockFontArray);
152 m_StockMap[pDoc]->SetFont(index, pFont); 77 m_StockMap[pDoc]->SetFont(index, pFont);
153 } 78 }
154 79
155 void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) { 80 void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) {
156 m_StockMap.erase(pDoc); 81 m_StockMap.erase(pDoc);
157 } 82 }
158 83
159 CPDF_Font::CPDF_Font()
160 : m_pFontFile(nullptr),
161 m_pFontDict(nullptr),
162 m_pToUnicodeMap(nullptr),
163 m_bToUnicodeLoaded(FALSE),
164 m_Flags(0),
165 m_StemV(0),
166 m_Ascent(0),
167 m_Descent(0),
168 m_ItalicAngle(0) {}
169 84
170 CPDF_Font::~CPDF_Font() {
171 delete m_pToUnicodeMap;
172 m_pToUnicodeMap = NULL;
173
174 if (m_pFontFile) {
175 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
176 const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
177 }
178 }
179
180 bool CPDF_Font::IsType1Font() const {
181 return false;
182 }
183
184 bool CPDF_Font::IsTrueTypeFont() const {
185 return false;
186 }
187
188 bool CPDF_Font::IsType3Font() const {
189 return false;
190 }
191
192 bool CPDF_Font::IsCIDFont() const {
193 return false;
194 }
195
196 const CPDF_Type1Font* CPDF_Font::AsType1Font() const {
197 return nullptr;
198 }
199
200 CPDF_Type1Font* CPDF_Font::AsType1Font() {
201 return nullptr;
202 }
203
204 const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const {
205 return nullptr;
206 }
207
208 CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() {
209 return nullptr;
210 }
211
212 const CPDF_Type3Font* CPDF_Font::AsType3Font() const {
213 return nullptr;
214 }
215
216 CPDF_Type3Font* CPDF_Font::AsType3Font() {
217 return nullptr;
218 }
219
220 const CPDF_CIDFont* CPDF_Font::AsCIDFont() const {
221 return nullptr;
222 }
223
224 CPDF_CIDFont* CPDF_Font::AsCIDFont() {
225 return nullptr;
226 }
227
228 FX_BOOL CPDF_Font::IsUnicodeCompatible() const {
229 return FALSE;
230 }
231
232 int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const {
233 return size;
234 }
235
236 int CPDF_Font::GetCharSize(FX_DWORD charcode) const {
237 return 1;
238 }
239
240 int CPDF_Font::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
241 ASSERT(false);
242 return 0;
243 }
244
245 int CPDF_Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
246 return GlyphFromCharCode(charcode);
247 }
248
249 FX_BOOL CPDF_Font::IsVertWriting() const {
250 FX_BOOL bVertWriting = FALSE;
251 const CPDF_CIDFont* pCIDFont = AsCIDFont();
252 if (pCIDFont) {
253 bVertWriting = pCIDFont->IsVertWriting();
254 } else {
255 bVertWriting = m_Font.IsVertical();
256 }
257 return bVertWriting;
258 }
259
260 int CPDF_Font::AppendChar(FX_CHAR* buf, FX_DWORD charcode) const {
261 *buf = (FX_CHAR)charcode;
262 return 1;
263 }
264
265 void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const {
266 char buf[4];
267 int len = AppendChar(buf, charcode);
268 if (len == 1) {
269 str += buf[0];
270 } else {
271 str += CFX_ByteString(buf, len);
272 }
273 }
274
275 CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const {
276 if (!m_bToUnicodeLoaded)
277 ((CPDF_Font*)this)->LoadUnicodeMap();
278
279 if (m_pToUnicodeMap)
280 return m_pToUnicodeMap->Lookup(charcode);
281 return CFX_WideString();
282 }
283
284 FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
285 if (!m_bToUnicodeLoaded)
286 ((CPDF_Font*)this)->LoadUnicodeMap();
287
288 if (m_pToUnicodeMap)
289 return m_pToUnicodeMap->ReverseLookup(unicode);
290 return 0;
291 }
292
293 void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
294 m_Flags = pFontDesc->GetIntegerBy("Flags", PDFFONT_NONSYMBOLIC);
295 int ItalicAngle = 0;
296 FX_BOOL bExistItalicAngle = FALSE;
297 if (pFontDesc->KeyExist("ItalicAngle")) {
298 ItalicAngle = pFontDesc->GetIntegerBy("ItalicAngle");
299 bExistItalicAngle = TRUE;
300 }
301 if (ItalicAngle < 0) {
302 m_Flags |= PDFFONT_ITALIC;
303 m_ItalicAngle = ItalicAngle;
304 }
305 FX_BOOL bExistStemV = FALSE;
306 if (pFontDesc->KeyExist("StemV")) {
307 m_StemV = pFontDesc->GetIntegerBy("StemV");
308 bExistStemV = TRUE;
309 }
310 FX_BOOL bExistAscent = FALSE;
311 if (pFontDesc->KeyExist("Ascent")) {
312 m_Ascent = pFontDesc->GetIntegerBy("Ascent");
313 bExistAscent = TRUE;
314 }
315 FX_BOOL bExistDescent = FALSE;
316 if (pFontDesc->KeyExist("Descent")) {
317 m_Descent = pFontDesc->GetIntegerBy("Descent");
318 bExistDescent = TRUE;
319 }
320 FX_BOOL bExistCapHeight = FALSE;
321 if (pFontDesc->KeyExist("CapHeight")) {
322 bExistCapHeight = TRUE;
323 }
324 if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
325 bExistStemV) {
326 m_Flags |= PDFFONT_USEEXTERNATTR;
327 }
328 if (m_Descent > 10) {
329 m_Descent = -m_Descent;
330 }
331 CPDF_Array* pBBox = pFontDesc->GetArrayBy("FontBBox");
332 if (pBBox) {
333 m_FontBBox.left = pBBox->GetIntegerAt(0);
334 m_FontBBox.bottom = pBBox->GetIntegerAt(1);
335 m_FontBBox.right = pBBox->GetIntegerAt(2);
336 m_FontBBox.top = pBBox->GetIntegerAt(3);
337 }
338
339 CPDF_Stream* pFontFile = pFontDesc->GetStreamBy("FontFile");
340 if (!pFontFile)
341 pFontFile = pFontDesc->GetStreamBy("FontFile2");
342 if (!pFontFile)
343 pFontFile = pFontDesc->GetStreamBy("FontFile3");
344 if (!pFontFile)
345 return;
346
347 m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
348 if (!m_pFontFile)
349 return;
350
351 const uint8_t* pFontData = m_pFontFile->GetData();
352 FX_DWORD dwFontSize = m_pFontFile->GetSize();
353 if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
354 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
355 const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
356 m_pFontFile = nullptr;
357 }
358 }
359 85
360 short TT2PDF(int m, FXFT_Face face) { 86 short TT2PDF(int m, FXFT_Face face) {
361 int upm = FXFT_Get_Face_UnitsPerEM(face); 87 int upm = FXFT_Get_Face_UnitsPerEM(face);
362 if (upm == 0) { 88 if (upm == 0)
363 return (short)m; 89 return (short)m;
364 }
365 return (m * 1000 + upm / 2) / upm; 90 return (m * 1000 + upm / 2) / upm;
366 } 91 }
367 92
368 void CPDF_Font::CheckFontMetrics() {
369 if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
370 m_FontBBox.right == 0) {
371 FXFT_Face face = m_Font.GetFace();
372 if (face) {
373 m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face);
374 m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face);
375 m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face);
376 m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face);
377 m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face);
378 m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face);
379 } else {
380 FX_BOOL bFirst = TRUE;
381 for (int i = 0; i < 256; i++) {
382 FX_RECT rect = GetCharBBox(i);
383 if (rect.left == rect.right) {
384 continue;
385 }
386 if (bFirst) {
387 m_FontBBox = rect;
388 bFirst = FALSE;
389 } else {
390 if (m_FontBBox.top < rect.top) {
391 m_FontBBox.top = rect.top;
392 }
393 if (m_FontBBox.right < rect.right) {
394 m_FontBBox.right = rect.right;
395 }
396 if (m_FontBBox.left > rect.left) {
397 m_FontBBox.left = rect.left;
398 }
399 if (m_FontBBox.bottom > rect.bottom) {
400 m_FontBBox.bottom = rect.bottom;
401 }
402 }
403 }
404 }
405 }
406 if (m_Ascent == 0 && m_Descent == 0) {
407 FX_RECT rect = GetCharBBox('A');
408 m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top;
409 rect = GetCharBBox('g');
410 m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom;
411 }
412 }
413
414 void CPDF_Font::LoadUnicodeMap() {
415 m_bToUnicodeLoaded = TRUE;
416 CPDF_Stream* pStream = m_pFontDict->GetStreamBy("ToUnicode");
417 if (!pStream) {
418 return;
419 }
420 m_pToUnicodeMap = new CPDF_ToUnicodeMap;
421 m_pToUnicodeMap->Load(pStream);
422 }
423
424 int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) {
425 int offset = 0;
426 int width = 0;
427 while (offset < size) {
428 FX_DWORD charcode = GetNextChar(pString, size, offset);
429 width += GetCharWidthF(charcode);
430 }
431 return width;
432 }
433
434 CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc,
435 const CFX_ByteStringC& name) {
436 CFX_ByteString fontname(name);
437 int font_id = PDF_GetStandardFontName(&fontname);
438 if (font_id < 0) {
439 return nullptr;
440 }
441 CPDF_FontGlobals* pFontGlobals =
442 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
443 CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
444 if (pFont) {
445 return pFont;
446 }
447 CPDF_Dictionary* pDict = new CPDF_Dictionary;
448 pDict->SetAtName("Type", "Font");
449 pDict->SetAtName("Subtype", "Type1");
450 pDict->SetAtName("BaseFont", fontname);
451 pDict->SetAtName("Encoding", "WinAnsiEncoding");
452 pFont = CPDF_Font::CreateFontF(NULL, pDict);
453 pFontGlobals->Set(pDoc, font_id, pFont);
454 return pFont;
455 }
456
457 CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc,
458 CPDF_Dictionary* pFontDict) {
459 CFX_ByteString type = pFontDict->GetStringBy("Subtype");
460 CPDF_Font* pFont;
461 if (type == "TrueType") {
462 {
463 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
464 _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \
465 _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \
466 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
467 CFX_ByteString basefont = pFontDict->GetStringBy("BaseFont");
468 CFX_ByteString tag = basefont.Left(4);
469 int i;
470 int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
471 for (i = 0; i < count; ++i) {
472 if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) {
473 break;
474 }
475 }
476 if (i < count) {
477 CPDF_Dictionary* pFontDesc = pFontDict->GetDictBy("FontDescriptor");
478 if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) {
479 pFont = new CPDF_CIDFont;
480 pFont->m_pFontDict = pFontDict;
481 pFont->m_pDocument = pDoc;
482 pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
483 if (!pFont->Load()) {
484 delete pFont;
485 return NULL;
486 }
487 return pFont;
488 }
489 }
490 #endif
491 }
492 pFont = new CPDF_TrueTypeFont;
493 } else if (type == "Type3") {
494 pFont = new CPDF_Type3Font;
495 } else if (type == "Type0") {
496 pFont = new CPDF_CIDFont;
497 } else {
498 pFont = new CPDF_Type1Font;
499 }
500 pFont->m_pFontDict = pFontDict;
501 pFont->m_pDocument = pDoc;
502 pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont");
503 if (!pFont->Load()) {
504 delete pFont;
505 return NULL;
506 }
507 return pFont;
508 }
509 93
510 CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) { 94 CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) {
511 auto it = m_Map.find(charcode); 95 auto it = m_Map.find(charcode);
512 if (it != m_Map.end()) { 96 if (it != m_Map.end()) {
513 FX_DWORD value = it->second; 97 FX_DWORD value = it->second;
514 FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff); 98 FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff);
515 if (unicode != 0xffff) { 99 if (unicode != 0xffff) {
516 return unicode; 100 return unicode;
517 } 101 }
518 const FX_WCHAR* buf = m_MultiCharBuf.GetBuffer(); 102 const FX_WCHAR* buf = m_MultiCharBuf.GetBuffer();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 } 293 }
710 if (cid_set) { 294 if (cid_set) {
711 m_pBaseMap = CPDF_ModuleMgr::Get() 295 m_pBaseMap = CPDF_ModuleMgr::Get()
712 ->GetPageModule() 296 ->GetPageModule()
713 ->GetFontGlobals() 297 ->GetFontGlobals()
714 ->m_CMapManager.GetCID2UnicodeMap(cid_set, FALSE); 298 ->m_CMapManager.GetCID2UnicodeMap(cid_set, FALSE);
715 } else { 299 } else {
716 m_pBaseMap = NULL; 300 m_pBaseMap = NULL;
717 } 301 }
718 } 302 }
719
720 FX_DWORD CPDF_Font::GetNextChar(const FX_CHAR* pString,
721 int nStrLen,
722 int& offset) const {
723 if (offset < 0 || nStrLen < 1) {
724 return 0;
725 }
726 uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1];
727 return static_cast<FX_DWORD>(ch);
728 }
729
730 void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
731 int& iBaseEncoding,
732 CFX_ByteString*& pCharNames,
733 FX_BOOL bEmbedded,
734 FX_BOOL bTrueType) {
735 if (!pEncoding) {
736 if (m_BaseFont == "Symbol") {
737 iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL
738 : PDFFONT_ENCODING_ADOBE_SYMBOL;
739 } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
740 iBaseEncoding = PDFFONT_ENCODING_WINANSI;
741 }
742 return;
743 }
744 if (pEncoding->IsName()) {
745 if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL ||
746 iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
747 return;
748 }
749 if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") {
750 if (!bTrueType) {
751 iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
752 }
753 return;
754 }
755 CFX_ByteString bsEncoding = pEncoding->GetString();
756 if (bsEncoding.Compare("MacExpertEncoding") == 0) {
757 bsEncoding = "WinAnsiEncoding";
758 }
759 GetPredefinedEncoding(iBaseEncoding, bsEncoding);
760 return;
761 }
762
763 CPDF_Dictionary* pDict = pEncoding->AsDictionary();
764 if (!pDict)
765 return;
766
767 if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
768 iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
769 CFX_ByteString bsEncoding = pDict->GetStringBy("BaseEncoding");
770 if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
771 bsEncoding = "WinAnsiEncoding";
772 }
773 GetPredefinedEncoding(iBaseEncoding, bsEncoding);
774 }
775 if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
776 iBaseEncoding = PDFFONT_ENCODING_STANDARD;
777 }
778 CPDF_Array* pDiffs = pDict->GetArrayBy("Differences");
779 if (!pDiffs) {
780 return;
781 }
782 pCharNames = new CFX_ByteString[256];
783 FX_DWORD cur_code = 0;
784 for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) {
785 CPDF_Object* pElement = pDiffs->GetElementValue(i);
786 if (!pElement)
787 continue;
788
789 if (CPDF_Name* pName = pElement->AsName()) {
790 if (cur_code < 256)
791 pCharNames[cur_code] = pName->GetString();
792 cur_code++;
793 } else {
794 cur_code = pElement->GetInteger();
795 }
796 }
797 }
798
799 FX_BOOL CPDF_Font::IsStandardFont() const {
800 if (!IsType1Font())
801 return FALSE;
802 if (m_pFontFile)
803 return FALSE;
804 if (AsType1Font()->GetBase14Font() < 0)
805 return FALSE;
806 return TRUE;
807 }
808
809 CPDF_SimpleFont::CPDF_SimpleFont()
810 : m_pCharNames(nullptr), m_BaseEncoding(PDFFONT_ENCODING_BUILTIN) {
811 FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth);
812 FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
813 FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID);
814 }
815
816 CPDF_SimpleFont::~CPDF_SimpleFont() {
817 delete[] m_pCharNames;
818 }
819
820 int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
821 if (pVertGlyph) {
822 *pVertGlyph = FALSE;
823 }
824 if (charcode > 0xff) {
825 return -1;
826 }
827 int index = m_GlyphIndex[(uint8_t)charcode];
828 if (index == 0xffff) {
829 return -1;
830 }
831 return index;
832 }
833
834 void CPDF_SimpleFont::LoadCharMetrics(int charcode) {
835 if (!m_Font.GetFace())
836 return;
837
838 if (charcode < 0 || charcode > 0xff) {
839 return;
840 }
841 int glyph_index = m_GlyphIndex[charcode];
842 if (glyph_index == 0xffff) {
843 if (!m_pFontFile && charcode != 32) {
844 LoadCharMetrics(32);
845 m_CharBBox[charcode] = m_CharBBox[32];
846 if (m_bUseFontWidth) {
847 m_CharWidth[charcode] = m_CharWidth[32];
848 }
849 }
850 return;
851 }
852 FXFT_Face face = m_Font.GetFace();
853 int err = FXFT_Load_Glyph(
854 face, glyph_index,
855 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
856 if (err) {
857 return;
858 }
859 m_CharBBox[charcode] = FX_SMALL_RECT(
860 TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face),
861 TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face),
862 TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face),
863 face),
864 TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face),
865 face));
866
867 if (m_bUseFontWidth) {
868 int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face);
869 if (m_CharWidth[charcode] == 0xffff) {
870 m_CharWidth[charcode] = TT_Width;
871 } else if (TT_Width && !IsEmbedded()) {
872 m_CharBBox[charcode].right =
873 m_CharBBox[charcode].right * m_CharWidth[charcode] / TT_Width;
874 m_CharBBox[charcode].left =
875 m_CharBBox[charcode].left * m_CharWidth[charcode] / TT_Width;
876 }
877 }
878 }
879
880 int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) {
881 if (charcode > 0xff) {
882 charcode = 0;
883 }
884 if (m_CharWidth[charcode] == 0xffff) {
885 LoadCharMetrics(charcode);
886 if (m_CharWidth[charcode] == 0xffff) {
887 m_CharWidth[charcode] = 0;
888 }
889 }
890 return (int16_t)m_CharWidth[charcode];
891 }
892
893 FX_RECT CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, int level) {
894 if (charcode > 0xff)
895 charcode = 0;
896
897 if (m_CharBBox[charcode].left == FX_SMALL_RECT::kInvalid)
898 LoadCharMetrics(charcode);
899
900 return FX_RECT(m_CharBBox[charcode]);
901 }
902
903 const FX_CHAR* GetAdobeCharName(int iBaseEncoding,
904 const CFX_ByteString* pCharNames,
905 int charcode) {
906 ASSERT(charcode >= 0 && charcode < 256);
907 if (charcode < 0 || charcode >= 256) {
908 return NULL;
909 }
910 const FX_CHAR* name = NULL;
911 if (pCharNames) {
912 name = pCharNames[charcode];
913 }
914 if ((!name || name[0] == 0) && iBaseEncoding) {
915 name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
916 }
917 return name && name[0] ? name : nullptr;
918 }
919
920 FX_BOOL CPDF_SimpleFont::LoadCommon() {
921 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
922 if (pFontDesc) {
923 LoadFontDescriptor(pFontDesc);
924 }
925 CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
926 int width_start = 0, width_end = -1;
927 m_bUseFontWidth = TRUE;
928 if (pWidthArray) {
929 m_bUseFontWidth = FALSE;
930 if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) {
931 int MissingWidth = pFontDesc->GetIntegerBy("MissingWidth");
932 for (int i = 0; i < 256; i++) {
933 m_CharWidth[i] = MissingWidth;
934 }
935 }
936 width_start = m_pFontDict->GetIntegerBy("FirstChar", 0);
937 width_end = m_pFontDict->GetIntegerBy("LastChar", 0);
938 if (width_start >= 0 && width_start <= 255) {
939 if (width_end <= 0 ||
940 width_end >= width_start + (int)pWidthArray->GetCount()) {
941 width_end = width_start + pWidthArray->GetCount() - 1;
942 }
943 if (width_end > 255) {
944 width_end = 255;
945 }
946 for (int i = width_start; i <= width_end; i++) {
947 m_CharWidth[i] = pWidthArray->GetIntegerAt(i - width_start);
948 }
949 }
950 }
951 if (m_pFontFile) {
952 if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') {
953 m_BaseFont = m_BaseFont.Mid(8);
954 }
955 } else {
956 LoadSubstFont();
957 }
958 if (!(m_Flags & PDFFONT_SYMBOLIC)) {
959 m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
960 }
961 CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
962 LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL,
963 m_Font.IsTTFont());
964 LoadGlyphMap();
965 delete[] m_pCharNames;
966 m_pCharNames = NULL;
967 if (!m_Font.GetFace())
968 return TRUE;
969
970 if (m_Flags & PDFFONT_ALLCAP) {
971 unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
972 for (size_t range = 0; range < sizeof lowercases / 2; range++) {
973 for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i++) {
974 if (m_GlyphIndex[i] != 0xffff && m_pFontFile) {
975 continue;
976 }
977 m_GlyphIndex[i] = m_GlyphIndex[i - 32];
978 if (m_CharWidth[i - 32]) {
979 m_CharWidth[i] = m_CharWidth[i - 32];
980 m_CharBBox[i] = m_CharBBox[i - 32];
981 }
982 }
983 }
984 }
985 CheckFontMetrics();
986 return TRUE;
987 }
988
989 void CPDF_SimpleFont::LoadSubstFont() {
990 if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) {
991 int width = 0, i;
992 for (i = 0; i < 256; i++) {
993 if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) {
994 continue;
995 }
996 if (width == 0) {
997 width = m_CharWidth[i];
998 } else if (width != m_CharWidth[i]) {
999 break;
1000 }
1001 }
1002 if (i == 256 && width) {
1003 m_Flags |= PDFFONT_FIXEDPITCH;
1004 }
1005 }
1006 int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
1007 m_Font.LoadSubst(m_BaseFont, IsTrueTypeFont(), m_Flags, weight, m_ItalicAngle,
1008 0);
1009 if (m_Font.GetSubstFont()->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
1010 }
1011 }
1012
1013 FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const {
1014 return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN &&
1015 m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
1016 m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS;
1017 }
1018
1019 CFX_WideString CPDF_SimpleFont::UnicodeFromCharCode(FX_DWORD charcode) const {
1020 CFX_WideString unicode = CPDF_Font::UnicodeFromCharCode(charcode);
1021 if (!unicode.IsEmpty())
1022 return unicode;
1023 FX_WCHAR ret = m_Encoding.UnicodeFromCharCode((uint8_t)charcode);
1024 if (ret == 0)
1025 return CFX_WideString();
1026 return ret;
1027 }
1028
1029 FX_DWORD CPDF_SimpleFont::CharCodeFromUnicode(FX_WCHAR unicode) const {
1030 FX_DWORD ret = CPDF_Font::CharCodeFromUnicode(unicode);
1031 if (ret)
1032 return ret;
1033 return m_Encoding.CharCodeFromUnicode(unicode);
1034 }
1035
1036 CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {}
1037
1038 bool CPDF_Type1Font::IsType1Font() const {
1039 return true;
1040 }
1041
1042 const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const {
1043 return this;
1044 }
1045
1046 CPDF_Type1Font* CPDF_Type1Font::AsType1Font() {
1047 return this;
1048 }
1049
1050 FX_BOOL CPDF_Type1Font::Load() {
1051 m_Base14Font = PDF_GetStandardFontName(&m_BaseFont);
1052 if (m_Base14Font >= 0) {
1053 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor");
1054 if (pFontDesc && pFontDesc->KeyExist("Flags"))
1055 m_Flags = pFontDesc->GetIntegerBy("Flags");
1056 else
1057 m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC;
1058
1059 if (m_Base14Font < 4) {
1060 for (int i = 0; i < 256; i++)
1061 m_CharWidth[i] = 600;
1062 }
1063 if (m_Base14Font == 12)
1064 m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
1065 else if (m_Base14Font == 13)
1066 m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;
1067 else if (m_Flags & PDFFONT_NONSYMBOLIC)
1068 m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
1069 }
1070 return LoadCommon();
1071 }
1072
1073 int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
1074 if (charcode > 0xff) {
1075 return -1;
1076 }
1077 int index = m_ExtGID[(uint8_t)charcode];
1078 if (index == 0xffff) {
1079 return -1;
1080 }
1081 return index;
1082 }
1083
1084 void CPDF_Type1Font::LoadGlyphMap() {
1085 if (!m_Font.GetFace())
1086 return;
1087
1088 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1089 FX_BOOL bCoreText = TRUE;
1090 CQuartz2D& quartz2d =
1091 ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
1092 if (!m_Font.GetPlatformFont()) {
1093 if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
1094 bCoreText = FALSE;
1095 }
1096 m_Font.SetPlatformFont(
1097 quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize()));
1098 if (!m_Font.GetPlatformFont()) {
1099 bCoreText = FALSE;
1100 }
1101 }
1102 #endif
1103 if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {
1104 if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
1105 FX_BOOL bGotOne = FALSE;
1106 for (int charcode = 0; charcode < 256; charcode++) {
1107 const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
1108 for (int j = 0; j < 4; j++) {
1109 uint16_t unicode = prefix[j] * 256 + charcode;
1110 m_GlyphIndex[charcode] =
1111 FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
1112 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1113 FX_CHAR name_glyph[256];
1114 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1115 name_glyph, 256);
1116 name_glyph[255] = 0;
1117 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1118 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1119 kCFAllocatorNull);
1120 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1121 (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1122 if (name_ct) {
1123 CFRelease(name_ct);
1124 }
1125 #endif
1126 if (m_GlyphIndex[charcode]) {
1127 bGotOne = TRUE;
1128 break;
1129 }
1130 }
1131 }
1132 if (bGotOne) {
1133 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1134 if (!bCoreText) {
1135 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
1136 }
1137 #endif
1138 return;
1139 }
1140 }
1141 FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
1142 if (m_BaseEncoding == 0) {
1143 m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
1144 }
1145 for (int charcode = 0; charcode < 256; charcode++) {
1146 const FX_CHAR* name =
1147 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1148 if (!name) {
1149 continue;
1150 }
1151 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1152 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1153 m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
1154 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1155 FX_CHAR name_glyph[256];
1156 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph,
1157 256);
1158 name_glyph[255] = 0;
1159 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1160 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1161 kCFAllocatorNull);
1162 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1163 (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1164 if (name_ct) {
1165 CFRelease(name_ct);
1166 }
1167 #endif
1168 if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) {
1169 m_Encoding.m_Unicodes[charcode] = 0x20;
1170 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20);
1171 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1172 FX_CHAR name_glyph[256];
1173 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1174 name_glyph, 256);
1175 name_glyph[255] = 0;
1176 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1177 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1178 kCFAllocatorNull);
1179 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1180 (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1181 if (name_ct) {
1182 CFRelease(name_ct);
1183 }
1184 #endif
1185 }
1186 }
1187 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1188 if (!bCoreText) {
1189 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
1190 }
1191 #endif
1192 return;
1193 }
1194 FT_UseType1Charmap(m_Font.GetFace());
1195 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1196 if (bCoreText) {
1197 if (m_Flags & PDFFONT_SYMBOLIC) {
1198 for (int charcode = 0; charcode < 256; charcode++) {
1199 const FX_CHAR* name =
1200 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1201 if (name) {
1202 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1203 m_GlyphIndex[charcode] =
1204 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1205 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1206 kCFAllocatorDefault, name, kCFStringEncodingASCII,
1207 kCFAllocatorNull);
1208 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1209 (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1210 if (name_ct) {
1211 CFRelease(name_ct);
1212 }
1213 } else {
1214 m_GlyphIndex[charcode] =
1215 FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
1216 FX_WCHAR unicode = 0;
1217 if (m_GlyphIndex[charcode]) {
1218 unicode =
1219 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
1220 }
1221 FX_CHAR name_glyph[256];
1222 FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
1223 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1224 name_glyph, 256);
1225 name_glyph[255] = 0;
1226 if (unicode == 0 && name_glyph[0] != 0) {
1227 unicode = PDF_UnicodeFromAdobeName(name_glyph);
1228 }
1229 m_Encoding.m_Unicodes[charcode] = unicode;
1230 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1231 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1232 kCFAllocatorNull);
1233 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1234 (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1235 if (name_ct) {
1236 CFRelease(name_ct);
1237 }
1238 }
1239 }
1240 return;
1241 }
1242 FX_BOOL bUnicode = FALSE;
1243 if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
1244 bUnicode = TRUE;
1245 }
1246 for (int charcode = 0; charcode < 256; charcode++) {
1247 const FX_CHAR* name =
1248 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1249 if (!name) {
1250 continue;
1251 }
1252 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1253 const FX_CHAR* pStrUnicode = GlyphNameRemap(name);
1254 if (pStrUnicode &&
1255 0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) {
1256 name = pStrUnicode;
1257 }
1258 m_GlyphIndex[charcode] =
1259 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1260 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1261 kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
1262 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1263 (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1264 if (name_ct) {
1265 CFRelease(name_ct);
1266 }
1267 if (m_GlyphIndex[charcode] == 0) {
1268 if (FXSYS_strcmp(name, ".notdef") != 0 &&
1269 FXSYS_strcmp(name, "space") != 0) {
1270 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1271 m_Font.GetFace(),
1272 bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
1273 FX_CHAR name_glyph[256];
1274 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1275 name_glyph, 256);
1276 name_glyph[255] = 0;
1277 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1278 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1279 kCFAllocatorNull);
1280 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1281 (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1282 if (name_ct) {
1283 CFRelease(name_ct);
1284 }
1285 } else {
1286 m_Encoding.m_Unicodes[charcode] = 0x20;
1287 m_GlyphIndex[charcode] =
1288 bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff;
1289 FX_CHAR name_glyph[256];
1290 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1291 name_glyph, 256);
1292 name_glyph[255] = 0;
1293 CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
1294 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
1295 kCFAllocatorNull);
1296 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
1297 (CGFontRef)m_Font.GetPlatformFont(), name_ct);
1298 if (name_ct) {
1299 CFRelease(name_ct);
1300 }
1301 }
1302 }
1303 }
1304 return;
1305 }
1306 #endif
1307 if (m_Flags & PDFFONT_SYMBOLIC) {
1308 for (int charcode = 0; charcode < 256; charcode++) {
1309 const FX_CHAR* name =
1310 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1311 if (name) {
1312 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1313 m_GlyphIndex[charcode] =
1314 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1315 } else {
1316 m_GlyphIndex[charcode] =
1317 FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
1318 if (m_GlyphIndex[charcode]) {
1319 FX_WCHAR unicode =
1320 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
1321 if (unicode == 0) {
1322 FX_CHAR name_glyph[256];
1323 FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
1324 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
1325 name_glyph, 256);
1326 name_glyph[255] = 0;
1327 if (name_glyph[0] != 0) {
1328 unicode = PDF_UnicodeFromAdobeName(name_glyph);
1329 }
1330 }
1331 m_Encoding.m_Unicodes[charcode] = unicode;
1332 }
1333 }
1334 }
1335 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1336 if (!bCoreText) {
1337 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
1338 }
1339 #endif
1340 return;
1341 }
1342 FX_BOOL bUnicode = FALSE;
1343 if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
1344 bUnicode = TRUE;
1345 }
1346 for (int charcode = 0; charcode < 256; charcode++) {
1347 const FX_CHAR* name =
1348 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1349 if (!name) {
1350 continue;
1351 }
1352 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1353 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1354 if (m_GlyphIndex[charcode] == 0) {
1355 if (FXSYS_strcmp(name, ".notdef") != 0 &&
1356 FXSYS_strcmp(name, "space") != 0) {
1357 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1358 m_Font.GetFace(),
1359 bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
1360 } else {
1361 m_Encoding.m_Unicodes[charcode] = 0x20;
1362 m_GlyphIndex[charcode] = 0xffff;
1363 }
1364 }
1365 }
1366 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
1367 if (!bCoreText) {
1368 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
1369 }
1370 #endif
1371 }
1372
1373 CPDF_FontEncoding::CPDF_FontEncoding() {
1374 FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
1375 }
1376
1377 int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const {
1378 for (int i = 0; i < 256; i++)
1379 if (m_Unicodes[i] == unicode) {
1380 return i;
1381 }
1382 return -1;
1383 }
1384
1385 CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) {
1386 const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);
1387 if (!pSrc) {
1388 FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
1389 } else {
1390 for (int i = 0; i < 256; i++)
1391 m_Unicodes[i] = pSrc[i];
1392 }
1393 }
1394
1395 FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const {
1396 return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) ==
1397 0;
1398 }
1399
1400 CPDF_Object* CPDF_FontEncoding::Realize() {
1401 int predefined = 0;
1402 for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS;
1403 cs++) {
1404 const uint16_t* pSrc = PDF_UnicodesForPredefinedCharSet(cs);
1405 FX_BOOL match = TRUE;
1406 for (int i = 0; i < 256; ++i) {
1407 if (m_Unicodes[i] != pSrc[i]) {
1408 match = FALSE;
1409 break;
1410 }
1411 }
1412 if (match) {
1413 predefined = cs;
1414 break;
1415 }
1416 }
1417 if (predefined) {
1418 if (predefined == PDFFONT_ENCODING_WINANSI) {
1419 return new CPDF_Name("WinAnsiEncoding");
1420 }
1421 if (predefined == PDFFONT_ENCODING_MACROMAN) {
1422 return new CPDF_Name("MacRomanEncoding");
1423 }
1424 if (predefined == PDFFONT_ENCODING_MACEXPERT) {
1425 return new CPDF_Name("MacExpertEncoding");
1426 }
1427 return NULL;
1428 }
1429 const uint16_t* pStandard =
1430 PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
1431 CPDF_Array* pDiff = new CPDF_Array;
1432 for (int i = 0; i < 256; i++) {
1433 if (pStandard[i] == m_Unicodes[i]) {
1434 continue;
1435 }
1436 pDiff->Add(new CPDF_Number(i));
1437 pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i])));
1438 }
1439
1440 CPDF_Dictionary* pDict = new CPDF_Dictionary;
1441 pDict->SetAtName("BaseEncoding", "WinAnsiEncoding");
1442 pDict->SetAt("Differences", pDiff);
1443 return pDict;
1444 }
1445
1446 CPDF_TrueTypeFont::CPDF_TrueTypeFont() {}
1447
1448 bool CPDF_TrueTypeFont::IsTrueTypeFont() const {
1449 return true;
1450 }
1451
1452 const CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() const {
1453 return this;
1454 }
1455
1456 CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() {
1457 return this;
1458 }
1459
1460 FX_BOOL CPDF_TrueTypeFont::Load() {
1461 return LoadCommon();
1462 }
1463
1464 void CPDF_TrueTypeFont::LoadGlyphMap() {
1465 if (!m_Font.GetFace())
1466 return;
1467
1468 int baseEncoding = m_BaseEncoding;
1469 if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 &&
1470 (baseEncoding == PDFFONT_ENCODING_MACROMAN ||
1471 baseEncoding == PDFFONT_ENCODING_WINANSI) &&
1472 (m_Flags & PDFFONT_SYMBOLIC)) {
1473 FX_BOOL bSupportWin = FALSE;
1474 FX_BOOL bSupportMac = FALSE;
1475 for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) {
1476 int platform_id = FXFT_Get_Charmap_PlatformID(
1477 FXFT_Get_Face_Charmaps(m_Font.GetFace())[i]);
1478 if (platform_id == 0 || platform_id == 3) {
1479 bSupportWin = TRUE;
1480 } else if (platform_id == 0 || platform_id == 1) {
1481 bSupportMac = TRUE;
1482 }
1483 }
1484 if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) {
1485 baseEncoding =
1486 bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN;
1487 } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) {
1488 baseEncoding =
1489 bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN;
1490 }
1491 }
1492 if (((baseEncoding == PDFFONT_ENCODING_MACROMAN ||
1493 baseEncoding == PDFFONT_ENCODING_WINANSI) &&
1494 !m_pCharNames) ||
1495 (m_Flags & PDFFONT_NONSYMBOLIC)) {
1496 if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) &&
1497 (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) {
1498 int nStartChar = m_pFontDict->GetIntegerBy("FirstChar");
1499 if (nStartChar < 0 || nStartChar > 255)
1500 return;
1501
1502 int charcode = 0;
1503 for (; charcode < nStartChar; charcode++) {
1504 m_GlyphIndex[charcode] = 0;
1505 }
1506 uint16_t nGlyph = charcode - nStartChar + 3;
1507 for (; charcode < 256; charcode++, nGlyph++) {
1508 m_GlyphIndex[charcode] = nGlyph;
1509 }
1510 return;
1511 }
1512 FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1);
1513 FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE;
1514 if (!bMSUnicode) {
1515 if (m_Flags & PDFFONT_NONSYMBOLIC) {
1516 bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0);
1517 bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0);
1518 } else {
1519 bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0);
1520 bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0);
1521 }
1522 }
1523 FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode");
1524 for (int charcode = 0; charcode < 256; charcode++) {
1525 const FX_CHAR* name =
1526 GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
1527 if (!name) {
1528 m_GlyphIndex[charcode] =
1529 m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1;
1530 continue;
1531 }
1532 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1533 if (bMSSymbol) {
1534 const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
1535 for (int j = 0; j < 4; j++) {
1536 uint16_t unicode = prefix[j] * 256 + charcode;
1537 m_GlyphIndex[charcode] =
1538 FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
1539 if (m_GlyphIndex[charcode]) {
1540 break;
1541 }
1542 }
1543 } else if (m_Encoding.m_Unicodes[charcode]) {
1544 if (bMSUnicode) {
1545 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1546 m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
1547 } else if (bMacRoman) {
1548 FX_DWORD maccode = FT_CharCodeFromUnicode(
1549 FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]);
1550 if (!maccode) {
1551 m_GlyphIndex[charcode] =
1552 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1553 } else {
1554 m_GlyphIndex[charcode] =
1555 FXFT_Get_Char_Index(m_Font.GetFace(), maccode);
1556 }
1557 }
1558 }
1559 if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) &&
1560 name) {
1561 if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) {
1562 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32);
1563 } else {
1564 m_GlyphIndex[charcode] =
1565 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
1566 if (m_GlyphIndex[charcode] == 0) {
1567 if (bToUnicode) {
1568 CFX_WideString wsUnicode = UnicodeFromCharCode(charcode);
1569 if (!wsUnicode.IsEmpty()) {
1570 m_GlyphIndex[charcode] =
1571 FXFT_Get_Char_Index(m_Font.GetFace(), wsUnicode[0]);
1572 m_Encoding.m_Unicodes[charcode] = wsUnicode[0];
1573 }
1574 }
1575 if (m_GlyphIndex[charcode] == 0) {
1576 m_GlyphIndex[charcode] =
1577 FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
1578 }
1579 }
1580 }
1581 }
1582 }
1583 return;
1584 }
1585 if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
1586 const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
1587 FX_BOOL bGotOne = FALSE;
1588 for (int charcode = 0; charcode < 256; charcode++) {
1589 for (int j = 0; j < 4; j++) {
1590 uint16_t unicode = prefix[j] * 256 + charcode;
1591 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
1592 if (m_GlyphIndex[charcode]) {
1593 bGotOne = TRUE;
1594 break;
1595 }
1596 }
1597 }
1598 if (bGotOne) {
1599 if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
1600 for (int charcode = 0; charcode < 256; charcode++) {
1601 const FX_CHAR* name =
1602 GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
1603 if (!name) {
1604 continue;
1605 }
1606 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1607 }
1608 } else if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) {
1609 for (int charcode = 0; charcode < 256; charcode++) {
1610 m_Encoding.m_Unicodes[charcode] =
1611 FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
1612 }
1613 }
1614 return;
1615 }
1616 }
1617 if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) {
1618 FX_BOOL bGotOne = FALSE;
1619 for (int charcode = 0; charcode < 256; charcode++) {
1620 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
1621 m_Encoding.m_Unicodes[charcode] =
1622 FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
1623 if (m_GlyphIndex[charcode]) {
1624 bGotOne = TRUE;
1625 }
1626 }
1627 if (m_pFontFile || bGotOne) {
1628 return;
1629 }
1630 }
1631 if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) {
1632 FX_BOOL bGotOne = FALSE;
1633 const uint16_t* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding);
1634 for (int charcode = 0; charcode < 256; charcode++) {
1635 if (m_pFontFile) {
1636 m_Encoding.m_Unicodes[charcode] = charcode;
1637 } else {
1638 const FX_CHAR* name = GetAdobeCharName(0, m_pCharNames, charcode);
1639 if (name) {
1640 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
1641 } else if (pUnicodes) {
1642 m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode];
1643 }
1644 }
1645 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
1646 m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
1647 if (m_GlyphIndex[charcode]) {
1648 bGotOne = TRUE;
1649 }
1650 }
1651 if (bGotOne) {
1652 return;
1653 }
1654 }
1655 for (int charcode = 0; charcode < 256; charcode++) {
1656 m_GlyphIndex[charcode] = charcode;
1657 }
1658 }
1659
1660 CPDF_Type3Font::CPDF_Type3Font()
1661 : m_pCharProcs(nullptr),
1662 m_pPageResources(nullptr),
1663 m_pFontResources(nullptr) {
1664 FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
1665 }
1666
1667 CPDF_Type3Font::~CPDF_Type3Font() {
1668 for (auto it : m_CacheMap)
1669 delete it.second;
1670 }
1671
1672 bool CPDF_Type3Font::IsType3Font() const {
1673 return true;
1674 }
1675
1676 const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const {
1677 return this;
1678 }
1679
1680 CPDF_Type3Font* CPDF_Type3Font::AsType3Font() {
1681 return this;
1682 }
1683
1684 FX_BOOL CPDF_Type3Font::Load() {
1685 m_pFontResources = m_pFontDict->GetDictBy("Resources");
1686 CPDF_Array* pMatrix = m_pFontDict->GetArrayBy("FontMatrix");
1687 FX_FLOAT xscale = 1.0f, yscale = 1.0f;
1688 if (pMatrix) {
1689 m_FontMatrix = pMatrix->GetMatrix();
1690 xscale = m_FontMatrix.a;
1691 yscale = m_FontMatrix.d;
1692 }
1693 CPDF_Array* pBBox = m_pFontDict->GetArrayBy("FontBBox");
1694 if (pBBox) {
1695 m_FontBBox.left = (int32_t)(pBBox->GetNumberAt(0) * xscale * 1000);
1696 m_FontBBox.bottom = (int32_t)(pBBox->GetNumberAt(1) * yscale * 1000);
1697 m_FontBBox.right = (int32_t)(pBBox->GetNumberAt(2) * xscale * 1000);
1698 m_FontBBox.top = (int32_t)(pBBox->GetNumberAt(3) * yscale * 1000);
1699 }
1700 int StartChar = m_pFontDict->GetIntegerBy("FirstChar");
1701 CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths");
1702 if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
1703 FX_DWORD count = pWidthArray->GetCount();
1704 if (count > 256) {
1705 count = 256;
1706 }
1707 if (StartChar + count > 256) {
1708 count = 256 - StartChar;
1709 }
1710 for (FX_DWORD i = 0; i < count; i++) {
1711 m_CharWidthL[StartChar + i] =
1712 FXSYS_round(pWidthArray->GetNumberAt(i) * xscale * 1000);
1713 }
1714 }
1715 m_pCharProcs = m_pFontDict->GetDictBy("CharProcs");
1716 CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
1717 if (pEncoding) {
1718 LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
1719 if (m_pCharNames) {
1720 for (int i = 0; i < 256; i++) {
1721 m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
1722 if (m_Encoding.m_Unicodes[i] == 0) {
1723 m_Encoding.m_Unicodes[i] = i;
1724 }
1725 }
1726 }
1727 }
1728 return TRUE;
1729 }
1730
1731 void CPDF_Type3Font::CheckType3FontMetrics() {
1732 CheckFontMetrics();
1733 }
1734
1735 CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) {
1736 if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_)
1737 return nullptr;
1738
1739 auto it = m_CacheMap.find(charcode);
1740 if (it != m_CacheMap.end())
1741 return it->second;
1742
1743 const FX_CHAR* name =
1744 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
1745 if (!name)
1746 return nullptr;
1747
1748 CPDF_Stream* pStream =
1749 ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr);
1750 if (!pStream)
1751 return nullptr;
1752
1753 std::unique_ptr<CPDF_Type3Char> pNewChar(new CPDF_Type3Char(new CPDF_Form(
1754 m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources,
1755 pStream, nullptr)));
1756
1757 // This can trigger recursion into this method. The content of |m_CacheMap|
1758 // can change as a result. Thus after it returns, check the cache again for
1759 // a cache hit.
1760 pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr,
1761 level + 1);
1762 it = m_CacheMap.find(charcode);
1763 if (it != m_CacheMap.end())
1764 return it->second;
1765
1766 FX_FLOAT scale = m_FontMatrix.GetXUnit();
1767 pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f);
1768 FX_RECT& rcBBox = pNewChar->m_BBox;
1769 CFX_FloatRect char_rect(
1770 (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
1771 (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
1772 if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top)
1773 char_rect = pNewChar->m_pForm->CalcBoundingBox();
1774
1775 char_rect.Transform(&m_FontMatrix);
1776 rcBBox.left = FXSYS_round(char_rect.left * 1000);
1777 rcBBox.right = FXSYS_round(char_rect.right * 1000);
1778 rcBBox.top = FXSYS_round(char_rect.top * 1000);
1779 rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);
1780
1781 ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode));
1782 CPDF_Type3Char* pCachedChar = pNewChar.release();
1783 m_CacheMap[charcode] = pCachedChar;
1784 if (pCachedChar->m_pForm->GetPageObjectList()->empty()) {
1785 delete pCachedChar->m_pForm;
1786 pCachedChar->m_pForm = nullptr;
1787 }
1788 return pCachedChar;
1789 }
1790
1791 int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) {
1792 if (charcode >= FX_ArraySize(m_CharWidthL))
1793 charcode = 0;
1794
1795 if (m_CharWidthL[charcode])
1796 return m_CharWidthL[charcode];
1797
1798 const CPDF_Type3Char* pChar = LoadChar(charcode, level);
1799 return pChar ? pChar->m_Width : 0;
1800 }
1801
1802 FX_RECT CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, int level) {
1803 const CPDF_Type3Char* pChar = LoadChar(charcode, level);
1804 return pChar ? pChar->m_BBox : FX_RECT();
1805 }
1806
1807 CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm)
1808 : m_pForm(pForm), m_pBitmap(nullptr), m_bColored(FALSE) {}
1809
1810 CPDF_Type3Char::~CPDF_Type3Char() {
1811 delete m_pForm;
1812 delete m_pBitmap;
1813 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_font/font_int.h ('k') | core/fpdfapi/fpdf_font/fpdf_font_charset.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698