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