| OLD | NEW |
| (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 } | |
| OLD | NEW |