1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include <limits>
8 #include <vector>
9
10 #include "core/include/fxge/fx_freetype.h"
11 #include "core/include/fxge/fx_ge.h"
12 #include "core/src/fxge/fontdata/chromefontdata/chromefontdata.h"
13 #include "core/src/fxge/ge/text_int.h"
14 #include "third_party/base/stl_util.h"
15
16 #define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1])
17 #define GET_TT_LONG(w) \
18 (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3])
19
20 #define FX_FONT_STYLE_None 0x00
21 #define FX_FONT_STYLE_Bold 0x01
22 #define FX_FONT_STYLE_Italic 0x02
23 #define FX_FONT_STYLE_BoldBold 0x04
24
25 namespace {
26
27 struct BuiltinFont {
28 const uint8_t* m_pFontData;
29 FX_DWORD m_dwSize;
30 };
31
32 const BuiltinFont g_FoxitFonts[14] = {
33 {g_FoxitFixedFontData, 17597},
34 {g_FoxitFixedBoldFontData, 18055},
35 {g_FoxitFixedBoldItalicFontData, 19151},
36 {g_FoxitFixedItalicFontData, 18746},
37 {g_FoxitSansFontData, 15025},
38 {g_FoxitSansBoldFontData, 16344},
39 {g_FoxitSansBoldItalicFontData, 16418},
40 {g_FoxitSansItalicFontData, 16339},
41 {g_FoxitSerifFontData, 19469},
42 {g_FoxitSerifBoldFontData, 19395},
43 {g_FoxitSerifBoldItalicFontData, 20733},
44 {g_FoxitSerifItalicFontData, 21227},
45 {g_FoxitSymbolFontData, 16729},
46 {g_FoxitDingbatsFontData, 29513},
47 };
48
49 const BuiltinFont g_MMFonts[2] = {
50 {g_FoxitSerifMMFontData, 113417},
51 {g_FoxitSansMMFontData, 66919},
52 };
53
54 const FX_CHAR* const g_Base14FontNames[14] = {
55 "Courier",
56 "Courier-Bold",
57 "Courier-BoldOblique",
58 "Courier-Oblique",
59 "Helvetica",
60 "Helvetica-Bold",
61 "Helvetica-BoldOblique",
62 "Helvetica-Oblique",
63 "Times-Roman",
64 "Times-Bold",
65 "Times-BoldItalic",
66 "Times-Italic",
67 "Symbol",
68 "ZapfDingbats",
69 };
70
71 const struct AltFontName {
72 const FX_CHAR* m_pName;
73 int m_Index;
74 } g_AltFontNames[] = {
75 {"Arial", 4},
76 {"Arial,Bold", 5},
77 {"Arial,BoldItalic", 6},
78 {"Arial,Italic", 7},
79 {"Arial-Bold", 5},
80 {"Arial-BoldItalic", 6},
81 {"Arial-BoldItalicMT", 6},
82 {"Arial-BoldMT", 5},
83 {"Arial-Italic", 7},
84 {"Arial-ItalicMT", 7},
85 {"ArialBold", 5},
86 {"ArialBoldItalic", 6},
87 {"ArialItalic", 7},
88 {"ArialMT", 4},
89 {"ArialMT,Bold", 5},
90 {"ArialMT,BoldItalic", 6},
91 {"ArialMT,Italic", 7},
92 {"ArialRoundedMTBold", 5},
93 {"Courier", 0},
94 {"Courier,Bold", 1},
95 {"Courier,BoldItalic", 2},
96 {"Courier,Italic", 3},
97 {"Courier-Bold", 1},
98 {"Courier-BoldOblique", 2},
99 {"Courier-Oblique", 3},
100 {"CourierBold", 1},
101 {"CourierBoldItalic", 2},
102 {"CourierItalic", 3},
103 {"CourierNew", 0},
104 {"CourierNew,Bold", 1},
105 {"CourierNew,BoldItalic", 2},
106 {"CourierNew,Italic", 3},
107 {"CourierNew-Bold", 1},
108 {"CourierNew-BoldItalic", 2},
109 {"CourierNew-Italic", 3},
110 {"CourierNewBold", 1},
111 {"CourierNewBoldItalic", 2},
112 {"CourierNewItalic", 3},
113 {"CourierNewPS-BoldItalicMT", 2},
114 {"CourierNewPS-BoldMT", 1},
115 {"CourierNewPS-ItalicMT", 3},
116 {"CourierNewPSMT", 0},
117 {"CourierStd", 0},
118 {"CourierStd-Bold", 1},
119 {"CourierStd-BoldOblique", 2},
120 {"CourierStd-Oblique", 3},
121 {"Helvetica", 4},
122 {"Helvetica,Bold", 5},
123 {"Helvetica,BoldItalic", 6},
124 {"Helvetica,Italic", 7},
125 {"Helvetica-Bold", 5},
126 {"Helvetica-BoldItalic", 6},
127 {"Helvetica-BoldOblique", 6},
128 {"Helvetica-Italic", 7},
129 {"Helvetica-Oblique", 7},
130 {"HelveticaBold", 5},
131 {"HelveticaBoldItalic", 6},
132 {"HelveticaItalic", 7},
133 {"Symbol", 12},
134 {"SymbolMT", 12},
135 {"Times-Bold", 9},
136 {"Times-BoldItalic", 10},
137 {"Times-Italic", 11},
138 {"Times-Roman", 8},
139 {"TimesBold", 9},
140 {"TimesBoldItalic", 10},
141 {"TimesItalic", 11},
142 {"TimesNewRoman", 8},
143 {"TimesNewRoman,Bold", 9},
144 {"TimesNewRoman,BoldItalic", 10},
145 {"TimesNewRoman,Italic", 11},
146 {"TimesNewRoman-Bold", 9},
147 {"TimesNewRoman-BoldItalic", 10},
148 {"TimesNewRoman-Italic", 11},
149 {"TimesNewRomanBold", 9},
150 {"TimesNewRomanBoldItalic", 10},
151 {"TimesNewRomanItalic", 11},
152 {"TimesNewRomanPS", 8},
153 {"TimesNewRomanPS-Bold", 9},
154 {"TimesNewRomanPS-BoldItalic", 10},
155 {"TimesNewRomanPS-BoldItalicMT", 10},
156 {"TimesNewRomanPS-BoldMT", 9},
157 {"TimesNewRomanPS-Italic", 11},
158 {"TimesNewRomanPS-ItalicMT", 11},
159 {"TimesNewRomanPSMT", 8},
160 {"TimesNewRomanPSMT,Bold", 9},
161 {"TimesNewRomanPSMT,BoldItalic", 10},
162 {"TimesNewRomanPSMT,Italic", 11},
163 {"ZapfDingbats", 13},
164 };
165
166 const struct {
167 const FX_CHAR* m_pName;
168 const FX_CHAR* m_pSubstName;
169 } Base14Substs[] = {
170 {"Courier", "Courier New"},
171 {"Courier-Bold", "Courier New Bold"},
172 {"Courier-BoldOblique", "Courier New Bold Italic"},
173 {"Courier-Oblique", "Courier New Italic"},
174 {"Helvetica", "Arial"},
175 {"Helvetica-Bold", "Arial Bold"},
176 {"Helvetica-BoldOblique", "Arial Bold Italic"},
177 {"Helvetica-Oblique", "Arial Italic"},
178 {"Times-Roman", "Times New Roman"},
179 {"Times-Bold", "Times New Roman Bold"},
180 {"Times-BoldItalic", "Times New Roman Bold Italic"},
181 {"Times-Italic", "Times New Roman Italic"},
182 };
183
184 const struct AltFontFamily {
185 const FX_CHAR* m_pFontName;
186 const FX_CHAR* m_pFontFamily;
187 } g_AltFontFamilies[] = {
188 {"AGaramondPro", "Adobe Garamond Pro"},
189 {"BankGothicBT-Medium", "BankGothic Md BT"},
190 {"ForteMT", "Forte"},
191 };
192
193 const struct FX_FontStyle {
194 const FX_CHAR* style;
195 int32_t len;
196 } g_FontStyles[] = {
197 {"Bold", 4}, {"Italic", 6}, {"BoldItalic", 10}, {"Reg", 3}, {"Regular", 7},
198 };
199
200 const struct CHARSET_MAP {
201 uint8_t charset;
202 FX_WORD codepage;
203 } g_Codepage2CharsetTable[] = {
204 {1, 0}, {2, 42}, {254, 437}, {255, 850}, {222, 874},
205 {128, 932}, {134, 936}, {129, 949}, {136, 950}, {238, 1250},
206 {204, 1251}, {0, 1252}, {161, 1253}, {162, 1254}, {177, 1255},
207 {178, 1256}, {186, 1257}, {163, 1258}, {130, 1361}, {77, 10000},
208 {78, 10001}, {79, 10003}, {80, 10008}, {81, 10002}, {83, 10005},
209 {84, 10004}, {85, 10006}, {86, 10081}, {87, 10021}, {88, 10029},
210 {89, 10007},
211 };
212
213 const FX_DWORD kTableNAME = FXDWORD_GET_MSBFIRST("name");
214 const FX_DWORD kTableTTCF = FXDWORD_GET_MSBFIRST("ttcf");
215
CompareFontFamilyString(const void * key,const void * element)216 int CompareFontFamilyString(const void* key, const void* element) {
217 CFX_ByteString str_key((const FX_CHAR*)key);
218 if (str_key.Find(((AltFontFamily*)element)->m_pFontName) != -1) {
219 return 0;
220 }
221 return FXSYS_stricmp((const FX_CHAR*)key,
222 ((AltFontFamily*)element)->m_pFontName);
223 }
224
CompareString(const void * key,const void * element)225 int CompareString(const void* key, const void* element) {
226 return FXSYS_stricmp((const FX_CHAR*)key, ((AltFontName*)element)->m_pName);
227 }
228
KeyNameFromFace(const CFX_ByteString & face_name,int weight,FX_BOOL bItalic)229 CFX_ByteString KeyNameFromFace(const CFX_ByteString& face_name,
230 int weight,
231 FX_BOOL bItalic) {
232 CFX_ByteString key(face_name);
233 key += ',';
234 key += CFX_ByteString::FormatInteger(weight);
235 key += bItalic ? 'I' : 'N';
236 return key;
237 }
238
KeyNameFromSize(int ttc_size,FX_DWORD checksum)239 CFX_ByteString KeyNameFromSize(int ttc_size, FX_DWORD checksum) {
240 CFX_ByteString key;
241 key.Format("%d:%d", ttc_size, checksum);
242 return key;
243 }
244
TT_NormalizeName(const FX_CHAR * family)245 CFX_ByteString TT_NormalizeName(const FX_CHAR* family) {
246 CFX_ByteString norm(family);
247 norm.Remove(' ');
248 norm.Remove('-');
249 norm.Remove(',');
250 int pos = norm.Find('+');
251 if (pos > 0) {
252 norm = norm.Left(pos);
253 }
254 norm.MakeLower();
255 return norm;
256 }
257
FPDF_ReadStringFromFile(FXSYS_FILE * pFile,FX_DWORD size)258 CFX_ByteString FPDF_ReadStringFromFile(FXSYS_FILE* pFile, FX_DWORD size) {
259 CFX_ByteString buffer;
260 if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile)) {
261 return CFX_ByteString();
262 }
263 buffer.ReleaseBuffer(size);
264 return buffer;
265 }
266
FPDF_LoadTableFromTT(FXSYS_FILE * pFile,const uint8_t * pTables,FX_DWORD nTables,FX_DWORD tag)267 CFX_ByteString FPDF_LoadTableFromTT(FXSYS_FILE* pFile,
268 const uint8_t* pTables,
269 FX_DWORD nTables,
270 FX_DWORD tag) {
271 for (FX_DWORD i = 0; i < nTables; i++) {
272 const uint8_t* p = pTables + i * 16;
273 if (GET_TT_LONG(p) == tag) {
274 FX_DWORD offset = GET_TT_LONG(p + 8);
275 FX_DWORD size = GET_TT_LONG(p + 12);
276 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
277 return FPDF_ReadStringFromFile(pFile, size);
278 }
279 }
280 return CFX_ByteString();
281 }
282
GetCharsetFromCodePage(FX_WORD codepage)283 uint8_t GetCharsetFromCodePage(FX_WORD codepage) {
284 int32_t iEnd = sizeof(g_Codepage2CharsetTable) / sizeof(CHARSET_MAP) - 1;
285 FXSYS_assert(iEnd >= 0);
286 int32_t iStart = 0, iMid;
287 do {
288 iMid = (iStart + iEnd) / 2;
289 const CHARSET_MAP& cp = g_Codepage2CharsetTable[iMid];
290 if (codepage == cp.codepage) {
291 return cp.charset;
292 }
293 if (codepage < cp.codepage) {
294 iEnd = iMid - 1;
295 } else {
296 iStart = iMid + 1;
297 }
298 } while (iStart <= iEnd);
299 return 1;
300 }
301
GetFontFamily(CFX_ByteString fontName,int nStyle)302 CFX_ByteString GetFontFamily(CFX_ByteString fontName, int nStyle) {
303 if (fontName.Find("Script") >= 0) {
304 if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) {
305 fontName = "ScriptMTBold";
306 } else if (fontName.Find("Palace") >= 0) {
307 fontName = "PalaceScriptMT";
308 } else if (fontName.Find("French") >= 0) {
309 fontName = "FrenchScriptMT";
310 } else if (fontName.Find("FreeStyle") >= 0) {
311 fontName = "FreeStyleScript";
312 }
313 return fontName;
314 }
315 AltFontFamily* found = (AltFontFamily*)FXSYS_bsearch(
316 fontName.c_str(), g_AltFontFamilies,
317 sizeof g_AltFontFamilies / sizeof(AltFontFamily), sizeof(AltFontFamily),
318 CompareFontFamilyString);
319 return found ? CFX_ByteString(found->m_pFontFamily) : fontName;
320 }
321
ParseStyle(const FX_CHAR * pStyle,int iLen,int iIndex)322 CFX_ByteString ParseStyle(const FX_CHAR* pStyle, int iLen, int iIndex) {
323 CFX_ByteTextBuf buf;
324 if (!iLen || iLen <= iIndex) {
325 return buf.GetByteString();
326 }
327 while (iIndex < iLen) {
328 if (pStyle[iIndex] == ',') {
329 break;
330 }
331 buf.AppendChar(pStyle[iIndex]);
332 ++iIndex;
333 }
334 return buf.GetByteString();
335 }
336
GetStyleType(const CFX_ByteString & bsStyle,FX_BOOL bRevert)337 int32_t GetStyleType(const CFX_ByteString& bsStyle, FX_BOOL bRevert) {
338 int32_t iLen = bsStyle.GetLength();
339 if (!iLen) {
340 return -1;
341 }
342 int iSize = sizeof(g_FontStyles) / sizeof(FX_FontStyle);
343 const FX_FontStyle* pStyle = NULL;
344 for (int i = iSize - 1; i >= 0; --i) {
345 pStyle = g_FontStyles + i;
346 if (!pStyle || pStyle->len > iLen) {
347 continue;
348 }
349 if (!bRevert) {
350 if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) {
351 return i;
352 }
353 } else {
354 if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) {
355 return i;
356 }
357 }
358 }
359 return -1;
360 }
361
CheckSupportThirdPartFont(CFX_ByteString name,int & PitchFamily)362 FX_BOOL CheckSupportThirdPartFont(CFX_ByteString name, int& PitchFamily) {
363 if (name == "MyriadPro") {
364 PitchFamily &= ~FXFONT_FF_ROMAN;
365 return TRUE;
366 }
367 return FALSE;
368 }
369
GetCharset(int charset)370 FX_DWORD GetCharset(int charset) {
371 switch (charset) {
372 case FXFONT_SHIFTJIS_CHARSET:
373 return CHARSET_FLAG_SHIFTJIS;
374 case FXFONT_GB2312_CHARSET:
375 return CHARSET_FLAG_GB;
376 case FXFONT_CHINESEBIG5_CHARSET:
377 return CHARSET_FLAG_BIG5;
378 case FXFONT_HANGEUL_CHARSET:
379 return CHARSET_FLAG_KOREAN;
380 case FXFONT_SYMBOL_CHARSET:
381 return CHARSET_FLAG_SYMBOL;
382 case FXFONT_ANSI_CHARSET:
383 return CHARSET_FLAG_ANSI;
384 default:
385 break;
386 }
387 return 0;
388 }
389
GetSimilarValue(int weight,FX_BOOL bItalic,int pitch_family,FX_DWORD style)390 int32_t GetSimilarValue(int weight,
391 FX_BOOL bItalic,
392 int pitch_family,
393 FX_DWORD style) {
394 int32_t iSimilarValue = 0;
395 if ((style & FXFONT_BOLD) == (weight > 400)) {
396 iSimilarValue += 16;
397 }
398 if ((style & FXFONT_ITALIC) == bItalic) {
399 iSimilarValue += 16;
400 }
401 if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) {
402 iSimilarValue += 16;
403 }
404 if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) {
405 iSimilarValue += 8;
406 }
407 if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) {
408 iSimilarValue += 8;
409 }
410 return iSimilarValue;
411 }
412
413 } // namespace
414
CFX_SubstFont()415 CFX_SubstFont::CFX_SubstFont() {
416 m_ExtHandle = NULL;
417 m_Charset = 0;
418 m_SubstFlags = 0;
419 m_Weight = 0;
420 m_ItalicAngle = 0;
421 m_bSubstOfCJK = FALSE;
422 m_WeightCJK = 0;
423 m_bItlicCJK = FALSE;
424 }
~CTTFontDesc()425 CTTFontDesc::~CTTFontDesc() {
426 if (m_Type == 1) {
427 if (m_SingleFace.m_pFace) {
428 FXFT_Done_Face(m_SingleFace.m_pFace);
429 }
430 } else if (m_Type == 2) {
431 for (int i = 0; i < 16; i++)
432 if (m_TTCFace.m_pFaces[i]) {
433 FXFT_Done_Face(m_TTCFace.m_pFaces[i]);
434 }
435 }
436 FX_Free(m_pFontData);
437 }
ReleaseFace(FXFT_Face face)438 int CTTFontDesc::ReleaseFace(FXFT_Face face) {
439 if (m_Type == 1) {
440 if (m_SingleFace.m_pFace != face) {
441 return -1;
442 }
443 } else if (m_Type == 2) {
444 int i;
445 for (i = 0; i < 16; i++)
446 if (m_TTCFace.m_pFaces[i] == face) {
447 break;
448 }
449 if (i == 16) {
450 return -1;
451 }
452 }
453 m_RefCount--;
454 if (m_RefCount) {
455 return m_RefCount;
456 }
457 delete this;
458 return 0;
459 }
460
CFX_FontMgr()461 CFX_FontMgr::CFX_FontMgr() : m_FTLibrary(nullptr) {
462 m_pBuiltinMapper.reset(new CFX_FontMapper(this));
463 }
464
~CFX_FontMgr()465 CFX_FontMgr::~CFX_FontMgr() {
466 for (const auto& pair : m_FaceMap)
467 delete pair.second;
468
469 // |m_pBuiltinMapper| references |m_FTLibrary|, so it has to be destroyed
470 // first.
471 m_pBuiltinMapper.reset();
472 FXFT_Done_FreeType(m_FTLibrary);
473 }
474
InitFTLibrary()475 void CFX_FontMgr::InitFTLibrary() {
476 if (m_FTLibrary)
477 return;
478 FXFT_Init_FreeType(&m_FTLibrary);
479 }
480
SetSystemFontInfo(IFX_SystemFontInfo * pFontInfo)481 void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) {
482 m_pBuiltinMapper->SetSystemFontInfo(pFontInfo);
483 }
484
FindSubstFont(const CFX_ByteString & face_name,FX_BOOL bTrueType,FX_DWORD flags,int weight,int italic_angle,int CharsetCP,CFX_SubstFont * pSubstFont)485 FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name,
486 FX_BOOL bTrueType,
487 FX_DWORD flags,
488 int weight,
489 int italic_angle,
490 int CharsetCP,
491 CFX_SubstFont* pSubstFont) {
492 InitFTLibrary();
493 return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight,
494 italic_angle, CharsetCP, pSubstFont);
495 }
496
GetCachedFace(const CFX_ByteString & face_name,int weight,FX_BOOL bItalic,uint8_t * & pFontData)497 FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name,
498 int weight,
499 FX_BOOL bItalic,
500 uint8_t*& pFontData) {
501 auto it = m_FaceMap.find(KeyNameFromFace(face_name, weight, bItalic));
502 if (it == m_FaceMap.end())
503 return nullptr;
504
505 CTTFontDesc* pFontDesc = it->second;
506 pFontData = pFontDesc->m_pFontData;
507 pFontDesc->m_RefCount++;
508 return pFontDesc->m_SingleFace.m_pFace;
509 }
AddCachedFace(const CFX_ByteString & face_name,int weight,FX_BOOL bItalic,uint8_t * pData,FX_DWORD size,int face_index)510 FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name,
511 int weight,
512 FX_BOOL bItalic,
513 uint8_t* pData,
514 FX_DWORD size,
515 int face_index) {
516 CTTFontDesc* pFontDesc = new CTTFontDesc;
517 pFontDesc->m_Type = 1;
518 pFontDesc->m_SingleFace.m_pFace = NULL;
519 pFontDesc->m_SingleFace.m_bBold = weight;
520 pFontDesc->m_SingleFace.m_bItalic = bItalic;
521 pFontDesc->m_pFontData = pData;
522 pFontDesc->m_RefCount = 1;
523
524 InitFTLibrary();
525 FXFT_Library library = m_FTLibrary;
526 int ret = FXFT_New_Memory_Face(library, pData, size, face_index,
527 &pFontDesc->m_SingleFace.m_pFace);
528 if (ret) {
529 delete pFontDesc;
530 return NULL;
531 }
532 ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace.m_pFace, 64, 64);
533 if (ret) {
534 delete pFontDesc;
535 return NULL;
536 }
537 m_FaceMap[KeyNameFromFace(face_name, weight, bItalic)] = pFontDesc;
538 return pFontDesc->m_SingleFace.m_pFace;
539 }
540
GetTTCIndex(const uint8_t * pFontData,FX_DWORD ttc_size,FX_DWORD font_offset)541 int GetTTCIndex(const uint8_t* pFontData,
542 FX_DWORD ttc_size,
543 FX_DWORD font_offset) {
544 int face_index = 0;
545 const uint8_t* p = pFontData + 8;
546 FX_DWORD nfont = GET_TT_LONG(p);
547 FX_DWORD index;
548 for (index = 0; index < nfont; index++) {
549 p = pFontData + 12 + index * 4;
550 if (GET_TT_LONG(p) == font_offset) {
551 break;
552 }
553 }
554 if (index >= nfont) {
555 face_index = 0;
556 } else {
557 face_index = index;
558 }
559 return face_index;
560 }
GetCachedTTCFace(int ttc_size,FX_DWORD checksum,int font_offset,uint8_t * & pFontData)561 FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size,
562 FX_DWORD checksum,
563 int font_offset,
564 uint8_t*& pFontData) {
565 auto it = m_FaceMap.find(KeyNameFromSize(ttc_size, checksum));
566 if (it == m_FaceMap.end())
567 return nullptr;
568
569 CTTFontDesc* pFontDesc = it->second;
570 pFontData = pFontDesc->m_pFontData;
571 pFontDesc->m_RefCount++;
572 int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
573 if (!pFontDesc->m_TTCFace.m_pFaces[face_index]) {
574 pFontDesc->m_TTCFace.m_pFaces[face_index] =
575 GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
576 }
577 return pFontDesc->m_TTCFace.m_pFaces[face_index];
578 }
AddCachedTTCFace(int ttc_size,FX_DWORD checksum,uint8_t * pData,FX_DWORD size,int font_offset)579 FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size,
580 FX_DWORD checksum,
581 uint8_t* pData,
582 FX_DWORD size,
583 int font_offset) {
584 CTTFontDesc* pFontDesc = new CTTFontDesc;
585 pFontDesc->m_Type = 2;
586 pFontDesc->m_pFontData = pData;
587 for (int i = 0; i < 16; i++) {
588 pFontDesc->m_TTCFace.m_pFaces[i] = NULL;
589 }
590 pFontDesc->m_RefCount++;
591 m_FaceMap[KeyNameFromSize(ttc_size, checksum)] = pFontDesc;
592 int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
593 pFontDesc->m_TTCFace.m_pFaces[face_index] =
594 GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
595 return pFontDesc->m_TTCFace.m_pFaces[face_index];
596 }
597
GetFixedFace(const uint8_t * pData,FX_DWORD size,int face_index)598 FXFT_Face CFX_FontMgr::GetFixedFace(const uint8_t* pData,
599 FX_DWORD size,
600 int face_index) {
601 InitFTLibrary();
602 FXFT_Library library = m_FTLibrary;
603 FXFT_Face face = nullptr;
604 if (FXFT_New_Memory_Face(library, pData, size, face_index, &face))
605 return nullptr;
606 return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face;
607 }
608
GetFileFace(const FX_CHAR * filename,int face_index)609 FXFT_Face CFX_FontMgr::GetFileFace(const FX_CHAR* filename, int face_index) {
610 InitFTLibrary();
611 FXFT_Library library = m_FTLibrary;
612 FXFT_Face face = nullptr;
613 if (FXFT_New_Face(library, filename, face_index, &face))
614 return nullptr;
615 return FXFT_Set_Pixel_Sizes(face, 64, 64) ? nullptr : face;
616 }
617
ReleaseFace(FXFT_Face face)618 void CFX_FontMgr::ReleaseFace(FXFT_Face face) {
619 if (!face) {
620 return;
621 }
622 FX_BOOL bNeedFaceDone = TRUE;
623 auto it = m_FaceMap.begin();
624 while (it != m_FaceMap.end()) {
625 auto temp = it++;
626 int nRet = temp->second->ReleaseFace(face);
627 if (nRet == -1)
628 continue;
629 bNeedFaceDone = FALSE;
630 if (nRet == 0)
631 m_FaceMap.erase(temp);
632 break;
633 }
634 if (bNeedFaceDone && !m_pBuiltinMapper->IsBuiltinFace(face))
635 FXFT_Done_Face(face);
636 }
637
GetBuiltinFont(size_t index,const uint8_t ** pFontData,FX_DWORD * size)638 bool CFX_FontMgr::GetBuiltinFont(size_t index,
639 const uint8_t** pFontData,
640 FX_DWORD* size) {
641 if (index < FX_ArraySize(g_FoxitFonts)) {
642 *pFontData = g_FoxitFonts[index].m_pFontData;
643 *size = g_FoxitFonts[index].m_dwSize;
644 return true;
645 }
646 index -= FX_ArraySize(g_FoxitFonts);
647 if (index < FX_ArraySize(g_MMFonts)) {
648 *pFontData = g_MMFonts[index].m_pFontData;
649 *size = g_MMFonts[index].m_dwSize;
650 return true;
651 }
652 return false;
653 }
654
CFX_FontMapper(CFX_FontMgr * mgr)655 CFX_FontMapper::CFX_FontMapper(CFX_FontMgr* mgr)
656 : m_bListLoaded(FALSE),
657 m_pFontInfo(nullptr),
658 m_pFontEnumerator(nullptr),
659 m_pFontMgr(mgr) {
660 m_MMFaces[0] = nullptr;
661 m_MMFaces[1] = nullptr;
662 FXSYS_memset(m_FoxitFaces, 0, sizeof(m_FoxitFaces));
663 }
~CFX_FontMapper()664 CFX_FontMapper::~CFX_FontMapper() {
665 for (size_t i = 0; i < FX_ArraySize(m_FoxitFaces); ++i) {
666 if (m_FoxitFaces[i])
667 FXFT_Done_Face(m_FoxitFaces[i]);
668 }
669 if (m_MMFaces[0]) {
670 FXFT_Done_Face(m_MMFaces[0]);
671 }
672 if (m_MMFaces[1]) {
673 FXFT_Done_Face(m_MMFaces[1]);
674 }
675 if (m_pFontInfo) {
676 m_pFontInfo->Release();
677 }
678 }
SetSystemFontInfo(IFX_SystemFontInfo * pFontInfo)679 void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo) {
680 if (!pFontInfo) {
681 return;
682 }
683 if (m_pFontInfo) {
684 m_pFontInfo->Release();
685 }
686 m_pFontInfo = pFontInfo;
687 }
688
GetNameFromTT(const uint8_t * name_table,FX_DWORD name_id)689 CFX_ByteString GetNameFromTT(const uint8_t* name_table, FX_DWORD name_id) {
690 const uint8_t* ptr = name_table + 2;
691 int name_count = GET_TT_SHORT(ptr);
692 int string_offset = GET_TT_SHORT(ptr + 2);
693 const uint8_t* string_ptr = name_table + string_offset;
694 ptr += 4;
695 for (int i = 0; i < name_count; i++) {
696 if (GET_TT_SHORT(ptr + 6) == name_id && GET_TT_SHORT(ptr) == 1 &&
697 GET_TT_SHORT(ptr + 2) == 0) {
698 return CFX_ByteStringC(string_ptr + GET_TT_SHORT(ptr + 10),
699 GET_TT_SHORT(ptr + 8));
700 }
701 ptr += 12;
702 }
703 return CFX_ByteString();
704 }
705
GetPSNameFromTT(void * hFont)706 CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont) {
707 if (!m_pFontInfo)
708 return CFX_ByteString();
709
710 FX_DWORD size = m_pFontInfo->GetFontData(hFont, kTableNAME, nullptr, 0);
711 if (!size)
712 return CFX_ByteString();
713
714 std::vector<uint8_t> buffer(size);
715 uint8_t* buffer_ptr = buffer.data();
716 FX_DWORD bytes_read =
717 m_pFontInfo->GetFontData(hFont, kTableNAME, buffer_ptr, size);
718 return (bytes_read == size) ? GetNameFromTT(buffer_ptr, 6) : CFX_ByteString();
719 }
720
AddInstalledFont(const CFX_ByteString & name,int charset)721 void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset) {
722 if (!m_pFontInfo) {
723 return;
724 }
725 if (m_CharsetArray.Find((FX_DWORD)charset) == -1) {
726 m_CharsetArray.Add((FX_DWORD)charset);
727 m_FaceArray.Add(name);
728 }
729 if (name == m_LastFamily) {
730 return;
731 }
732 const uint8_t* ptr = name;
733 FX_BOOL bLocalized = FALSE;
734 for (int i = 0; i < name.GetLength(); i++)
735 if (ptr[i] > 0x80) {
736 bLocalized = TRUE;
737 break;
738 }
739 if (bLocalized) {
740 void* hFont = m_pFontInfo->GetFont(name);
741 if (!hFont) {
742 int iExact;
743 hFont =
744 m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, name, iExact);
745 if (!hFont) {
746 return;
747 }
748 }
749 CFX_ByteString new_name = GetPSNameFromTT(hFont);
750 if (!new_name.IsEmpty()) {
751 new_name.Insert(0, ' ');
752 m_InstalledTTFonts.Add(new_name);
753 }
754 m_pFontInfo->DeleteFont(hFont);
755 }
756 m_InstalledTTFonts.Add(name);
757 m_LastFamily = name;
758 }
LoadInstalledFonts()759 void CFX_FontMapper::LoadInstalledFonts() {
760 if (!m_pFontInfo) {
761 return;
762 }
763 if (m_bListLoaded) {
764 return;
765 }
766 if (m_bListLoaded) {
767 return;
768 }
769 m_pFontInfo->EnumFontList(this);
770 m_bListLoaded = TRUE;
771 }
MatchInstalledFonts(const CFX_ByteString & norm_name)772 CFX_ByteString CFX_FontMapper::MatchInstalledFonts(
773 const CFX_ByteString& norm_name) {
774 LoadInstalledFonts();
775 int i;
776 for (i = m_InstalledTTFonts.GetSize() - 1; i >= 0; i--) {
777 CFX_ByteString norm1 = TT_NormalizeName(m_InstalledTTFonts[i]);
778 if (norm1 == norm_name) {
779 break;
780 }
781 }
782 if (i < 0) {
783 return CFX_ByteString();
784 }
785 CFX_ByteString match = m_InstalledTTFonts[i];
786 if (match[0] == ' ') {
787 match = m_InstalledTTFonts[i + 1];
788 }
789 return match;
790 }
791
UseInternalSubst(CFX_SubstFont * pSubstFont,int iBaseFont,int italic_angle,int weight,int picthfamily)792 FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont,
793 int iBaseFont,
794 int italic_angle,
795 int weight,
796 int picthfamily) {
797 if (iBaseFont < 12) {
798 if (m_FoxitFaces[iBaseFont]) {
799 return m_FoxitFaces[iBaseFont];
800 }
801 const uint8_t* pFontData = NULL;
802 FX_DWORD size = 0;
803 if (m_pFontMgr->GetBuiltinFont(iBaseFont, &pFontData, &size)) {
804 m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
805 return m_FoxitFaces[iBaseFont];
806 }
807 }
808 pSubstFont->m_SubstFlags |= FXFONT_SUBST_MM;
809 pSubstFont->m_ItalicAngle = italic_angle;
810 if (weight) {
811 pSubstFont->m_Weight = weight;
812 }
813 if (picthfamily & FXFONT_FF_ROMAN) {
814 pSubstFont->m_Weight = pSubstFont->m_Weight * 4 / 5;
815 pSubstFont->m_Family = "Chrome Serif";
816 if (m_MMFaces[1]) {
817 return m_MMFaces[1];
818 }
819 const uint8_t* pFontData = NULL;
820 FX_DWORD size = 0;
821 m_pFontMgr->GetBuiltinFont(14, &pFontData, &size);
822 m_MMFaces[1] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
823 return m_MMFaces[1];
824 }
825 pSubstFont->m_Family = "Chrome Sans";
826 if (m_MMFaces[0]) {
827 return m_MMFaces[0];
828 }
829 const uint8_t* pFontData = NULL;
830 FX_DWORD size = 0;
831 m_pFontMgr->GetBuiltinFont(15, &pFontData, &size);
832 m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
833 return m_MMFaces[0];
834 }
835
FindSubstFont(const CFX_ByteString & name,FX_BOOL bTrueType,FX_DWORD flags,int weight,int italic_angle,int WindowCP,CFX_SubstFont * pSubstFont)836 FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name,
837 FX_BOOL bTrueType,
838 FX_DWORD flags,
839 int weight,
840 int italic_angle,
841 int WindowCP,
842 CFX_SubstFont* pSubstFont) {
843 if (!(flags & FXFONT_USEEXTERNATTR)) {
844 weight = FXFONT_FW_NORMAL;
845 italic_angle = 0;
846 }
847 CFX_ByteString SubstName = name;
848 SubstName.Remove(0x20);
849 if (bTrueType) {
850 if (name[0] == '@') {
851 SubstName = name.Mid(1);
852 }
853 }
854 PDF_GetStandardFontName(&SubstName);
855 if (SubstName == "Symbol" && !bTrueType) {
856 pSubstFont->m_Family = "Chrome Symbol";
857 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
858 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
859 if (m_FoxitFaces[12]) {
860 return m_FoxitFaces[12];
861 }
862 const uint8_t* pFontData = NULL;
863 FX_DWORD size = 0;
864 m_pFontMgr->GetBuiltinFont(12, &pFontData, &size);
865 m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
866 return m_FoxitFaces[12];
867 }
868 if (SubstName == "ZapfDingbats") {
869 pSubstFont->m_Family = "Chrome Dingbats";
870 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
871 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
872 if (m_FoxitFaces[13]) {
873 return m_FoxitFaces[13];
874 }
875 const uint8_t* pFontData = NULL;
876 FX_DWORD size = 0;
877 m_pFontMgr->GetBuiltinFont(13, &pFontData, &size);
878 m_FoxitFaces[13] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
879 return m_FoxitFaces[13];
880 }
881 int iBaseFont = 0;
882 CFX_ByteString family, style;
883 FX_BOOL bHasComma = FALSE;
884 FX_BOOL bHasHypen = FALSE;
885 int find = SubstName.Find(",", 0);
886 if (find >= 0) {
887 family = SubstName.Left(find);
888 PDF_GetStandardFontName(&family);
889 style = SubstName.Mid(find + 1);
890 bHasComma = TRUE;
891 } else {
892 family = SubstName;
893 }
894 for (; iBaseFont < 12; iBaseFont++)
895 if (family == CFX_ByteStringC(g_Base14FontNames[iBaseFont])) {
896 break;
897 }
898 int PitchFamily = 0;
899 FX_BOOL bItalic = FALSE;
900 FX_DWORD nStyle = 0;
901 FX_BOOL bStyleAvail = FALSE;
902 if (iBaseFont < 12) {
903 family = g_Base14FontNames[iBaseFont];
904 if ((iBaseFont % 4) == 1 || (iBaseFont % 4) == 2) {
905 nStyle |= FX_FONT_STYLE_Bold;
906 }
907 if ((iBaseFont % 4) / 2) {
908 nStyle |= FX_FONT_STYLE_Italic;
909 }
910 if (iBaseFont < 4) {
911 PitchFamily |= FXFONT_FF_FIXEDPITCH;
912 }
913 if (iBaseFont >= 8) {
914 PitchFamily |= FXFONT_FF_ROMAN;
915 }
916 } else {
917 if (!bHasComma) {
918 find = family.ReverseFind('-');
919 if (find >= 0) {
920 style = family.Mid(find + 1);
921 family = family.Left(find);
922 bHasHypen = TRUE;
923 }
924 }
925 if (!bHasHypen) {
926 int nLen = family.GetLength();
927 int32_t nRet = GetStyleType(family, TRUE);
928 if (nRet > -1) {
929 family = family.Left(nLen - g_FontStyles[nRet].len);
930 if (nRet == 0) {
931 nStyle |= FX_FONT_STYLE_Bold;
932 }
933 if (nRet == 1) {
934 nStyle |= FX_FONT_STYLE_Italic;
935 }
936 if (nRet == 2) {
937 nStyle |= (FX_FONT_STYLE_Bold | FX_FONT_STYLE_Italic);
938 }
939 }
940 }
941 if (flags & FXFONT_SERIF) {
942 PitchFamily |= FXFONT_FF_ROMAN;
943 }
944 if (flags & FXFONT_SCRIPT) {
945 PitchFamily |= FXFONT_FF_SCRIPT;
946 }
947 if (flags & FXFONT_FIXED_PITCH) {
948 PitchFamily |= FXFONT_FF_FIXEDPITCH;
949 }
950 }
951 if (!style.IsEmpty()) {
952 int nLen = style.GetLength();
953 const FX_CHAR* pStyle = style;
954 int i = 0;
955 FX_BOOL bFirstItem = TRUE;
956 CFX_ByteString buf;
957 while (i < nLen) {
958 buf = ParseStyle(pStyle, nLen, i);
959 int32_t nRet = GetStyleType(buf, FALSE);
960 if ((i && !bStyleAvail) || (!i && nRet < 0)) {
961 family = SubstName;
962 iBaseFont = 12;
963 break;
964 } else if (nRet >= 0) {
965 bStyleAvail = TRUE;
966 }
967 if (nRet == 0) {
968 if (nStyle & FX_FONT_STYLE_Bold) {
969 nStyle |= FX_FONT_STYLE_BoldBold;
970 } else {
971 nStyle |= FX_FONT_STYLE_Bold;
972 }
973 bFirstItem = FALSE;
974 }
975 if (nRet == 1) {
976 if (bFirstItem) {
977 nStyle |= FX_FONT_STYLE_Italic;
978 } else {
979 family = SubstName;
980 iBaseFont = 12;
981 }
982 break;
983 }
984 if (nRet == 2) {
985 nStyle |= FX_FONT_STYLE_Italic;
986 if (nStyle & FX_FONT_STYLE_Bold) {
987 nStyle |= FX_FONT_STYLE_BoldBold;
988 } else {
989 nStyle |= FX_FONT_STYLE_Bold;
990 }
991 bFirstItem = FALSE;
992 }
993 i += buf.GetLength() + 1;
994 }
995 }
996 weight = weight ? weight : FXFONT_FW_NORMAL;
997 int old_weight = weight;
998 if (nStyle) {
999 weight =
1000 nStyle & FX_FONT_STYLE_BoldBold
1001 ? 900
1002 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL);
1003 }
1004 if (nStyle & FX_FONT_STYLE_Italic) {
1005 bItalic = TRUE;
1006 }
1007 FX_BOOL bCJK = FALSE;
1008 int iExact = 0;
1009 int Charset = FXFONT_ANSI_CHARSET;
1010 if (WindowCP) {
1011 Charset = GetCharsetFromCodePage(WindowCP);
1012 } else if (iBaseFont == 12 && (flags & FXFONT_SYMBOLIC)) {
1013 Charset = FXFONT_SYMBOL_CHARSET;
1014 }
1015 if (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET ||
1016 Charset == FXFONT_HANGEUL_CHARSET ||
1017 Charset == FXFONT_CHINESEBIG5_CHARSET) {
1018 bCJK = TRUE;
1019 }
1020 if (!m_pFontInfo) {
1021 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
1022 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight,
1023 PitchFamily);
1024 }
1025 family = GetFontFamily(family, nStyle);
1026 CFX_ByteString match = MatchInstalledFonts(TT_NormalizeName(family));
1027 if (match.IsEmpty() && family != SubstName &&
1028 (!bHasComma && (!bHasHypen || (bHasHypen && !bStyleAvail)))) {
1029 match = MatchInstalledFonts(TT_NormalizeName(SubstName));
1030 }
1031 if (match.IsEmpty() && iBaseFont >= 12) {
1032 if (!bCJK) {
1033 if (!CheckSupportThirdPartFont(family, PitchFamily)) {
1034 if (italic_angle != 0) {
1035 bItalic = TRUE;
1036 } else {
1037 bItalic = FALSE;
1038 }
1039 weight = old_weight;
1040 }
1041 } else {
1042 pSubstFont->m_bSubstOfCJK = TRUE;
1043 if (nStyle) {
1044 pSubstFont->m_WeightCJK = weight;
1045 } else {
1046 pSubstFont->m_WeightCJK = FXFONT_FW_NORMAL;
1047 }
1048 if (nStyle & FX_FONT_STYLE_Italic) {
1049 pSubstFont->m_bItlicCJK = TRUE;
1050 }
1051 }
1052 } else {
1053 italic_angle = 0;
1054 weight =
1055 nStyle & FX_FONT_STYLE_BoldBold
1056 ? 900
1057 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL);
1058 }
1059 if (!match.IsEmpty() || iBaseFont < 12) {
1060 if (!match.IsEmpty()) {
1061 family = match;
1062 }
1063 if (iBaseFont < 12) {
1064 if (nStyle && !(iBaseFont % 4)) {
1065 if ((nStyle & 0x3) == 1) {
1066 iBaseFont += 1;
1067 }
1068 if ((nStyle & 0x3) == 2) {
1069 iBaseFont += 3;
1070 }
1071 if ((nStyle & 0x3) == 3) {
1072 iBaseFont += 2;
1073 }
1074 }
1075 family = g_Base14FontNames[iBaseFont];
1076 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
1077 }
1078 } else {
1079 if (flags & FXFONT_ITALIC) {
1080 bItalic = TRUE;
1081 }
1082 }
1083 iExact = !match.IsEmpty();
1084 void* hFont = m_pFontInfo->MapFont(weight, bItalic, Charset, PitchFamily,
1085 family, iExact);
1086 if (iExact) {
1087 pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT;
1088 }
1089 if (!hFont) {
1090 #ifdef PDF_ENABLE_XFA
1091 if (flags & FXFONT_EXACTMATCH) {
1092 return NULL;
1093 }
1094 #endif // PDF_ENABLE_XFA
1095 if (bCJK) {
1096 if (italic_angle != 0) {
1097 bItalic = TRUE;
1098 } else {
1099 bItalic = FALSE;
1100 }
1101 weight = old_weight;
1102 }
1103 if (!match.IsEmpty()) {
1104 hFont = m_pFontInfo->GetFont(match);
1105 if (!hFont) {
1106 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight,
1107 PitchFamily);
1108 }
1109 } else {
1110 if (Charset == FXFONT_SYMBOL_CHARSET) {
1111 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \
1112 _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
1113 if (SubstName == "Symbol") {
1114 pSubstFont->m_Family = "Chrome Symbol";
1115 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
1116 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
1117 if (m_FoxitFaces[12]) {
1118 return m_FoxitFaces[12];
1119 }
1120 const uint8_t* pFontData = NULL;
1121 FX_DWORD size = 0;
1122 m_pFontMgr->GetBuiltinFont(12, &pFontData, &size);
1123 m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
1124 return m_FoxitFaces[12];
1125 }
1126 #endif
1127 pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL;
1128 return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC,
1129 weight, italic_angle, 0, pSubstFont);
1130 }
1131 if (Charset == FXFONT_ANSI_CHARSET) {
1132 pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
1133 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight,
1134 PitchFamily);
1135 }
1136 int index = m_CharsetArray.Find(Charset);
1137 if (index < 0) {
1138 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight,
1139 PitchFamily);
1140 }
1141 hFont = m_pFontInfo->GetFont(m_FaceArray[index]);
1142 }
1143 }
1144 pSubstFont->m_ExtHandle = m_pFontInfo->RetainFont(hFont);
1145 if (!hFont)
1146 return nullptr;
1147
1148 m_pFontInfo->GetFaceName(hFont, SubstName);
1149 if (Charset == FXFONT_DEFAULT_CHARSET) {
1150 m_pFontInfo->GetFontCharset(hFont, Charset);
1151 }
1152 FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, kTableTTCF, nullptr, 0);
1153 FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, nullptr, 0);
1154 if (font_size == 0 && ttc_size == 0) {
1155 m_pFontInfo->DeleteFont(hFont);
1156 return nullptr;
1157 }
1158 FXFT_Face face = nullptr;
1159 if (ttc_size) {
1160 uint8_t temp[1024];
1161 m_pFontInfo->GetFontData(hFont, kTableTTCF, temp, 1024);
1162 FX_DWORD checksum = 0;
1163 for (int i = 0; i < 256; i++) {
1164 checksum += ((FX_DWORD*)temp)[i];
1165 }
1166 uint8_t* pFontData;
1167 face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum,
1168 ttc_size - font_size, pFontData);
1169 if (!face) {
1170 pFontData = FX_Alloc(uint8_t, ttc_size);
1171 m_pFontInfo->GetFontData(hFont, kTableTTCF, pFontData, ttc_size);
1172 face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData,
1173 ttc_size, ttc_size - font_size);
1174 }
1175 } else {
1176 uint8_t* pFontData;
1177 face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData);
1178 if (!face) {
1179 pFontData = FX_Alloc(uint8_t, font_size);
1180 m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size);
1181 face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData,
1182 font_size,
1183 m_pFontInfo->GetFaceIndex(hFont));
1184 }
1185 }
1186 if (!face) {
1187 m_pFontInfo->DeleteFont(hFont);
1188 return NULL;
1189 }
1190 pSubstFont->m_Family = SubstName;
1191 pSubstFont->m_Charset = Charset;
1192 FX_BOOL bNeedUpdateWeight = FALSE;
1193 if (FXFT_Is_Face_Bold(face)) {
1194 if (weight == FXFONT_FW_BOLD) {
1195 bNeedUpdateWeight = FALSE;
1196 } else {
1197 bNeedUpdateWeight = TRUE;
1198 }
1199 } else {
1200 if (weight == FXFONT_FW_NORMAL) {
1201 bNeedUpdateWeight = FALSE;
1202 } else {
1203 bNeedUpdateWeight = TRUE;
1204 }
1205 }
1206 if (bNeedUpdateWeight) {
1207 pSubstFont->m_Weight = weight;
1208 }
1209 if (bItalic && !FXFT_Is_Face_Italic(face)) {
1210 if (italic_angle == 0) {
1211 italic_angle = -12;
1212 } else if (FXSYS_abs(italic_angle) < 5) {
1213 italic_angle = 0;
1214 }
1215 pSubstFont->m_ItalicAngle = italic_angle;
1216 }
1217 m_pFontInfo->DeleteFont(hFont);
1218 return face;
1219 }
1220 #ifdef PDF_ENABLE_XFA
FindSubstFontByUnicode(FX_DWORD dwUnicode,FX_DWORD flags,int weight,int italic_angle)1221 FXFT_Face CFX_FontMapper::FindSubstFontByUnicode(FX_DWORD dwUnicode,
1222 FX_DWORD flags,
1223 int weight,
1224 int italic_angle) {
1225 if (m_pFontInfo == NULL) {
1226 return NULL;
1227 }
1228 FX_BOOL bItalic = (flags & FXFONT_ITALIC) != 0;
1229 int PitchFamily = 0;
1230 if (flags & FXFONT_SERIF) {
1231 PitchFamily |= FXFONT_FF_ROMAN;
1232 }
1233 if (flags & FXFONT_SCRIPT) {
1234 PitchFamily |= FXFONT_FF_SCRIPT;
1235 }
1236 if (flags & FXFONT_FIXED_PITCH) {
1237 PitchFamily |= FXFONT_FF_FIXEDPITCH;
1238 }
1239 void* hFont =
1240 m_pFontInfo->MapFontByUnicode(dwUnicode, weight, bItalic, PitchFamily);
1241 if (hFont == NULL) {
1242 return NULL;
1243 }
1244 FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, NULL, 0);
1245 FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, NULL, 0);
1246 if (font_size == 0 && ttc_size == 0) {
1247 m_pFontInfo->DeleteFont(hFont);
1248 return NULL;
1249 }
1250 FXFT_Face face = NULL;
1251 if (ttc_size) {
1252 uint8_t temp[1024];
1253 m_pFontInfo->GetFontData(hFont, 0x74746366, temp, 1024);
1254 FX_DWORD checksum = 0;
1255 for (int i = 0; i < 256; i++) {
1256 checksum += ((FX_DWORD*)temp)[i];
1257 }
1258 uint8_t* pFontData;
1259 face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum,
1260 ttc_size - font_size, pFontData);
1261 if (face == NULL) {
1262 pFontData = FX_Alloc(uint8_t, ttc_size);
1263 if (pFontData) {
1264 m_pFontInfo->GetFontData(hFont, 0x74746366, pFontData, ttc_size);
1265 face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData,
1266 ttc_size, ttc_size - font_size);
1267 }
1268 }
1269 } else {
1270 CFX_ByteString SubstName;
1271 m_pFontInfo->GetFaceName(hFont, SubstName);
1272 uint8_t* pFontData;
1273 face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData);
1274 if (face == NULL) {
1275 pFontData = FX_Alloc(uint8_t, font_size);
1276 if (!pFontData) {
1277 m_pFontInfo->DeleteFont(hFont);
1278 return NULL;
1279 }
1280 m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size);
1281 face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData,
1282 font_size,
1283 m_pFontInfo->GetFaceIndex(hFont));
1284 }
1285 }
1286 m_pFontInfo->DeleteFont(hFont);
1287 return face;
1288 }
1289 #endif // PDF_ENABLE_XFA
1290
IsBuiltinFace(const FXFT_Face face) const1291 FX_BOOL CFX_FontMapper::IsBuiltinFace(const FXFT_Face face) const {
1292 for (int i = 0; i < MM_FACE_COUNT; ++i) {
1293 if (m_MMFaces[i] == face) {
1294 return TRUE;
1295 }
1296 }
1297 for (int i = 0; i < FOXIT_FACE_COUNT; ++i) {
1298 if (m_FoxitFaces[i] == face) {
1299 return TRUE;
1300 }
1301 }
1302 return FALSE;
1303 }
1304
1305 extern "C" {
1306 unsigned long _FTStreamRead(FXFT_Stream stream,
1307 unsigned long offset,
1308 unsigned char* buffer,
1309 unsigned long count);
1310 void _FTStreamClose(FXFT_Stream stream);
1311 };
1312 #if _FX_OS_ == _FX_ANDROID_
CreateDefault(const char ** pUnused)1313 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault(const char** pUnused) {
1314 return NULL;
1315 }
1316 #endif
CFX_FolderFontInfo()1317 CFX_FolderFontInfo::CFX_FolderFontInfo() {}
~CFX_FolderFontInfo()1318 CFX_FolderFontInfo::~CFX_FolderFontInfo() {
1319 for (const auto& pair : m_FontList) {
1320 delete pair.second;
1321 }
1322 }
AddPath(const CFX_ByteStringC & path)1323 void CFX_FolderFontInfo::AddPath(const CFX_ByteStringC& path) {
1324 m_PathList.Add(path);
1325 }
Release()1326 void CFX_FolderFontInfo::Release() {
1327 delete this;
1328 }
EnumFontList(CFX_FontMapper * pMapper)1329 FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper) {
1330 m_pMapper = pMapper;
1331 for (int i = 0; i < m_PathList.GetSize(); i++) {
1332 ScanPath(m_PathList[i]);
1333 }
1334 return TRUE;
1335 }
ScanPath(CFX_ByteString & path)1336 void CFX_FolderFontInfo::ScanPath(CFX_ByteString& path) {
1337 void* handle = FX_OpenFolder(path);
1338 if (!handle) {
1339 return;
1340 }
1341 CFX_ByteString filename;
1342 FX_BOOL bFolder;
1343 while (FX_GetNextFile(handle, filename, bFolder)) {
1344 if (bFolder) {
1345 if (filename == "." || filename == "..") {
1346 continue;
1347 }
1348 } else {
1349 CFX_ByteString ext = filename.Right(4);
1350 ext.MakeUpper();
1351 if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC") {
1352 continue;
1353 }
1354 }
1355 CFX_ByteString fullpath = path;
1356 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
1357 fullpath += "\\";
1358 #else
1359 fullpath += "/";
1360 #endif
1361 fullpath += filename;
1362 if (bFolder) {
1363 ScanPath(fullpath);
1364 } else {
1365 ScanFile(fullpath);
1366 }
1367 }
1368 FX_CloseFolder(handle);
1369 }
ScanFile(CFX_ByteString & path)1370 void CFX_FolderFontInfo::ScanFile(CFX_ByteString& path) {
1371 FXSYS_FILE* pFile = FXSYS_fopen(path, "rb");
1372 if (!pFile) {
1373 return;
1374 }
1375 FXSYS_fseek(pFile, 0, FXSYS_SEEK_END);
1376 FX_DWORD filesize = FXSYS_ftell(pFile);
1377 uint8_t buffer[16];
1378 FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET);
1379 size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile);
1380 if (readCnt != 1) {
1381 FXSYS_fclose(pFile);
1382 return;
1383 }
1384
1385 if (GET_TT_LONG(buffer) == kTableTTCF) {
1386 FX_DWORD nFaces = GET_TT_LONG(buffer + 8);
1387 if (nFaces > std::numeric_limits<FX_DWORD>::max() / 4) {
1388 FXSYS_fclose(pFile);
1389 return;
1390 }
1391 FX_DWORD face_bytes = nFaces * 4;
1392 uint8_t* offsets = FX_Alloc(uint8_t, face_bytes);
1393 readCnt = FXSYS_fread(offsets, 1, face_bytes, pFile);
1394 if (readCnt != face_bytes) {
1395 FX_Free(offsets);
1396 FXSYS_fclose(pFile);
1397 return;
1398 }
1399 for (FX_DWORD i = 0; i < nFaces; i++) {
1400 uint8_t* p = offsets + i * 4;
1401 ReportFace(path, pFile, filesize, GET_TT_LONG(p));
1402 }
1403 FX_Free(offsets);
1404 } else {
1405 ReportFace(path, pFile, filesize, 0);
1406 }
1407 FXSYS_fclose(pFile);
1408 }
ReportFace(CFX_ByteString & path,FXSYS_FILE * pFile,FX_DWORD filesize,FX_DWORD offset)1409 void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path,
1410 FXSYS_FILE* pFile,
1411 FX_DWORD filesize,
1412 FX_DWORD offset) {
1413 FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
1414 char buffer[16];
1415 if (!FXSYS_fread(buffer, 12, 1, pFile)) {
1416 return;
1417 }
1418 FX_DWORD nTables = GET_TT_SHORT(buffer + 4);
1419 CFX_ByteString tables = FPDF_ReadStringFromFile(pFile, nTables * 16);
1420 if (tables.IsEmpty()) {
1421 return;
1422 }
1423 CFX_ByteString names =
1424 FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616d65);
1425 CFX_ByteString facename = GetNameFromTT(names, 1);
1426 CFX_ByteString style = GetNameFromTT(names, 2);
1427 if (style != "Regular") {
1428 facename += " " + style;
1429 }
1430 if (pdfium::ContainsKey(m_FontList, facename))
1431 return;
1432
1433 CFX_FontFaceInfo* pInfo =
1434 new CFX_FontFaceInfo(path, facename, tables, offset, filesize);
1435 CFX_ByteString os2 = FPDF_LoadTableFromTT(pFile, tables, nTables, 0x4f532f32);
1436 if (os2.GetLength() >= 86) {
1437 const uint8_t* p = (const uint8_t*)os2 + 78;
1438 FX_DWORD codepages = GET_TT_LONG(p);
1439 if (codepages & (1 << 17)) {
1440 m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET);
1441 pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS;
1442 }
1443 if (codepages & (1 << 18)) {
1444 m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET);
1445 pInfo->m_Charsets |= CHARSET_FLAG_GB;
1446 }
1447 if (codepages & (1 << 20)) {
1448 m_pMapper->AddInstalledFont(facename, FXFONT_CHINESEBIG5_CHARSET);
1449 pInfo->m_Charsets |= CHARSET_FLAG_BIG5;
1450 }
1451 if ((codepages & (1 << 19)) || (codepages & (1 << 21))) {
1452 m_pMapper->AddInstalledFont(facename, FXFONT_HANGEUL_CHARSET);
1453 pInfo->m_Charsets |= CHARSET_FLAG_KOREAN;
1454 }
1455 if (codepages & (1 << 31)) {
1456 m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET);
1457 pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL;
1458 }
1459 }
1460 m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET);
1461 pInfo->m_Charsets |= CHARSET_FLAG_ANSI;
1462 pInfo->m_Styles = 0;
1463 if (style.Find("Bold") > -1) {
1464 pInfo->m_Styles |= FXFONT_BOLD;
1465 }
1466 if (style.Find("Italic") > -1 || style.Find("Oblique") > -1) {
1467 pInfo->m_Styles |= FXFONT_ITALIC;
1468 }
1469 if (facename.Find("Serif") > -1) {
1470 pInfo->m_Styles |= FXFONT_SERIF;
1471 }
1472 m_FontList[facename] = pInfo;
1473 }
1474
GetSubstFont(const CFX_ByteString & face)1475 void* CFX_FolderFontInfo::GetSubstFont(const CFX_ByteString& face) {
1476 for (size_t iBaseFont = 0; iBaseFont < FX_ArraySize(Base14Substs);
1477 iBaseFont++) {
1478 if (face == Base14Substs[iBaseFont].m_pName) {
1479 return GetFont(Base14Substs[iBaseFont].m_pSubstName);
1480 }
1481 }
1482 return nullptr;
1483 }
1484
FindFont(int weight,FX_BOOL bItalic,int charset,int pitch_family,const FX_CHAR * family,FX_BOOL bMatchName)1485 void* CFX_FolderFontInfo::FindFont(int weight,
1486 FX_BOOL bItalic,
1487 int charset,
1488 int pitch_family,
1489 const FX_CHAR* family,
1490 FX_BOOL bMatchName) {
1491 CFX_FontFaceInfo* pFind = nullptr;
1492 if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) {
1493 return GetFont("Courier New");
1494 }
1495 FX_DWORD charset_flag = GetCharset(charset);
1496 int32_t iBestSimilar = 0;
1497 for (const auto& it : m_FontList) {
1498 const CFX_ByteString& bsName = it.first;
1499 CFX_FontFaceInfo* pFont = it.second;
1500 if (!(pFont->m_Charsets & charset_flag) &&
1501 charset != FXFONT_DEFAULT_CHARSET) {
1502 continue;
1503 }
1504 int32_t index = bsName.Find(family);
1505 if (bMatchName && index < 0) {
1506 continue;
1507 }
1508 int32_t iSimilarValue =
1509 GetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles);
1510 if (iSimilarValue > iBestSimilar) {
1511 iBestSimilar = iSimilarValue;
1512 pFind = pFont;
1513 }
1514 }
1515 return pFind;
1516 }
MapFont(int weight,FX_BOOL bItalic,int charset,int pitch_family,const FX_CHAR * family,int & iExact)1517 void* CFX_FolderFontInfo::MapFont(int weight,
1518 FX_BOOL bItalic,
1519 int charset,
1520 int pitch_family,
1521 const FX_CHAR* family,
1522 int& iExact) {
1523 return NULL;
1524 }
1525
1526 #ifdef PDF_ENABLE_XFA
MapFontByUnicode(FX_DWORD dwUnicode,int weight,FX_BOOL bItalic,int pitch_family)1527 void* CFX_FolderFontInfo::MapFontByUnicode(FX_DWORD dwUnicode,
1528 int weight,
1529 FX_BOOL bItalic,
1530 int pitch_family) {
1531 return NULL;
1532 }
1533 #endif // PDF_ENABLE_XFA
1534
GetFont(const FX_CHAR * face)1535 void* CFX_FolderFontInfo::GetFont(const FX_CHAR* face) {
1536 auto it = m_FontList.find(face);
1537 return it != m_FontList.end() ? it->second : nullptr;
1538 }
1539
GetFontData(void * hFont,FX_DWORD table,uint8_t * buffer,FX_DWORD size)1540 FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont,
1541 FX_DWORD table,
1542 uint8_t* buffer,
1543 FX_DWORD size) {
1544 if (!hFont)
1545 return 0;
1546
1547 const CFX_FontFaceInfo* pFont = static_cast<CFX_FontFaceInfo*>(hFont);
1548 FX_DWORD datasize = 0;
1549 FX_DWORD offset = 0;
1550 if (table == 0) {
1551 datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize;
1552 } else if (table == kTableTTCF) {
1553 datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0;
1554 } else {
1555 FX_DWORD nTables = pFont->m_FontTables.GetLength() / 16;
1556 for (FX_DWORD i = 0; i < nTables; i++) {
1557 const uint8_t* p =
1558 static_cast<const uint8_t*>(pFont->m_FontTables) + i * 16;
1559 if (GET_TT_LONG(p) == table) {
1560 offset = GET_TT_LONG(p + 8);
1561 datasize = GET_TT_LONG(p + 12);
1562 }
1563 }
1564 }
1565
1566 if (!datasize || size < datasize)
1567 return datasize;
1568
1569 FXSYS_FILE* pFile = FXSYS_fopen(pFont->m_FilePath, "rb");
1570 if (!pFile)
1571 return 0;
1572
1573 if (FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET) < 0 ||
1574 FXSYS_fread(buffer, datasize, 1, pFile) != 1) {
1575 datasize = 0;
1576 }
1577 FXSYS_fclose(pFile);
1578 return datasize;
1579 }
1580
DeleteFont(void * hFont)1581 void CFX_FolderFontInfo::DeleteFont(void* hFont) {}
GetFaceName(void * hFont,CFX_ByteString & name)1582 FX_BOOL CFX_FolderFontInfo::GetFaceName(void* hFont, CFX_ByteString& name) {
1583 if (!hFont) {
1584 return FALSE;
1585 }
1586 CFX_FontFaceInfo* pFont = (CFX_FontFaceInfo*)hFont;
1587 name = pFont->m_FaceName;
1588 return TRUE;
1589 }
GetFontCharset(void * hFont,int & charset)1590 FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset) {
1591 return FALSE;
1592 }
1593
PDF_GetStandardFontName(CFX_ByteString * name)1594 int PDF_GetStandardFontName(CFX_ByteString* name) {
1595 AltFontName* found = static_cast<AltFontName*>(
1596 FXSYS_bsearch(name->c_str(), g_AltFontNames, FX_ArraySize(g_AltFontNames),
1597 sizeof(AltFontName), CompareString));
1598 if (!found)
1599 return -1;
1600
1601 *name = g_Base14FontNames[found->m_Index];
1602 return found->m_Index;
1603 }
1604