Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: core/src/fxge/ge/fx_ge_fontmap.cpp

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

Powered by Google App Engine
This is Rietveld 408576698