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