Home | History | Annotate | Download | only in font
      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 
     31 namespace {
     32 
     33 const 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 
     39 void 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 
     52 CPDF_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 
     62 CPDF_Font::~CPDF_Font() {
     63   if (m_pFontFile) {
     64     m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
     65         m_pFontFile->GetStream()->AsStream());
     66   }
     67 }
     68 
     69 bool CPDF_Font::IsType1Font() const {
     70   return false;
     71 }
     72 
     73 bool CPDF_Font::IsTrueTypeFont() const {
     74   return false;
     75 }
     76 
     77 bool CPDF_Font::IsType3Font() const {
     78   return false;
     79 }
     80 
     81 bool CPDF_Font::IsCIDFont() const {
     82   return false;
     83 }
     84 
     85 const CPDF_Type1Font* CPDF_Font::AsType1Font() const {
     86   return nullptr;
     87 }
     88 
     89 CPDF_Type1Font* CPDF_Font::AsType1Font() {
     90   return nullptr;
     91 }
     92 
     93 const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const {
     94   return nullptr;
     95 }
     96 
     97 CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() {
     98   return nullptr;
     99 }
    100 
    101 const CPDF_Type3Font* CPDF_Font::AsType3Font() const {
    102   return nullptr;
    103 }
    104 
    105 CPDF_Type3Font* CPDF_Font::AsType3Font() {
    106   return nullptr;
    107 }
    108 
    109 const CPDF_CIDFont* CPDF_Font::AsCIDFont() const {
    110   return nullptr;
    111 }
    112 
    113 CPDF_CIDFont* CPDF_Font::AsCIDFont() {
    114   return nullptr;
    115 }
    116 
    117 bool CPDF_Font::IsUnicodeCompatible() const {
    118   return false;
    119 }
    120 
    121 int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const {
    122   return size;
    123 }
    124 
    125 int CPDF_Font::GlyphFromCharCodeExt(uint32_t charcode) {
    126   return GlyphFromCharCode(charcode, nullptr);
    127 }
    128 
    129 bool CPDF_Font::IsVertWriting() const {
    130   const CPDF_CIDFont* pCIDFont = AsCIDFont();
    131   return pCIDFont ? pCIDFont->IsVertWriting() : m_Font.IsVertical();
    132 }
    133 
    134 int CPDF_Font::AppendChar(FX_CHAR* buf, uint32_t charcode) const {
    135   *buf = static_cast<FX_CHAR>(charcode);
    136   return 1;
    137 }
    138 
    139 void 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 
    149 CFX_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 
    156 uint32_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 
    163 void 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 
    228 void 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 
    274 void 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 
    284 int 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 
    294 CPDF_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 
    315 std::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 
    344 uint32_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 
    354 void 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 
    422 bool 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 
    432 const 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 
    450 uint32_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 
    460 int 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