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