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