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 "font_int.h" 8 9 #include "core/src/fpdfapi/fpdf_page/pageint.h" 10 #include "core/include/fpdfapi/fpdf_module.h" 11 #include "core/include/fpdfapi/fpdf_page.h" 12 #include "core/include/fpdfapi/fpdf_pageobj.h" 13 #include "core/include/fpdfapi/fpdf_resource.h" 14 #include "core/include/fxcrt/fx_ext.h" 15 #include "core/include/fxge/fx_freetype.h" 16 #include "third_party/base/stl_util.h" 17 18 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 19 #include "core/src/fxge/apple/apple_int.h" 20 #endif 21 22 FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) { 23 for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) { 24 if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) == 25 platform_id && 26 FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) == 27 encoding_id) { 28 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]); 29 return TRUE; 30 } 31 } 32 return FALSE; 33 } 34 35 CFX_StockFontArray::CFX_StockFontArray() {} 36 37 CFX_StockFontArray::~CFX_StockFontArray() { 38 for (size_t i = 0; i < FX_ArraySize(m_StockFonts); ++i) { 39 if (!m_StockFonts[i]) 40 continue; 41 CPDF_Dictionary* pFontDict = m_StockFonts[i]->GetFontDict(); 42 if (pFontDict) 43 pFontDict->Release(); 44 } 45 } 46 47 CPDF_Font* CFX_StockFontArray::GetFont(int index) const { 48 if (index < 0 || index >= FX_ArraySize(m_StockFonts)) 49 return nullptr; 50 return m_StockFonts[index].get(); 51 } 52 53 void CFX_StockFontArray::SetFont(int index, CPDF_Font* font) { 54 if (index < 0 || index >= FX_ArraySize(m_StockFonts)) 55 return; 56 m_StockFonts[index].reset(font); 57 } 58 59 CPDF_FontGlobals::CPDF_FontGlobals() { 60 FXSYS_memset(m_EmbeddedCharsets, 0, sizeof(m_EmbeddedCharsets)); 61 FXSYS_memset(m_EmbeddedToUnicodes, 0, sizeof(m_EmbeddedToUnicodes)); 62 } 63 64 CPDF_FontGlobals::~CPDF_FontGlobals() { 65 } 66 67 CPDF_Font* CPDF_FontGlobals::Find(CPDF_Document* pDoc, int index) { 68 auto it = m_StockMap.find(pDoc); 69 if (it == m_StockMap.end()) 70 return nullptr; 71 return it->second ? it->second->GetFont(index) : nullptr; 72 } 73 74 void CPDF_FontGlobals::Set(CPDF_Document* pDoc, int index, CPDF_Font* pFont) { 75 if (!pdfium::ContainsKey(m_StockMap, pDoc)) 76 m_StockMap[pDoc].reset(new CFX_StockFontArray); 77 m_StockMap[pDoc]->SetFont(index, pFont); 78 } 79 80 void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) { 81 m_StockMap.erase(pDoc); 82 } 83 84 CPDF_Font::CPDF_Font(int fonttype) : m_FontType(fonttype) { 85 m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0; 86 m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0; 87 m_pFontFile = NULL; 88 m_Flags = 0; 89 m_pToUnicodeMap = NULL; 90 m_bToUnicodeLoaded = FALSE; 91 m_pCharMap = new CPDF_FontCharMap(this); 92 } 93 CPDF_Font::~CPDF_Font() { 94 delete m_pCharMap; 95 m_pCharMap = NULL; 96 97 delete m_pToUnicodeMap; 98 m_pToUnicodeMap = NULL; 99 100 if (m_pFontFile) { 101 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( 102 const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream())); 103 } 104 } 105 FX_BOOL CPDF_Font::IsVertWriting() const { 106 FX_BOOL bVertWriting = FALSE; 107 CPDF_CIDFont* pCIDFont = GetCIDFont(); 108 if (pCIDFont) { 109 bVertWriting = pCIDFont->IsVertWriting(); 110 } else { 111 bVertWriting = m_Font.IsVertical(); 112 } 113 return bVertWriting; 114 } 115 CFX_ByteString CPDF_Font::GetFontTypeName() const { 116 switch (m_FontType) { 117 case PDFFONT_TYPE1: 118 return "Type1"; 119 case PDFFONT_TRUETYPE: 120 return "TrueType"; 121 case PDFFONT_TYPE3: 122 return "Type3"; 123 case PDFFONT_CIDFONT: 124 return "Type0"; 125 } 126 return CFX_ByteString(); 127 } 128 void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const { 129 char buf[4]; 130 int len = AppendChar(buf, charcode); 131 if (len == 1) { 132 str += buf[0]; 133 } else { 134 str += CFX_ByteString(buf, len); 135 } 136 } 137 CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const { 138 if (!m_bToUnicodeLoaded) { 139 ((CPDF_Font*)this)->LoadUnicodeMap(); 140 } 141 if (m_pToUnicodeMap) { 142 CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode); 143 if (!wsRet.IsEmpty()) { 144 return wsRet; 145 } 146 } 147 FX_WCHAR unicode = _UnicodeFromCharCode(charcode); 148 if (unicode == 0) { 149 return CFX_WideString(); 150 } 151 return unicode; 152 } 153 FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const { 154 if (!m_bToUnicodeLoaded) { 155 ((CPDF_Font*)this)->LoadUnicodeMap(); 156 } 157 if (m_pToUnicodeMap) { 158 FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode); 159 if (charcode) { 160 return charcode; 161 } 162 } 163 return _CharCodeFromUnicode(unicode); 164 } 165 CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const { 166 CFX_WideString result; 167 int src_len = str.GetLength(); 168 result.Reserve(src_len); 169 const FX_CHAR* src_buf = str; 170 int src_pos = 0; 171 while (src_pos < src_len) { 172 FX_DWORD charcode = GetNextChar(src_buf, src_len, src_pos); 173 CFX_WideString unicode = UnicodeFromCharCode(charcode); 174 if (!unicode.IsEmpty()) { 175 result += unicode; 176 } else { 177 result += (FX_WCHAR)charcode; 178 } 179 } 180 return result; 181 } 182 CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const { 183 CFX_ByteString result; 184 int src_len = str.GetLength(); 185 FX_CHAR* dest_buf = result.GetBuffer(src_len * 2); 186 const FX_WCHAR* src_buf = str.c_str(); 187 int dest_pos = 0; 188 for (int src_pos = 0; src_pos < src_len; src_pos++) { 189 FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]); 190 dest_pos += AppendChar(dest_buf + dest_pos, charcode); 191 } 192 result.ReleaseBuffer(dest_pos); 193 return result; 194 } 195 196 void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) { 197 m_Flags = pFontDesc->GetInteger("Flags", PDFFONT_NONSYMBOLIC); 198 int ItalicAngle = 0; 199 FX_BOOL bExistItalicAngle = FALSE; 200 if (pFontDesc->KeyExist("ItalicAngle")) { 201 ItalicAngle = pFontDesc->GetInteger("ItalicAngle"); 202 bExistItalicAngle = TRUE; 203 } 204 if (ItalicAngle < 0) { 205 m_Flags |= PDFFONT_ITALIC; 206 m_ItalicAngle = ItalicAngle; 207 } 208 FX_BOOL bExistStemV = FALSE; 209 if (pFontDesc->KeyExist("StemV")) { 210 m_StemV = pFontDesc->GetInteger("StemV"); 211 bExistStemV = TRUE; 212 } 213 FX_BOOL bExistAscent = FALSE; 214 if (pFontDesc->KeyExist("Ascent")) { 215 m_Ascent = pFontDesc->GetInteger("Ascent"); 216 bExistAscent = TRUE; 217 } 218 FX_BOOL bExistDescent = FALSE; 219 if (pFontDesc->KeyExist("Descent")) { 220 m_Descent = pFontDesc->GetInteger("Descent"); 221 bExistDescent = TRUE; 222 } 223 FX_BOOL bExistCapHeight = FALSE; 224 if (pFontDesc->KeyExist("CapHeight")) { 225 bExistCapHeight = TRUE; 226 } 227 if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && 228 bExistStemV) { 229 m_Flags |= PDFFONT_USEEXTERNATTR; 230 } 231 if (m_Descent > 10) { 232 m_Descent = -m_Descent; 233 } 234 CPDF_Array* pBBox = pFontDesc->GetArray("FontBBox"); 235 if (pBBox) { 236 m_FontBBox.left = pBBox->GetInteger(0); 237 m_FontBBox.bottom = pBBox->GetInteger(1); 238 m_FontBBox.right = pBBox->GetInteger(2); 239 m_FontBBox.top = pBBox->GetInteger(3); 240 } 241 242 CPDF_Stream* pFontFile = pFontDesc->GetStream("FontFile"); 243 if (!pFontFile) 244 pFontFile = pFontDesc->GetStream("FontFile2"); 245 if (!pFontFile) 246 pFontFile = pFontDesc->GetStream("FontFile3"); 247 if (!pFontFile) 248 return; 249 250 m_pFontFile = m_pDocument->LoadFontFile(pFontFile); 251 if (!m_pFontFile) 252 return; 253 254 const uint8_t* pFontData = m_pFontFile->GetData(); 255 FX_DWORD dwFontSize = m_pFontFile->GetSize(); 256 if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) { 257 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( 258 const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream())); 259 m_pFontFile = nullptr; 260 } 261 } 262 263 short TT2PDF(int m, FXFT_Face face) { 264 int upm = FXFT_Get_Face_UnitsPerEM(face); 265 if (upm == 0) { 266 return (short)m; 267 } 268 return (m * 1000 + upm / 2) / upm; 269 } 270 void CPDF_Font::CheckFontMetrics() { 271 if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && 272 m_FontBBox.right == 0) { 273 FXFT_Face face = m_Font.GetFace(); 274 if (face) { 275 m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face); 276 m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face); 277 m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face); 278 m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face); 279 m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face); 280 m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face); 281 } else { 282 FX_BOOL bFirst = TRUE; 283 for (int i = 0; i < 256; i++) { 284 FX_RECT rect; 285 GetCharBBox(i, rect); 286 if (rect.left == rect.right) { 287 continue; 288 } 289 if (bFirst) { 290 m_FontBBox = rect; 291 bFirst = FALSE; 292 } else { 293 if (m_FontBBox.top < rect.top) { 294 m_FontBBox.top = rect.top; 295 } 296 if (m_FontBBox.right < rect.right) { 297 m_FontBBox.right = rect.right; 298 } 299 if (m_FontBBox.left > rect.left) { 300 m_FontBBox.left = rect.left; 301 } 302 if (m_FontBBox.bottom > rect.bottom) { 303 m_FontBBox.bottom = rect.bottom; 304 } 305 } 306 } 307 } 308 } 309 if (m_Ascent == 0 && m_Descent == 0) { 310 FX_RECT rect; 311 GetCharBBox('A', rect); 312 if (rect.bottom == rect.top) { 313 m_Ascent = m_FontBBox.top; 314 } else { 315 m_Ascent = rect.top; 316 } 317 GetCharBBox('g', rect); 318 if (rect.bottom == rect.top) { 319 m_Descent = m_FontBBox.bottom; 320 } else { 321 m_Descent = rect.bottom; 322 } 323 } 324 } 325 void CPDF_Font::LoadUnicodeMap() { 326 m_bToUnicodeLoaded = TRUE; 327 CPDF_Stream* pStream = m_pFontDict->GetStream("ToUnicode"); 328 if (!pStream) { 329 return; 330 } 331 m_pToUnicodeMap = new CPDF_ToUnicodeMap; 332 m_pToUnicodeMap->Load(pStream); 333 } 334 int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) { 335 int offset = 0; 336 int width = 0; 337 while (offset < size) { 338 FX_DWORD charcode = GetNextChar(pString, size, offset); 339 width += GetCharWidthF(charcode); 340 } 341 return width; 342 } 343 int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode) { 344 if (!m_Font.GetFace()) 345 return 0; 346 347 int glyph_index = GlyphFromCharCode(charcode); 348 if (glyph_index == 0xffff) { 349 return 0; 350 } 351 return m_Font.GetGlyphWidth(glyph_index); 352 } 353 354 CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, 355 const CFX_ByteStringC& name) { 356 CFX_ByteString fontname(name); 357 int font_id = PDF_GetStandardFontName(&fontname); 358 if (font_id < 0) { 359 return nullptr; 360 } 361 CPDF_FontGlobals* pFontGlobals = 362 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); 363 CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id); 364 if (pFont) { 365 return pFont; 366 } 367 CPDF_Dictionary* pDict = new CPDF_Dictionary; 368 pDict->SetAtName("Type", "Font"); 369 pDict->SetAtName("Subtype", "Type1"); 370 pDict->SetAtName("BaseFont", fontname); 371 pDict->SetAtName("Encoding", "WinAnsiEncoding"); 372 pFont = CPDF_Font::CreateFontF(NULL, pDict); 373 pFontGlobals->Set(pDoc, font_id, pFont); 374 return pFont; 375 } 376 const uint8_t ChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00}, 377 {0xBF, 0xAC, 0xCC, 0xE5, 0x00}, 378 {0xBA, 0xDA, 0xCC, 0xE5, 0x00}, 379 {0xB7, 0xC2, 0xCB, 0xCE, 0x00}, 380 {0xD0, 0xC2, 0xCB, 0xCE, 0x00}}; 381 CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, 382 CPDF_Dictionary* pFontDict) { 383 CFX_ByteString type = pFontDict->GetString("Subtype"); 384 CPDF_Font* pFont; 385 if (type == "TrueType") { 386 { 387 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \ 388 _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \ 389 _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \ 390 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 391 CFX_ByteString basefont = pFontDict->GetString("BaseFont"); 392 CFX_ByteString tag = basefont.Left(4); 393 int i; 394 int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]); 395 for (i = 0; i < count; ++i) { 396 if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) { 397 break; 398 } 399 } 400 if (i < count) { 401 CPDF_Dictionary* pFontDesc = pFontDict->GetDict("FontDescriptor"); 402 if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) { 403 pFont = new CPDF_CIDFont; 404 pFont->m_pFontDict = pFontDict; 405 pFont->m_pDocument = pDoc; 406 if (!pFont->Load()) { 407 delete pFont; 408 return NULL; 409 } 410 return pFont; 411 } 412 } 413 #endif 414 } 415 pFont = new CPDF_TrueTypeFont; 416 } else if (type == "Type3") { 417 pFont = new CPDF_Type3Font; 418 } else if (type == "Type0") { 419 pFont = new CPDF_CIDFont; 420 } else { 421 pFont = new CPDF_Type1Font; 422 } 423 pFont->m_pFontDict = pFontDict; 424 pFont->m_pDocument = pDoc; 425 if (!pFont->Load()) { 426 delete pFont; 427 return NULL; 428 } 429 return pFont; 430 } 431 FX_BOOL CPDF_Font::Load() { 432 if (!m_pFontDict) { 433 return FALSE; 434 } 435 CFX_ByteString type = m_pFontDict->GetString("Subtype"); 436 m_BaseFont = m_pFontDict->GetString("BaseFont"); 437 if (type == "MMType1") { 438 type = "Type1"; 439 } 440 return _Load(); 441 } 442 static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap, 443 const CFX_ByteString& bytestr) { 444 return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr); 445 } 446 static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap, 447 const CFX_WideString& widestr) { 448 return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr); 449 } 450 CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont) { 451 m_GetByteString = _FontMap_GetByteString; 452 m_GetWideString = _FontMap_GetWideString; 453 m_pFont = pFont; 454 } 455 CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) { 456 auto it = m_Map.find(charcode); 457 if (it != m_Map.end()) { 458 FX_DWORD value = it->second; 459 FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff); 460 if (unicode != 0xffff) { 461 return unicode; 462 } 463 const FX_WCHAR* buf = m_MultiCharBuf.GetBuffer(); 464 FX_DWORD buf_len = m_MultiCharBuf.GetLength(); 465 if (!buf || buf_len == 0) { 466 return CFX_WideString(); 467 } 468 FX_DWORD index = value >> 16; 469 if (index >= buf_len) { 470 return CFX_WideString(); 471 } 472 FX_DWORD len = buf[index]; 473 if (index + len < index || index + len >= buf_len) { 474 return CFX_WideString(); 475 } 476 return CFX_WideString(buf + index + 1, len); 477 } 478 if (m_pBaseMap) { 479 return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode); 480 } 481 return CFX_WideString(); 482 } 483 FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode) { 484 for (const auto& pair : m_Map) { 485 if (pair.second == unicode) 486 return pair.first; 487 } 488 return 0; 489 } 490 491 // Static. 492 FX_DWORD CPDF_ToUnicodeMap::StringToCode(const CFX_ByteStringC& str) { 493 const FX_CHAR* buf = str.GetCStr(); 494 int len = str.GetLength(); 495 if (len == 0) 496 return 0; 497 498 int result = 0; 499 if (buf[0] == '<') { 500 for (int i = 1; i < len && std::isxdigit(buf[i]); ++i) 501 result = result * 16 + FXSYS_toHexDigit(buf[i]); 502 return result; 503 } 504 505 for (int i = 0; i < len && std::isdigit(buf[i]); ++i) 506 result = result * 10 + FXSYS_toDecimalDigit(buf[i]); 507 508 return result; 509 } 510 static CFX_WideString StringDataAdd(CFX_WideString str) { 511 CFX_WideString ret; 512 int len = str.GetLength(); 513 FX_WCHAR value = 1; 514 for (int i = len - 1; i >= 0; --i) { 515 FX_WCHAR ch = str[i] + value; 516 if (ch < str[i]) { 517 ret.Insert(0, 0); 518 } else { 519 ret.Insert(0, ch); 520 value = 0; 521 } 522 } 523 if (value) { 524 ret.Insert(0, value); 525 } 526 return ret; 527 } 528 529 // Static. 530 CFX_WideString CPDF_ToUnicodeMap::StringToWideString( 531 const CFX_ByteStringC& str) { 532 const FX_CHAR* buf = str.GetCStr(); 533 int len = str.GetLength(); 534 if (len == 0) 535 return CFX_WideString(); 536 537 CFX_WideString result; 538 if (buf[0] == '<') { 539 int byte_pos = 0; 540 FX_WCHAR ch = 0; 541 for (int i = 1; i < len && std::isxdigit(buf[i]); ++i) { 542 ch = ch * 16 + FXSYS_toHexDigit(buf[i]); 543 byte_pos++; 544 if (byte_pos == 4) { 545 result += ch; 546 byte_pos = 0; 547 ch = 0; 548 } 549 } 550 return result; 551 } 552 return result; 553 } 554 void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) { 555 CIDSet cid_set = CIDSET_UNKNOWN; 556 CPDF_StreamAcc stream; 557 stream.LoadAllData(pStream, FALSE); 558 CPDF_SimpleParser parser(stream.GetData(), stream.GetSize()); 559 while (1) { 560 CFX_ByteStringC word = parser.GetWord(); 561 if (word.IsEmpty()) { 562 break; 563 } 564 if (word == "beginbfchar") { 565 while (1) { 566 word = parser.GetWord(); 567 if (word.IsEmpty() || word == "endbfchar") { 568 break; 569 } 570 FX_DWORD srccode = StringToCode(word); 571 word = parser.GetWord(); 572 CFX_WideString destcode = StringToWideString(word); 573 int len = destcode.GetLength(); 574 if (len == 0) { 575 continue; 576 } 577 if (len == 1) { 578 m_Map[srccode] = destcode.GetAt(0); 579 } else { 580 m_Map[srccode] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff; 581 m_MultiCharBuf.AppendChar(destcode.GetLength()); 582 m_MultiCharBuf << destcode; 583 } 584 } 585 } else if (word == "beginbfrange") { 586 while (1) { 587 CFX_ByteString low, high; 588 low = parser.GetWord(); 589 if (low.IsEmpty() || low == "endbfrange") { 590 break; 591 } 592 high = parser.GetWord(); 593 FX_DWORD lowcode = StringToCode(low); 594 FX_DWORD highcode = 595 (lowcode & 0xffffff00) | (StringToCode(high) & 0xff); 596 if (highcode == (FX_DWORD)-1) { 597 break; 598 } 599 CFX_ByteString start = parser.GetWord(); 600 if (start == "[") { 601 for (FX_DWORD code = lowcode; code <= highcode; code++) { 602 CFX_ByteString dest = parser.GetWord(); 603 CFX_WideString destcode = StringToWideString(dest); 604 int len = destcode.GetLength(); 605 if (len == 0) { 606 continue; 607 } 608 if (len == 1) { 609 m_Map[code] = destcode.GetAt(0); 610 } else { 611 m_Map[code] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff; 612 m_MultiCharBuf.AppendChar(destcode.GetLength()); 613 m_MultiCharBuf << destcode; 614 } 615 } 616 parser.GetWord(); 617 } else { 618 CFX_WideString destcode = StringToWideString(start); 619 int len = destcode.GetLength(); 620 FX_DWORD value = 0; 621 if (len == 1) { 622 value = StringToCode(start); 623 for (FX_DWORD code = lowcode; code <= highcode; code++) { 624 m_Map[code] = value++; 625 } 626 } else { 627 for (FX_DWORD code = lowcode; code <= highcode; code++) { 628 CFX_WideString retcode; 629 if (code == lowcode) { 630 retcode = destcode; 631 } else { 632 retcode = StringDataAdd(destcode); 633 } 634 m_Map[code] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff; 635 m_MultiCharBuf.AppendChar(retcode.GetLength()); 636 m_MultiCharBuf << retcode; 637 destcode = retcode; 638 } 639 } 640 } 641 } 642 } else if (word == "/Adobe-Korea1-UCS2") { 643 cid_set = CIDSET_KOREA1; 644 } else if (word == "/Adobe-Japan1-UCS2") { 645 cid_set = CIDSET_JAPAN1; 646 } else if (word == "/Adobe-CNS1-UCS2") { 647 cid_set = CIDSET_CNS1; 648 } else if (word == "/Adobe-GB1-UCS2") { 649 cid_set = CIDSET_GB1; 650 } 651 } 652 if (cid_set) { 653 m_pBaseMap = CPDF_ModuleMgr::Get() 654 ->GetPageModule() 655 ->GetFontGlobals() 656 ->m_CMapManager.GetCID2UnicodeMap(cid_set, FALSE); 657 } else { 658 m_pBaseMap = NULL; 659 } 660 } 661 static FX_BOOL GetPredefinedEncoding(int& basemap, 662 const CFX_ByteString& value) { 663 if (value == "WinAnsiEncoding") { 664 basemap = PDFFONT_ENCODING_WINANSI; 665 } else if (value == "MacRomanEncoding") { 666 basemap = PDFFONT_ENCODING_MACROMAN; 667 } else if (value == "MacExpertEncoding") { 668 basemap = PDFFONT_ENCODING_MACEXPERT; 669 } else if (value == "PDFDocEncoding") { 670 basemap = PDFFONT_ENCODING_PDFDOC; 671 } else { 672 return FALSE; 673 } 674 return TRUE; 675 } 676 void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, 677 int& iBaseEncoding, 678 CFX_ByteString*& pCharNames, 679 FX_BOOL bEmbedded, 680 FX_BOOL bTrueType) { 681 if (!pEncoding) { 682 if (m_BaseFont == "Symbol") { 683 iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL 684 : PDFFONT_ENCODING_ADOBE_SYMBOL; 685 } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { 686 iBaseEncoding = PDFFONT_ENCODING_WINANSI; 687 } 688 return; 689 } 690 if (pEncoding->IsName()) { 691 if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || 692 iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) { 693 return; 694 } 695 if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") { 696 if (!bTrueType) { 697 iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; 698 } 699 return; 700 } 701 CFX_ByteString bsEncoding = pEncoding->GetString(); 702 if (bsEncoding.Compare("MacExpertEncoding") == 0) { 703 bsEncoding = "WinAnsiEncoding"; 704 } 705 GetPredefinedEncoding(iBaseEncoding, bsEncoding); 706 return; 707 } 708 709 CPDF_Dictionary* pDict = pEncoding->AsDictionary(); 710 if (!pDict) 711 return; 712 713 if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && 714 iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) { 715 CFX_ByteString bsEncoding = pDict->GetString("BaseEncoding"); 716 if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) { 717 bsEncoding = "WinAnsiEncoding"; 718 } 719 GetPredefinedEncoding(iBaseEncoding, bsEncoding); 720 } 721 if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { 722 iBaseEncoding = PDFFONT_ENCODING_STANDARD; 723 } 724 CPDF_Array* pDiffs = pDict->GetArray("Differences"); 725 if (!pDiffs) { 726 return; 727 } 728 pCharNames = new CFX_ByteString[256]; 729 FX_DWORD cur_code = 0; 730 for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) { 731 CPDF_Object* pElement = pDiffs->GetElementValue(i); 732 if (!pElement) 733 continue; 734 735 if (CPDF_Name* pName = pElement->AsName()) { 736 if (cur_code < 256) 737 pCharNames[cur_code] = pName->GetString(); 738 cur_code++; 739 } else { 740 cur_code = pElement->GetInteger(); 741 } 742 } 743 } 744 745 FX_BOOL CPDF_Font::IsStandardFont() const { 746 if (m_FontType != PDFFONT_TYPE1) 747 return FALSE; 748 if (m_pFontFile) 749 return FALSE; 750 if (((CPDF_Type1Font*)this)->GetBase14Font() < 0) 751 return FALSE; 752 return TRUE; 753 } 754 CPDF_SimpleFont::CPDF_SimpleFont(int fonttype) : CPDF_Font(fonttype) { 755 FXSYS_memset(m_CharBBox, 0xff, sizeof m_CharBBox); 756 FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth); 757 FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex); 758 FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID); 759 m_pCharNames = NULL; 760 m_BaseEncoding = PDFFONT_ENCODING_BUILTIN; 761 } 762 CPDF_SimpleFont::~CPDF_SimpleFont() { 763 delete[] m_pCharNames; 764 } 765 int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) { 766 if (pVertGlyph) { 767 *pVertGlyph = FALSE; 768 } 769 if (charcode > 0xff) { 770 return -1; 771 } 772 int index = m_GlyphIndex[(uint8_t)charcode]; 773 if (index == 0xffff) { 774 return -1; 775 } 776 return index; 777 } 778 void CPDF_SimpleFont::LoadCharMetrics(int charcode) { 779 if (!m_Font.GetFace()) 780 return; 781 782 if (charcode < 0 || charcode > 0xff) { 783 return; 784 } 785 int glyph_index = m_GlyphIndex[charcode]; 786 if (glyph_index == 0xffff) { 787 if (!m_pFontFile && charcode != 32) { 788 LoadCharMetrics(32); 789 m_CharBBox[charcode] = m_CharBBox[32]; 790 if (m_bUseFontWidth) { 791 m_CharWidth[charcode] = m_CharWidth[32]; 792 } 793 } 794 return; 795 } 796 FXFT_Face face = m_Font.GetFace(); 797 int err = FXFT_Load_Glyph( 798 face, glyph_index, 799 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); 800 if (err) { 801 return; 802 } 803 m_CharBBox[charcode].Left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face); 804 m_CharBBox[charcode].Right = TT2PDF( 805 FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face), face); 806 m_CharBBox[charcode].Top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face); 807 m_CharBBox[charcode].Bottom = TT2PDF( 808 FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face), face); 809 if (m_bUseFontWidth) { 810 int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face); 811 if (m_CharWidth[charcode] == 0xffff) { 812 m_CharWidth[charcode] = TT_Width; 813 } else if (TT_Width && !IsEmbedded()) { 814 m_CharBBox[charcode].Right = 815 m_CharBBox[charcode].Right * m_CharWidth[charcode] / TT_Width; 816 m_CharBBox[charcode].Left = 817 m_CharBBox[charcode].Left * m_CharWidth[charcode] / TT_Width; 818 } 819 } 820 } 821 int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) { 822 if (charcode > 0xff) { 823 charcode = 0; 824 } 825 if (m_CharWidth[charcode] == 0xffff) { 826 LoadCharMetrics(charcode); 827 if (m_CharWidth[charcode] == 0xffff) { 828 m_CharWidth[charcode] = 0; 829 } 830 } 831 return (int16_t)m_CharWidth[charcode]; 832 } 833 void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) { 834 if (charcode > 0xff) { 835 charcode = 0; 836 } 837 if (m_CharBBox[charcode].Left == (int16_t)0xffff) { 838 LoadCharMetrics(charcode); 839 } 840 rect.left = m_CharBBox[charcode].Left; 841 rect.right = m_CharBBox[charcode].Right; 842 rect.bottom = m_CharBBox[charcode].Bottom; 843 rect.top = m_CharBBox[charcode].Top; 844 } 845 const FX_CHAR* GetAdobeCharName(int iBaseEncoding, 846 const CFX_ByteString* pCharNames, 847 int charcode) { 848 ASSERT(charcode >= 0 && charcode < 256); 849 if (charcode < 0 || charcode >= 256) { 850 return NULL; 851 } 852 const FX_CHAR* name = NULL; 853 if (pCharNames) { 854 name = pCharNames[charcode]; 855 } 856 if ((!name || name[0] == 0) && iBaseEncoding) { 857 name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode); 858 } 859 return name && name[0] ? name : nullptr; 860 } 861 FX_BOOL CPDF_SimpleFont::LoadCommon() { 862 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict("FontDescriptor"); 863 if (pFontDesc) { 864 LoadFontDescriptor(pFontDesc); 865 } 866 CPDF_Array* pWidthArray = m_pFontDict->GetArray("Widths"); 867 int width_start = 0, width_end = -1; 868 m_bUseFontWidth = TRUE; 869 if (pWidthArray) { 870 m_bUseFontWidth = FALSE; 871 if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) { 872 int MissingWidth = pFontDesc->GetInteger("MissingWidth"); 873 for (int i = 0; i < 256; i++) { 874 m_CharWidth[i] = MissingWidth; 875 } 876 } 877 width_start = m_pFontDict->GetInteger("FirstChar", 0); 878 width_end = m_pFontDict->GetInteger("LastChar", 0); 879 if (width_start >= 0 && width_start <= 255) { 880 if (width_end <= 0 || 881 width_end >= width_start + (int)pWidthArray->GetCount()) { 882 width_end = width_start + pWidthArray->GetCount() - 1; 883 } 884 if (width_end > 255) { 885 width_end = 255; 886 } 887 for (int i = width_start; i <= width_end; i++) { 888 m_CharWidth[i] = pWidthArray->GetInteger(i - width_start); 889 } 890 } 891 } 892 if (m_pFontFile) { 893 if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') { 894 m_BaseFont = m_BaseFont.Mid(8); 895 } 896 } else { 897 LoadSubstFont(); 898 } 899 if (!(m_Flags & PDFFONT_SYMBOLIC)) { 900 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; 901 } 902 CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding"); 903 LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL, 904 m_Font.IsTTFont()); 905 LoadGlyphMap(); 906 delete[] m_pCharNames; 907 m_pCharNames = NULL; 908 if (!m_Font.GetFace()) 909 return TRUE; 910 911 if (m_Flags & PDFFONT_ALLCAP) { 912 unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd}; 913 for (size_t range = 0; range < sizeof lowercases / 2; range++) { 914 for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i++) { 915 if (m_GlyphIndex[i] != 0xffff && m_pFontFile) { 916 continue; 917 } 918 m_GlyphIndex[i] = m_GlyphIndex[i - 32]; 919 if (m_CharWidth[i - 32]) { 920 m_CharWidth[i] = m_CharWidth[i - 32]; 921 m_CharBBox[i] = m_CharBBox[i - 32]; 922 } 923 } 924 } 925 } 926 CheckFontMetrics(); 927 return TRUE; 928 } 929 void CPDF_SimpleFont::LoadSubstFont() { 930 if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) { 931 int width = 0, i; 932 for (i = 0; i < 256; i++) { 933 if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) { 934 continue; 935 } 936 if (width == 0) { 937 width = m_CharWidth[i]; 938 } else if (width != m_CharWidth[i]) { 939 break; 940 } 941 } 942 if (i == 256 && width) { 943 m_Flags |= PDFFONT_FIXEDPITCH; 944 } 945 } 946 int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140); 947 m_Font.LoadSubst(m_BaseFont, IsFontType(PDFFONT_TRUETYPE), m_Flags, weight, 948 m_ItalicAngle, 0); 949 if (m_Font.GetSubstFont()->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) { 950 } 951 } 952 FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const { 953 return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && 954 m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && 955 m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS; 956 } 957 CPDF_Type1Font::CPDF_Type1Font() : CPDF_SimpleFont(PDFFONT_TYPE1) { 958 m_Base14Font = -1; 959 } 960 FX_BOOL CPDF_Type1Font::_Load() { 961 m_Base14Font = PDF_GetStandardFontName(&m_BaseFont); 962 if (m_Base14Font >= 0) { 963 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict("FontDescriptor"); 964 if (pFontDesc && pFontDesc->KeyExist("Flags")) { 965 m_Flags = pFontDesc->GetInteger("Flags"); 966 } else { 967 m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC; 968 } 969 if (m_Base14Font < 4) 970 for (int i = 0; i < 256; i++) { 971 m_CharWidth[i] = 600; 972 } 973 if (m_Base14Font == 12) { 974 m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; 975 } else if (m_Base14Font == 13) { 976 m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS; 977 } else if (m_Flags & PDFFONT_NONSYMBOLIC) { 978 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; 979 } 980 } 981 return LoadCommon(); 982 } 983 static FX_BOOL FT_UseType1Charmap(FXFT_Face face) { 984 if (FXFT_Get_Face_CharmapCount(face) == 0) { 985 return FALSE; 986 } 987 if (FXFT_Get_Face_CharmapCount(face) == 1 && 988 FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == 989 FXFT_ENCODING_UNICODE) { 990 return FALSE; 991 } 992 if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == 993 FXFT_ENCODING_UNICODE) { 994 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]); 995 } else { 996 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); 997 } 998 return TRUE; 999 } 1000 int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) { 1001 if (charcode > 0xff) { 1002 return -1; 1003 } 1004 int index = m_ExtGID[(uint8_t)charcode]; 1005 if (index == 0xffff) { 1006 return -1; 1007 } 1008 return index; 1009 } 1010 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1011 struct _GlyphNameMap { 1012 const FX_CHAR* m_pStrAdobe; 1013 const FX_CHAR* m_pStrUnicode; 1014 }; 1015 static const _GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"}, 1016 {"fi", "uniFB01"}, 1017 {"fl", "uniFB02"}, 1018 {"ffi", "uniFB03"}, 1019 {"ffl", "uniFB04"}}; 1020 extern "C" { 1021 static int compareString(const void* key, const void* element) { 1022 return FXSYS_stricmp((const FX_CHAR*)key, 1023 ((_GlyphNameMap*)element)->m_pStrAdobe); 1024 } 1025 } 1026 static const FX_CHAR* _GlyphNameRemap(const FX_CHAR* pStrAdobe) { 1027 _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch( 1028 pStrAdobe, g_GlyphNameSubsts, 1029 sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), sizeof(_GlyphNameMap), 1030 compareString); 1031 if (found) { 1032 return found->m_pStrUnicode; 1033 } 1034 return NULL; 1035 } 1036 #endif 1037 void CPDF_Type1Font::LoadGlyphMap() { 1038 if (!m_Font.GetFace()) 1039 return; 1040 1041 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1042 FX_BOOL bCoreText = TRUE; 1043 CQuartz2D& quartz2d = 1044 ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; 1045 if (!m_Font.GetPlatformFont()) { 1046 if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { 1047 bCoreText = FALSE; 1048 } 1049 m_Font.SetPlatformFont( 1050 quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize())); 1051 if (!m_Font.GetPlatformFont()) { 1052 bCoreText = FALSE; 1053 } 1054 } 1055 #endif 1056 if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) { 1057 if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { 1058 FX_BOOL bGotOne = FALSE; 1059 for (int charcode = 0; charcode < 256; charcode++) { 1060 const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; 1061 for (int j = 0; j < 4; j++) { 1062 FX_WORD unicode = prefix[j] * 256 + charcode; 1063 m_GlyphIndex[charcode] = 1064 FXFT_Get_Char_Index(m_Font.GetFace(), unicode); 1065 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1066 FX_CHAR name_glyph[256]; 1067 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], 1068 name_glyph, 256); 1069 name_glyph[255] = 0; 1070 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( 1071 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, 1072 kCFAllocatorNull); 1073 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( 1074 (CGFontRef)m_Font.GetPlatformFont(), name_ct); 1075 if (name_ct) { 1076 CFRelease(name_ct); 1077 } 1078 #endif 1079 if (m_GlyphIndex[charcode]) { 1080 bGotOne = TRUE; 1081 break; 1082 } 1083 } 1084 } 1085 if (bGotOne) { 1086 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1087 if (!bCoreText) { 1088 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); 1089 } 1090 #endif 1091 return; 1092 } 1093 } 1094 FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE); 1095 if (m_BaseEncoding == 0) { 1096 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; 1097 } 1098 for (int charcode = 0; charcode < 256; charcode++) { 1099 const FX_CHAR* name = 1100 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); 1101 if (!name) { 1102 continue; 1103 } 1104 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 1105 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( 1106 m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); 1107 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1108 FX_CHAR name_glyph[256]; 1109 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph, 1110 256); 1111 name_glyph[255] = 0; 1112 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( 1113 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, 1114 kCFAllocatorNull); 1115 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( 1116 (CGFontRef)m_Font.GetPlatformFont(), name_ct); 1117 if (name_ct) { 1118 CFRelease(name_ct); 1119 } 1120 #endif 1121 if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) { 1122 m_Encoding.m_Unicodes[charcode] = 0x20; 1123 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20); 1124 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1125 FX_CHAR name_glyph[256]; 1126 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], 1127 name_glyph, 256); 1128 name_glyph[255] = 0; 1129 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( 1130 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, 1131 kCFAllocatorNull); 1132 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( 1133 (CGFontRef)m_Font.GetPlatformFont(), name_ct); 1134 if (name_ct) { 1135 CFRelease(name_ct); 1136 } 1137 #endif 1138 } 1139 } 1140 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1141 if (!bCoreText) { 1142 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); 1143 } 1144 #endif 1145 return; 1146 } 1147 FT_UseType1Charmap(m_Font.GetFace()); 1148 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1149 if (bCoreText) { 1150 if (m_Flags & PDFFONT_SYMBOLIC) { 1151 for (int charcode = 0; charcode < 256; charcode++) { 1152 const FX_CHAR* name = 1153 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); 1154 if (name) { 1155 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 1156 m_GlyphIndex[charcode] = 1157 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 1158 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( 1159 kCFAllocatorDefault, name, kCFStringEncodingASCII, 1160 kCFAllocatorNull); 1161 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( 1162 (CGFontRef)m_Font.GetPlatformFont(), name_ct); 1163 if (name_ct) { 1164 CFRelease(name_ct); 1165 } 1166 } else { 1167 m_GlyphIndex[charcode] = 1168 FXFT_Get_Char_Index(m_Font.GetFace(), charcode); 1169 FX_WCHAR unicode = 0; 1170 if (m_GlyphIndex[charcode]) { 1171 unicode = 1172 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); 1173 } 1174 FX_CHAR name_glyph[256]; 1175 FXSYS_memset(name_glyph, 0, sizeof(name_glyph)); 1176 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], 1177 name_glyph, 256); 1178 name_glyph[255] = 0; 1179 if (unicode == 0 && name_glyph[0] != 0) { 1180 unicode = PDF_UnicodeFromAdobeName(name_glyph); 1181 } 1182 m_Encoding.m_Unicodes[charcode] = unicode; 1183 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( 1184 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, 1185 kCFAllocatorNull); 1186 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( 1187 (CGFontRef)m_Font.GetPlatformFont(), name_ct); 1188 if (name_ct) { 1189 CFRelease(name_ct); 1190 } 1191 } 1192 } 1193 return; 1194 } 1195 FX_BOOL bUnicode = FALSE; 1196 if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { 1197 bUnicode = TRUE; 1198 } 1199 for (int charcode = 0; charcode < 256; charcode++) { 1200 const FX_CHAR* name = 1201 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); 1202 if (!name) { 1203 continue; 1204 } 1205 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 1206 const FX_CHAR* pStrUnicode = _GlyphNameRemap(name); 1207 if (pStrUnicode && 1208 0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) { 1209 name = pStrUnicode; 1210 } 1211 m_GlyphIndex[charcode] = 1212 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 1213 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( 1214 kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull); 1215 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( 1216 (CGFontRef)m_Font.GetPlatformFont(), name_ct); 1217 if (name_ct) { 1218 CFRelease(name_ct); 1219 } 1220 if (m_GlyphIndex[charcode] == 0) { 1221 if (FXSYS_strcmp(name, ".notdef") != 0 && 1222 FXSYS_strcmp(name, "space") != 0) { 1223 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( 1224 m_Font.GetFace(), 1225 bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); 1226 FX_CHAR name_glyph[256]; 1227 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], 1228 name_glyph, 256); 1229 name_glyph[255] = 0; 1230 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( 1231 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, 1232 kCFAllocatorNull); 1233 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( 1234 (CGFontRef)m_Font.GetPlatformFont(), name_ct); 1235 if (name_ct) { 1236 CFRelease(name_ct); 1237 } 1238 } else { 1239 m_Encoding.m_Unicodes[charcode] = 0x20; 1240 m_GlyphIndex[charcode] = 1241 bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff; 1242 FX_CHAR name_glyph[256]; 1243 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], 1244 name_glyph, 256); 1245 name_glyph[255] = 0; 1246 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( 1247 kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, 1248 kCFAllocatorNull); 1249 m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( 1250 (CGFontRef)m_Font.GetPlatformFont(), name_ct); 1251 if (name_ct) { 1252 CFRelease(name_ct); 1253 } 1254 } 1255 } 1256 } 1257 return; 1258 } 1259 #endif 1260 if (m_Flags & PDFFONT_SYMBOLIC) { 1261 for (int charcode = 0; charcode < 256; charcode++) { 1262 const FX_CHAR* name = 1263 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); 1264 if (name) { 1265 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 1266 m_GlyphIndex[charcode] = 1267 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 1268 } else { 1269 m_GlyphIndex[charcode] = 1270 FXFT_Get_Char_Index(m_Font.GetFace(), charcode); 1271 if (m_GlyphIndex[charcode]) { 1272 FX_WCHAR unicode = 1273 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); 1274 if (unicode == 0) { 1275 FX_CHAR name_glyph[256]; 1276 FXSYS_memset(name_glyph, 0, sizeof(name_glyph)); 1277 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], 1278 name_glyph, 256); 1279 name_glyph[255] = 0; 1280 if (name_glyph[0] != 0) { 1281 unicode = PDF_UnicodeFromAdobeName(name_glyph); 1282 } 1283 } 1284 m_Encoding.m_Unicodes[charcode] = unicode; 1285 } 1286 } 1287 } 1288 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1289 if (!bCoreText) { 1290 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); 1291 } 1292 #endif 1293 return; 1294 } 1295 FX_BOOL bUnicode = FALSE; 1296 if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { 1297 bUnicode = TRUE; 1298 } 1299 for (int charcode = 0; charcode < 256; charcode++) { 1300 const FX_CHAR* name = 1301 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); 1302 if (!name) { 1303 continue; 1304 } 1305 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 1306 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 1307 if (m_GlyphIndex[charcode] == 0) { 1308 if (FXSYS_strcmp(name, ".notdef") != 0 && 1309 FXSYS_strcmp(name, "space") != 0) { 1310 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( 1311 m_Font.GetFace(), 1312 bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); 1313 } else { 1314 m_Encoding.m_Unicodes[charcode] = 0x20; 1315 m_GlyphIndex[charcode] = 0xffff; 1316 } 1317 } 1318 } 1319 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 1320 if (!bCoreText) { 1321 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); 1322 } 1323 #endif 1324 } 1325 1326 CPDF_FontEncoding::CPDF_FontEncoding() { 1327 FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes)); 1328 } 1329 int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const { 1330 for (int i = 0; i < 256; i++) 1331 if (m_Unicodes[i] == unicode) { 1332 return i; 1333 } 1334 return -1; 1335 } 1336 CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) { 1337 const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding); 1338 if (!pSrc) { 1339 FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes)); 1340 } else 1341 for (int i = 0; i < 256; i++) { 1342 m_Unicodes[i] = pSrc[i]; 1343 } 1344 } 1345 FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const { 1346 return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) == 1347 0; 1348 } 1349 CPDF_Object* CPDF_FontEncoding::Realize() { 1350 int predefined = 0; 1351 for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; 1352 cs++) { 1353 const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs); 1354 FX_BOOL match = TRUE; 1355 for (int i = 0; i < 256; ++i) { 1356 if (m_Unicodes[i] != pSrc[i]) { 1357 match = FALSE; 1358 break; 1359 } 1360 } 1361 if (match) { 1362 predefined = cs; 1363 break; 1364 } 1365 } 1366 if (predefined) { 1367 if (predefined == PDFFONT_ENCODING_WINANSI) { 1368 return new CPDF_Name("WinAnsiEncoding"); 1369 } 1370 if (predefined == PDFFONT_ENCODING_MACROMAN) { 1371 return new CPDF_Name("MacRomanEncoding"); 1372 } 1373 if (predefined == PDFFONT_ENCODING_MACEXPERT) { 1374 return new CPDF_Name("MacExpertEncoding"); 1375 } 1376 return NULL; 1377 } 1378 const FX_WORD* pStandard = 1379 PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI); 1380 CPDF_Array* pDiff = new CPDF_Array; 1381 for (int i = 0; i < 256; i++) { 1382 if (pStandard[i] == m_Unicodes[i]) { 1383 continue; 1384 } 1385 pDiff->Add(new CPDF_Number(i)); 1386 pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i]))); 1387 } 1388 1389 CPDF_Dictionary* pDict = new CPDF_Dictionary; 1390 pDict->SetAtName("BaseEncoding", "WinAnsiEncoding"); 1391 pDict->SetAt("Differences", pDiff); 1392 return pDict; 1393 } 1394 CPDF_TrueTypeFont::CPDF_TrueTypeFont() : CPDF_SimpleFont(PDFFONT_TRUETYPE) {} 1395 FX_BOOL CPDF_TrueTypeFont::_Load() { 1396 return LoadCommon(); 1397 } 1398 void CPDF_TrueTypeFont::LoadGlyphMap() { 1399 if (!m_Font.GetFace()) 1400 return; 1401 1402 int baseEncoding = m_BaseEncoding; 1403 if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 && 1404 (baseEncoding == PDFFONT_ENCODING_MACROMAN || 1405 baseEncoding == PDFFONT_ENCODING_WINANSI) && 1406 (m_Flags & PDFFONT_SYMBOLIC)) { 1407 FX_BOOL bSupportWin = FALSE; 1408 FX_BOOL bSupportMac = FALSE; 1409 for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) { 1410 int platform_id = FXFT_Get_Charmap_PlatformID( 1411 FXFT_Get_Face_Charmaps(m_Font.GetFace())[i]); 1412 if (platform_id == 0 || platform_id == 3) { 1413 bSupportWin = TRUE; 1414 } else if (platform_id == 0 || platform_id == 1) { 1415 bSupportMac = TRUE; 1416 } 1417 } 1418 if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) { 1419 baseEncoding = 1420 bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN; 1421 } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) { 1422 baseEncoding = 1423 bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN; 1424 } 1425 } 1426 if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || 1427 baseEncoding == PDFFONT_ENCODING_WINANSI) && 1428 !m_pCharNames) || 1429 (m_Flags & PDFFONT_NONSYMBOLIC)) { 1430 if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) && 1431 (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) { 1432 int nStartChar = m_pFontDict->GetInteger("FirstChar"); 1433 if (nStartChar < 0 || nStartChar > 255) 1434 return; 1435 1436 int charcode = 0; 1437 for (; charcode < nStartChar; charcode++) { 1438 m_GlyphIndex[charcode] = 0; 1439 } 1440 FX_WORD nGlyph = charcode - nStartChar + 3; 1441 for (; charcode < 256; charcode++, nGlyph++) { 1442 m_GlyphIndex[charcode] = nGlyph; 1443 } 1444 return; 1445 } 1446 FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1); 1447 FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE; 1448 if (!bMSUnicode) { 1449 if (m_Flags & PDFFONT_NONSYMBOLIC) { 1450 bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0); 1451 bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0); 1452 } else { 1453 bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0); 1454 bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0); 1455 } 1456 } 1457 FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode"); 1458 for (int charcode = 0; charcode < 256; charcode++) { 1459 const FX_CHAR* name = 1460 GetAdobeCharName(baseEncoding, m_pCharNames, charcode); 1461 if (!name) { 1462 m_GlyphIndex[charcode] = 1463 m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1; 1464 continue; 1465 } 1466 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 1467 if (bMSSymbol) { 1468 const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; 1469 for (int j = 0; j < 4; j++) { 1470 FX_WORD unicode = prefix[j] * 256 + charcode; 1471 m_GlyphIndex[charcode] = 1472 FXFT_Get_Char_Index(m_Font.GetFace(), unicode); 1473 if (m_GlyphIndex[charcode]) { 1474 break; 1475 } 1476 } 1477 } else if (m_Encoding.m_Unicodes[charcode]) { 1478 if (bMSUnicode) { 1479 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( 1480 m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); 1481 } else if (bMacRoman) { 1482 FX_DWORD maccode = FT_CharCodeFromUnicode( 1483 FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]); 1484 if (!maccode) { 1485 m_GlyphIndex[charcode] = 1486 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 1487 } else { 1488 m_GlyphIndex[charcode] = 1489 FXFT_Get_Char_Index(m_Font.GetFace(), maccode); 1490 } 1491 } 1492 } 1493 if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && 1494 name) { 1495 if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) { 1496 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32); 1497 } else { 1498 m_GlyphIndex[charcode] = 1499 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 1500 if (m_GlyphIndex[charcode] == 0) { 1501 if (bToUnicode) { 1502 CFX_WideString wsUnicode = UnicodeFromCharCode(charcode); 1503 if (!wsUnicode.IsEmpty()) { 1504 m_GlyphIndex[charcode] = 1505 FXFT_Get_Char_Index(m_Font.GetFace(), wsUnicode[0]); 1506 m_Encoding.m_Unicodes[charcode] = wsUnicode[0]; 1507 } 1508 } 1509 if (m_GlyphIndex[charcode] == 0) { 1510 m_GlyphIndex[charcode] = 1511 FXFT_Get_Char_Index(m_Font.GetFace(), charcode); 1512 } 1513 } 1514 } 1515 } 1516 } 1517 return; 1518 } 1519 if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { 1520 const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; 1521 FX_BOOL bGotOne = FALSE; 1522 for (int charcode = 0; charcode < 256; charcode++) { 1523 for (int j = 0; j < 4; j++) { 1524 FX_WORD unicode = prefix[j] * 256 + charcode; 1525 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode); 1526 if (m_GlyphIndex[charcode]) { 1527 bGotOne = TRUE; 1528 break; 1529 } 1530 } 1531 } 1532 if (bGotOne) { 1533 if (baseEncoding != PDFFONT_ENCODING_BUILTIN) { 1534 for (int charcode = 0; charcode < 256; charcode++) { 1535 const FX_CHAR* name = 1536 GetAdobeCharName(baseEncoding, m_pCharNames, charcode); 1537 if (!name) { 1538 continue; 1539 } 1540 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 1541 } 1542 } else if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { 1543 for (int charcode = 0; charcode < 256; charcode++) { 1544 m_Encoding.m_Unicodes[charcode] = 1545 FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); 1546 } 1547 } 1548 return; 1549 } 1550 } 1551 if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) { 1552 FX_BOOL bGotOne = FALSE; 1553 for (int charcode = 0; charcode < 256; charcode++) { 1554 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode); 1555 m_Encoding.m_Unicodes[charcode] = 1556 FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); 1557 if (m_GlyphIndex[charcode]) { 1558 bGotOne = TRUE; 1559 } 1560 } 1561 if (m_pFontFile || bGotOne) { 1562 return; 1563 } 1564 } 1565 if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) { 1566 FX_BOOL bGotOne = FALSE; 1567 const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding); 1568 for (int charcode = 0; charcode < 256; charcode++) { 1569 if (m_pFontFile) { 1570 m_Encoding.m_Unicodes[charcode] = charcode; 1571 } else { 1572 const FX_CHAR* name = GetAdobeCharName(0, m_pCharNames, charcode); 1573 if (name) { 1574 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 1575 } else if (pUnicodes) { 1576 m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode]; 1577 } 1578 } 1579 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( 1580 m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); 1581 if (m_GlyphIndex[charcode]) { 1582 bGotOne = TRUE; 1583 } 1584 } 1585 if (bGotOne) { 1586 return; 1587 } 1588 } 1589 for (int charcode = 0; charcode < 256; charcode++) { 1590 m_GlyphIndex[charcode] = charcode; 1591 } 1592 } 1593 1594 CPDF_Type3Font::CPDF_Type3Font() 1595 : CPDF_SimpleFont(PDFFONT_TYPE3), 1596 m_pCharProcs(nullptr), 1597 m_pPageResources(nullptr), 1598 m_pFontResources(nullptr) { 1599 FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL)); 1600 } 1601 1602 CPDF_Type3Font::~CPDF_Type3Font() { 1603 for (auto it : m_CacheMap) 1604 delete it.second; 1605 } 1606 1607 FX_BOOL CPDF_Type3Font::_Load() { 1608 m_pFontResources = m_pFontDict->GetDict("Resources"); 1609 CPDF_Array* pMatrix = m_pFontDict->GetArray("FontMatrix"); 1610 FX_FLOAT xscale = 1.0f, yscale = 1.0f; 1611 if (pMatrix) { 1612 m_FontMatrix = pMatrix->GetMatrix(); 1613 xscale = m_FontMatrix.a; 1614 yscale = m_FontMatrix.d; 1615 } 1616 CPDF_Array* pBBox = m_pFontDict->GetArray("FontBBox"); 1617 if (pBBox) { 1618 m_FontBBox.left = (int32_t)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000); 1619 m_FontBBox.bottom = 1620 (int32_t)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000); 1621 m_FontBBox.right = (int32_t)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000); 1622 m_FontBBox.top = (int32_t)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 1000); 1623 } 1624 int StartChar = m_pFontDict->GetInteger("FirstChar"); 1625 CPDF_Array* pWidthArray = m_pFontDict->GetArray("Widths"); 1626 if (pWidthArray && (StartChar >= 0 && StartChar < 256)) { 1627 FX_DWORD count = pWidthArray->GetCount(); 1628 if (count > 256) { 1629 count = 256; 1630 } 1631 if (StartChar + count > 256) { 1632 count = 256 - StartChar; 1633 } 1634 for (FX_DWORD i = 0; i < count; i++) { 1635 m_CharWidthL[StartChar + i] = 1636 FXSYS_round(FXSYS_Mul(pWidthArray->GetNumber(i), xscale) * 1000); 1637 } 1638 } 1639 m_pCharProcs = m_pFontDict->GetDict("CharProcs"); 1640 CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding"); 1641 if (pEncoding) { 1642 LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE); 1643 if (m_pCharNames) { 1644 for (int i = 0; i < 256; i++) { 1645 m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]); 1646 if (m_Encoding.m_Unicodes[i] == 0) { 1647 m_Encoding.m_Unicodes[i] = i; 1648 } 1649 } 1650 } 1651 } 1652 return TRUE; 1653 } 1654 void CPDF_Type3Font::CheckType3FontMetrics() { 1655 CheckFontMetrics(); 1656 } 1657 1658 CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) { 1659 if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_) 1660 return nullptr; 1661 1662 auto it = m_CacheMap.find(charcode); 1663 if (it != m_CacheMap.end()) 1664 return it->second; 1665 1666 const FX_CHAR* name = 1667 GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); 1668 if (!name) 1669 return nullptr; 1670 1671 CPDF_Stream* pStream = 1672 ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr); 1673 if (!pStream) 1674 return nullptr; 1675 1676 std::unique_ptr<CPDF_Type3Char> pNewChar(new CPDF_Type3Char(new CPDF_Form( 1677 m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources, 1678 pStream, nullptr))); 1679 1680 // This can trigger recursion into this method. The content of |m_CacheMap| 1681 // can change as a result. Thus after it returns, check the cache again for 1682 // a cache hit. 1683 pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr, 1684 level + 1); 1685 it = m_CacheMap.find(charcode); 1686 if (it != m_CacheMap.end()) 1687 return it->second; 1688 1689 FX_FLOAT scale = m_FontMatrix.GetXUnit(); 1690 pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f); 1691 FX_RECT& rcBBox = pNewChar->m_BBox; 1692 CFX_FloatRect char_rect( 1693 (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f, 1694 (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f); 1695 if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) 1696 char_rect = pNewChar->m_pForm->CalcBoundingBox(); 1697 1698 char_rect.Transform(&m_FontMatrix); 1699 rcBBox.left = FXSYS_round(char_rect.left * 1000); 1700 rcBBox.right = FXSYS_round(char_rect.right * 1000); 1701 rcBBox.top = FXSYS_round(char_rect.top * 1000); 1702 rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000); 1703 1704 ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode)); 1705 CPDF_Type3Char* pCachedChar = pNewChar.release(); 1706 m_CacheMap[charcode] = pCachedChar; 1707 if (pCachedChar->m_pForm->CountObjects() == 0) { 1708 delete pCachedChar->m_pForm; 1709 pCachedChar->m_pForm = nullptr; 1710 } 1711 return pCachedChar; 1712 } 1713 1714 int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) { 1715 if (charcode >= FX_ArraySize(m_CharWidthL)) 1716 charcode = 0; 1717 1718 if (m_CharWidthL[charcode]) 1719 return m_CharWidthL[charcode]; 1720 1721 const CPDF_Type3Char* pChar = LoadChar(charcode, level); 1722 return pChar ? pChar->m_Width : 0; 1723 } 1724 1725 void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) { 1726 const CPDF_Type3Char* pChar = LoadChar(charcode, level); 1727 if (!pChar) { 1728 rect.left = 0; 1729 rect.right = 0; 1730 rect.top = 0; 1731 rect.bottom = 0; 1732 return; 1733 } 1734 rect = pChar->m_BBox; 1735 } 1736 1737 CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm) 1738 : m_pForm(pForm), m_pBitmap(nullptr), m_bColored(FALSE) {} 1739 1740 CPDF_Type3Char::~CPDF_Type3Char() { 1741 delete m_pForm; 1742 delete m_pBitmap; 1743 } 1744