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