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