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