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