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 = 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 CFX_ByteString sAlias = EncodeFontAlias("Arial_Chrome", nCharset); 316 AddedFont(pNewFont, sAlias); 317 318 return AddFontData(pNewFont, sAlias, nCharset); 319 } 320 321 CPDF_Font* CPWL_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias, FX_INT32 nCharset) 322 { 323 return NULL; 324 } 325 326 FX_INT32 CPWL_FontMap::AddFontData(CPDF_Font* pFont, const CFX_ByteString& sFontAlias, FX_INT32 nCharset) 327 { 328 CPWL_FontMap_Data* pNewData = new CPWL_FontMap_Data; 329 pNewData->pFont = pFont; 330 pNewData->sFontName = sFontAlias; 331 pNewData->nCharset = nCharset; 332 333 m_aData.Add(pNewData); 334 335 return m_aData.GetSize() -1; 336 } 337 338 void CPWL_FontMap::AddedFont(CPDF_Font* pFont, const CFX_ByteString& sFontAlias) 339 { 340 } 341 342 CFX_ByteString CPWL_FontMap::GetFontName(FX_INT32 nFontIndex) 343 { 344 if (nFontIndex >=0 && nFontIndex < m_aData.GetSize()) 345 { 346 if (CPWL_FontMap_Data* pData = m_aData.GetAt(nFontIndex)) 347 { 348 return pData->sFontName; 349 } 350 } 351 352 return ""; 353 } 354 355 CFX_ByteString CPWL_FontMap::GetNativeFont(FX_INT32 nCharset) 356 { 357 CFX_ByteString sFontName; 358 359 if (nCharset == DEFAULT_CHARSET) 360 nCharset = GetNativeCharset(); 361 362 sFontName = GetDefaultFontByCharset(nCharset); 363 364 if (m_pSystemHandler) 365 { 366 if (m_pSystemHandler->FindNativeTrueTypeFont(nCharset, sFontName)) 367 return sFontName; 368 369 sFontName = m_pSystemHandler->GetNativeTrueTypeFont(nCharset); 370 } 371 372 return sFontName; 373 } 374 375 CPDF_Font* CPWL_FontMap::AddFontToDocument(CPDF_Document* pDoc, CFX_ByteString& sFontName, FX_BYTE nCharset) 376 { 377 if (IsStandardFont(sFontName)) 378 return AddStandardFont(pDoc, sFontName); 379 else 380 return AddSystemFont(pDoc, sFontName, nCharset); 381 } 382 383 CPDF_Font* CPWL_FontMap::AddStandardFont(CPDF_Document* pDoc, CFX_ByteString& sFontName) 384 { 385 if (!pDoc) return NULL; 386 387 CPDF_Font* pFont = NULL; 388 389 if (sFontName == "ZapfDingbats") 390 pFont = pDoc->AddStandardFont(sFontName, NULL); 391 else 392 { 393 CPDF_FontEncoding fe(PDFFONT_ENCODING_WINANSI); 394 pFont = pDoc->AddStandardFont(sFontName, &fe); 395 } 396 397 return pFont; 398 } 399 400 CPDF_Font* CPWL_FontMap::AddSystemFont(CPDF_Document* pDoc, CFX_ByteString& sFontName, FX_BYTE nCharset) 401 { 402 if (!pDoc) return NULL; 403 404 if (sFontName.IsEmpty()) sFontName = GetNativeFont(nCharset); 405 if (nCharset == DEFAULT_CHARSET) nCharset = GetNativeCharset(); 406 407 if (m_pSystemHandler) 408 return m_pSystemHandler->AddNativeTrueTypeFontToPDF(pDoc, sFontName, nCharset); 409 410 return NULL; 411 } 412 413 CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName, FX_INT32 nCharset) 414 { 415 CFX_ByteString sPostfix; 416 sPostfix.Format("_%02X", nCharset); 417 return EncodeFontAlias(sFontName) + sPostfix; 418 } 419 420 CFX_ByteString CPWL_FontMap::EncodeFontAlias(const CFX_ByteString& sFontName) 421 { 422 CFX_ByteString sRet = sFontName; 423 sRet.Remove(' '); 424 return sRet; 425 } 426 427 FX_INT32 CPWL_FontMap::GetFontMapCount() const 428 { 429 return m_aData.GetSize(); 430 } 431 432 const CPWL_FontMap_Data* CPWL_FontMap::GetFontMapData(FX_INT32 nIndex) const 433 { 434 if (nIndex >=0 && nIndex < m_aData.GetSize()) 435 { 436 return m_aData.GetAt(nIndex); 437 } 438 439 return NULL; 440 } 441 442 FX_INT32 CPWL_FontMap::GetNativeCharset() 443 { 444 FX_BYTE nCharset = ANSI_CHARSET; 445 FX_INT32 iCodePage = FXSYS_GetACP(); 446 switch (iCodePage) 447 { 448 case 932://Japan 449 nCharset = SHIFTJIS_CHARSET; 450 break; 451 case 936://Chinese (PRC, Singapore) 452 nCharset = GB2312_CHARSET; 453 break; 454 case 950://Chinese (Taiwan; Hong Kong SAR, PRC) 455 nCharset = GB2312_CHARSET; 456 break; 457 case 1252://Windows 3.1 Latin 1 (US, Western Europe) 458 nCharset = ANSI_CHARSET; 459 break; 460 case 874://Thai 461 nCharset = THAI_CHARSET; 462 break; 463 case 949://Korean 464 nCharset = HANGUL_CHARSET; 465 break; 466 case 1200://Unicode (BMP of ISO 10646) 467 nCharset = ANSI_CHARSET; 468 break; 469 case 1250://Windows 3.1 Eastern European 470 nCharset = EASTEUROPE_CHARSET; 471 break; 472 case 1251://Windows 3.1 Cyrillic 473 nCharset = RUSSIAN_CHARSET; 474 break; 475 case 1253://Windows 3.1 Greek 476 nCharset = GREEK_CHARSET; 477 break; 478 case 1254://Windows 3.1 Turkish 479 nCharset = TURKISH_CHARSET; 480 break; 481 case 1255://Hebrew 482 nCharset = HEBREW_CHARSET; 483 break; 484 case 1256://Arabic 485 nCharset = ARABIC_CHARSET; 486 break; 487 case 1257://Baltic 488 nCharset = BALTIC_CHARSET; 489 break; 490 case 1258://Vietnamese 491 nCharset = VIETNAMESE_CHARSET; 492 break; 493 case 1361://Korean(Johab) 494 nCharset = JOHAB_CHARSET; 495 break; 496 } 497 return nCharset; 498 } 499 500 const CPWL_FontMap::CharsetFontMap CPWL_FontMap::defaultTTFMap[] = { 501 { ANSI_CHARSET, "Helvetica" }, 502 { GB2312_CHARSET, "SimSun" }, 503 { CHINESEBIG5_CHARSET, "MingLiU" }, 504 { SHIFTJIS_CHARSET, "MS Gothic" }, 505 { HANGUL_CHARSET, "Batang" }, 506 { RUSSIAN_CHARSET, "Arial" }, 507 #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 508 { EASTEUROPE_CHARSET, "Arial" }, 509 #else 510 { EASTEUROPE_CHARSET, "Tahoma" }, 511 #endif 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