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