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