1 // Copyright 2016 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 "core/fxge/cfx_fontmapper.h" 8 9 #include <memory> 10 #include <utility> 11 #include <vector> 12 13 #include "core/fxge/cfx_substfont.h" 14 #include "core/fxge/fx_font.h" 15 #include "core/fxge/ifx_systemfontinfo.h" 16 17 #include "third_party/base/stl_util.h" 18 19 #define FX_FONT_STYLE_None 0x00 20 #define FX_FONT_STYLE_Bold 0x01 21 #define FX_FONT_STYLE_Italic 0x02 22 #define FX_FONT_STYLE_BoldBold 0x04 23 24 namespace { 25 26 const int kNumStandardFonts = 14; 27 28 const FX_CHAR* const g_Base14FontNames[kNumStandardFonts] = { 29 "Courier", 30 "Courier-Bold", 31 "Courier-BoldOblique", 32 "Courier-Oblique", 33 "Helvetica", 34 "Helvetica-Bold", 35 "Helvetica-BoldOblique", 36 "Helvetica-Oblique", 37 "Times-Roman", 38 "Times-Bold", 39 "Times-BoldItalic", 40 "Times-Italic", 41 "Symbol", 42 "ZapfDingbats", 43 }; 44 45 const struct AltFontName { 46 const FX_CHAR* m_pName; 47 int m_Index; 48 } g_AltFontNames[] = { 49 {"Arial", 4}, 50 {"Arial,Bold", 5}, 51 {"Arial,BoldItalic", 6}, 52 {"Arial,Italic", 7}, 53 {"Arial-Bold", 5}, 54 {"Arial-BoldItalic", 6}, 55 {"Arial-BoldItalicMT", 6}, 56 {"Arial-BoldMT", 5}, 57 {"Arial-Italic", 7}, 58 {"Arial-ItalicMT", 7}, 59 {"ArialBold", 5}, 60 {"ArialBoldItalic", 6}, 61 {"ArialItalic", 7}, 62 {"ArialMT", 4}, 63 {"ArialMT,Bold", 5}, 64 {"ArialMT,BoldItalic", 6}, 65 {"ArialMT,Italic", 7}, 66 {"ArialRoundedMTBold", 5}, 67 {"Courier", 0}, 68 {"Courier,Bold", 1}, 69 {"Courier,BoldItalic", 2}, 70 {"Courier,Italic", 3}, 71 {"Courier-Bold", 1}, 72 {"Courier-BoldOblique", 2}, 73 {"Courier-Oblique", 3}, 74 {"CourierBold", 1}, 75 {"CourierBoldItalic", 2}, 76 {"CourierItalic", 3}, 77 {"CourierNew", 0}, 78 {"CourierNew,Bold", 1}, 79 {"CourierNew,BoldItalic", 2}, 80 {"CourierNew,Italic", 3}, 81 {"CourierNew-Bold", 1}, 82 {"CourierNew-BoldItalic", 2}, 83 {"CourierNew-Italic", 3}, 84 {"CourierNewBold", 1}, 85 {"CourierNewBoldItalic", 2}, 86 {"CourierNewItalic", 3}, 87 {"CourierNewPS-BoldItalicMT", 2}, 88 {"CourierNewPS-BoldMT", 1}, 89 {"CourierNewPS-ItalicMT", 3}, 90 {"CourierNewPSMT", 0}, 91 {"CourierStd", 0}, 92 {"CourierStd-Bold", 1}, 93 {"CourierStd-BoldOblique", 2}, 94 {"CourierStd-Oblique", 3}, 95 {"Helvetica", 4}, 96 {"Helvetica,Bold", 5}, 97 {"Helvetica,BoldItalic", 6}, 98 {"Helvetica,Italic", 7}, 99 {"Helvetica-Bold", 5}, 100 {"Helvetica-BoldItalic", 6}, 101 {"Helvetica-BoldOblique", 6}, 102 {"Helvetica-Italic", 7}, 103 {"Helvetica-Oblique", 7}, 104 {"HelveticaBold", 5}, 105 {"HelveticaBoldItalic", 6}, 106 {"HelveticaItalic", 7}, 107 {"Symbol", 12}, 108 {"SymbolMT", 12}, 109 {"Times-Bold", 9}, 110 {"Times-BoldItalic", 10}, 111 {"Times-Italic", 11}, 112 {"Times-Roman", 8}, 113 {"TimesBold", 9}, 114 {"TimesBoldItalic", 10}, 115 {"TimesItalic", 11}, 116 {"TimesNewRoman", 8}, 117 {"TimesNewRoman,Bold", 9}, 118 {"TimesNewRoman,BoldItalic", 10}, 119 {"TimesNewRoman,Italic", 11}, 120 {"TimesNewRoman-Bold", 9}, 121 {"TimesNewRoman-BoldItalic", 10}, 122 {"TimesNewRoman-Italic", 11}, 123 {"TimesNewRomanBold", 9}, 124 {"TimesNewRomanBoldItalic", 10}, 125 {"TimesNewRomanItalic", 11}, 126 {"TimesNewRomanPS", 8}, 127 {"TimesNewRomanPS-Bold", 9}, 128 {"TimesNewRomanPS-BoldItalic", 10}, 129 {"TimesNewRomanPS-BoldItalicMT", 10}, 130 {"TimesNewRomanPS-BoldMT", 9}, 131 {"TimesNewRomanPS-Italic", 11}, 132 {"TimesNewRomanPS-ItalicMT", 11}, 133 {"TimesNewRomanPSMT", 8}, 134 {"TimesNewRomanPSMT,Bold", 9}, 135 {"TimesNewRomanPSMT,BoldItalic", 10}, 136 {"TimesNewRomanPSMT,Italic", 11}, 137 {"ZapfDingbats", 13}, 138 }; 139 140 const struct AltFontFamily { 141 const FX_CHAR* m_pFontName; 142 const FX_CHAR* m_pFontFamily; 143 } g_AltFontFamilies[] = { 144 {"AGaramondPro", "Adobe Garamond Pro"}, 145 {"BankGothicBT-Medium", "BankGothic Md BT"}, 146 {"ForteMT", "Forte"}, 147 }; 148 149 const struct FX_FontStyle { 150 const FX_CHAR* style; 151 int32_t len; 152 } g_FontStyles[] = { 153 {"Bold", 4}, {"Italic", 6}, {"BoldItalic", 10}, {"Reg", 3}, {"Regular", 7}, 154 }; 155 156 const struct CODEPAGE_MAP { 157 uint16_t codepage; 158 uint8_t charset; 159 } g_Codepage2CharsetTable[] = { 160 {0, 1}, {42, 2}, {437, 254}, {850, 255}, {874, 222}, 161 {932, 128}, {936, 134}, {949, 129}, {950, 136}, {1250, 238}, 162 {1251, 204}, {1252, 0}, {1253, 161}, {1254, 162}, {1255, 177}, 163 {1256, 178}, {1257, 186}, {1258, 163}, {1361, 130}, {10000, 77}, 164 {10001, 78}, {10002, 81}, {10003, 79}, {10004, 84}, {10005, 83}, 165 {10006, 85}, {10007, 89}, {10008, 80}, {10021, 87}, {10029, 88}, 166 {10081, 86}, 167 }; 168 169 int CompareFontFamilyString(const void* key, const void* element) { 170 CFX_ByteString str_key((const FX_CHAR*)key); 171 const AltFontFamily* family = reinterpret_cast<const AltFontFamily*>(element); 172 if (str_key.Find(family->m_pFontName) != -1) 173 return 0; 174 return FXSYS_stricmp(reinterpret_cast<const FX_CHAR*>(key), 175 family->m_pFontName); 176 } 177 178 int CompareString(const void* key, const void* element) { 179 return FXSYS_stricmp(reinterpret_cast<const FX_CHAR*>(key), 180 reinterpret_cast<const AltFontName*>(element)->m_pName); 181 } 182 183 CFX_ByteString TT_NormalizeName(const FX_CHAR* family) { 184 CFX_ByteString norm(family); 185 norm.Remove(' '); 186 norm.Remove('-'); 187 norm.Remove(','); 188 int pos = norm.Find('+'); 189 if (pos > 0) 190 norm = norm.Left(pos); 191 norm.MakeLower(); 192 return norm; 193 } 194 195 uint8_t GetCharsetFromCodePage(uint16_t codepage) { 196 const CODEPAGE_MAP* pEnd = 197 g_Codepage2CharsetTable + FX_ArraySize(g_Codepage2CharsetTable); 198 const CODEPAGE_MAP* pCharmap = 199 std::lower_bound(g_Codepage2CharsetTable, pEnd, codepage, 200 [](const CODEPAGE_MAP& charset, uint16_t page) { 201 return charset.codepage < page; 202 }); 203 if (pCharmap < pEnd && codepage == pCharmap->codepage) 204 return pCharmap->charset; 205 return FXFONT_DEFAULT_CHARSET; 206 } 207 208 CFX_ByteString GetFontFamily(CFX_ByteString fontName, int nStyle) { 209 if (fontName.Find("Script") >= 0) { 210 if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) 211 fontName = "ScriptMTBold"; 212 else if (fontName.Find("Palace") >= 0) 213 fontName = "PalaceScriptMT"; 214 else if (fontName.Find("French") >= 0) 215 fontName = "FrenchScriptMT"; 216 else if (fontName.Find("FreeStyle") >= 0) 217 fontName = "FreeStyleScript"; 218 return fontName; 219 } 220 AltFontFamily* found = reinterpret_cast<AltFontFamily*>(FXSYS_bsearch( 221 fontName.c_str(), g_AltFontFamilies, FX_ArraySize(g_AltFontFamilies), 222 sizeof(AltFontFamily), CompareFontFamilyString)); 223 return found ? CFX_ByteString(found->m_pFontFamily) : fontName; 224 } 225 226 CFX_ByteString ParseStyle(const FX_CHAR* pStyle, int iLen, int iIndex) { 227 CFX_ByteTextBuf buf; 228 if (!iLen || iLen <= iIndex) 229 return buf.MakeString(); 230 while (iIndex < iLen) { 231 if (pStyle[iIndex] == ',') 232 break; 233 buf.AppendChar(pStyle[iIndex]); 234 ++iIndex; 235 } 236 return buf.MakeString(); 237 } 238 239 int32_t GetStyleType(const CFX_ByteString& bsStyle, bool bReverse) { 240 int32_t iLen = bsStyle.GetLength(); 241 if (!iLen) 242 return -1; 243 int iSize = FX_ArraySize(g_FontStyles); 244 const FX_FontStyle* pStyle = nullptr; 245 for (int i = iSize - 1; i >= 0; --i) { 246 pStyle = g_FontStyles + i; 247 if (!pStyle || pStyle->len > iLen) 248 continue; 249 250 if (bReverse) { 251 if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) 252 return i; 253 } else { 254 if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) 255 return i; 256 } 257 } 258 return -1; 259 } 260 261 bool CheckSupportThirdPartFont(CFX_ByteString name, int& PitchFamily) { 262 if (name == "MyriadPro") { 263 PitchFamily &= ~FXFONT_FF_ROMAN; 264 return true; 265 } 266 return false; 267 } 268 269 void UpdatePitchFamily(uint32_t flags, int& PitchFamily) { 270 if (flags & FXFONT_SERIF) 271 PitchFamily |= FXFONT_FF_ROMAN; 272 if (flags & FXFONT_SCRIPT) 273 PitchFamily |= FXFONT_FF_SCRIPT; 274 if (flags & FXFONT_FIXED_PITCH) 275 PitchFamily |= FXFONT_FF_FIXEDPITCH; 276 } 277 278 } // namespace 279 280 CFX_FontMapper::CFX_FontMapper(CFX_FontMgr* mgr) 281 : m_bListLoaded(false), m_pFontMgr(mgr) { 282 m_MMFaces[0] = nullptr; 283 m_MMFaces[1] = nullptr; 284 FXSYS_memset(m_FoxitFaces, 0, sizeof(m_FoxitFaces)); 285 } 286 287 CFX_FontMapper::~CFX_FontMapper() { 288 for (size_t i = 0; i < FX_ArraySize(m_FoxitFaces); ++i) { 289 if (m_FoxitFaces[i]) 290 FXFT_Done_Face(m_FoxitFaces[i]); 291 } 292 if (m_MMFaces[0]) 293 FXFT_Done_Face(m_MMFaces[0]); 294 if (m_MMFaces[1]) 295 FXFT_Done_Face(m_MMFaces[1]); 296 } 297 298 void CFX_FontMapper::SetSystemFontInfo( 299 std::unique_ptr<IFX_SystemFontInfo> pFontInfo) { 300 if (!pFontInfo) 301 return; 302 303 m_pFontInfo = std::move(pFontInfo); 304 } 305 306 CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont) { 307 if (!m_pFontInfo) 308 return CFX_ByteString(); 309 310 uint32_t size = m_pFontInfo->GetFontData(hFont, kTableNAME, nullptr, 0); 311 if (!size) 312 return CFX_ByteString(); 313 314 std::vector<uint8_t> buffer(size); 315 uint8_t* buffer_ptr = buffer.data(); 316 uint32_t bytes_read = 317 m_pFontInfo->GetFontData(hFont, kTableNAME, buffer_ptr, size); 318 return bytes_read == size ? GetNameFromTT(buffer_ptr, bytes_read, 6) 319 : CFX_ByteString(); 320 } 321 322 void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset) { 323 if (!m_pFontInfo) 324 return; 325 326 m_FaceArray.push_back({name, static_cast<uint32_t>(charset)}); 327 if (name == m_LastFamily) 328 return; 329 330 const uint8_t* ptr = name.raw_str(); 331 bool bLocalized = false; 332 for (int i = 0; i < name.GetLength(); i++) { 333 if (ptr[i] > 0x80) { 334 bLocalized = true; 335 break; 336 } 337 } 338 339 if (bLocalized) { 340 void* hFont = m_pFontInfo->GetFont(name.c_str()); 341 if (!hFont) { 342 int iExact; 343 hFont = m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, 344 name.c_str(), iExact); 345 if (!hFont) 346 return; 347 } 348 349 CFX_ByteString new_name = GetPSNameFromTT(hFont); 350 if (!new_name.IsEmpty()) 351 m_LocalizedTTFonts.push_back(std::make_pair(new_name, name)); 352 m_pFontInfo->DeleteFont(hFont); 353 } 354 m_InstalledTTFonts.push_back(name); 355 m_LastFamily = name; 356 } 357 358 void CFX_FontMapper::LoadInstalledFonts() { 359 if (!m_pFontInfo || m_bListLoaded) 360 return; 361 362 m_pFontInfo->EnumFontList(this); 363 m_bListLoaded = true; 364 } 365 366 CFX_ByteString CFX_FontMapper::MatchInstalledFonts( 367 const CFX_ByteString& norm_name) { 368 LoadInstalledFonts(); 369 int i; 370 for (i = pdfium::CollectionSize<int>(m_InstalledTTFonts) - 1; i >= 0; i--) { 371 CFX_ByteString norm1 = TT_NormalizeName(m_InstalledTTFonts[i].c_str()); 372 if (norm1 == norm_name) 373 return m_InstalledTTFonts[i]; 374 } 375 for (i = pdfium::CollectionSize<int>(m_LocalizedTTFonts) - 1; i >= 0; i--) { 376 CFX_ByteString norm1 = 377 TT_NormalizeName(m_LocalizedTTFonts[i].first.c_str()); 378 if (norm1 == norm_name) 379 return m_LocalizedTTFonts[i].second; 380 } 381 return CFX_ByteString(); 382 } 383 384 FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont, 385 int iBaseFont, 386 int italic_angle, 387 int weight, 388 int picthfamily) { 389 if (iBaseFont < kNumStandardFonts) { 390 if (m_FoxitFaces[iBaseFont]) 391 return m_FoxitFaces[iBaseFont]; 392 const uint8_t* pFontData = nullptr; 393 uint32_t size = 0; 394 if (m_pFontMgr->GetBuiltinFont(iBaseFont, &pFontData, &size)) { 395 m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(pFontData, size, 0); 396 return m_FoxitFaces[iBaseFont]; 397 } 398 } 399 pSubstFont->m_SubstFlags |= FXFONT_SUBST_MM; 400 pSubstFont->m_ItalicAngle = italic_angle; 401 if (weight) 402 pSubstFont->m_Weight = weight; 403 if (picthfamily & FXFONT_FF_ROMAN) { 404 pSubstFont->m_Weight = pSubstFont->m_Weight * 4 / 5; 405 pSubstFont->m_Family = "Chrome Serif"; 406 if (m_MMFaces[1]) 407 return m_MMFaces[1]; 408 const uint8_t* pFontData = nullptr; 409 uint32_t size = 0; 410 m_pFontMgr->GetBuiltinFont(14, &pFontData, &size); 411 m_MMFaces[1] = m_pFontMgr->GetFixedFace(pFontData, size, 0); 412 return m_MMFaces[1]; 413 } 414 pSubstFont->m_Family = "Chrome Sans"; 415 if (m_MMFaces[0]) 416 return m_MMFaces[0]; 417 const uint8_t* pFontData = nullptr; 418 uint32_t size = 0; 419 m_pFontMgr->GetBuiltinFont(15, &pFontData, &size); 420 m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0); 421 return m_MMFaces[0]; 422 } 423 424 FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, 425 bool bTrueType, 426 uint32_t flags, 427 int weight, 428 int italic_angle, 429 int WindowCP, 430 CFX_SubstFont* pSubstFont) { 431 if (!(flags & FXFONT_USEEXTERNATTR)) { 432 weight = FXFONT_FW_NORMAL; 433 italic_angle = 0; 434 } 435 CFX_ByteString SubstName = name; 436 SubstName.Remove(' '); 437 if (bTrueType && name[0] == '@') 438 SubstName = name.Mid(1); 439 PDF_GetStandardFontName(&SubstName); 440 if (SubstName == "Symbol" && !bTrueType) { 441 pSubstFont->m_Family = "Chrome Symbol"; 442 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; 443 return UseInternalSubst(pSubstFont, 12, italic_angle, weight, 0); 444 } 445 if (SubstName == "ZapfDingbats") { 446 pSubstFont->m_Family = "Chrome Dingbats"; 447 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; 448 return UseInternalSubst(pSubstFont, 13, italic_angle, weight, 0); 449 } 450 int iBaseFont = 0; 451 CFX_ByteString family; 452 CFX_ByteString style; 453 bool bHasComma = false; 454 bool bHasHyphen = false; 455 int find = SubstName.Find(",", 0); 456 if (find >= 0) { 457 family = SubstName.Left(find); 458 PDF_GetStandardFontName(&family); 459 style = SubstName.Mid(find + 1); 460 bHasComma = true; 461 } else { 462 family = SubstName; 463 } 464 for (; iBaseFont < 12; iBaseFont++) { 465 if (family == CFX_ByteStringC(g_Base14FontNames[iBaseFont])) 466 break; 467 } 468 int PitchFamily = 0; 469 bool bItalic = false; 470 uint32_t nStyle = 0; 471 bool bStyleAvail = false; 472 if (iBaseFont < 12) { 473 if ((iBaseFont % 4) == 1 || (iBaseFont % 4) == 2) 474 nStyle |= FX_FONT_STYLE_Bold; 475 if ((iBaseFont % 4) / 2) 476 nStyle |= FX_FONT_STYLE_Italic; 477 if (iBaseFont < 4) 478 PitchFamily |= FXFONT_FF_FIXEDPITCH; 479 if (iBaseFont >= 8) 480 PitchFamily |= FXFONT_FF_ROMAN; 481 } else { 482 iBaseFont = kNumStandardFonts; 483 if (!bHasComma) { 484 find = family.ReverseFind('-'); 485 if (find >= 0) { 486 style = family.Mid(find + 1); 487 family = family.Left(find); 488 bHasHyphen = true; 489 } 490 } 491 if (!bHasHyphen) { 492 int nLen = family.GetLength(); 493 int32_t nRet = GetStyleType(family, true); 494 if (nRet > -1) { 495 family = family.Left(nLen - g_FontStyles[nRet].len); 496 if (nRet == 0) 497 nStyle |= FX_FONT_STYLE_Bold; 498 else if (nRet == 1) 499 nStyle |= FX_FONT_STYLE_Italic; 500 else if (nRet == 2) 501 nStyle |= (FX_FONT_STYLE_Bold | FX_FONT_STYLE_Italic); 502 } 503 } 504 UpdatePitchFamily(flags, PitchFamily); 505 } 506 if (!style.IsEmpty()) { 507 int nLen = style.GetLength(); 508 const FX_CHAR* pStyle = style.c_str(); 509 int i = 0; 510 bool bFirstItem = true; 511 CFX_ByteString buf; 512 while (i < nLen) { 513 buf = ParseStyle(pStyle, nLen, i); 514 int32_t nRet = GetStyleType(buf, false); 515 if ((i && !bStyleAvail) || (!i && nRet < 0)) { 516 family = SubstName; 517 iBaseFont = kNumStandardFonts; 518 break; 519 } 520 if (nRet >= 0) { 521 bStyleAvail = true; 522 } 523 if (nRet == 1) { 524 if (bFirstItem) { 525 nStyle |= FX_FONT_STYLE_Italic; 526 } else { 527 family = SubstName; 528 iBaseFont = kNumStandardFonts; 529 } 530 break; 531 } 532 if (nRet == 0) { 533 if (nStyle & FX_FONT_STYLE_Bold) 534 nStyle |= FX_FONT_STYLE_BoldBold; 535 else 536 nStyle |= FX_FONT_STYLE_Bold; 537 bFirstItem = false; 538 } else if (nRet == 2) { 539 nStyle |= FX_FONT_STYLE_Italic; 540 if (nStyle & FX_FONT_STYLE_Bold) 541 nStyle |= FX_FONT_STYLE_BoldBold; 542 else 543 nStyle |= FX_FONT_STYLE_Bold; 544 bFirstItem = false; 545 } 546 i += buf.GetLength() + 1; 547 } 548 } 549 weight = weight ? weight : FXFONT_FW_NORMAL; 550 int old_weight = weight; 551 if (nStyle) { 552 weight = 553 nStyle & FX_FONT_STYLE_BoldBold 554 ? 900 555 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); 556 } 557 if (nStyle & FX_FONT_STYLE_Italic) 558 bItalic = true; 559 int iExact = 0; 560 int Charset = FXFONT_ANSI_CHARSET; 561 if (WindowCP) 562 Charset = GetCharsetFromCodePage(WindowCP); 563 else if (iBaseFont == kNumStandardFonts && (flags & FXFONT_SYMBOLIC)) 564 Charset = FXFONT_SYMBOL_CHARSET; 565 bool bCJK = 566 (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET || 567 Charset == FXFONT_HANGUL_CHARSET || 568 Charset == FXFONT_CHINESEBIG5_CHARSET); 569 if (!m_pFontInfo) { 570 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, 571 PitchFamily); 572 } 573 family = GetFontFamily(family, nStyle); 574 CFX_ByteString match = MatchInstalledFonts(TT_NormalizeName(family.c_str())); 575 if (match.IsEmpty() && family != SubstName && 576 (!bHasComma && (!bHasHyphen || (bHasHyphen && !bStyleAvail)))) { 577 match = MatchInstalledFonts(TT_NormalizeName(SubstName.c_str())); 578 } 579 if (match.IsEmpty() && iBaseFont >= kNumStandardFonts) { 580 if (!bCJK) { 581 if (!CheckSupportThirdPartFont(family, PitchFamily)) { 582 bItalic = italic_angle != 0; 583 weight = old_weight; 584 } 585 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ 586 if (SubstName.Find("Narrow") > 0 || SubstName.Find("Condensed") > 0) 587 family = "LiberationSansNarrow"; 588 #elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ 589 if (family.Find("Narrow") > 0 || family.Find("Condensed") > 0) 590 family = "RobotoCondensed"; 591 #else 592 if (family.Find("Narrow") > 0 || family.Find("Condensed") > 0) 593 family = "ArialNarrow"; 594 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ 595 } else { 596 pSubstFont->m_bSubstCJK = true; 597 if (nStyle) 598 pSubstFont->m_WeightCJK = nStyle ? weight : FXFONT_FW_NORMAL; 599 if (nStyle & FX_FONT_STYLE_Italic) 600 pSubstFont->m_bItalicCJK = true; 601 } 602 } else { 603 italic_angle = 0; 604 weight = 605 nStyle & FX_FONT_STYLE_BoldBold 606 ? 900 607 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL); 608 } 609 if (!match.IsEmpty() || iBaseFont < kNumStandardFonts) { 610 if (!match.IsEmpty()) 611 family = match; 612 if (iBaseFont < kNumStandardFonts) { 613 if (nStyle && !(iBaseFont % 4)) { 614 if ((nStyle & 0x3) == 1) 615 iBaseFont += 1; 616 if ((nStyle & 0x3) == 2) 617 iBaseFont += 3; 618 if ((nStyle & 0x3) == 3) 619 iBaseFont += 2; 620 } 621 family = g_Base14FontNames[iBaseFont]; 622 } 623 } else { 624 if (flags & FXFONT_ITALIC) 625 bItalic = true; 626 } 627 iExact = !match.IsEmpty(); 628 void* hFont = m_pFontInfo->MapFont(weight, bItalic, Charset, PitchFamily, 629 family.c_str(), iExact); 630 if (iExact) 631 pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT; 632 if (!hFont) { 633 #ifdef PDF_ENABLE_XFA 634 if (flags & FXFONT_EXACTMATCH) 635 return nullptr; 636 #endif // PDF_ENABLE_XFA 637 if (bCJK) { 638 bItalic = italic_angle != 0; 639 weight = old_weight; 640 } 641 if (!match.IsEmpty()) { 642 hFont = m_pFontInfo->GetFont(match.c_str()); 643 if (!hFont) { 644 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, 645 PitchFamily); 646 } 647 } else { 648 if (Charset == FXFONT_SYMBOL_CHARSET) { 649 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \ 650 _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ 651 if (SubstName == "Symbol") { 652 pSubstFont->m_Family = "Chrome Symbol"; 653 pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET; 654 return UseInternalSubst(pSubstFont, 12, italic_angle, old_weight, 655 PitchFamily); 656 } 657 #endif 658 return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, 659 weight, italic_angle, 0, pSubstFont); 660 } 661 if (Charset == FXFONT_ANSI_CHARSET) { 662 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, 663 PitchFamily); 664 } 665 666 auto it = 667 std::find_if(m_FaceArray.begin(), m_FaceArray.end(), 668 [Charset](const FaceData& face) { 669 return face.charset == static_cast<uint32_t>(Charset); 670 }); 671 if (it == m_FaceArray.end()) { 672 return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, 673 PitchFamily); 674 } 675 hFont = m_pFontInfo->GetFont(it->name.c_str()); 676 } 677 } 678 if (!hFont) 679 return nullptr; 680 681 m_pFontInfo->GetFaceName(hFont, SubstName); 682 if (Charset == FXFONT_DEFAULT_CHARSET) 683 m_pFontInfo->GetFontCharset(hFont, Charset); 684 uint32_t ttc_size = m_pFontInfo->GetFontData(hFont, kTableTTCF, nullptr, 0); 685 uint32_t font_size = m_pFontInfo->GetFontData(hFont, 0, nullptr, 0); 686 if (font_size == 0 && ttc_size == 0) { 687 m_pFontInfo->DeleteFont(hFont); 688 return nullptr; 689 } 690 FXFT_Face face = nullptr; 691 if (ttc_size) 692 face = GetCachedTTCFace(hFont, kTableTTCF, ttc_size, font_size); 693 else 694 face = GetCachedFace(hFont, SubstName, weight, bItalic, font_size); 695 if (!face) { 696 m_pFontInfo->DeleteFont(hFont); 697 return nullptr; 698 } 699 pSubstFont->m_Family = SubstName; 700 pSubstFont->m_Charset = Charset; 701 bool bNeedUpdateWeight = false; 702 if (FXFT_Is_Face_Bold(face)) 703 bNeedUpdateWeight = weight != FXFONT_FW_BOLD; 704 else 705 bNeedUpdateWeight = weight != FXFONT_FW_NORMAL; 706 if (bNeedUpdateWeight) 707 pSubstFont->m_Weight = weight; 708 if (bItalic && !FXFT_Is_Face_Italic(face)) { 709 if (italic_angle == 0) 710 italic_angle = -12; 711 else if (FXSYS_abs(italic_angle) < 5) 712 italic_angle = 0; 713 pSubstFont->m_ItalicAngle = italic_angle; 714 } 715 m_pFontInfo->DeleteFont(hFont); 716 return face; 717 } 718 719 #ifdef PDF_ENABLE_XFA 720 FXFT_Face CFX_FontMapper::FindSubstFontByUnicode(uint32_t dwUnicode, 721 uint32_t flags, 722 int weight, 723 int italic_angle) { 724 if (!m_pFontInfo) 725 return nullptr; 726 727 bool bItalic = (flags & FXFONT_ITALIC) != 0; 728 int PitchFamily = 0; 729 UpdatePitchFamily(flags, PitchFamily); 730 void* hFont = 731 m_pFontInfo->MapFontByUnicode(dwUnicode, weight, bItalic, PitchFamily); 732 if (!hFont) 733 return nullptr; 734 735 uint32_t ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, nullptr, 0); 736 uint32_t font_size = m_pFontInfo->GetFontData(hFont, 0, nullptr, 0); 737 if (font_size == 0 && ttc_size == 0) { 738 m_pFontInfo->DeleteFont(hFont); 739 return nullptr; 740 } 741 FXFT_Face face = nullptr; 742 if (ttc_size) { 743 face = GetCachedTTCFace(hFont, 0x74746366, ttc_size, font_size); 744 } else { 745 CFX_ByteString SubstName; 746 m_pFontInfo->GetFaceName(hFont, SubstName); 747 face = GetCachedFace(hFont, SubstName, weight, bItalic, font_size); 748 } 749 m_pFontInfo->DeleteFont(hFont); 750 return face; 751 } 752 #endif // PDF_ENABLE_XFA 753 754 int CFX_FontMapper::GetFaceSize() const { 755 return pdfium::CollectionSize<int>(m_FaceArray); 756 } 757 758 bool CFX_FontMapper::IsBuiltinFace(const FXFT_Face face) const { 759 for (size_t i = 0; i < MM_FACE_COUNT; ++i) { 760 if (m_MMFaces[i] == face) 761 return true; 762 } 763 for (size_t i = 0; i < FOXIT_FACE_COUNT; ++i) { 764 if (m_FoxitFaces[i] == face) 765 return true; 766 } 767 return false; 768 } 769 770 FXFT_Face CFX_FontMapper::GetCachedTTCFace(void* hFont, 771 const uint32_t tableTTCF, 772 uint32_t ttc_size, 773 uint32_t font_size) { 774 FXFT_Face face; 775 uint8_t buffer[1024]; 776 m_pFontInfo->GetFontData(hFont, tableTTCF, buffer, FX_ArraySize(buffer)); 777 uint32_t* pBuffer = reinterpret_cast<uint32_t*>(buffer); 778 uint32_t checksum = 0; 779 for (int i = 0; i < 256; i++) 780 checksum += pBuffer[i]; 781 uint8_t* pFontData; 782 face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, ttc_size - font_size, 783 pFontData); 784 if (!face) { 785 pFontData = FX_Alloc(uint8_t, ttc_size); 786 m_pFontInfo->GetFontData(hFont, tableTTCF, pFontData, ttc_size); 787 face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData, ttc_size, 788 ttc_size - font_size); 789 } 790 return face; 791 } 792 793 FXFT_Face CFX_FontMapper::GetCachedFace(void* hFont, 794 CFX_ByteString SubstName, 795 int weight, 796 bool bItalic, 797 uint32_t font_size) { 798 FXFT_Face face; 799 uint8_t* pFontData; 800 face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData); 801 if (!face) { 802 pFontData = FX_Alloc(uint8_t, font_size); 803 m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size); 804 face = 805 m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData, 806 font_size, m_pFontInfo->GetFaceIndex(hFont)); 807 } 808 return face; 809 } 810 811 int PDF_GetStandardFontName(CFX_ByteString* name) { 812 AltFontName* found = static_cast<AltFontName*>( 813 FXSYS_bsearch(name->c_str(), g_AltFontNames, FX_ArraySize(g_AltFontNames), 814 sizeof(AltFontName), CompareString)); 815 if (!found) 816 return -1; 817 818 *name = g_Base14FontNames[found->m_Index]; 819 return found->m_Index; 820 } 821