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