Home | History | Annotate | Download | only in fpdf_font
      1 // Copyright 2014 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 "font_int.h"
      8 
      9 #include "core/src/fpdfapi/fpdf_page/pageint.h"
     10 #include "core/include/fpdfapi/fpdf_module.h"
     11 #include "core/include/fpdfapi/fpdf_page.h"
     12 #include "core/include/fpdfapi/fpdf_pageobj.h"
     13 #include "core/include/fpdfapi/fpdf_resource.h"
     14 #include "core/include/fxcrt/fx_ext.h"
     15 #include "core/include/fxge/fx_freetype.h"
     16 #include "third_party/base/stl_util.h"
     17 
     18 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
     19 #include "core/src/fxge/apple/apple_int.h"
     20 #endif
     21 
     22 FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) {
     23   for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) {
     24     if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) ==
     25             platform_id &&
     26         FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) ==
     27             encoding_id) {
     28       FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
     29       return TRUE;
     30     }
     31   }
     32   return FALSE;
     33 }
     34 
     35 CFX_StockFontArray::CFX_StockFontArray() {}
     36 
     37 CFX_StockFontArray::~CFX_StockFontArray() {
     38   for (size_t i = 0; i < FX_ArraySize(m_StockFonts); ++i) {
     39     if (!m_StockFonts[i])
     40       continue;
     41     CPDF_Dictionary* pFontDict = m_StockFonts[i]->GetFontDict();
     42     if (pFontDict)
     43       pFontDict->Release();
     44   }
     45 }
     46 
     47 CPDF_Font* CFX_StockFontArray::GetFont(int index) const {
     48   if (index < 0 || index >= FX_ArraySize(m_StockFonts))
     49     return nullptr;
     50   return m_StockFonts[index].get();
     51 }
     52 
     53 void CFX_StockFontArray::SetFont(int index, CPDF_Font* font) {
     54   if (index < 0 || index >= FX_ArraySize(m_StockFonts))
     55     return;
     56   m_StockFonts[index].reset(font);
     57 }
     58 
     59 CPDF_FontGlobals::CPDF_FontGlobals() {
     60   FXSYS_memset(m_EmbeddedCharsets, 0, sizeof(m_EmbeddedCharsets));
     61   FXSYS_memset(m_EmbeddedToUnicodes, 0, sizeof(m_EmbeddedToUnicodes));
     62 }
     63 
     64 CPDF_FontGlobals::~CPDF_FontGlobals() {
     65 }
     66 
     67 CPDF_Font* CPDF_FontGlobals::Find(CPDF_Document* pDoc, int index) {
     68   auto it = m_StockMap.find(pDoc);
     69   if (it == m_StockMap.end())
     70     return nullptr;
     71   return it->second ? it->second->GetFont(index) : nullptr;
     72 }
     73 
     74 void CPDF_FontGlobals::Set(CPDF_Document* pDoc, int index, CPDF_Font* pFont) {
     75   if (!pdfium::ContainsKey(m_StockMap, pDoc))
     76     m_StockMap[pDoc].reset(new CFX_StockFontArray);
     77   m_StockMap[pDoc]->SetFont(index, pFont);
     78 }
     79 
     80 void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) {
     81   m_StockMap.erase(pDoc);
     82 }
     83 
     84 CPDF_Font::CPDF_Font(int fonttype) : m_FontType(fonttype) {
     85   m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0;
     86   m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0;
     87   m_pFontFile = NULL;
     88   m_Flags = 0;
     89   m_pToUnicodeMap = NULL;
     90   m_bToUnicodeLoaded = FALSE;
     91   m_pCharMap = new CPDF_FontCharMap(this);
     92 }
     93 CPDF_Font::~CPDF_Font() {
     94   delete m_pCharMap;
     95   m_pCharMap = NULL;
     96 
     97   delete m_pToUnicodeMap;
     98   m_pToUnicodeMap = NULL;
     99 
    100   if (m_pFontFile) {
    101     m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
    102         const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
    103   }
    104 }
    105 FX_BOOL CPDF_Font::IsVertWriting() const {
    106   FX_BOOL bVertWriting = FALSE;
    107   CPDF_CIDFont* pCIDFont = GetCIDFont();
    108   if (pCIDFont) {
    109     bVertWriting = pCIDFont->IsVertWriting();
    110   } else {
    111     bVertWriting = m_Font.IsVertical();
    112   }
    113   return bVertWriting;
    114 }
    115 CFX_ByteString CPDF_Font::GetFontTypeName() const {
    116   switch (m_FontType) {
    117     case PDFFONT_TYPE1:
    118       return "Type1";
    119     case PDFFONT_TRUETYPE:
    120       return "TrueType";
    121     case PDFFONT_TYPE3:
    122       return "Type3";
    123     case PDFFONT_CIDFONT:
    124       return "Type0";
    125   }
    126   return CFX_ByteString();
    127 }
    128 void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const {
    129   char buf[4];
    130   int len = AppendChar(buf, charcode);
    131   if (len == 1) {
    132     str += buf[0];
    133   } else {
    134     str += CFX_ByteString(buf, len);
    135   }
    136 }
    137 CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const {
    138   if (!m_bToUnicodeLoaded) {
    139     ((CPDF_Font*)this)->LoadUnicodeMap();
    140   }
    141   if (m_pToUnicodeMap) {
    142     CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode);
    143     if (!wsRet.IsEmpty()) {
    144       return wsRet;
    145     }
    146   }
    147   FX_WCHAR unicode = _UnicodeFromCharCode(charcode);
    148   if (unicode == 0) {
    149     return CFX_WideString();
    150   }
    151   return unicode;
    152 }
    153 FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const {
    154   if (!m_bToUnicodeLoaded) {
    155     ((CPDF_Font*)this)->LoadUnicodeMap();
    156   }
    157   if (m_pToUnicodeMap) {
    158     FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode);
    159     if (charcode) {
    160       return charcode;
    161     }
    162   }
    163   return _CharCodeFromUnicode(unicode);
    164 }
    165 CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const {
    166   CFX_WideString result;
    167   int src_len = str.GetLength();
    168   result.Reserve(src_len);
    169   const FX_CHAR* src_buf = str;
    170   int src_pos = 0;
    171   while (src_pos < src_len) {
    172     FX_DWORD charcode = GetNextChar(src_buf, src_len, src_pos);
    173     CFX_WideString unicode = UnicodeFromCharCode(charcode);
    174     if (!unicode.IsEmpty()) {
    175       result += unicode;
    176     } else {
    177       result += (FX_WCHAR)charcode;
    178     }
    179   }
    180   return result;
    181 }
    182 CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const {
    183   CFX_ByteString result;
    184   int src_len = str.GetLength();
    185   FX_CHAR* dest_buf = result.GetBuffer(src_len * 2);
    186   const FX_WCHAR* src_buf = str.c_str();
    187   int dest_pos = 0;
    188   for (int src_pos = 0; src_pos < src_len; src_pos++) {
    189     FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]);
    190     dest_pos += AppendChar(dest_buf + dest_pos, charcode);
    191   }
    192   result.ReleaseBuffer(dest_pos);
    193   return result;
    194 }
    195 
    196 void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) {
    197   m_Flags = pFontDesc->GetInteger("Flags", PDFFONT_NONSYMBOLIC);
    198   int ItalicAngle = 0;
    199   FX_BOOL bExistItalicAngle = FALSE;
    200   if (pFontDesc->KeyExist("ItalicAngle")) {
    201     ItalicAngle = pFontDesc->GetInteger("ItalicAngle");
    202     bExistItalicAngle = TRUE;
    203   }
    204   if (ItalicAngle < 0) {
    205     m_Flags |= PDFFONT_ITALIC;
    206     m_ItalicAngle = ItalicAngle;
    207   }
    208   FX_BOOL bExistStemV = FALSE;
    209   if (pFontDesc->KeyExist("StemV")) {
    210     m_StemV = pFontDesc->GetInteger("StemV");
    211     bExistStemV = TRUE;
    212   }
    213   FX_BOOL bExistAscent = FALSE;
    214   if (pFontDesc->KeyExist("Ascent")) {
    215     m_Ascent = pFontDesc->GetInteger("Ascent");
    216     bExistAscent = TRUE;
    217   }
    218   FX_BOOL bExistDescent = FALSE;
    219   if (pFontDesc->KeyExist("Descent")) {
    220     m_Descent = pFontDesc->GetInteger("Descent");
    221     bExistDescent = TRUE;
    222   }
    223   FX_BOOL bExistCapHeight = FALSE;
    224   if (pFontDesc->KeyExist("CapHeight")) {
    225     bExistCapHeight = TRUE;
    226   }
    227   if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
    228       bExistStemV) {
    229     m_Flags |= PDFFONT_USEEXTERNATTR;
    230   }
    231   if (m_Descent > 10) {
    232     m_Descent = -m_Descent;
    233   }
    234   CPDF_Array* pBBox = pFontDesc->GetArray("FontBBox");
    235   if (pBBox) {
    236     m_FontBBox.left = pBBox->GetInteger(0);
    237     m_FontBBox.bottom = pBBox->GetInteger(1);
    238     m_FontBBox.right = pBBox->GetInteger(2);
    239     m_FontBBox.top = pBBox->GetInteger(3);
    240   }
    241 
    242   CPDF_Stream* pFontFile = pFontDesc->GetStream("FontFile");
    243   if (!pFontFile)
    244     pFontFile = pFontDesc->GetStream("FontFile2");
    245   if (!pFontFile)
    246     pFontFile = pFontDesc->GetStream("FontFile3");
    247   if (!pFontFile)
    248     return;
    249 
    250   m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
    251   if (!m_pFontFile)
    252     return;
    253 
    254   const uint8_t* pFontData = m_pFontFile->GetData();
    255   FX_DWORD dwFontSize = m_pFontFile->GetSize();
    256   if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) {
    257     m_pDocument->GetPageData()->ReleaseFontFileStreamAcc(
    258         const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream()));
    259     m_pFontFile = nullptr;
    260   }
    261 }
    262 
    263 short TT2PDF(int m, FXFT_Face face) {
    264   int upm = FXFT_Get_Face_UnitsPerEM(face);
    265   if (upm == 0) {
    266     return (short)m;
    267   }
    268   return (m * 1000 + upm / 2) / upm;
    269 }
    270 void CPDF_Font::CheckFontMetrics() {
    271   if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
    272       m_FontBBox.right == 0) {
    273     FXFT_Face face = m_Font.GetFace();
    274     if (face) {
    275       m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face);
    276       m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face);
    277       m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face);
    278       m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face);
    279       m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face);
    280       m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face);
    281     } else {
    282       FX_BOOL bFirst = TRUE;
    283       for (int i = 0; i < 256; i++) {
    284         FX_RECT rect;
    285         GetCharBBox(i, rect);
    286         if (rect.left == rect.right) {
    287           continue;
    288         }
    289         if (bFirst) {
    290           m_FontBBox = rect;
    291           bFirst = FALSE;
    292         } else {
    293           if (m_FontBBox.top < rect.top) {
    294             m_FontBBox.top = rect.top;
    295           }
    296           if (m_FontBBox.right < rect.right) {
    297             m_FontBBox.right = rect.right;
    298           }
    299           if (m_FontBBox.left > rect.left) {
    300             m_FontBBox.left = rect.left;
    301           }
    302           if (m_FontBBox.bottom > rect.bottom) {
    303             m_FontBBox.bottom = rect.bottom;
    304           }
    305         }
    306       }
    307     }
    308   }
    309   if (m_Ascent == 0 && m_Descent == 0) {
    310     FX_RECT rect;
    311     GetCharBBox('A', rect);
    312     if (rect.bottom == rect.top) {
    313       m_Ascent = m_FontBBox.top;
    314     } else {
    315       m_Ascent = rect.top;
    316     }
    317     GetCharBBox('g', rect);
    318     if (rect.bottom == rect.top) {
    319       m_Descent = m_FontBBox.bottom;
    320     } else {
    321       m_Descent = rect.bottom;
    322     }
    323   }
    324 }
    325 void CPDF_Font::LoadUnicodeMap() {
    326   m_bToUnicodeLoaded = TRUE;
    327   CPDF_Stream* pStream = m_pFontDict->GetStream("ToUnicode");
    328   if (!pStream) {
    329     return;
    330   }
    331   m_pToUnicodeMap = new CPDF_ToUnicodeMap;
    332   m_pToUnicodeMap->Load(pStream);
    333 }
    334 int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size) {
    335   int offset = 0;
    336   int width = 0;
    337   while (offset < size) {
    338     FX_DWORD charcode = GetNextChar(pString, size, offset);
    339     width += GetCharWidthF(charcode);
    340   }
    341   return width;
    342 }
    343 int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode) {
    344   if (!m_Font.GetFace())
    345     return 0;
    346 
    347   int glyph_index = GlyphFromCharCode(charcode);
    348   if (glyph_index == 0xffff) {
    349     return 0;
    350   }
    351   return m_Font.GetGlyphWidth(glyph_index);
    352 }
    353 
    354 CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc,
    355                                    const CFX_ByteStringC& name) {
    356   CFX_ByteString fontname(name);
    357   int font_id = PDF_GetStandardFontName(&fontname);
    358   if (font_id < 0) {
    359     return nullptr;
    360   }
    361   CPDF_FontGlobals* pFontGlobals =
    362       CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
    363   CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
    364   if (pFont) {
    365     return pFont;
    366   }
    367   CPDF_Dictionary* pDict = new CPDF_Dictionary;
    368   pDict->SetAtName("Type", "Font");
    369   pDict->SetAtName("Subtype", "Type1");
    370   pDict->SetAtName("BaseFont", fontname);
    371   pDict->SetAtName("Encoding", "WinAnsiEncoding");
    372   pFont = CPDF_Font::CreateFontF(NULL, pDict);
    373   pFontGlobals->Set(pDoc, font_id, pFont);
    374   return pFont;
    375 }
    376 const uint8_t ChineseFontNames[][5] = {{0xCB, 0xCE, 0xCC, 0xE5, 0x00},
    377                                        {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
    378                                        {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
    379                                        {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
    380                                        {0xD0, 0xC2, 0xCB, 0xCE, 0x00}};
    381 CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc,
    382                                   CPDF_Dictionary* pFontDict) {
    383   CFX_ByteString type = pFontDict->GetString("Subtype");
    384   CPDF_Font* pFont;
    385   if (type == "TrueType") {
    386     {
    387 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || \
    388     _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ ||   \
    389     _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || \
    390     _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
    391       CFX_ByteString basefont = pFontDict->GetString("BaseFont");
    392       CFX_ByteString tag = basefont.Left(4);
    393       int i;
    394       int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
    395       for (i = 0; i < count; ++i) {
    396         if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) {
    397           break;
    398         }
    399       }
    400       if (i < count) {
    401         CPDF_Dictionary* pFontDesc = pFontDict->GetDict("FontDescriptor");
    402         if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) {
    403           pFont = new CPDF_CIDFont;
    404           pFont->m_pFontDict = pFontDict;
    405           pFont->m_pDocument = pDoc;
    406           if (!pFont->Load()) {
    407             delete pFont;
    408             return NULL;
    409           }
    410           return pFont;
    411         }
    412       }
    413 #endif
    414     }
    415     pFont = new CPDF_TrueTypeFont;
    416   } else if (type == "Type3") {
    417     pFont = new CPDF_Type3Font;
    418   } else if (type == "Type0") {
    419     pFont = new CPDF_CIDFont;
    420   } else {
    421     pFont = new CPDF_Type1Font;
    422   }
    423   pFont->m_pFontDict = pFontDict;
    424   pFont->m_pDocument = pDoc;
    425   if (!pFont->Load()) {
    426     delete pFont;
    427     return NULL;
    428   }
    429   return pFont;
    430 }
    431 FX_BOOL CPDF_Font::Load() {
    432   if (!m_pFontDict) {
    433     return FALSE;
    434   }
    435   CFX_ByteString type = m_pFontDict->GetString("Subtype");
    436   m_BaseFont = m_pFontDict->GetString("BaseFont");
    437   if (type == "MMType1") {
    438     type = "Type1";
    439   }
    440   return _Load();
    441 }
    442 static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap,
    443                                              const CFX_ByteString& bytestr) {
    444   return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr);
    445 }
    446 static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap,
    447                                              const CFX_WideString& widestr) {
    448   return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr);
    449 }
    450 CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont) {
    451   m_GetByteString = _FontMap_GetByteString;
    452   m_GetWideString = _FontMap_GetWideString;
    453   m_pFont = pFont;
    454 }
    455 CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) {
    456   auto it = m_Map.find(charcode);
    457   if (it != m_Map.end()) {
    458     FX_DWORD value = it->second;
    459     FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff);
    460     if (unicode != 0xffff) {
    461       return unicode;
    462     }
    463     const FX_WCHAR* buf = m_MultiCharBuf.GetBuffer();
    464     FX_DWORD buf_len = m_MultiCharBuf.GetLength();
    465     if (!buf || buf_len == 0) {
    466       return CFX_WideString();
    467     }
    468     FX_DWORD index = value >> 16;
    469     if (index >= buf_len) {
    470       return CFX_WideString();
    471     }
    472     FX_DWORD len = buf[index];
    473     if (index + len < index || index + len >= buf_len) {
    474       return CFX_WideString();
    475     }
    476     return CFX_WideString(buf + index + 1, len);
    477   }
    478   if (m_pBaseMap) {
    479     return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode);
    480   }
    481   return CFX_WideString();
    482 }
    483 FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode) {
    484   for (const auto& pair : m_Map) {
    485     if (pair.second == unicode)
    486       return pair.first;
    487   }
    488   return 0;
    489 }
    490 
    491 // Static.
    492 FX_DWORD CPDF_ToUnicodeMap::StringToCode(const CFX_ByteStringC& str) {
    493   const FX_CHAR* buf = str.GetCStr();
    494   int len = str.GetLength();
    495   if (len == 0)
    496     return 0;
    497 
    498   int result = 0;
    499   if (buf[0] == '<') {
    500     for (int i = 1; i < len && std::isxdigit(buf[i]); ++i)
    501       result = result * 16 + FXSYS_toHexDigit(buf[i]);
    502     return result;
    503   }
    504 
    505   for (int i = 0; i < len && std::isdigit(buf[i]); ++i)
    506     result = result * 10 + FXSYS_toDecimalDigit(buf[i]);
    507 
    508   return result;
    509 }
    510 static CFX_WideString StringDataAdd(CFX_WideString str) {
    511   CFX_WideString ret;
    512   int len = str.GetLength();
    513   FX_WCHAR value = 1;
    514   for (int i = len - 1; i >= 0; --i) {
    515     FX_WCHAR ch = str[i] + value;
    516     if (ch < str[i]) {
    517       ret.Insert(0, 0);
    518     } else {
    519       ret.Insert(0, ch);
    520       value = 0;
    521     }
    522   }
    523   if (value) {
    524     ret.Insert(0, value);
    525   }
    526   return ret;
    527 }
    528 
    529 // Static.
    530 CFX_WideString CPDF_ToUnicodeMap::StringToWideString(
    531     const CFX_ByteStringC& str) {
    532   const FX_CHAR* buf = str.GetCStr();
    533   int len = str.GetLength();
    534   if (len == 0)
    535     return CFX_WideString();
    536 
    537   CFX_WideString result;
    538   if (buf[0] == '<') {
    539     int byte_pos = 0;
    540     FX_WCHAR ch = 0;
    541     for (int i = 1; i < len && std::isxdigit(buf[i]); ++i) {
    542       ch = ch * 16 + FXSYS_toHexDigit(buf[i]);
    543       byte_pos++;
    544       if (byte_pos == 4) {
    545         result += ch;
    546         byte_pos = 0;
    547         ch = 0;
    548       }
    549     }
    550     return result;
    551   }
    552   return result;
    553 }
    554 void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) {
    555   CIDSet cid_set = CIDSET_UNKNOWN;
    556   CPDF_StreamAcc stream;
    557   stream.LoadAllData(pStream, FALSE);
    558   CPDF_SimpleParser parser(stream.GetData(), stream.GetSize());
    559   while (1) {
    560     CFX_ByteStringC word = parser.GetWord();
    561     if (word.IsEmpty()) {
    562       break;
    563     }
    564     if (word == "beginbfchar") {
    565       while (1) {
    566         word = parser.GetWord();
    567         if (word.IsEmpty() || word == "endbfchar") {
    568           break;
    569         }
    570         FX_DWORD srccode = StringToCode(word);
    571         word = parser.GetWord();
    572         CFX_WideString destcode = StringToWideString(word);
    573         int len = destcode.GetLength();
    574         if (len == 0) {
    575           continue;
    576         }
    577         if (len == 1) {
    578           m_Map[srccode] = destcode.GetAt(0);
    579         } else {
    580           m_Map[srccode] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff;
    581           m_MultiCharBuf.AppendChar(destcode.GetLength());
    582           m_MultiCharBuf << destcode;
    583         }
    584       }
    585     } else if (word == "beginbfrange") {
    586       while (1) {
    587         CFX_ByteString low, high;
    588         low = parser.GetWord();
    589         if (low.IsEmpty() || low == "endbfrange") {
    590           break;
    591         }
    592         high = parser.GetWord();
    593         FX_DWORD lowcode = StringToCode(low);
    594         FX_DWORD highcode =
    595             (lowcode & 0xffffff00) | (StringToCode(high) & 0xff);
    596         if (highcode == (FX_DWORD)-1) {
    597           break;
    598         }
    599         CFX_ByteString start = parser.GetWord();
    600         if (start == "[") {
    601           for (FX_DWORD code = lowcode; code <= highcode; code++) {
    602             CFX_ByteString dest = parser.GetWord();
    603             CFX_WideString destcode = StringToWideString(dest);
    604             int len = destcode.GetLength();
    605             if (len == 0) {
    606               continue;
    607             }
    608             if (len == 1) {
    609               m_Map[code] = destcode.GetAt(0);
    610             } else {
    611               m_Map[code] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff;
    612               m_MultiCharBuf.AppendChar(destcode.GetLength());
    613               m_MultiCharBuf << destcode;
    614             }
    615           }
    616           parser.GetWord();
    617         } else {
    618           CFX_WideString destcode = StringToWideString(start);
    619           int len = destcode.GetLength();
    620           FX_DWORD value = 0;
    621           if (len == 1) {
    622             value = StringToCode(start);
    623             for (FX_DWORD code = lowcode; code <= highcode; code++) {
    624               m_Map[code] = value++;
    625             }
    626           } else {
    627             for (FX_DWORD code = lowcode; code <= highcode; code++) {
    628               CFX_WideString retcode;
    629               if (code == lowcode) {
    630                 retcode = destcode;
    631               } else {
    632                 retcode = StringDataAdd(destcode);
    633               }
    634               m_Map[code] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff;
    635               m_MultiCharBuf.AppendChar(retcode.GetLength());
    636               m_MultiCharBuf << retcode;
    637               destcode = retcode;
    638             }
    639           }
    640         }
    641       }
    642     } else if (word == "/Adobe-Korea1-UCS2") {
    643       cid_set = CIDSET_KOREA1;
    644     } else if (word == "/Adobe-Japan1-UCS2") {
    645       cid_set = CIDSET_JAPAN1;
    646     } else if (word == "/Adobe-CNS1-UCS2") {
    647       cid_set = CIDSET_CNS1;
    648     } else if (word == "/Adobe-GB1-UCS2") {
    649       cid_set = CIDSET_GB1;
    650     }
    651   }
    652   if (cid_set) {
    653     m_pBaseMap = CPDF_ModuleMgr::Get()
    654                      ->GetPageModule()
    655                      ->GetFontGlobals()
    656                      ->m_CMapManager.GetCID2UnicodeMap(cid_set, FALSE);
    657   } else {
    658     m_pBaseMap = NULL;
    659   }
    660 }
    661 static FX_BOOL GetPredefinedEncoding(int& basemap,
    662                                      const CFX_ByteString& value) {
    663   if (value == "WinAnsiEncoding") {
    664     basemap = PDFFONT_ENCODING_WINANSI;
    665   } else if (value == "MacRomanEncoding") {
    666     basemap = PDFFONT_ENCODING_MACROMAN;
    667   } else if (value == "MacExpertEncoding") {
    668     basemap = PDFFONT_ENCODING_MACEXPERT;
    669   } else if (value == "PDFDocEncoding") {
    670     basemap = PDFFONT_ENCODING_PDFDOC;
    671   } else {
    672     return FALSE;
    673   }
    674   return TRUE;
    675 }
    676 void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding,
    677                                 int& iBaseEncoding,
    678                                 CFX_ByteString*& pCharNames,
    679                                 FX_BOOL bEmbedded,
    680                                 FX_BOOL bTrueType) {
    681   if (!pEncoding) {
    682     if (m_BaseFont == "Symbol") {
    683       iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL
    684                                 : PDFFONT_ENCODING_ADOBE_SYMBOL;
    685     } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
    686       iBaseEncoding = PDFFONT_ENCODING_WINANSI;
    687     }
    688     return;
    689   }
    690   if (pEncoding->IsName()) {
    691     if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL ||
    692         iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
    693       return;
    694     }
    695     if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") {
    696       if (!bTrueType) {
    697         iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
    698       }
    699       return;
    700     }
    701     CFX_ByteString bsEncoding = pEncoding->GetString();
    702     if (bsEncoding.Compare("MacExpertEncoding") == 0) {
    703       bsEncoding = "WinAnsiEncoding";
    704     }
    705     GetPredefinedEncoding(iBaseEncoding, bsEncoding);
    706     return;
    707   }
    708 
    709   CPDF_Dictionary* pDict = pEncoding->AsDictionary();
    710   if (!pDict)
    711     return;
    712 
    713   if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
    714       iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
    715     CFX_ByteString bsEncoding = pDict->GetString("BaseEncoding");
    716     if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) {
    717       bsEncoding = "WinAnsiEncoding";
    718     }
    719     GetPredefinedEncoding(iBaseEncoding, bsEncoding);
    720   }
    721   if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
    722     iBaseEncoding = PDFFONT_ENCODING_STANDARD;
    723   }
    724   CPDF_Array* pDiffs = pDict->GetArray("Differences");
    725   if (!pDiffs) {
    726     return;
    727   }
    728   pCharNames = new CFX_ByteString[256];
    729   FX_DWORD cur_code = 0;
    730   for (FX_DWORD i = 0; i < pDiffs->GetCount(); i++) {
    731     CPDF_Object* pElement = pDiffs->GetElementValue(i);
    732     if (!pElement)
    733       continue;
    734 
    735     if (CPDF_Name* pName = pElement->AsName()) {
    736       if (cur_code < 256)
    737         pCharNames[cur_code] = pName->GetString();
    738       cur_code++;
    739     } else {
    740       cur_code = pElement->GetInteger();
    741     }
    742   }
    743 }
    744 
    745 FX_BOOL CPDF_Font::IsStandardFont() const {
    746   if (m_FontType != PDFFONT_TYPE1)
    747     return FALSE;
    748   if (m_pFontFile)
    749     return FALSE;
    750   if (((CPDF_Type1Font*)this)->GetBase14Font() < 0)
    751     return FALSE;
    752   return TRUE;
    753 }
    754 CPDF_SimpleFont::CPDF_SimpleFont(int fonttype) : CPDF_Font(fonttype) {
    755   FXSYS_memset(m_CharBBox, 0xff, sizeof m_CharBBox);
    756   FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth);
    757   FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
    758   FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID);
    759   m_pCharNames = NULL;
    760   m_BaseEncoding = PDFFONT_ENCODING_BUILTIN;
    761 }
    762 CPDF_SimpleFont::~CPDF_SimpleFont() {
    763   delete[] m_pCharNames;
    764 }
    765 int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) {
    766   if (pVertGlyph) {
    767     *pVertGlyph = FALSE;
    768   }
    769   if (charcode > 0xff) {
    770     return -1;
    771   }
    772   int index = m_GlyphIndex[(uint8_t)charcode];
    773   if (index == 0xffff) {
    774     return -1;
    775   }
    776   return index;
    777 }
    778 void CPDF_SimpleFont::LoadCharMetrics(int charcode) {
    779   if (!m_Font.GetFace())
    780     return;
    781 
    782   if (charcode < 0 || charcode > 0xff) {
    783     return;
    784   }
    785   int glyph_index = m_GlyphIndex[charcode];
    786   if (glyph_index == 0xffff) {
    787     if (!m_pFontFile && charcode != 32) {
    788       LoadCharMetrics(32);
    789       m_CharBBox[charcode] = m_CharBBox[32];
    790       if (m_bUseFontWidth) {
    791         m_CharWidth[charcode] = m_CharWidth[32];
    792       }
    793     }
    794     return;
    795   }
    796   FXFT_Face face = m_Font.GetFace();
    797   int err = FXFT_Load_Glyph(
    798       face, glyph_index,
    799       FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
    800   if (err) {
    801     return;
    802   }
    803   m_CharBBox[charcode].Left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face);
    804   m_CharBBox[charcode].Right = TT2PDF(
    805       FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face), face);
    806   m_CharBBox[charcode].Top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face);
    807   m_CharBBox[charcode].Bottom = TT2PDF(
    808       FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face), face);
    809   if (m_bUseFontWidth) {
    810     int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face);
    811     if (m_CharWidth[charcode] == 0xffff) {
    812       m_CharWidth[charcode] = TT_Width;
    813     } else if (TT_Width && !IsEmbedded()) {
    814       m_CharBBox[charcode].Right =
    815           m_CharBBox[charcode].Right * m_CharWidth[charcode] / TT_Width;
    816       m_CharBBox[charcode].Left =
    817           m_CharBBox[charcode].Left * m_CharWidth[charcode] / TT_Width;
    818     }
    819   }
    820 }
    821 int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) {
    822   if (charcode > 0xff) {
    823     charcode = 0;
    824   }
    825   if (m_CharWidth[charcode] == 0xffff) {
    826     LoadCharMetrics(charcode);
    827     if (m_CharWidth[charcode] == 0xffff) {
    828       m_CharWidth[charcode] = 0;
    829     }
    830   }
    831   return (int16_t)m_CharWidth[charcode];
    832 }
    833 void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) {
    834   if (charcode > 0xff) {
    835     charcode = 0;
    836   }
    837   if (m_CharBBox[charcode].Left == (int16_t)0xffff) {
    838     LoadCharMetrics(charcode);
    839   }
    840   rect.left = m_CharBBox[charcode].Left;
    841   rect.right = m_CharBBox[charcode].Right;
    842   rect.bottom = m_CharBBox[charcode].Bottom;
    843   rect.top = m_CharBBox[charcode].Top;
    844 }
    845 const FX_CHAR* GetAdobeCharName(int iBaseEncoding,
    846                                 const CFX_ByteString* pCharNames,
    847                                 int charcode) {
    848   ASSERT(charcode >= 0 && charcode < 256);
    849   if (charcode < 0 || charcode >= 256) {
    850     return NULL;
    851   }
    852   const FX_CHAR* name = NULL;
    853   if (pCharNames) {
    854     name = pCharNames[charcode];
    855   }
    856   if ((!name || name[0] == 0) && iBaseEncoding) {
    857     name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
    858   }
    859   return name && name[0] ? name : nullptr;
    860 }
    861 FX_BOOL CPDF_SimpleFont::LoadCommon() {
    862   CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict("FontDescriptor");
    863   if (pFontDesc) {
    864     LoadFontDescriptor(pFontDesc);
    865   }
    866   CPDF_Array* pWidthArray = m_pFontDict->GetArray("Widths");
    867   int width_start = 0, width_end = -1;
    868   m_bUseFontWidth = TRUE;
    869   if (pWidthArray) {
    870     m_bUseFontWidth = FALSE;
    871     if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) {
    872       int MissingWidth = pFontDesc->GetInteger("MissingWidth");
    873       for (int i = 0; i < 256; i++) {
    874         m_CharWidth[i] = MissingWidth;
    875       }
    876     }
    877     width_start = m_pFontDict->GetInteger("FirstChar", 0);
    878     width_end = m_pFontDict->GetInteger("LastChar", 0);
    879     if (width_start >= 0 && width_start <= 255) {
    880       if (width_end <= 0 ||
    881           width_end >= width_start + (int)pWidthArray->GetCount()) {
    882         width_end = width_start + pWidthArray->GetCount() - 1;
    883       }
    884       if (width_end > 255) {
    885         width_end = 255;
    886       }
    887       for (int i = width_start; i <= width_end; i++) {
    888         m_CharWidth[i] = pWidthArray->GetInteger(i - width_start);
    889       }
    890     }
    891   }
    892   if (m_pFontFile) {
    893     if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') {
    894       m_BaseFont = m_BaseFont.Mid(8);
    895     }
    896   } else {
    897     LoadSubstFont();
    898   }
    899   if (!(m_Flags & PDFFONT_SYMBOLIC)) {
    900     m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
    901   }
    902   CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
    903   LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL,
    904                   m_Font.IsTTFont());
    905   LoadGlyphMap();
    906   delete[] m_pCharNames;
    907   m_pCharNames = NULL;
    908   if (!m_Font.GetFace())
    909     return TRUE;
    910 
    911   if (m_Flags & PDFFONT_ALLCAP) {
    912     unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
    913     for (size_t range = 0; range < sizeof lowercases / 2; range++) {
    914       for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i++) {
    915         if (m_GlyphIndex[i] != 0xffff && m_pFontFile) {
    916           continue;
    917         }
    918         m_GlyphIndex[i] = m_GlyphIndex[i - 32];
    919         if (m_CharWidth[i - 32]) {
    920           m_CharWidth[i] = m_CharWidth[i - 32];
    921           m_CharBBox[i] = m_CharBBox[i - 32];
    922         }
    923       }
    924     }
    925   }
    926   CheckFontMetrics();
    927   return TRUE;
    928 }
    929 void CPDF_SimpleFont::LoadSubstFont() {
    930   if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) {
    931     int width = 0, i;
    932     for (i = 0; i < 256; i++) {
    933       if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) {
    934         continue;
    935       }
    936       if (width == 0) {
    937         width = m_CharWidth[i];
    938       } else if (width != m_CharWidth[i]) {
    939         break;
    940       }
    941     }
    942     if (i == 256 && width) {
    943       m_Flags |= PDFFONT_FIXEDPITCH;
    944     }
    945   }
    946   int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
    947   m_Font.LoadSubst(m_BaseFont, IsFontType(PDFFONT_TRUETYPE), m_Flags, weight,
    948                    m_ItalicAngle, 0);
    949   if (m_Font.GetSubstFont()->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
    950   }
    951 }
    952 FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const {
    953   return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN &&
    954          m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
    955          m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS;
    956 }
    957 CPDF_Type1Font::CPDF_Type1Font() : CPDF_SimpleFont(PDFFONT_TYPE1) {
    958   m_Base14Font = -1;
    959 }
    960 FX_BOOL CPDF_Type1Font::_Load() {
    961   m_Base14Font = PDF_GetStandardFontName(&m_BaseFont);
    962   if (m_Base14Font >= 0) {
    963     CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict("FontDescriptor");
    964     if (pFontDesc && pFontDesc->KeyExist("Flags")) {
    965       m_Flags = pFontDesc->GetInteger("Flags");
    966     } else {
    967       m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC;
    968     }
    969     if (m_Base14Font < 4)
    970       for (int i = 0; i < 256; i++) {
    971         m_CharWidth[i] = 600;
    972       }
    973     if (m_Base14Font == 12) {
    974       m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
    975     } else if (m_Base14Font == 13) {
    976       m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;
    977     } else if (m_Flags & PDFFONT_NONSYMBOLIC) {
    978       m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
    979     }
    980   }
    981   return LoadCommon();
    982 }
    983 static FX_BOOL FT_UseType1Charmap(FXFT_Face face) {
    984   if (FXFT_Get_Face_CharmapCount(face) == 0) {
    985     return FALSE;
    986   }
    987   if (FXFT_Get_Face_CharmapCount(face) == 1 &&
    988       FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
    989           FXFT_ENCODING_UNICODE) {
    990     return FALSE;
    991   }
    992   if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) ==
    993       FXFT_ENCODING_UNICODE) {
    994     FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);
    995   } else {
    996     FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
    997   }
    998   return TRUE;
    999 }
   1000 int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode) {
   1001   if (charcode > 0xff) {
   1002     return -1;
   1003   }
   1004   int index = m_ExtGID[(uint8_t)charcode];
   1005   if (index == 0xffff) {
   1006     return -1;
   1007   }
   1008   return index;
   1009 }
   1010 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1011 struct _GlyphNameMap {
   1012   const FX_CHAR* m_pStrAdobe;
   1013   const FX_CHAR* m_pStrUnicode;
   1014 };
   1015 static const _GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"},
   1016                                                   {"fi", "uniFB01"},
   1017                                                   {"fl", "uniFB02"},
   1018                                                   {"ffi", "uniFB03"},
   1019                                                   {"ffl", "uniFB04"}};
   1020 extern "C" {
   1021 static int compareString(const void* key, const void* element) {
   1022   return FXSYS_stricmp((const FX_CHAR*)key,
   1023                        ((_GlyphNameMap*)element)->m_pStrAdobe);
   1024 }
   1025 }
   1026 static const FX_CHAR* _GlyphNameRemap(const FX_CHAR* pStrAdobe) {
   1027   _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch(
   1028       pStrAdobe, g_GlyphNameSubsts,
   1029       sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), sizeof(_GlyphNameMap),
   1030       compareString);
   1031   if (found) {
   1032     return found->m_pStrUnicode;
   1033   }
   1034   return NULL;
   1035 }
   1036 #endif
   1037 void CPDF_Type1Font::LoadGlyphMap() {
   1038   if (!m_Font.GetFace())
   1039     return;
   1040 
   1041 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1042   FX_BOOL bCoreText = TRUE;
   1043   CQuartz2D& quartz2d =
   1044       ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
   1045   if (!m_Font.GetPlatformFont()) {
   1046     if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
   1047       bCoreText = FALSE;
   1048     }
   1049     m_Font.SetPlatformFont(
   1050         quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize()));
   1051     if (!m_Font.GetPlatformFont()) {
   1052       bCoreText = FALSE;
   1053     }
   1054   }
   1055 #endif
   1056   if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {
   1057     if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
   1058       FX_BOOL bGotOne = FALSE;
   1059       for (int charcode = 0; charcode < 256; charcode++) {
   1060         const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
   1061         for (int j = 0; j < 4; j++) {
   1062           FX_WORD unicode = prefix[j] * 256 + charcode;
   1063           m_GlyphIndex[charcode] =
   1064               FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
   1065 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1066           FX_CHAR name_glyph[256];
   1067           FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
   1068                               name_glyph, 256);
   1069           name_glyph[255] = 0;
   1070           CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
   1071               kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
   1072               kCFAllocatorNull);
   1073           m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
   1074               (CGFontRef)m_Font.GetPlatformFont(), name_ct);
   1075           if (name_ct) {
   1076             CFRelease(name_ct);
   1077           }
   1078 #endif
   1079           if (m_GlyphIndex[charcode]) {
   1080             bGotOne = TRUE;
   1081             break;
   1082           }
   1083         }
   1084       }
   1085       if (bGotOne) {
   1086 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1087         if (!bCoreText) {
   1088           FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
   1089         }
   1090 #endif
   1091         return;
   1092       }
   1093     }
   1094     FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
   1095     if (m_BaseEncoding == 0) {
   1096       m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
   1097     }
   1098     for (int charcode = 0; charcode < 256; charcode++) {
   1099       const FX_CHAR* name =
   1100           GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
   1101       if (!name) {
   1102         continue;
   1103       }
   1104       m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
   1105       m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
   1106           m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
   1107 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1108       FX_CHAR name_glyph[256];
   1109       FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph,
   1110                           256);
   1111       name_glyph[255] = 0;
   1112       CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
   1113           kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
   1114           kCFAllocatorNull);
   1115       m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
   1116           (CGFontRef)m_Font.GetPlatformFont(), name_ct);
   1117       if (name_ct) {
   1118         CFRelease(name_ct);
   1119       }
   1120 #endif
   1121       if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) {
   1122         m_Encoding.m_Unicodes[charcode] = 0x20;
   1123         m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20);
   1124 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1125         FX_CHAR name_glyph[256];
   1126         FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
   1127                             name_glyph, 256);
   1128         name_glyph[255] = 0;
   1129         CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
   1130             kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
   1131             kCFAllocatorNull);
   1132         m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
   1133             (CGFontRef)m_Font.GetPlatformFont(), name_ct);
   1134         if (name_ct) {
   1135           CFRelease(name_ct);
   1136         }
   1137 #endif
   1138       }
   1139     }
   1140 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1141     if (!bCoreText) {
   1142       FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
   1143     }
   1144 #endif
   1145     return;
   1146   }
   1147   FT_UseType1Charmap(m_Font.GetFace());
   1148 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1149   if (bCoreText) {
   1150     if (m_Flags & PDFFONT_SYMBOLIC) {
   1151       for (int charcode = 0; charcode < 256; charcode++) {
   1152         const FX_CHAR* name =
   1153             GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
   1154         if (name) {
   1155           m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
   1156           m_GlyphIndex[charcode] =
   1157               FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
   1158           CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
   1159               kCFAllocatorDefault, name, kCFStringEncodingASCII,
   1160               kCFAllocatorNull);
   1161           m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
   1162               (CGFontRef)m_Font.GetPlatformFont(), name_ct);
   1163           if (name_ct) {
   1164             CFRelease(name_ct);
   1165           }
   1166         } else {
   1167           m_GlyphIndex[charcode] =
   1168               FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
   1169           FX_WCHAR unicode = 0;
   1170           if (m_GlyphIndex[charcode]) {
   1171             unicode =
   1172                 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
   1173           }
   1174           FX_CHAR name_glyph[256];
   1175           FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
   1176           FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
   1177                               name_glyph, 256);
   1178           name_glyph[255] = 0;
   1179           if (unicode == 0 && name_glyph[0] != 0) {
   1180             unicode = PDF_UnicodeFromAdobeName(name_glyph);
   1181           }
   1182           m_Encoding.m_Unicodes[charcode] = unicode;
   1183           CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
   1184               kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
   1185               kCFAllocatorNull);
   1186           m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
   1187               (CGFontRef)m_Font.GetPlatformFont(), name_ct);
   1188           if (name_ct) {
   1189             CFRelease(name_ct);
   1190           }
   1191         }
   1192       }
   1193       return;
   1194     }
   1195     FX_BOOL bUnicode = FALSE;
   1196     if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
   1197       bUnicode = TRUE;
   1198     }
   1199     for (int charcode = 0; charcode < 256; charcode++) {
   1200       const FX_CHAR* name =
   1201           GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
   1202       if (!name) {
   1203         continue;
   1204       }
   1205       m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
   1206       const FX_CHAR* pStrUnicode = _GlyphNameRemap(name);
   1207       if (pStrUnicode &&
   1208           0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) {
   1209         name = pStrUnicode;
   1210       }
   1211       m_GlyphIndex[charcode] =
   1212           FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
   1213       CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
   1214           kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
   1215       m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
   1216           (CGFontRef)m_Font.GetPlatformFont(), name_ct);
   1217       if (name_ct) {
   1218         CFRelease(name_ct);
   1219       }
   1220       if (m_GlyphIndex[charcode] == 0) {
   1221         if (FXSYS_strcmp(name, ".notdef") != 0 &&
   1222             FXSYS_strcmp(name, "space") != 0) {
   1223           m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
   1224               m_Font.GetFace(),
   1225               bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
   1226           FX_CHAR name_glyph[256];
   1227           FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
   1228                               name_glyph, 256);
   1229           name_glyph[255] = 0;
   1230           CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
   1231               kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
   1232               kCFAllocatorNull);
   1233           m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
   1234               (CGFontRef)m_Font.GetPlatformFont(), name_ct);
   1235           if (name_ct) {
   1236             CFRelease(name_ct);
   1237           }
   1238         } else {
   1239           m_Encoding.m_Unicodes[charcode] = 0x20;
   1240           m_GlyphIndex[charcode] =
   1241               bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff;
   1242           FX_CHAR name_glyph[256];
   1243           FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
   1244                               name_glyph, 256);
   1245           name_glyph[255] = 0;
   1246           CFStringRef name_ct = CFStringCreateWithCStringNoCopy(
   1247               kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII,
   1248               kCFAllocatorNull);
   1249           m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName(
   1250               (CGFontRef)m_Font.GetPlatformFont(), name_ct);
   1251           if (name_ct) {
   1252             CFRelease(name_ct);
   1253           }
   1254         }
   1255       }
   1256     }
   1257     return;
   1258   }
   1259 #endif
   1260   if (m_Flags & PDFFONT_SYMBOLIC) {
   1261     for (int charcode = 0; charcode < 256; charcode++) {
   1262       const FX_CHAR* name =
   1263           GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
   1264       if (name) {
   1265         m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
   1266         m_GlyphIndex[charcode] =
   1267             FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
   1268       } else {
   1269         m_GlyphIndex[charcode] =
   1270             FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
   1271         if (m_GlyphIndex[charcode]) {
   1272           FX_WCHAR unicode =
   1273               FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
   1274           if (unicode == 0) {
   1275             FX_CHAR name_glyph[256];
   1276             FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
   1277             FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode],
   1278                                 name_glyph, 256);
   1279             name_glyph[255] = 0;
   1280             if (name_glyph[0] != 0) {
   1281               unicode = PDF_UnicodeFromAdobeName(name_glyph);
   1282             }
   1283           }
   1284           m_Encoding.m_Unicodes[charcode] = unicode;
   1285         }
   1286       }
   1287     }
   1288 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1289     if (!bCoreText) {
   1290       FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
   1291     }
   1292 #endif
   1293     return;
   1294   }
   1295   FX_BOOL bUnicode = FALSE;
   1296   if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) {
   1297     bUnicode = TRUE;
   1298   }
   1299   for (int charcode = 0; charcode < 256; charcode++) {
   1300     const FX_CHAR* name =
   1301         GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
   1302     if (!name) {
   1303       continue;
   1304     }
   1305     m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
   1306     m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
   1307     if (m_GlyphIndex[charcode] == 0) {
   1308       if (FXSYS_strcmp(name, ".notdef") != 0 &&
   1309           FXSYS_strcmp(name, "space") != 0) {
   1310         m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
   1311             m_Font.GetFace(),
   1312             bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
   1313       } else {
   1314         m_Encoding.m_Unicodes[charcode] = 0x20;
   1315         m_GlyphIndex[charcode] = 0xffff;
   1316       }
   1317     }
   1318   }
   1319 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
   1320   if (!bCoreText) {
   1321     FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
   1322   }
   1323 #endif
   1324 }
   1325 
   1326 CPDF_FontEncoding::CPDF_FontEncoding() {
   1327   FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
   1328 }
   1329 int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const {
   1330   for (int i = 0; i < 256; i++)
   1331     if (m_Unicodes[i] == unicode) {
   1332       return i;
   1333     }
   1334   return -1;
   1335 }
   1336 CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding) {
   1337   const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);
   1338   if (!pSrc) {
   1339     FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
   1340   } else
   1341     for (int i = 0; i < 256; i++) {
   1342       m_Unicodes[i] = pSrc[i];
   1343     }
   1344 }
   1345 FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const {
   1346   return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) ==
   1347          0;
   1348 }
   1349 CPDF_Object* CPDF_FontEncoding::Realize() {
   1350   int predefined = 0;
   1351   for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS;
   1352        cs++) {
   1353     const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs);
   1354     FX_BOOL match = TRUE;
   1355     for (int i = 0; i < 256; ++i) {
   1356       if (m_Unicodes[i] != pSrc[i]) {
   1357         match = FALSE;
   1358         break;
   1359       }
   1360     }
   1361     if (match) {
   1362       predefined = cs;
   1363       break;
   1364     }
   1365   }
   1366   if (predefined) {
   1367     if (predefined == PDFFONT_ENCODING_WINANSI) {
   1368       return new CPDF_Name("WinAnsiEncoding");
   1369     }
   1370     if (predefined == PDFFONT_ENCODING_MACROMAN) {
   1371       return new CPDF_Name("MacRomanEncoding");
   1372     }
   1373     if (predefined == PDFFONT_ENCODING_MACEXPERT) {
   1374       return new CPDF_Name("MacExpertEncoding");
   1375     }
   1376     return NULL;
   1377   }
   1378   const FX_WORD* pStandard =
   1379       PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
   1380   CPDF_Array* pDiff = new CPDF_Array;
   1381   for (int i = 0; i < 256; i++) {
   1382     if (pStandard[i] == m_Unicodes[i]) {
   1383       continue;
   1384     }
   1385     pDiff->Add(new CPDF_Number(i));
   1386     pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i])));
   1387   }
   1388 
   1389   CPDF_Dictionary* pDict = new CPDF_Dictionary;
   1390   pDict->SetAtName("BaseEncoding", "WinAnsiEncoding");
   1391   pDict->SetAt("Differences", pDiff);
   1392   return pDict;
   1393 }
   1394 CPDF_TrueTypeFont::CPDF_TrueTypeFont() : CPDF_SimpleFont(PDFFONT_TRUETYPE) {}
   1395 FX_BOOL CPDF_TrueTypeFont::_Load() {
   1396   return LoadCommon();
   1397 }
   1398 void CPDF_TrueTypeFont::LoadGlyphMap() {
   1399   if (!m_Font.GetFace())
   1400     return;
   1401 
   1402   int baseEncoding = m_BaseEncoding;
   1403   if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 &&
   1404       (baseEncoding == PDFFONT_ENCODING_MACROMAN ||
   1405        baseEncoding == PDFFONT_ENCODING_WINANSI) &&
   1406       (m_Flags & PDFFONT_SYMBOLIC)) {
   1407     FX_BOOL bSupportWin = FALSE;
   1408     FX_BOOL bSupportMac = FALSE;
   1409     for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) {
   1410       int platform_id = FXFT_Get_Charmap_PlatformID(
   1411           FXFT_Get_Face_Charmaps(m_Font.GetFace())[i]);
   1412       if (platform_id == 0 || platform_id == 3) {
   1413         bSupportWin = TRUE;
   1414       } else if (platform_id == 0 || platform_id == 1) {
   1415         bSupportMac = TRUE;
   1416       }
   1417     }
   1418     if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) {
   1419       baseEncoding =
   1420           bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN;
   1421     } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) {
   1422       baseEncoding =
   1423           bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN;
   1424     }
   1425   }
   1426   if (((baseEncoding == PDFFONT_ENCODING_MACROMAN ||
   1427         baseEncoding == PDFFONT_ENCODING_WINANSI) &&
   1428        !m_pCharNames) ||
   1429       (m_Flags & PDFFONT_NONSYMBOLIC)) {
   1430     if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) &&
   1431         (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) {
   1432       int nStartChar = m_pFontDict->GetInteger("FirstChar");
   1433       if (nStartChar < 0 || nStartChar > 255)
   1434         return;
   1435 
   1436       int charcode = 0;
   1437       for (; charcode < nStartChar; charcode++) {
   1438         m_GlyphIndex[charcode] = 0;
   1439       }
   1440       FX_WORD nGlyph = charcode - nStartChar + 3;
   1441       for (; charcode < 256; charcode++, nGlyph++) {
   1442         m_GlyphIndex[charcode] = nGlyph;
   1443       }
   1444       return;
   1445     }
   1446     FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1);
   1447     FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE;
   1448     if (!bMSUnicode) {
   1449       if (m_Flags & PDFFONT_NONSYMBOLIC) {
   1450         bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0);
   1451         bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0);
   1452       } else {
   1453         bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0);
   1454         bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0);
   1455       }
   1456     }
   1457     FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode");
   1458     for (int charcode = 0; charcode < 256; charcode++) {
   1459       const FX_CHAR* name =
   1460           GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
   1461       if (!name) {
   1462         m_GlyphIndex[charcode] =
   1463             m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1;
   1464         continue;
   1465       }
   1466       m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
   1467       if (bMSSymbol) {
   1468         const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
   1469         for (int j = 0; j < 4; j++) {
   1470           FX_WORD unicode = prefix[j] * 256 + charcode;
   1471           m_GlyphIndex[charcode] =
   1472               FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
   1473           if (m_GlyphIndex[charcode]) {
   1474             break;
   1475           }
   1476         }
   1477       } else if (m_Encoding.m_Unicodes[charcode]) {
   1478         if (bMSUnicode) {
   1479           m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
   1480               m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
   1481         } else if (bMacRoman) {
   1482           FX_DWORD maccode = FT_CharCodeFromUnicode(
   1483               FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]);
   1484           if (!maccode) {
   1485             m_GlyphIndex[charcode] =
   1486                 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
   1487           } else {
   1488             m_GlyphIndex[charcode] =
   1489                 FXFT_Get_Char_Index(m_Font.GetFace(), maccode);
   1490           }
   1491         }
   1492       }
   1493       if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) &&
   1494           name) {
   1495         if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) {
   1496           m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32);
   1497         } else {
   1498           m_GlyphIndex[charcode] =
   1499               FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name);
   1500           if (m_GlyphIndex[charcode] == 0) {
   1501             if (bToUnicode) {
   1502               CFX_WideString wsUnicode = UnicodeFromCharCode(charcode);
   1503               if (!wsUnicode.IsEmpty()) {
   1504                 m_GlyphIndex[charcode] =
   1505                     FXFT_Get_Char_Index(m_Font.GetFace(), wsUnicode[0]);
   1506                 m_Encoding.m_Unicodes[charcode] = wsUnicode[0];
   1507               }
   1508             }
   1509             if (m_GlyphIndex[charcode] == 0) {
   1510               m_GlyphIndex[charcode] =
   1511                   FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
   1512             }
   1513           }
   1514         }
   1515       }
   1516     }
   1517     return;
   1518   }
   1519   if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) {
   1520     const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
   1521     FX_BOOL bGotOne = FALSE;
   1522     for (int charcode = 0; charcode < 256; charcode++) {
   1523       for (int j = 0; j < 4; j++) {
   1524         FX_WORD unicode = prefix[j] * 256 + charcode;
   1525         m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode);
   1526         if (m_GlyphIndex[charcode]) {
   1527           bGotOne = TRUE;
   1528           break;
   1529         }
   1530       }
   1531     }
   1532     if (bGotOne) {
   1533       if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
   1534         for (int charcode = 0; charcode < 256; charcode++) {
   1535           const FX_CHAR* name =
   1536               GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
   1537           if (!name) {
   1538             continue;
   1539           }
   1540           m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
   1541         }
   1542       } else if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) {
   1543         for (int charcode = 0; charcode < 256; charcode++) {
   1544           m_Encoding.m_Unicodes[charcode] =
   1545               FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
   1546         }
   1547       }
   1548       return;
   1549     }
   1550   }
   1551   if (FT_UseTTCharmap(m_Font.GetFace(), 1, 0)) {
   1552     FX_BOOL bGotOne = FALSE;
   1553     for (int charcode = 0; charcode < 256; charcode++) {
   1554       m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode);
   1555       m_Encoding.m_Unicodes[charcode] =
   1556           FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
   1557       if (m_GlyphIndex[charcode]) {
   1558         bGotOne = TRUE;
   1559       }
   1560     }
   1561     if (m_pFontFile || bGotOne) {
   1562       return;
   1563     }
   1564   }
   1565   if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) {
   1566     FX_BOOL bGotOne = FALSE;
   1567     const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding);
   1568     for (int charcode = 0; charcode < 256; charcode++) {
   1569       if (m_pFontFile) {
   1570         m_Encoding.m_Unicodes[charcode] = charcode;
   1571       } else {
   1572         const FX_CHAR* name = GetAdobeCharName(0, m_pCharNames, charcode);
   1573         if (name) {
   1574           m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
   1575         } else if (pUnicodes) {
   1576           m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode];
   1577         }
   1578       }
   1579       m_GlyphIndex[charcode] = FXFT_Get_Char_Index(
   1580           m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]);
   1581       if (m_GlyphIndex[charcode]) {
   1582         bGotOne = TRUE;
   1583       }
   1584     }
   1585     if (bGotOne) {
   1586       return;
   1587     }
   1588   }
   1589   for (int charcode = 0; charcode < 256; charcode++) {
   1590     m_GlyphIndex[charcode] = charcode;
   1591   }
   1592 }
   1593 
   1594 CPDF_Type3Font::CPDF_Type3Font()
   1595     : CPDF_SimpleFont(PDFFONT_TYPE3),
   1596       m_pCharProcs(nullptr),
   1597       m_pPageResources(nullptr),
   1598       m_pFontResources(nullptr) {
   1599   FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL));
   1600 }
   1601 
   1602 CPDF_Type3Font::~CPDF_Type3Font() {
   1603   for (auto it : m_CacheMap)
   1604     delete it.second;
   1605 }
   1606 
   1607 FX_BOOL CPDF_Type3Font::_Load() {
   1608   m_pFontResources = m_pFontDict->GetDict("Resources");
   1609   CPDF_Array* pMatrix = m_pFontDict->GetArray("FontMatrix");
   1610   FX_FLOAT xscale = 1.0f, yscale = 1.0f;
   1611   if (pMatrix) {
   1612     m_FontMatrix = pMatrix->GetMatrix();
   1613     xscale = m_FontMatrix.a;
   1614     yscale = m_FontMatrix.d;
   1615   }
   1616   CPDF_Array* pBBox = m_pFontDict->GetArray("FontBBox");
   1617   if (pBBox) {
   1618     m_FontBBox.left = (int32_t)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000);
   1619     m_FontBBox.bottom =
   1620         (int32_t)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000);
   1621     m_FontBBox.right = (int32_t)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000);
   1622     m_FontBBox.top = (int32_t)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 1000);
   1623   }
   1624   int StartChar = m_pFontDict->GetInteger("FirstChar");
   1625   CPDF_Array* pWidthArray = m_pFontDict->GetArray("Widths");
   1626   if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
   1627     FX_DWORD count = pWidthArray->GetCount();
   1628     if (count > 256) {
   1629       count = 256;
   1630     }
   1631     if (StartChar + count > 256) {
   1632       count = 256 - StartChar;
   1633     }
   1634     for (FX_DWORD i = 0; i < count; i++) {
   1635       m_CharWidthL[StartChar + i] =
   1636           FXSYS_round(FXSYS_Mul(pWidthArray->GetNumber(i), xscale) * 1000);
   1637     }
   1638   }
   1639   m_pCharProcs = m_pFontDict->GetDict("CharProcs");
   1640   CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding");
   1641   if (pEncoding) {
   1642     LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
   1643     if (m_pCharNames) {
   1644       for (int i = 0; i < 256; i++) {
   1645         m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
   1646         if (m_Encoding.m_Unicodes[i] == 0) {
   1647           m_Encoding.m_Unicodes[i] = i;
   1648         }
   1649       }
   1650     }
   1651   }
   1652   return TRUE;
   1653 }
   1654 void CPDF_Type3Font::CheckType3FontMetrics() {
   1655   CheckFontMetrics();
   1656 }
   1657 
   1658 CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level) {
   1659   if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_)
   1660     return nullptr;
   1661 
   1662   auto it = m_CacheMap.find(charcode);
   1663   if (it != m_CacheMap.end())
   1664     return it->second;
   1665 
   1666   const FX_CHAR* name =
   1667       GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
   1668   if (!name)
   1669     return nullptr;
   1670 
   1671   CPDF_Stream* pStream =
   1672       ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr);
   1673   if (!pStream)
   1674     return nullptr;
   1675 
   1676   std::unique_ptr<CPDF_Type3Char> pNewChar(new CPDF_Type3Char(new CPDF_Form(
   1677       m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources,
   1678       pStream, nullptr)));
   1679 
   1680   // This can trigger recursion into this method. The content of |m_CacheMap|
   1681   // can change as a result. Thus after it returns, check the cache again for
   1682   // a cache hit.
   1683   pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr,
   1684                                   level + 1);
   1685   it = m_CacheMap.find(charcode);
   1686   if (it != m_CacheMap.end())
   1687     return it->second;
   1688 
   1689   FX_FLOAT scale = m_FontMatrix.GetXUnit();
   1690   pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f);
   1691   FX_RECT& rcBBox = pNewChar->m_BBox;
   1692   CFX_FloatRect char_rect(
   1693       (FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
   1694       (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
   1695   if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top)
   1696     char_rect = pNewChar->m_pForm->CalcBoundingBox();
   1697 
   1698   char_rect.Transform(&m_FontMatrix);
   1699   rcBBox.left = FXSYS_round(char_rect.left * 1000);
   1700   rcBBox.right = FXSYS_round(char_rect.right * 1000);
   1701   rcBBox.top = FXSYS_round(char_rect.top * 1000);
   1702   rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);
   1703 
   1704   ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode));
   1705   CPDF_Type3Char* pCachedChar = pNewChar.release();
   1706   m_CacheMap[charcode] = pCachedChar;
   1707   if (pCachedChar->m_pForm->CountObjects() == 0) {
   1708     delete pCachedChar->m_pForm;
   1709     pCachedChar->m_pForm = nullptr;
   1710   }
   1711   return pCachedChar;
   1712 }
   1713 
   1714 int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) {
   1715   if (charcode >= FX_ArraySize(m_CharWidthL))
   1716     charcode = 0;
   1717 
   1718   if (m_CharWidthL[charcode])
   1719     return m_CharWidthL[charcode];
   1720 
   1721   const CPDF_Type3Char* pChar = LoadChar(charcode, level);
   1722   return pChar ? pChar->m_Width : 0;
   1723 }
   1724 
   1725 void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level) {
   1726   const CPDF_Type3Char* pChar = LoadChar(charcode, level);
   1727   if (!pChar) {
   1728     rect.left = 0;
   1729     rect.right = 0;
   1730     rect.top = 0;
   1731     rect.bottom = 0;
   1732     return;
   1733   }
   1734   rect = pChar->m_BBox;
   1735 }
   1736 
   1737 CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm)
   1738     : m_pForm(pForm), m_pBitmap(nullptr), m_bColored(FALSE) {}
   1739 
   1740 CPDF_Type3Char::~CPDF_Type3Char() {
   1741   delete m_pForm;
   1742   delete m_pBitmap;
   1743 }
   1744