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