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/pdfwindow/PDFWindow.h" 8 #include "../../include/pdfwindow/PWL_Wnd.h" 9 #include "../../include/pdfwindow/PWL_FontMap.h" 10 11 #define DEFAULT_FONT_NAME "Helvetica" 12 13 /* ------------------------------ CPWL_FontMap ------------------------------ */ 14 15 CPWL_FontMap::CPWL_FontMap(IFX_SystemHandler* pSystemHandler) : 16 m_pPDFDoc(NULL), 17 m_pSystemHandler(pSystemHandler) 18 { 19 ASSERT(m_pSystemHandler != NULL); 20 } 21 22 CPWL_FontMap::~CPWL_FontMap() 23 { 24 if (m_pPDFDoc) 25 { 26 delete m_pPDFDoc; 27 m_pPDFDoc = NULL; 28 } 29 30 Empty(); 31 } 32 33 void CPWL_FontMap::SetSystemHandler(IFX_SystemHandler* pSystemHandler) 34 { 35 m_pSystemHandler = pSystemHandler; 36 } 37 38 CPDF_Document* CPWL_FontMap::GetDocument() 39 { 40 if (!m_pPDFDoc) 41 { 42 if (CPDF_ModuleMgr::Get()) 43 { 44 m_pPDFDoc = FX_NEW CPDF_Document; 45 m_pPDFDoc->CreateNewDoc(); 46 } 47 } 48 49 return m_pPDFDoc; 50 } 51 52 CPDF_Font* CPWL_FontMap::GetPDFFont(FX_INT32 nFontIndex) 53 { 54 if (nFontIndex >=0 && nFontIndex < m_aData.GetSize()) 55 { 56 if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) 57 { 58 return pData->pFont; 59 } 60 } 61 62 return NULL; 63 } 64 65 CFX_ByteString CPWL_FontMap::GetPDFFontAlias(FX_INT32 nFontIndex) 66 { 67 if (nFontIndex >=0 && nFontIndex < m_aData.GetSize()) 68 { 69 if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) 70 { 71 return pData->sFontName; 72 } 73 } 74 75 return ""; 76 } 77 78 FX_BOOL CPWL_FontMap::KnowWord(FX_INT32 nFontIndex, FX_WORD word) 79 { 80 if (nFontIndex >=0 && nFontIndex < m_aData.GetSize()) 81 { 82 if (m_aData.GetAt(nFontIndex)) 83 { 84 return CharCodeFromUnicode(nFontIndex, word) >= 0; 85 } 86 } 87 88 return FALSE; 89 } 90 91 FX_INT32 CPWL_FontMap::GetWordFontIndex(FX_WORD word, FX_INT32 nCharset, FX_INT32 nFontIndex) 92 { 93 if (nFontIndex > 0) 94 { 95 if (KnowWord(nFontIndex, word)) 96 return nFontIndex; 97 } 98 else 99 { 100 if (const CPWL_FontMap_Data* pData = GetFontMapData(0)) 101 { 102 if (nCharset == DEFAULT_CHARSET || 103 pData->nCharset == SYMBOL_CHARSET || 104 nCharset == pData->nCharset) 105 { 106 if (KnowWord(0, word)) 107 { 108 return 0; 109 } 110 } 111 } 112 } 113 114 FX_INT32 nNewFontIndex = -1; 115 116 nNewFontIndex = this->GetFontIndex(GetNativeFontName(nCharset), nCharset, TRUE); 117 if (nNewFontIndex >= 0) 118 { 119 if (KnowWord(nNewFontIndex, word)) 120 return nNewFontIndex; 121 } 122 123 nNewFontIndex = this->GetFontIndex("Arial Unicode MS", DEFAULT_CHARSET, FALSE); 124 if (nNewFontIndex >= 0) 125 { 126 if (KnowWord(nNewFontIndex, word)) 127 return nNewFontIndex; 128 } 129 130 return -1; 131 } 132 133 FX_INT32 CPWL_FontMap::CharCodeFromUnicode(FX_INT32 nFontIndex, FX_WORD word) 134 { 135 if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) 136 { 137 if (pData->pFont) 138 { 139 if (pData->pFont->IsUnicodeCompatible()) 140 { 141 int nCharCode = pData->pFont->CharCodeFromUnicode(word); 142 pData->pFont->GlyphFromCharCode(nCharCode); 143 return nCharCode; 144 } 145 else 146 { 147 if (word < 0xFF) 148 return word; 149 } 150 } 151 } 152 153 return -1; 154 } 155 156 CFX_ByteString CPWL_FontMap::GetNativeFontName(FX_INT32 nCharset) 157 { 158 //searching native font is slow, so we must save time 159 for (FX_INT32 i=0,sz=m_aNativeFont.GetSize(); i<sz; i++) 160 { 161 if (CPWL_FontMap_Native* pData = m_aNativeFont.GetAt(i)) 162 { 163 if (pData->nCharset == nCharset) 164 return pData->sFontName; 165 } 166 } 167 168 CFX_ByteString sNew = GetNativeFont(nCharset); 169 170 if (!sNew.IsEmpty()) 171 { 172 CPWL_FontMap_Native* pNewData = new CPWL_FontMap_Native; 173 pNewData->nCharset = nCharset; 174 pNewData->sFontName = sNew; 175 176 m_aNativeFont.Add(pNewData); 177 } 178 179 return sNew; 180 } 181 182 void CPWL_FontMap::Empty() 183 { 184 { 185 for (FX_INT32 i=0, sz=m_aData.GetSize(); i<sz; i++) 186 delete m_aData.GetAt(i); 187 188 m_aData.RemoveAll(); 189 } 190 { 191 for (FX_INT32 i=0, sz=m_aNativeFont.GetSize(); i<sz; i++) 192 delete m_aNativeFont.GetAt(i); 193 194 m_aNativeFont.RemoveAll(); 195 } 196 } 197 198 void CPWL_FontMap::Initial(FX_LPCSTR fontname) 199 { 200 CFX_ByteString sFontName = fontname; 201 202 if (sFontName.IsEmpty()) 203 sFontName = DEFAULT_FONT_NAME; 204 205 GetFontIndex(sFontName, ANSI_CHARSET, FALSE); 206 207 //GetFontIndex(this->GetNativeFontName(nCharset), nCharset); 208 } 209 210 211 /* 212 List of currently supported standard fonts: 213 Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique 214 Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique 215 Times-Roman, Times-Bold, Times-Italic, Times-BoldItalic 216 Symbol, ZapfDingbats 217 */ 218 219 const char* g_sDEStandardFontName[] = {"Courier", "Courier-Bold", "Courier-BoldOblique", "Courier-Oblique", 220 "Helvetica", "Helvetica-Bold", "Helvetica-BoldOblique", "Helvetica-Oblique", 221 "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic", 222 "Symbol", "ZapfDingbats"}; 223 224 FX_BOOL CPWL_FontMap::IsStandardFont(const CFX_ByteString& sFontName) 225 { 226 for (FX_INT32 i=0; i<14; i++) 227 { 228 if (sFontName == g_sDEStandardFontName[i]) 229 return TRUE; 230 } 231 232 return FALSE; 233 } 234 235 FX_INT32 CPWL_FontMap::FindFont(const CFX_ByteString& sFontName, FX_INT32 nCharset) 236 { 237 for (FX_INT32 i=0,sz=m_aData.GetSize(); i<sz; i++) 238 { 239 if (CPWL_FontMap_Data* pData = m_aData.GetAt(i)) 240 { 241 if (nCharset == DEFAULT_CHARSET || nCharset == pData->nCharset) 242 { 243 if (sFontName.IsEmpty() || pData->sFontName == sFontName) 244 return i; 245 } 246 } 247 } 248 249 return -1; 250 } 251 252 FX_INT32 CPWL_FontMap::GetFontIndex(const CFX_ByteString& sFontName, FX_INT32 nCharset, FX_BOOL bFind) 253 { 254 FX_INT32 nFontIndex = FindFont(EncodeFontAlias(sFontName, nCharset), nCharset); 255 if (nFontIndex >= 0) return nFontIndex; 256 257 // nFontIndex = FindFont("", nCharset); 258 // if (nFontIndex >= 0) return nFontIndex; 259 260 CFX_ByteString sAlias; 261 CPDF_Font* pFont = NULL; 262 263 if (bFind) 264 pFont = FindFontSameCharset(sAlias, nCharset); 265 266 if (!pFont) 267 { 268 CFX_ByteString sTemp = sFontName; 269 pFont = AddFontToDocument(GetDocument(), sTemp, nCharset); 270 271 /* 272 if (FindFont(sAlias)) 273 { 274 sAlias = EncodeFontAlias(sTemp, nCharset); 275 } 276 else 277 */ 278 { 279 sAlias = EncodeFontAlias(sTemp, nCharset); 280 } 281 } 282 283 AddedFont(pFont, sAlias); 284 285 return AddFontData(pFont, sAlias, nCharset); 286 } 287 288 FX_INT32 CPWL_FontMap::GetPWLFontIndex(FX_WORD word, FX_INT32 nCharset) 289 { 290 FX_INT32 nFind = -1; 291 292 for (FX_INT32 i=0,sz=m_aData.GetSize(); i<sz; i++) 293 { 294 if (CPWL_FontMap_Data* pData = m_aData.GetAt(i)) 295 { 296 if (pData->nCharset == nCharset) 297 { 298 nFind = i; 299 break; 300 } 301 } 302 } 303 304 CPDF_Font* pNewFont = GetPDFFont(nFind); 305 306 if (!pNewFont) return -1; 307 308 /* 309 if (CPDF_Font* pFont = GetPDFFont(nFind)) 310 { 311 PWLFont.AddWordToFontDict(pFontDict, word); 312 } 313 */ 314 315 #ifdef FOXIT_CHROME_BUILD 316 CFX_ByteString sAlias = EncodeFontAlias("Arial_Chrome", nCharset); 317 #else 318 CFX_ByteString sAlias = EncodeFontAlias("Arial_Foxit", nCharset); 319 #endif 320 AddedFont(pNewFont, sAlias); 321 322 return AddFontData(pNewFont, sAlias, nCharset); 323 } 324 325 CPDF_Font* CPWL_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias, FX_INT32 nCharset) 326 { 327 return NULL; 328 } 329 330 FX_INT32 CPWL_FontMap::AddFontData(CPDF_Font* pFont, const CFX_ByteString& sFontAlias, FX_INT32 nCharset) 331 { 332 CPWL_FontMap_Data* pNewData = new CPWL_FontMap_Data; 333 pNewData->pFont = pFont; 334 pNewData->sFontName = sFontAlias; 335 pNewData->nCharset = nCharset; 336 337 m_aData.Add(pNewData); 338 339 return m_aData.GetSize() -1; 340 } 341 342 void CPWL_FontMap::AddedFont(CPDF_Font* pFont, const CFX_ByteString& sFontAlias) 343 { 344 } 345 346 CFX_ByteString CPWL_FontMap::GetFontName(FX_INT32 nFontIndex) 347 { 348 if (nFontIndex >=0 && nFontIndex < m_aData.GetSize()) 349 { 350 if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) 351 { 352 return pData->sFontName; 353 } 354 } 355 356 return ""; 357 } 358 359 CFX_ByteString CPWL_FontMap::GetNativeFont(FX_INT32 nCharset) 360 { 361 CFX_ByteString sFontName; 362 363 if (nCharset == DEFAULT_CHARSET) 364 nCharset = GetNativeCharset(); 365 366 sFontName = GetDefaultFontByCharset(nCharset); 367 368 if (m_pSystemHandler) 369 { 370 if (m_pSystemHandler->FindNativeTrueTypeFont(nCharset, sFontName)) 371 return sFontName; 372 373 sFontName = m_pSystemHandler->GetNativeTrueTypeFont(nCharset); 374 } 375 376 return sFontName; 377 } 378 379 CPDF_Font* CPWL_FontMap::AddFontToDocument(CPDF_Document* pDoc, CFX_ByteString& sFontName, FX_BYTE nCharset) 380 { 381 if (IsStandardFont(sFontName)) 382 return AddStandardFont(pDoc, sFontName); 383 else 384 return AddSystemFont(pDoc, sFontName, nCharset); 385 } 386 387 CPDF_Font* CPWL_FontMap::AddStandardFont(CPDF_Document* pDoc, CFX_ByteString& sFontName) 388 { 389 if (!pDoc) return NULL; 390 391 CPDF_Font* pFont = NULL; 392 393 if (sFontName == "ZapfDingbats") 394 pFont = pDoc->AddStandardFont(sFontName, NULL); 395 else 396 { 397 CPDF_FontEncoding fe(PDFFONT_ENCODING_WINANSI); 398 pFont = pDoc->AddStandardFont(sFontName, &fe); 399 } 400 401 return pFont; 402 } 403 404 CPDF_Font* CPWL_FontMap::AddSystemFont(CPDF_Document* pDoc, CFX_ByteString& sFontName, FX_BYTE nCharset) 405 { 406 if (!pDoc) return NULL; 407 408 if (sFontName.IsEmpty()) sFontName = GetNativeFont(nCharset); 409 if (nCharset == DEFAULT_CHARSET) nCharset = GetNativeCharset(); 410 411 if (m_pSystemHandler) 412 return m_pSystemHandler->AddNativeTrueTypeFontToPDF(pDoc, sFontName, nCharset); 413 414 return NULL; 415 } 416 417 CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName, FX_INT32 nCharset) 418 { 419 CFX_ByteString sPostfix; 420 sPostfix.Format("_%02X", nCharset); 421 return EncodeFontAlias(sFontName) + sPostfix; 422 } 423 424 CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName) 425 { 426 CFX_ByteString sRet = sFontName; 427 sRet.Remove(' '); 428 return sRet; 429 } 430 431 FX_INT32 CPWL_FontMap::GetFontMapCount() const 432 { 433 return m_aData.GetSize(); 434 } 435 436 const CPWL_FontMap_Data* CPWL_FontMap::GetFontMapData(FX_INT32 nIndex) const 437 { 438 if (nIndex >=0 && nIndex < m_aData.GetSize()) 439 { 440 return m_aData.GetAt(nIndex); 441 } 442 443 return NULL; 444 } 445 446 FX_INT32 CPWL_FontMap::GetNativeCharset() 447 { 448 FX_BYTE nCharset = ANSI_CHARSET; 449 FX_INT32 iCodePage = FXSYS_GetACP(); 450 switch (iCodePage) 451 { 452 case 932://Japan 453 nCharset = SHIFTJIS_CHARSET; 454 break; 455 case 936://Chinese (PRC, Singapore) 456 nCharset = GB2312_CHARSET; 457 break; 458 case 950://Chinese (Taiwan; Hong Kong SAR, PRC) 459 nCharset = GB2312_CHARSET; 460 break; 461 case 1252://Windows 3.1 Latin 1 (US, Western Europe) 462 nCharset = ANSI_CHARSET; 463 break; 464 case 874://Thai 465 nCharset = THAI_CHARSET; 466 break; 467 case 949://Korean 468 nCharset = HANGUL_CHARSET; 469 break; 470 case 1200://Unicode (BMP of ISO 10646) 471 nCharset = ANSI_CHARSET; 472 break; 473 case 1250://Windows 3.1 Eastern European 474 nCharset = EASTEUROPE_CHARSET; 475 break; 476 case 1251://Windows 3.1 Cyrillic 477 nCharset = RUSSIAN_CHARSET; 478 break; 479 case 1253://Windows 3.1 Greek 480 nCharset = GREEK_CHARSET; 481 break; 482 case 1254://Windows 3.1 Turkish 483 nCharset = TURKISH_CHARSET; 484 break; 485 case 1255://Hebrew 486 nCharset = HEBREW_CHARSET; 487 break; 488 case 1256://Arabic 489 nCharset = ARABIC_CHARSET; 490 break; 491 case 1257://Baltic 492 nCharset = BALTIC_CHARSET; 493 break; 494 case 1258://Vietnamese 495 nCharset = VIETNAMESE_CHARSET; 496 break; 497 case 1361://Korean(Johab) 498 nCharset = JOHAB_CHARSET; 499 break; 500 } 501 return nCharset; 502 } 503 504 const CPWL_FontMap::CharsetFontMap CPWL_FontMap::defaultTTFMap[] = { 505 { ANSI_CHARSET, "Helvetica" }, 506 { GB2312_CHARSET, "SimSun" }, 507 { CHINESEBIG5_CHARSET, "MingLiU" }, 508 { SHIFTJIS_CHARSET, "MS Gothic" }, 509 { HANGUL_CHARSET, "Batang" }, 510 { RUSSIAN_CHARSET, "Arial" }, 511 { EASTEUROPE_CHARSET, "Tahoma" }, 512 { ARABIC_CHARSET, "Arial" }, 513 { -1, NULL } 514 }; 515 516 CFX_ByteString CPWL_FontMap::GetDefaultFontByCharset(FX_INT32 nCharset) 517 { 518 int i = 0; 519 while (defaultTTFMap[i].charset != -1) { 520 if (nCharset == defaultTTFMap[i].charset) 521 return defaultTTFMap[i].fontname; 522 ++i; 523 } 524 return ""; 525 } 526 527 FX_INT32 CPWL_FontMap::CharSetFromUnicode(FX_WORD word, FX_INT32 nOldCharset) 528 { 529 if(m_pSystemHandler && (-1 != m_pSystemHandler->GetCharSet())) 530 return m_pSystemHandler->GetCharSet(); 531 //to avoid CJK Font to show ASCII 532 if (word < 0x7F) return ANSI_CHARSET; 533 //follow the old charset 534 if (nOldCharset != DEFAULT_CHARSET) return nOldCharset; 535 536 //find new charset 537 if ((word >= 0x4E00 && word <= 0x9FA5) || 538 (word >= 0xE7C7 && word <= 0xE7F3) || 539 (word >= 0x3000 && word <= 0x303F) || //"" "" "" "" 540 (word >= 0x2000 && word <= 0x206F)) 541 { 542 return GB2312_CHARSET; 543 } 544 545 if (((word >= 0x3040) && (word <= 0x309F)) || 546 ((word >= 0x30A0) && (word <= 0x30FF)) || 547 ((word >= 0x31F0) && (word <= 0x31FF)) || 548 ((word >= 0xFF00) && (word <= 0xFFEF)) ) 549 { 550 return SHIFTJIS_CHARSET; 551 } 552 553 if (((word >= 0xAC00) && (word <= 0xD7AF)) || 554 ((word >= 0x1100) && (word <= 0x11FF)) || 555 ((word >= 0x3130) && (word <= 0x318F))) 556 { 557 return HANGUL_CHARSET; 558 } 559 560 if (word >= 0x0E00 && word <= 0x0E7F) 561 return THAI_CHARSET; 562 563 if ((word >= 0x0370 && word <= 0x03FF) || 564 (word >= 0x1F00 && word <= 0x1FFF)) 565 return GREEK_CHARSET; 566 567 if ((word >= 0x0600 && word <= 0x06FF) || 568 (word >= 0xFB50 && word <= 0xFEFC)) 569 return ARABIC_CHARSET; 570 571 if (word >= 0x0590 && word <= 0x05FF) 572 return HEBREW_CHARSET; 573 574 if (word >= 0x0400 && word <= 0x04FF) 575 return RUSSIAN_CHARSET; 576 577 if (word >= 0x0100 && word <= 0x024F) 578 return EASTEUROPE_CHARSET; 579 580 if (word >= 0x1E00 && word <= 0x1EFF) 581 return VIETNAMESE_CHARSET; 582 583 return ANSI_CHARSET; 584 } 585 586 /* ------------------------ CPWL_DocFontMap ------------------------ */ 587 588 CPWL_DocFontMap::CPWL_DocFontMap(IFX_SystemHandler* pSystemHandler, CPDF_Document* pAttachedDoc) 589 : CPWL_FontMap(pSystemHandler), 590 m_pAttachedDoc(pAttachedDoc) 591 { 592 } 593 594 CPWL_DocFontMap::~CPWL_DocFontMap() 595 { 596 } 597 598 CPDF_Document* CPWL_DocFontMap::GetDocument() 599 { 600 return m_pAttachedDoc; 601 } 602