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