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