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