OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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/fpdfapi/fpdf_font/include/cpdf_font.h" |
| 8 |
| 9 #include "core/fpdfapi/fpdf_font/cpdf_truetypefont.h" |
| 10 #include "core/fpdfapi/fpdf_font/cpdf_type1font.h" |
| 11 #include "core/fpdfapi/fpdf_font/cpdf_type3font.h" |
| 12 #include "core/fpdfapi/fpdf_font/font_int.h" |
| 13 #include "core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h" |
| 14 #include "core/fpdfapi/fpdf_page/pageint.h" |
| 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
| 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
| 17 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
| 18 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" |
| 19 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
| 20 #include "core/fpdfapi/include/cpdf_modulemgr.h" |
| 21 #include "core/include/fxge/fx_freetype.h" |
| 22 |
| 23 namespace { |
| 24 |
| 25 const uint8_t ChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00}, |
| 26 {0xBF, 0xAC, 0xCC, 0xE5, 0x00}, |
| 27 {0xBA, 0xDA, 0xCC, 0xE5, 0x00}, |
| 28 {0xB7, 0xC2, 0xCB, 0xCE, 0x00}, |
| 29 {0xD0, 0xC2, 0xCB, 0xCE, 0x00}}; |
| 30 |
| 31 FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) { |
| 32 if (value == "WinAnsiEncoding") |
| 33 basemap = PDFFONT_ENCODING_WINANSI; |
| 34 else if (value == "MacRomanEncoding") |
| 35 basemap = PDFFONT_ENCODING_MACROMAN; |
| 36 else if (value == "MacExpertEncoding") |
| 37 basemap = PDFFONT_ENCODING_MACEXPERT; |
| 38 else if (value == "PDFDocEncoding") |
| 39 basemap = PDFFONT_ENCODING_PDFDOC; |
| 40 else |
| 41 return FALSE; |
| 42 return TRUE; |
| 43 } |
| 44 |
| 45 } // namespace |
| 46 |
| 47 CPDF_Font::CPDF_Font() |
| 48 : m_pFontFile(nullptr), |
| 49 m_pFontDict(nullptr), |
| 50 m_pToUnicodeMap(nullptr), |
| 51 m_bToUnicodeLoaded(FALSE), |
| 52 m_Flags(0), |
| 53 m_StemV(0), |
| 54 m_Ascent(0), |
| 55 m_Descent(0), |
| 56 m_ItalicAngle(0) {} |
| 57 |
| 58 CPDF_Font::~CPDF_Font() { |
| 59 delete m_pToUnicodeMap; |
| 60 m_pToUnicodeMap = NULL; |
| 61 |
| 62 if (m_pFontFile) { |
| 63 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( |
| 64 const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream())); |
| 65 } |
| 66 } |
| 67 |
| 68 bool CPDF_Font::IsType1Font() const { |
| 69 return false; |
| 70 } |
| 71 |
| 72 bool CPDF_Font::IsTrueTypeFont() const { |
| 73 return false; |
| 74 } |
| 75 |
| 76 bool CPDF_Font::IsType3Font() const { |
| 77 return false; |
| 78 } |
| 79 |
| 80 bool CPDF_Font::IsCIDFont() const { |
| 81 return false; |
| 82 } |
| 83 |
| 84 const CPDF_Type1Font* CPDF_Font::AsType1Font() const { |
| 85 return nullptr; |
| 86 } |
| 87 |
| 88 CPDF_Type1Font* CPDF_Font::AsType1Font() { |
| 89 return nullptr; |
| 90 } |
| 91 |
| 92 const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const { |
| 93 return nullptr; |
| 94 } |
| 95 |
| 96 CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() { |
| 97 return nullptr; |
| 98 } |
| 99 |
| 100 const CPDF_Type3Font* CPDF_Font::AsType3Font() const { |
| 101 return nullptr; |
| 102 } |
| 103 |
| 104 CPDF_Type3Font* CPDF_Font::AsType3Font() { |
| 105 return nullptr; |
| 106 } |
| 107 |
| 108 const CPDF_CIDFont* CPDF_Font::AsCIDFont() const { |
| 109 return nullptr; |
| 110 } |
| 111 |
| 112 CPDF_CIDFont* CPDF_Font::AsCIDFont() { |
| 113 return nullptr; |
| 114 } |
| 115 |
| 116 FX_BOOL CPDF_Font::IsUnicodeCompatible() const { |
| 117 return FALSE; |
| 118 } |
| 119 |
| 120 int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const { |
| 121 return size; |
| 122 } |
| 123 |
| 124 int CPDF_Font::GetCharSize(FX_DWORD charcode) const { |
| 125 return 1; |
| 126 } |
| 127 |
| 128 int CPDF_Font::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) { |
| 129 ASSERT(false); |
| 130 return 0; |
| 131 } |
| 132 |
| 133 int CPDF_Font::GlyphFromCharCodeExt(FX_DWORD charcode) { |
| 134 return GlyphFromCharCode(charcode); |
| 135 } |
| 136 |
| 137 FX_BOOL CPDF_Font::IsVertWriting() const { |
| 138 FX_BOOL bVertWriting = FALSE; |
| 139 const CPDF_CIDFont* pCIDFont = AsCIDFont(); |
| 140 if (pCIDFont) { |
| 141 bVertWriting = pCIDFont->IsVertWriting(); |
| 142 } else { |
| 143 bVertWriting = m_Font.IsVertical(); |
| 144 } |
| 145 return bVertWriting; |
| 146 } |
| 147 |
| 148 int CPDF_Font::AppendChar(FX_CHAR* buf, FX_DWORD charcode) const { |
| 149 *buf = (FX_CHAR)charcode; |
| 150 return 1; |
| 151 } |
| 152 |
| 153 void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const { |
| 154 char buf[4]; |
| 155 int len = AppendChar(buf, charcode); |
| 156 if (len == 1) { |
| 157 str += buf[0]; |
| 158 } else { |
| 159 str += CFX_ByteString(buf, len); |
| 160 } |
| 161 } |
| 162 |
| 163 CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const { |
| 164 if (!m_bToUnicodeLoaded) |
| 165 ((CPDF_Font*)this)->LoadUnicodeMap(); |
| 166 |
| 167 if (m_pToUnicodeMap) |
| 168 return m_pToUnicodeMap->Lookup(charcode); |
| 169 return CFX_WideString(); |
| 170 } |
| 171 |
| 172 FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const { |
| 173 if (!m_bToUnicodeLoaded) |
| 174 ((CPDF_Font*)this)->LoadUnicodeMap(); |
| 175 |
| 176 if (m_pToUnicodeMap) |
| 177 return m_pToUnicodeMap->ReverseLookup(unicode); |
| 178 return 0; |
| 179 } |
| 180 |
| 181 void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) { |
| 182 m_Flags = pFontDesc->GetIntegerBy("Flags", PDFFONT_NONSYMBOLIC); |
| 183 int ItalicAngle = 0; |
| 184 FX_BOOL bExistItalicAngle = FALSE; |
| 185 if (pFontDesc->KeyExist("ItalicAngle")) { |
| 186 ItalicAngle = pFontDesc->GetIntegerBy("ItalicAngle"); |
| 187 bExistItalicAngle = TRUE; |
| 188 } |
| 189 if (ItalicAngle < 0) { |
| 190 m_Flags |= PDFFONT_ITALIC; |
| 191 m_ItalicAngle = ItalicAngle; |
| 192 } |
| 193 FX_BOOL bExistStemV = FALSE; |
| 194 if (pFontDesc->KeyExist("StemV")) { |
| 195 m_StemV = pFontDesc->GetIntegerBy("StemV"); |
| 196 bExistStemV = TRUE; |
| 197 } |
| 198 FX_BOOL bExistAscent = FALSE; |
| 199 if (pFontDesc->KeyExist("Ascent")) { |
| 200 m_Ascent = pFontDesc->GetIntegerBy("Ascent"); |
| 201 bExistAscent = TRUE; |
| 202 } |
| 203 FX_BOOL bExistDescent = FALSE; |
| 204 if (pFontDesc->KeyExist("Descent")) { |
| 205 m_Descent = pFontDesc->GetIntegerBy("Descent"); |
| 206 bExistDescent = TRUE; |
| 207 } |
| 208 FX_BOOL bExistCapHeight = FALSE; |
| 209 if (pFontDesc->KeyExist("CapHeight")) { |
| 210 bExistCapHeight = TRUE; |
| 211 } |
| 212 if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && |
| 213 bExistStemV) { |
| 214 m_Flags |= PDFFONT_USEEXTERNATTR; |
| 215 } |
| 216 if (m_Descent > 10) { |
| 217 m_Descent = -m_Descent; |
| 218 } |
| 219 CPDF_Array* pBBox = pFontDesc->GetArrayBy("FontBBox"); |
| 220 if (pBBox) { |
| 221 m_FontBBox.left = pBBox->GetIntegerAt(0); |
| 222 m_FontBBox.bottom = pBBox->GetIntegerAt(1); |
| 223 m_FontBBox.right = pBBox->GetIntegerAt(2); |
| 224 m_FontBBox.top = pBBox->GetIntegerAt(3); |
| 225 } |
| 226 |
| 227 CPDF_Stream* pFontFile = pFontDesc->GetStreamBy("FontFile"); |
| 228 if (!pFontFile) |
| 229 pFontFile = pFontDesc->GetStreamBy("FontFile2"); |
| 230 if (!pFontFile) |
| 231 pFontFile = pFontDesc->GetStreamBy("FontFile3"); |
| 232 if (!pFontFile) |
| 233 return; |
| 234 |
| 235 m_pFontFile = m_pDocument->LoadFontFile(pFontFile); |
| 236 if (!m_pFontFile) |
| 237 return; |
| 238 |
| 239 const uint8_t* pFontData = m_pFontFile->GetData(); |
| 240 FX_DWORD dwFontSize = m_pFontFile->GetSize(); |
| 241 if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) { |
| 242 m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( |
| 243 const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream())); |
| 244 m_pFontFile = nullptr; |
| 245 } |
| 246 } |
| 247 |
| 248 void CPDF_Font::CheckFontMetrics() { |
| 249 if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && |
| 250 m_FontBBox.right == 0) { |
| 251 FXFT_Face face = m_Font.GetFace(); |
| 252 if (face) { |
| 253 m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face); |
| 254 m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face); |
| 255 m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face); |
| 256 m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face); |
| 257 m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face); |
| 258 m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face); |
| 259 } else { |
| 260 FX_BOOL bFirst = TRUE; |
| 261 for (int i = 0; i < 256; i++) { |
| 262 FX_RECT rect = GetCharBBox(i); |
| 263 if (rect.left == rect.right) { |
| 264 continue; |
| 265 } |
| 266 if (bFirst) { |
| 267 m_FontBBox = rect; |
| 268 bFirst = FALSE; |
| 269 } else { |
| 270 if (m_FontBBox.top < rect.top) { |
| 271 m_FontBBox.top = rect.top; |
| 272 } |
| 273 if (m_FontBBox.right < rect.right) { |
| 274 m_FontBBox.right = rect.right; |
| 275 } |
| 276 if (m_FontBBox.left > rect.left) { |
| 277 m_FontBBox.left = rect.left; |
| 278 } |
| 279 if (m_FontBBox.bottom > rect.bottom) { |
| 280 m_FontBBox.bottom = rect.bottom; |
| 281 } |
| 282 } |
| 283 } |
| 284 } |
| 285 } |
| 286 if (m_Ascent == 0 && m_Descent == 0) { |
| 287 FX_RECT rect = GetCharBBox('A'); |
| 288 m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top; |
| 289 rect = GetCharBBox('g'); |
| 290 m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom; |
| 291 } |
| 292 } |
| 293 |
| 294 void CPDF_Font::LoadUnicodeMap() { |
| 295 m_bToUnicodeLoaded = TRUE; |
| 296 CPDF_Stream* pStream = m_pFontDict->GetStreamBy("ToUnicode"); |
| 297 if (!pStream) { |
| 298 return; |
| 299 } |
| 300 m_pToUnicodeMap = new CPDF_ToUnicodeMap; |
| 301 m_pToUnicodeMap->Load(pStream); |
| 302 } |
| 303 |
| 304 int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) { |
| 305 int offset = 0; |
| 306 int width = 0; |
| 307 while (offset < size) { |
| 308 FX_DWORD charcode = GetNextChar(pString, size, offset); |
| 309 width += GetCharWidthF(charcode); |
| 310 } |
| 311 return width; |
| 312 } |
| 313 |
| 314 CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, |
| 315 const CFX_ByteStringC& name) { |
| 316 CFX_ByteString fontname(name); |
| 317 int font_id = PDF_GetStandardFontName(&fontname); |
| 318 if (font_id < 0) { |
| 319 return nullptr; |
| 320 } |
| 321 CPDF_FontGlobals* pFontGlobals = |
| 322 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); |
| 323 CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id); |
| 324 if (pFont) { |
| 325 return pFont; |
| 326 } |
| 327 CPDF_Dictionary* pDict = new CPDF_Dictionary; |
| 328 pDict->SetAtName("Type", "Font"); |
| 329 pDict->SetAtName("Subtype", "Type1"); |
| 330 pDict->SetAtName("BaseFont", fontname); |
| 331 pDict->SetAtName("Encoding", "WinAnsiEncoding"); |
| 332 pFont = CPDF_Font::CreateFontF(NULL, pDict); |
| 333 pFontGlobals->Set(pDoc, font_id, pFont); |
| 334 return pFont; |
| 335 } |
| 336 |
| 337 CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, |
| 338 CPDF_Dictionary* pFontDict) { |
| 339 CFX_ByteString type = pFontDict->GetStringBy("Subtype"); |
| 340 CPDF_Font* pFont; |
| 341 if (type == "TrueType") { |
| 342 { |
| 343 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \ |
| 344 _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || \ |
| 345 _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \ |
| 346 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| 347 CFX_ByteString basefont = pFontDict->GetStringBy("BaseFont"); |
| 348 CFX_ByteString tag = basefont.Left(4); |
| 349 int i; |
| 350 int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]); |
| 351 for (i = 0; i < count; ++i) { |
| 352 if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) { |
| 353 break; |
| 354 } |
| 355 } |
| 356 if (i < count) { |
| 357 CPDF_Dictionary* pFontDesc = pFontDict->GetDictBy("FontDescriptor"); |
| 358 if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) { |
| 359 pFont = new CPDF_CIDFont; |
| 360 pFont->m_pFontDict = pFontDict; |
| 361 pFont->m_pDocument = pDoc; |
| 362 pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont"); |
| 363 if (!pFont->Load()) { |
| 364 delete pFont; |
| 365 return NULL; |
| 366 } |
| 367 return pFont; |
| 368 } |
| 369 } |
| 370 #endif |
| 371 } |
| 372 pFont = new CPDF_TrueTypeFont; |
| 373 } else if (type == "Type3") { |
| 374 pFont = new CPDF_Type3Font; |
| 375 } else if (type == "Type0") { |
| 376 pFont = new CPDF_CIDFont; |
| 377 } else { |
| 378 pFont = new CPDF_Type1Font; |
| 379 } |
| 380 pFont->m_pFontDict = pFontDict; |
| 381 pFont->m_pDocument = pDoc; |
| 382 pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont"); |
| 383 if (!pFont->Load()) { |
| 384 delete pFont; |
| 385 return NULL; |
| 386 } |
| 387 return pFont; |
| 388 } |
| 389 |
| 390 FX_DWORD CPDF_Font::GetNextChar(const FX_CHAR* pString, |
| 391 int nStrLen, |
| 392 int& offset) const { |
| 393 if (offset < 0 || nStrLen < 1) { |
| 394 return 0; |
| 395 } |
| 396 uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1]; |
| 397 return static_cast<FX_DWORD>(ch); |
| 398 } |
| 399 |
| 400 void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, |
| 401 int& iBaseEncoding, |
| 402 CFX_ByteString*& pCharNames, |
| 403 FX_BOOL bEmbedded, |
| 404 FX_BOOL bTrueType) { |
| 405 if (!pEncoding) { |
| 406 if (m_BaseFont == "Symbol") { |
| 407 iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL |
| 408 : PDFFONT_ENCODING_ADOBE_SYMBOL; |
| 409 } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { |
| 410 iBaseEncoding = PDFFONT_ENCODING_WINANSI; |
| 411 } |
| 412 return; |
| 413 } |
| 414 if (pEncoding->IsName()) { |
| 415 if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || |
| 416 iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) { |
| 417 return; |
| 418 } |
| 419 if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") { |
| 420 if (!bTrueType) { |
| 421 iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; |
| 422 } |
| 423 return; |
| 424 } |
| 425 CFX_ByteString bsEncoding = pEncoding->GetString(); |
| 426 if (bsEncoding.Compare("MacExpertEncoding") == 0) { |
| 427 bsEncoding = "WinAnsiEncoding"; |
| 428 } |
| 429 GetPredefinedEncoding(iBaseEncoding, bsEncoding); |
| 430 return; |
| 431 } |
| 432 |
| 433 CPDF_Dictionary* pDict = pEncoding->AsDictionary(); |
| 434 if (!pDict) |
| 435 return; |
| 436 |
| 437 if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && |
| 438 iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) { |
| 439 CFX_ByteString bsEncoding = pDict->GetStringBy("BaseEncoding"); |
| 440 if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) { |
| 441 bsEncoding = "WinAnsiEncoding"; |
| 442 } |
| 443 GetPredefinedEncoding(iBaseEncoding, bsEncoding); |
| 444 } |
| 445 if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { |
| 446 iBaseEncoding = PDFFONT_ENCODING_STANDARD; |
| 447 } |
| 448 CPDF_Array* pDiffs = pDict->GetArrayBy("Differences"); |
| 449 if (!pDiffs) { |
| 450 return; |
| 451 } |
| 452 pCharNames = new CFX_ByteString[256]; |
| 453 FX_DWORD cur_code = 0; |
| 454 for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) { |
| 455 CPDF_Object* pElement = pDiffs->GetElementValue(i); |
| 456 if (!pElement) |
| 457 continue; |
| 458 |
| 459 if (CPDF_Name* pName = pElement->AsName()) { |
| 460 if (cur_code < 256) |
| 461 pCharNames[cur_code] = pName->GetString(); |
| 462 cur_code++; |
| 463 } else { |
| 464 cur_code = pElement->GetInteger(); |
| 465 } |
| 466 } |
| 467 } |
| 468 |
| 469 FX_BOOL CPDF_Font::IsStandardFont() const { |
| 470 if (!IsType1Font()) |
| 471 return FALSE; |
| 472 if (m_pFontFile) |
| 473 return FALSE; |
| 474 if (AsType1Font()->GetBase14Font() < 0) |
| 475 return FALSE; |
| 476 return TRUE; |
| 477 } |
| 478 |
| 479 const FX_CHAR* CPDF_Font::GetAdobeCharName(int iBaseEncoding, |
| 480 const CFX_ByteString* pCharNames, |
| 481 int charcode) { |
| 482 ASSERT(charcode >= 0 && charcode < 256); |
| 483 if (charcode < 0 || charcode >= 256) |
| 484 return nullptr; |
| 485 |
| 486 const FX_CHAR* name = nullptr; |
| 487 if (pCharNames) |
| 488 name = pCharNames[charcode]; |
| 489 if ((!name || name[0] == 0) && iBaseEncoding) |
| 490 name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode); |
| 491 return name && name[0] ? name : nullptr; |
| 492 } |
OLD | NEW |