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_type1font.h"
      8 
      9 #include <algorithm>
     10 
     11 #include "core/fpdfapi/parser/cpdf_dictionary.h"
     12 #include "core/fxge/cfx_gemodule.h"
     13 #include "core/fxge/fx_freetype.h"
     14 
     15 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
     16 #include "core/fxge/apple/apple_int.h"
     17 #endif
     18 
     19 namespace {
     20 
     21 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
     22 struct GlyphNameMap {
     23   const char* m_pStrAdobe;
     24   const char* m_pStrUnicode;
     25 };
     26 
     27 const GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"},
     28                                           {"ffi", "uniFB03"},
     29                                           {"ffl", "uniFB04"},
     30                                           {"fi", "uniFB01"},
     31                                           {"fl", "uniFB02"}};
     32 
     33 const char* GlyphNameRemap(const char* pStrAdobe) {
     34   for (const auto& element : g_GlyphNameSubsts) {
     35     if (!FXSYS_stricmp(element.m_pStrAdobe, pStrAdobe))
     36       return element.m_pStrUnicode;
     37   }
     38   return nullptr;
     39 }
     40 
     41 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
     42 
     43 bool FT_UseType1Charmap(FXFT_Face face) {
     44   if (FXFT_Get_Face_CharmapCount(face) == 0) {
     45     return false;
     46   }
     47   if (FXFT_Get_Face_CharmapCount(face) == 1 &&
     48       FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
     49           FXFT_ENCODING_UNICODE) {
     50     return false;
     51   }
     52   if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
     53       FXFT_ENCODING_UNICODE) {
     54     FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);
     55   } else {
     56     FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
     57   }
     58   return true;
     59 }
     60 
     61 }  // namespace
     62 
     63 CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {}
     64 
     65 bool CPDF_Type1Font::IsType1Font() const {
     66   return true;
     67 }
     68 
     69 const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const {
     70   return this;
     71 }
     72 
     73 CPDF_Type1Font* CPDF_Type1Font::AsType1Font() {
     74   return this;
     75 }
     76 
     77 bool CPDF_Type1Font::Load() {
     78   m_Base14Font = PDF_GetStandardFontName(&m_BaseFont);
     79   if (m_Base14Font >= 0) {
     80     CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor");
     81     if (pFontDesc && pFontDesc->KeyExist("Flags"))
     82       m_Flags = pFontDesc->GetIntegerFor("Flags");
     83     else
     84       m_Flags = m_Base14Font >= 12 ? FXFONT_SYMBOLIC : FXFONT_NONSYMBOLIC;
     85 
     86     if (m_Base14Font < 4) {
     87       for (int i = 0; i < 256; i++)
     88         m_CharWidth[i] = 600;
     89     }
     90     if (m_Base14Font == 12)
     91       m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
     92     else if (m_Base14Font == 13)
     93       m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;
     94     else if (FontStyleIsNonSymbolic(m_Flags))
     95       m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
     96   }
     97   return LoadCommon();
     98 }
     99 
    100 int CPDF_Type1Font::GlyphFromCharCodeExt(uint32_t charcode) {
    101   if (charcode > 0xff) {
    102     return -1;
    103   }
    104   int index = m_ExtGID[(uint8_t)charcode];
    105   if (index == 0xffff) {
    106     return -1;
    107   }
    108   return index;
    109 }
    110 
    111 void CPDF_Type1Font::LoadGlyphMap() {
    112   if (!m_Font.GetFace())
    113     return;
    114 
    115 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    116   bool bCoreText = true;
    117   CQuartz2D& quartz2d =
    118       static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData())
    119           ->m_quartz2d;
    120   if (!m_Font.GetPlatformFont()) {
    121     if (m_Font.GetPsName() == "DFHeiStd-W5")
    122       bCoreText = false;
    123 
    124     m_Font.SetPlatformFont(
    125         quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize()));
    126     if (!m_Font.GetPlatformFont())
    127       bCoreText = false;
    128   }
    129 #endif
    130   if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {
    131     if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
    132       bool bGotOne = false;
    133       for (int charcode = 0; charcode < 256; charcode++) {
    134         const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
    135         for (int j = 0; j < 4; j++) {
    136           uint16_t unicode = prefix[j] * 256 + charcode;
    137           m_GlyphIndex[charcode] =
    138               FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
    139 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    140           CalcExtGID(charcode);
    141 #endif
    142           if (m_GlyphIndex[charcode]) {
    143             bGotOne = true;
    144             break;
    145           }
    146         }
    147       }
    148       if (bGotOne) {
    149 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    150         if (!bCoreText)
    151           memcpy(m_ExtGID, m_GlyphIndex, 256);
    152 #endif
    153         return;
    154       }
    155     }
    156     FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
    157     if (m_BaseEncoding == 0)
    158       m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
    159 
    160     for (int charcode = 0; charcode < 256; charcode++) {
    161       const char* name =
    162           GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
    163       if (!name)
    164         continue;
    165 
    166       m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
    167       m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
    168           m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
    169 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    170       CalcExtGID(charcode);
    171 #endif
    172       if (m_GlyphIndex[charcode] == 0 && strcmp(name, ".notdef") == 0) {
    173         m_Encoding.m_Unicodes[charcode] = 0x20;
    174         m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20);
    175 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    176         CalcExtGID(charcode);
    177 #endif
    178       }
    179     }
    180 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    181     if (!bCoreText)
    182       memcpy(m_ExtGID, m_GlyphIndex, 256);
    183 #endif
    184     return;
    185   }
    186   FT_UseType1Charmap(m_Font.GetFace());
    187 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    188   if (bCoreText) {
    189     if (FontStyleIsSymbolic(m_Flags)) {
    190       for (int charcode = 0; charcode < 256; charcode++) {
    191         const char* name =
    192             GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
    193         if (name) {
    194           m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
    195           m_GlyphIndex[charcode] =
    196               FXFT_Get_Name_Index(m_Font.GetFace(), const_cast<char*>(name));
    197           SetExtGID(name, charcode);
    198         } else {
    199           m_GlyphIndex[charcode] =
    200               FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
    201           wchar_t unicode = 0;
    202           if (m_GlyphIndex[charcode]) {
    203             unicode =
    204                 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
    205           }
    206           char name_glyph[256];
    207           memset(name_glyph, 0, sizeof(name_glyph));
    208           FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
    209                               name_glyph, 256);
    210           name_glyph[255] = 0;
    211           if (unicode == 0 && name_glyph[0] != 0)
    212             unicode = PDF_UnicodeFromAdobeName(name_glyph);
    213 
    214           m_Encoding.m_Unicodes[charcode] = unicode;
    215           SetExtGID(name_glyph, charcode);
    216         }
    217       }
    218       return;
    219     }
    220 
    221     bool bUnicode =
    222         FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0;
    223     for (int charcode = 0; charcode < 256; charcode++) {
    224       const char* name =
    225           GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
    226       if (!name)
    227         continue;
    228 
    229       m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
    230       const char* pStrUnicode = GlyphNameRemap(name);
    231       if (pStrUnicode &&
    232           FXFT_Get_Name_Index(m_Font.GetFace(), const_cast<char*>(name)) == 0) {
    233         name = pStrUnicode;
    234       }
    235       m_GlyphIndex[charcode] =
    236           FXFT_Get_Name_Index(m_Font.GetFace(), const_cast<char*>(name));
    237       SetExtGID(name, charcode);
    238       if (m_GlyphIndex[charcode] != 0)
    239         continue;
    240 
    241       if (strcmp(name, ".notdef") != 0 && strcmp(name, "space") != 0) {
    242         m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
    243             m_Font.GetFace(),
    244             bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
    245         CalcExtGID(charcode);
    246       } else {
    247         m_Encoding.m_Unicodes[charcode] = 0x20;
    248         m_GlyphIndex[charcode] =
    249             bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff;
    250         CalcExtGID(charcode);
    251       }
    252     }
    253     return;
    254   }
    255 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    256   if (FontStyleIsSymbolic(m_Flags)) {
    257     for (int charcode = 0; charcode < 256; charcode++) {
    258       const char* name =
    259           GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
    260       if (name) {
    261         m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
    262         m_GlyphIndex[charcode] =
    263             FXFT_Get_Name_Index(m_Font.GetFace(), const_cast<char*>(name));
    264       } else {
    265         m_GlyphIndex[charcode] =
    266             FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
    267         if (m_GlyphIndex[charcode]) {
    268           wchar_t unicode =
    269               FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
    270           if (unicode == 0) {
    271             char name_glyph[256];
    272             memset(name_glyph, 0, sizeof(name_glyph));
    273             FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
    274                                 name_glyph, 256);
    275             name_glyph[255] = 0;
    276             if (name_glyph[0] != 0)
    277               unicode = PDF_UnicodeFromAdobeName(name_glyph);
    278           }
    279           m_Encoding.m_Unicodes[charcode] = unicode;
    280         }
    281       }
    282     }
    283 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    284     if (!bCoreText)
    285       memcpy(m_ExtGID, m_GlyphIndex, 256);
    286 
    287 #endif
    288     return;
    289   }
    290 
    291   bool bUnicode =
    292       FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0;
    293   for (int charcode = 0; charcode < 256; charcode++) {
    294     const char* name = GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
    295     if (!name)
    296       continue;
    297 
    298     m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
    299     m_GlyphIndex[charcode] =
    300         FXFT_Get_Name_Index(m_Font.GetFace(), const_cast<char*>(name));
    301     if (m_GlyphIndex[charcode] != 0)
    302       continue;
    303 
    304     if (strcmp(name, ".notdef") != 0 && strcmp(name, "space") != 0) {
    305       m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
    306           m_Font.GetFace(),
    307           bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
    308     } else {
    309       m_Encoding.m_Unicodes[charcode] = 0x20;
    310       m_GlyphIndex[charcode] = 0xffff;
    311     }
    312   }
    313 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    314   if (!bCoreText)
    315     memcpy(m_ExtGID, m_GlyphIndex, 256);
    316 #endif
    317 }
    318 
    319 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    320 void CPDF_Type1Font::SetExtGID(const char* name, int charcode) {
    321   CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
    322       kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
    323   m_ExtGID[charcode] =
    324       CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.GetPlatformFont(), name_ct);
    325   if (name_ct)
    326     CFRelease(name_ct);
    327 }
    328 
    329 void CPDF_Type1Font::CalcExtGID(int charcode) {
    330   char name_glyph[256];
    331   FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph,
    332                       256);
    333   name_glyph[255] = 0;
    334   SetExtGID(name_glyph, charcode);
    335 }
    336 #endif  // _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    337