Merge to XFA: Kill FXSYS_mem{cpy,cmp,set.move}{32,8}.
[pdfium.git] / core / src / fpdfapi / fpdf_font / fpdf_font.cpp
index 886199b..345e291 100644 (file)
-// Copyright 2014 PDFium Authors. All rights reserved.\r
-// Use of this source code is governed by a BSD-style license that can be\r
-// found in the LICENSE file.\r
\r
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
-\r
-#include "../../../include/fpdfapi/fpdf_page.h"\r
-#include "../../../include/fpdfapi/fpdf_module.h"\r
-#include "../../../include/fpdfapi/fpdf_pageobj.h"\r
-#include "font_int.h"\r
-#include "../fpdf_page/pageint.h"\r
-#include "../../../include/fxge/fx_freetype.h"\r
-FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id)\r
-{\r
-    for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i ++) {\r
-        if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) == platform_id &&\r
-                FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) == encoding_id) {\r
-            FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);\r
-            return TRUE;\r
-        }\r
-    }\r
-    return FALSE;\r
-}\r
-extern const FX_WORD* PDF_UnicodesForPredefinedCharSet(int);\r
-CPDF_FontGlobals::CPDF_FontGlobals()\r
-{\r
-    FXSYS_memset32(m_EmbeddedCharsets, 0, sizeof m_EmbeddedCharsets);\r
-    FXSYS_memset32(m_EmbeddedToUnicodes, 0, sizeof m_EmbeddedToUnicodes);\r
-    m_pContrastRamps = NULL;\r
-}\r
-CPDF_FontGlobals::~CPDF_FontGlobals()\r
-{\r
-    ClearAll();\r
-    if (m_pContrastRamps) {\r
-        FX_Free(m_pContrastRamps);\r
-    }\r
-}\r
-class CFX_StockFontArray : public CFX_Object\r
-{\r
-public:\r
-    CFX_StockFontArray()\r
-    {\r
-        FXSYS_memset32(m_pStockFonts, 0, sizeof(CPDF_Font*) * 14);\r
-    }\r
-    CPDF_Font*                 m_pStockFonts[14];\r
-};\r
-CPDF_Font* CPDF_FontGlobals::Find(void* key, int index)\r
-{\r
-    void* value = NULL;\r
-    if (!m_pStockMap.Lookup(key, value)) {\r
-        return NULL;\r
-    }\r
-    if (!value) {\r
-        return NULL;\r
-    }\r
-    return ((CFX_StockFontArray*)value)->m_pStockFonts[index];\r
-}\r
-void CPDF_FontGlobals::Set(void* key, int index, CPDF_Font* pFont)\r
-{\r
-    void* value = NULL;\r
-    if (m_pStockMap.Lookup(key, value)) {\r
-        ((CFX_StockFontArray*)value)->m_pStockFonts[index] = pFont;\r
-        return;\r
-    }\r
-    CFX_StockFontArray* pFonts = FX_NEW CFX_StockFontArray();\r
-    if (pFonts) {\r
-        pFonts->m_pStockFonts[index] = pFont;\r
-    }\r
-    m_pStockMap.SetAt(key, pFonts);\r
-}\r
-void CPDF_FontGlobals::Clear(void* key)\r
-{\r
-    void* value = NULL;\r
-    if (!m_pStockMap.Lookup(key, value)) {\r
-        return;\r
-    }\r
-    if (value) {\r
-        CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value;\r
-        for (int i = 0; i < 14; i ++) {\r
-            if (pStockFonts->m_pStockFonts[i]) {\r
-                pStockFonts->m_pStockFonts[i]->GetFontDict()->Release();\r
-                delete pStockFonts->m_pStockFonts[i];\r
-            }\r
-        }\r
-        delete pStockFonts;\r
-    }\r
-    m_pStockMap.RemoveKey(key);\r
-}\r
-void CPDF_FontGlobals::ClearAll()\r
-{\r
-    FX_POSITION pos = m_pStockMap.GetStartPosition();\r
-    while (pos) {\r
-        void *key = NULL;\r
-        void* value = NULL;\r
-        m_pStockMap.GetNextAssoc(pos, key, value);\r
-        if (value) {\r
-            CFX_StockFontArray* pStockFonts = (CFX_StockFontArray*)value;\r
-            for (int i = 0; i < 14; i ++) {\r
-                if (pStockFonts->m_pStockFonts[i]) {\r
-                    pStockFonts->m_pStockFonts[i]->GetFontDict()->Release();\r
-                    delete pStockFonts->m_pStockFonts[i];\r
-                }\r
-            }\r
-            delete pStockFonts;\r
-        }\r
-        m_pStockMap.RemoveKey(key);\r
-    }\r
-}\r
-CPDF_Font::CPDF_Font()\r
-{\r
-    m_FontType = 0;\r
-    m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0;\r
-    m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0;\r
-    m_pFontFile = NULL;\r
-    m_Flags = 0;\r
-    m_pToUnicodeMap = NULL;\r
-    m_bToUnicodeLoaded = FALSE;\r
-    m_pCharMap = NULL;\r
-}\r
-FX_BOOL CPDF_Font::Initialize()\r
-{\r
-    m_pCharMap = FX_NEW CPDF_FontCharMap(this);\r
-    return TRUE;\r
-}\r
-CPDF_Font::~CPDF_Font()\r
-{\r
-    if (m_pCharMap) {\r
-        FX_Free(m_pCharMap);\r
-        m_pCharMap = NULL;\r
-    }\r
-    if (m_pToUnicodeMap) {\r
-        delete m_pToUnicodeMap;\r
-        m_pToUnicodeMap = NULL;\r
-    }\r
-    if (m_pFontFile) {\r
-        m_pDocument->GetPageData()->ReleaseFontFileStreamAcc((CPDF_Stream*)m_pFontFile->GetStream());\r
-    }\r
-}\r
-FX_BOOL CPDF_Font::IsVertWriting() const\r
-{\r
-    FX_BOOL bVertWriting = FALSE;\r
-    CPDF_CIDFont* pCIDFont = GetCIDFont();\r
-    if (pCIDFont) {\r
-        bVertWriting = pCIDFont->IsVertWriting();\r
-    } else {\r
-        bVertWriting = m_Font.IsVertical();\r
-    }\r
-    return bVertWriting;\r
-}\r
-CFX_ByteString CPDF_Font::GetFontTypeName() const\r
-{\r
-    switch (m_FontType) {\r
-        case PDFFONT_TYPE1:\r
-            return FX_BSTRC("Type1");\r
-        case PDFFONT_TRUETYPE:\r
-            return FX_BSTRC("TrueType");\r
-        case PDFFONT_TYPE3:\r
-            return FX_BSTRC("Type3");\r
-        case PDFFONT_CIDFONT:\r
-            return FX_BSTRC("Type0");\r
-    }\r
-    return CFX_ByteString();\r
-}\r
-void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const\r
-{\r
-    char buf[4];\r
-    int len = AppendChar(buf, charcode);\r
-    if (len == 1) {\r
-        str += buf[0];\r
-    } else {\r
-        str += CFX_ByteString(buf, len);\r
-    }\r
-}\r
-CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const\r
-{\r
-    if (!m_bToUnicodeLoaded) {\r
-        ((CPDF_Font*)this)->LoadUnicodeMap();\r
-    }\r
-    if (m_pToUnicodeMap) {\r
-        CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode);\r
-        if (!wsRet.IsEmpty()) {\r
-            return wsRet;\r
-        }\r
-    }\r
-    FX_WCHAR unicode = _UnicodeFromCharCode(charcode);\r
-    if (unicode == 0) {\r
-        return CFX_WideString();\r
-    }\r
-    return unicode;\r
-}\r
-FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const\r
-{\r
-    if (!m_bToUnicodeLoaded) {\r
-        ((CPDF_Font*)this)->LoadUnicodeMap();\r
-    }\r
-    if (m_pToUnicodeMap) {\r
-        FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode);\r
-        if (charcode) {\r
-            return charcode;\r
-        }\r
-    }\r
-    return _CharCodeFromUnicode(unicode);\r
-}\r
-CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const\r
-{\r
-    CFX_WideString result;\r
-    int src_len = str.GetLength();\r
-    result.Reserve(src_len);\r
-    FX_LPCSTR src_buf = str;\r
-    int src_pos = 0;\r
-    while (src_pos < src_len) {\r
-        FX_DWORD charcode = GetNextChar(src_buf, src_pos);\r
-        CFX_WideString unicode = UnicodeFromCharCode(charcode);\r
-        if (!unicode.IsEmpty()) {\r
-            result += unicode;\r
-        } else {\r
-            result += (FX_WCHAR)charcode;\r
-        }\r
-    }\r
-    return result;\r
-}\r
-CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const\r
-{\r
-    CFX_ByteString result;\r
-    int src_len = str.GetLength();\r
-    FX_LPSTR dest_buf = result.GetBuffer(src_len * 2);\r
-    FX_LPCWSTR src_buf = str;\r
-    int dest_pos = 0;\r
-    for (int src_pos = 0; src_pos < src_len; src_pos ++) {\r
-        FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]);\r
-        dest_pos += AppendChar(dest_buf + dest_pos, charcode);\r
-    }\r
-    result.ReleaseBuffer(dest_pos);\r
-    return result;\r
-}\r
-void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc)\r
-{\r
-    m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"), PDFFONT_NONSYMBOLIC);\r
-    int ItalicAngle = 0;\r
-    FX_BOOL bExistItalicAngle = FALSE;\r
-    if (pFontDesc->KeyExist(FX_BSTRC("ItalicAngle"))) {\r
-        ItalicAngle = pFontDesc->GetInteger(FX_BSTRC("ItalicAngle"));\r
-        bExistItalicAngle = TRUE;\r
-    }\r
-    if (ItalicAngle < 0) {\r
-        m_Flags |= PDFFONT_ITALIC;\r
-        m_ItalicAngle = ItalicAngle;\r
-    }\r
-    FX_BOOL bExistStemV = FALSE;\r
-    if (pFontDesc->KeyExist(FX_BSTRC("StemV"))) {\r
-        m_StemV = pFontDesc->GetInteger(FX_BSTRC("StemV"));\r
-        bExistStemV = TRUE;\r
-    }\r
-    FX_BOOL bExistAscent = FALSE;\r
-    if (pFontDesc->KeyExist(FX_BSTRC("Ascent"))) {\r
-        m_Ascent = pFontDesc->GetInteger(FX_BSTRC("Ascent"));\r
-        bExistAscent = TRUE;\r
-    }\r
-    FX_BOOL bExistDescent = FALSE;\r
-    if (pFontDesc->KeyExist(FX_BSTRC("Descent"))) {\r
-        m_Descent = pFontDesc->GetInteger(FX_BSTRC("Descent"));\r
-        bExistDescent = TRUE;\r
-    }\r
-    FX_BOOL bExistCapHeight = FALSE;\r
-    if (pFontDesc->KeyExist(FX_BSTRC("CapHeight"))) {\r
-        bExistCapHeight = TRUE;\r
-    }\r
-    if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && bExistStemV) {\r
-        m_Flags |= PDFFONT_USEEXTERNATTR;\r
-    }\r
-    if (m_Descent > 10) {\r
-        m_Descent = -m_Descent;\r
-    }\r
-    CPDF_Array* pBBox = pFontDesc->GetArray(FX_BSTRC("FontBBox"));\r
-    if (pBBox) {\r
-        m_FontBBox.left = pBBox->GetInteger(0);\r
-        m_FontBBox.bottom = pBBox->GetInteger(1);\r
-        m_FontBBox.right = pBBox->GetInteger(2);\r
-        m_FontBBox.top = pBBox->GetInteger(3);\r
-    }\r
-    CPDF_Stream* pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile"));\r
-    if (pFontFile == NULL) {\r
-        pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile2"));\r
-    }\r
-    if (pFontFile == NULL) {\r
-        pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile3"));\r
-    }\r
-    if (pFontFile) {\r
-        m_pFontFile = m_pDocument->LoadFontFile(pFontFile);\r
-        if (m_pFontFile == NULL) {\r
-            return;\r
-        }\r
-        FX_LPCBYTE pFontData = m_pFontFile->GetData();\r
-        FX_DWORD dwFontSize = m_pFontFile->GetSize();\r
-        m_Font.LoadEmbedded(pFontData, dwFontSize);\r
-        if (m_Font.m_Face == NULL) {\r
-            m_pFontFile = NULL;\r
-        }\r
-    }\r
-}\r
-short TT2PDF(int m, FXFT_Face face)\r
-{\r
-    int upm = FXFT_Get_Face_UnitsPerEM(face);\r
-    if (upm == 0) {\r
-        return (short)m;\r
-    }\r
-    return (m * 1000 + upm / 2) / upm;\r
-}\r
-void CPDF_Font::CheckFontMetrics()\r
-{\r
-    if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && m_FontBBox.right == 0) {\r
-        if (m_Font.m_Face) {\r
-            m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(m_Font.m_Face), m_Font.m_Face);\r
-            m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(m_Font.m_Face), m_Font.m_Face);\r
-            m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(m_Font.m_Face), m_Font.m_Face);\r
-            m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(m_Font.m_Face), m_Font.m_Face);\r
-            m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(m_Font.m_Face), m_Font.m_Face);\r
-            m_Descent = TT2PDF(FXFT_Get_Face_Descender(m_Font.m_Face), m_Font.m_Face);\r
-        } else {\r
-            FX_BOOL bFirst = TRUE;\r
-            for (int i = 0; i < 256; i ++) {\r
-                FX_RECT rect;\r
-                GetCharBBox(i, rect);\r
-                if (rect.left == rect.right) {\r
-                    continue;\r
-                }\r
-                if (bFirst) {\r
-                    m_FontBBox = rect;\r
-                    bFirst = FALSE;\r
-                } else {\r
-                    if (m_FontBBox.top < rect.top) {\r
-                        m_FontBBox.top = rect.top;\r
-                    }\r
-                    if (m_FontBBox.right < rect.right) {\r
-                        m_FontBBox.right = rect.right;\r
-                    }\r
-                    if (m_FontBBox.left > rect.left) {\r
-                        m_FontBBox.left = rect.left;\r
-                    }\r
-                    if (m_FontBBox.bottom > rect.bottom) {\r
-                        m_FontBBox.bottom = rect.bottom;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-    if (m_Ascent == 0 && m_Descent == 0) {\r
-        FX_RECT rect;\r
-        GetCharBBox('A', rect);\r
-        if (rect.bottom == rect.top) {\r
-            m_Ascent = m_FontBBox.top;\r
-        } else {\r
-            m_Ascent = rect.top;\r
-        }\r
-        GetCharBBox('g', rect);\r
-        if (rect.bottom == rect.top) {\r
-            m_Descent = m_FontBBox.bottom;\r
-        } else {\r
-            m_Descent = rect.bottom;\r
-        }\r
-    }\r
-}\r
-void CPDF_Font::LoadUnicodeMap()\r
-{\r
-    m_bToUnicodeLoaded = TRUE;\r
-    CPDF_Stream* pStream = m_pFontDict->GetStream(FX_BSTRC("ToUnicode"));\r
-    if (pStream == NULL) {\r
-        return;\r
-    }\r
-    m_pToUnicodeMap = FX_NEW CPDF_ToUnicodeMap;\r
-    m_pToUnicodeMap->Load(pStream);\r
-}\r
-int CPDF_Font::GetStringWidth(FX_LPCSTR pString, int size)\r
-{\r
-    int offset = 0;\r
-    int width = 0;\r
-    while (offset < size) {\r
-        FX_DWORD charcode = GetNextChar(pString, offset);\r
-        width += GetCharWidthF(charcode);\r
-    }\r
-    return width;\r
-}\r
-int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode)\r
-{\r
-    if (m_Font.m_Face == NULL) {\r
-        return 0;\r
-    }\r
-    int glyph_index = GlyphFromCharCode(charcode);\r
-    if (glyph_index == 0xffff) {\r
-        return 0;\r
-    }\r
-    return m_Font.GetGlyphWidth(glyph_index);\r
-}\r
-int _PDF_GetStandardFontName(CFX_ByteString& name);\r
-CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, FX_BSTR name)\r
-{\r
-    CFX_ByteString fontname(name);\r
-    int font_id = _PDF_GetStandardFontName(fontname);\r
-    if (font_id < 0) {\r
-        return NULL;\r
-    }\r
-    CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();\r
-    CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);\r
-    if (pFont) {\r
-        return pFont;\r
-    }\r
-    CPDF_Dictionary* pDict = CPDF_Dictionary::Create();\r
-    pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font"));\r
-    pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1"));\r
-    pDict->SetAtName(FX_BSTRC("BaseFont"), fontname);\r
-    pDict->SetAtName(FX_BSTRC("Encoding"), FX_BSTRC("WinAnsiEncoding"));\r
-    pFont = CPDF_Font::CreateFontF(NULL, pDict);\r
-    pFontGlobals->Set(pDoc, font_id, pFont);\r
-    return pFont;\r
-}\r
-const FX_BYTE ChineseFontNames[][5] = {\r
-    {0xCB, 0xCE, 0xCC, 0xE5, 0x00},\r
-    {0xBF, 0xAC, 0xCC, 0xE5, 0x00},\r
-    {0xBA, 0xDA, 0xCC, 0xE5, 0x00},\r
-    {0xB7, 0xC2, 0xCB, 0xCE, 0x00},\r
-    {0xD0, 0xC2, 0xCB, 0xCE, 0x00}\r
-};\r
-CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, CPDF_Dictionary* pFontDict)\r
-{\r
-    CFX_ByteString type = pFontDict->GetString(FX_BSTRC("Subtype"));\r
-    CPDF_Font* pFont;\r
-    if (type == FX_BSTRC("TrueType")) {\r
-        {\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_WINDOWS_ || _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_\r
-            CFX_ByteString basefont = pFontDict->GetString(FX_BSTRC("BaseFont"));\r
-            CFX_ByteString tag = basefont.Left(4);\r
-            int i;\r
-            int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);\r
-            for (i = 0; i < count; ++i) {\r
-                if (tag == CFX_ByteString((FX_LPCSTR)ChineseFontNames[i])) {\r
-                    break;\r
-                }\r
-            }\r
-            if (i < count) {\r
-                CPDF_Dictionary* pFontDesc = pFontDict->GetDict(FX_BSTRC("FontDescriptor"));\r
-                if (pFontDesc == NULL || !pFontDesc->KeyExist(FX_BSTRC("FontFile2"))) {\r
-                    pFont = FX_NEW CPDF_CIDFont;\r
-                    pFont->Initialize();\r
-                    pFont->m_FontType = PDFFONT_CIDFONT;\r
-                    pFont->m_pFontDict = pFontDict;\r
-                    pFont->m_pDocument = pDoc;\r
-                    if (!pFont->Load()) {\r
-                        delete pFont;\r
-                        return NULL;\r
-                    }\r
-                    return pFont;\r
-                }\r
-            }\r
-#endif\r
-        }\r
-        pFont = FX_NEW CPDF_TrueTypeFont;\r
-        pFont->Initialize();\r
-        pFont->m_FontType = PDFFONT_TRUETYPE;\r
-    } else if (type == FX_BSTRC("Type3")) {\r
-        pFont = FX_NEW CPDF_Type3Font;\r
-        pFont->Initialize();\r
-        pFont->m_FontType = PDFFONT_TYPE3;\r
-    } else if (type == FX_BSTRC("Type0")) {\r
-        pFont = FX_NEW CPDF_CIDFont;\r
-        pFont->Initialize();\r
-        pFont->m_FontType = PDFFONT_CIDFONT;\r
-    } else {\r
-        pFont = FX_NEW CPDF_Type1Font;\r
-        pFont->Initialize();\r
-        pFont->m_FontType = PDFFONT_TYPE1;\r
-    }\r
-    pFont->m_pFontDict = pFontDict;\r
-    pFont->m_pDocument = pDoc;\r
-    if (!pFont->Load()) {\r
-        delete pFont;\r
-        return NULL;\r
-    }\r
-    return pFont;\r
-}\r
-FX_BOOL CPDF_Font::Load()\r
-{\r
-    if (m_pFontDict == NULL) {\r
-        return FALSE;\r
-    }\r
-    CFX_ByteString type = m_pFontDict->GetString(FX_BSTRC("Subtype"));\r
-    m_BaseFont = m_pFontDict->GetString(FX_BSTRC("BaseFont"));\r
-    if (type == FX_BSTRC("MMType1")) {\r
-        type = FX_BSTRC("Type1");\r
-    }\r
-    return _Load();\r
-}\r
-static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap, const CFX_ByteString& bytestr)\r
-{\r
-    return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr);\r
-}\r
-static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap, const CFX_WideString& widestr)\r
-{\r
-    return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr);\r
-}\r
-CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont)\r
-{\r
-    m_GetByteString = _FontMap_GetByteString;\r
-    m_GetWideString = _FontMap_GetWideString;\r
-    m_pFont = pFont;\r
-}\r
-CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode)\r
-{\r
-    FX_DWORD value;\r
-    if (m_Map.Lookup(charcode, value)) {\r
-        FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff);\r
-        if (unicode != 0xffff) {\r
-            return unicode;\r
-        }\r
-        FX_LPCWSTR buf = m_MultiCharBuf.GetBuffer();\r
-        FX_DWORD buf_len = m_MultiCharBuf.GetLength();\r
-        if (buf == NULL || buf_len == 0) {\r
-            return CFX_WideString();\r
-        }\r
-        FX_DWORD index = value >> 16;\r
-        if (index >= buf_len) {\r
-            return CFX_WideString();\r
-        }\r
-        FX_DWORD len = buf[index];\r
-        if (index + len < index || index + len >= buf_len) {\r
-            return CFX_WideString();\r
-        }\r
-        return CFX_WideString(buf + index + 1, len);\r
-    }\r
-    if (m_pBaseMap) {\r
-        return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode);\r
-    }\r
-    return CFX_WideString();\r
-}\r
-FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode)\r
-{\r
-    FX_POSITION pos = m_Map.GetStartPosition();\r
-    while (pos) {\r
-        FX_DWORD key, value;\r
-        m_Map.GetNextAssoc(pos, key, value);\r
-        if ((FX_WCHAR)value == unicode) {\r
-            return key;\r
-        }\r
-    }\r
-    return 0;\r
-}\r
-static FX_DWORD _StringToCode(FX_BSTR str)\r
-{\r
-    FX_LPCSTR buf = str.GetCStr();\r
-    int len = str.GetLength();\r
-    if (len == 0) {\r
-        return 0;\r
-    }\r
-    int result = 0;\r
-    if (buf[0] == '<') {\r
-        for (int i = 1; i < len; i ++) {\r
-            int digit;\r
-            if (buf[i] >= '0' && buf[i] <= '9') {\r
-                digit = buf[i] - '0';\r
-            } else if (buf[i] >= 'a' && buf[i] <= 'f') {\r
-                digit = buf[i] - 'a' + 10;\r
-            } else if (buf[i] >= 'A' && buf[i] <= 'F') {\r
-                digit = buf[i] - 'A' + 10;\r
-            } else {\r
-                break;\r
-            }\r
-            result = result * 16 + digit;\r
-        }\r
-        return result;\r
-    } else {\r
-        for (int i = 0; i < len; i ++) {\r
-            if (buf[i] < '0' || buf[i] > '9') {\r
-                break;\r
-            }\r
-            result = result * 10 + buf[i] - '0';\r
-        }\r
-    }\r
-    return result;\r
-}\r
-static CFX_WideString _StringDataAdd(CFX_WideString str)\r
-{\r
-    CFX_WideString ret;\r
-    int len = str.GetLength();\r
-    FX_WCHAR value = 1;\r
-    for (int i = len - 1; i >= 0 ; --i) {\r
-        FX_WCHAR ch = str[i] + value;\r
-        if (ch < str[i]) {\r
-            ret.Insert(0, 0);\r
-        } else {\r
-            ret.Insert(0, ch);\r
-            value = 0;\r
-        }\r
-    }\r
-    if (value) {\r
-        ret.Insert(0, value);\r
-    }\r
-    return ret;\r
-}\r
-static CFX_WideString _StringToWideString(FX_BSTR str)\r
-{\r
-    FX_LPCSTR buf = str.GetCStr();\r
-    int len = str.GetLength();\r
-    if (len == 0) {\r
-        return CFX_WideString();\r
-    }\r
-    CFX_WideString result;\r
-    if (buf[0] == '<') {\r
-        int byte_pos = 0;\r
-        FX_WCHAR ch = 0;\r
-        for (int i = 1; i < len; i ++) {\r
-            int digit;\r
-            if (buf[i] >= '0' && buf[i] <= '9') {\r
-                digit = buf[i] - '0';\r
-            } else if (buf[i] >= 'a' && buf[i] <= 'f') {\r
-                digit = buf[i] - 'a' + 10;\r
-            } else if (buf[i] >= 'A' && buf[i] <= 'F') {\r
-                digit = buf[i] - 'A' + 10;\r
-            } else {\r
-                break;\r
-            }\r
-            ch = ch * 16 + digit;\r
-            byte_pos ++;\r
-            if (byte_pos == 4) {\r
-                result += ch;\r
-                byte_pos = 0;\r
-                ch = 0;\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-    if (buf[0] == '(') {\r
-    }\r
-    return result;\r
-}\r
-void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream)\r
-{\r
-    int CIDSet = 0;\r
-    CPDF_StreamAcc stream;\r
-    stream.LoadAllData(pStream, FALSE);\r
-    CPDF_SimpleParser parser(stream.GetData(), stream.GetSize());\r
-    m_Map.EstimateSize(stream.GetSize() / 8, 1024);\r
-    while (1) {\r
-        CFX_ByteStringC word = parser.GetWord();\r
-        if (word.IsEmpty()) {\r
-            break;\r
-        }\r
-        if (word == FX_BSTRC("beginbfchar")) {\r
-            while (1) {\r
-                word = parser.GetWord();\r
-                if (word.IsEmpty() || word == FX_BSTRC("endbfchar")) {\r
-                    break;\r
-                }\r
-                FX_DWORD srccode = _StringToCode(word);\r
-                word = parser.GetWord();\r
-                CFX_WideString destcode = _StringToWideString(word);\r
-                int len = destcode.GetLength();\r
-                if (len == 0) {\r
-                    continue;\r
-                }\r
-                if (len == 1) {\r
-                    m_Map.SetAt(srccode, destcode.GetAt(0));\r
-                } else {\r
-                    m_Map.SetAt(srccode, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);\r
-                    m_MultiCharBuf.AppendChar(destcode.GetLength());\r
-                    m_MultiCharBuf << destcode;\r
-                }\r
-            }\r
-        } else if (word == FX_BSTRC("beginbfrange")) {\r
-            while (1) {\r
-                CFX_ByteString low, high;\r
-                low = parser.GetWord();\r
-                if (low.IsEmpty() || low == FX_BSTRC("endbfrange")) {\r
-                    break;\r
-                }\r
-                high = parser.GetWord();\r
-                FX_DWORD lowcode = _StringToCode(low);\r
-                FX_DWORD highcode = (lowcode & 0xffffff00) | (_StringToCode(high) & 0xff);\r
-                if (highcode == (FX_DWORD) - 1) {\r
-                    break;\r
-                }\r
-                CFX_ByteString start = parser.GetWord();\r
-                if (start == FX_BSTRC("[")) {\r
-                    for (FX_DWORD code = lowcode; code <= highcode; code ++) {\r
-                        CFX_ByteString dest = parser.GetWord();\r
-                        CFX_WideString destcode = _StringToWideString(dest);\r
-                        int len = destcode.GetLength();\r
-                        if (len == 0) {\r
-                            continue;\r
-                        }\r
-                        if (len == 1) {\r
-                            m_Map.SetAt(code, destcode.GetAt(0));\r
-                        } else {\r
-                            m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);\r
-                            m_MultiCharBuf.AppendChar(destcode.GetLength());\r
-                            m_MultiCharBuf << destcode;\r
-                        }\r
-                    }\r
-                    parser.GetWord();\r
-                } else {\r
-                    CFX_WideString destcode = _StringToWideString(start);\r
-                    int len = destcode.GetLength();\r
-                    FX_DWORD value = 0;\r
-                    if (len == 1) {\r
-                        value = _StringToCode(start);\r
-                        for (FX_DWORD code = lowcode; code <= highcode; code ++) {\r
-                            m_Map.SetAt(code, value++);\r
-                        }\r
-                    } else {\r
-                        for (FX_DWORD code = lowcode; code <= highcode; code ++) {\r
-                            CFX_WideString retcode;\r
-                            if (code == lowcode) {\r
-                                retcode = destcode;\r
-                            } else {\r
-                                retcode = _StringDataAdd(destcode);\r
-                            }\r
-                            m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);\r
-                            m_MultiCharBuf.AppendChar(retcode.GetLength());\r
-                            m_MultiCharBuf << retcode;\r
-                            destcode = retcode;\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        } else if (word == FX_BSTRC("/Adobe-Korea1-UCS2")) {\r
-            CIDSet = CIDSET_KOREA1;\r
-        } else if (word == FX_BSTRC("/Adobe-Japan1-UCS2")) {\r
-            CIDSet = CIDSET_JAPAN1;\r
-        } else if (word == FX_BSTRC("/Adobe-CNS1-UCS2")) {\r
-            CIDSet = CIDSET_CNS1;\r
-        } else if (word == FX_BSTRC("/Adobe-GB1-UCS2")) {\r
-            CIDSet = CIDSET_GB1;\r
-        }\r
-    }\r
-    if (CIDSet) {\r
-        m_pBaseMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetCID2UnicodeMap(CIDSet, FALSE);\r
-    } else {\r
-        m_pBaseMap = NULL;\r
-    }\r
-}\r
-static FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value)\r
-{\r
-    if (value == FX_BSTRC("WinAnsiEncoding")) {\r
-        basemap = PDFFONT_ENCODING_WINANSI;\r
-    } else if (value == FX_BSTRC("MacRomanEncoding")) {\r
-        basemap = PDFFONT_ENCODING_MACROMAN;\r
-    } else if (value == FX_BSTRC("MacExpertEncoding")) {\r
-        basemap = PDFFONT_ENCODING_MACEXPERT;\r
-    } else if (value == FX_BSTRC("PDFDocEncoding")) {\r
-        basemap = PDFFONT_ENCODING_PDFDOC;\r
-    } else {\r
-        return FALSE;\r
-    }\r
-    return TRUE;\r
-}\r
-void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, int& iBaseEncoding, CFX_ByteString*& pCharNames,\r
-                                FX_BOOL bEmbedded, FX_BOOL bTrueType)\r
-{\r
-    if (pEncoding == NULL) {\r
-        if (m_BaseFont == FX_BSTRC("Symbol")) {\r
-            iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL : PDFFONT_ENCODING_ADOBE_SYMBOL;\r
-        } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {\r
-            iBaseEncoding = PDFFONT_ENCODING_WINANSI;\r
-        }\r
-        return;\r
-    }\r
-    if (pEncoding->GetType() == PDFOBJ_NAME) {\r
-        if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {\r
-            return;\r
-        }\r
-        if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == FX_BSTRC("Symbol")) {\r
-            if (!bTrueType) {\r
-                iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;\r
-            }\r
-            return;\r
-        }\r
-        CFX_ByteString bsEncoding = pEncoding->GetString();\r
-        if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0) {\r
-            bsEncoding = FX_BSTRC("WinAnsiEncoding");\r
-        }\r
-        GetPredefinedEncoding(iBaseEncoding, bsEncoding);\r
-        return;\r
-    }\r
-    if (pEncoding->GetType() != PDFOBJ_DICTIONARY) {\r
-        return;\r
-    }\r
-    CPDF_Dictionary* pDict = (CPDF_Dictionary*)pEncoding;\r
-    if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {\r
-        CFX_ByteString bsEncoding = pDict->GetString(FX_BSTRC("BaseEncoding"));\r
-        if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0 && bTrueType) {\r
-            bsEncoding = FX_BSTRC("WinAnsiEncoding");\r
-        }\r
-        GetPredefinedEncoding(iBaseEncoding, bsEncoding);\r
-    }\r
-    if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {\r
-        iBaseEncoding = PDFFONT_ENCODING_STANDARD;\r
-    }\r
-    CPDF_Array* pDiffs = pDict->GetArray(FX_BSTRC("Differences"));\r
-    if (pDiffs == NULL) {\r
-        return;\r
-    }\r
-    FX_NEW_VECTOR(pCharNames, CFX_ByteString, 256);\r
-    FX_DWORD cur_code = 0;\r
-    for (FX_DWORD i = 0; i < pDiffs->GetCount(); i ++) {\r
-        CPDF_Object* pElement = pDiffs->GetElementValue(i);\r
-        if (pElement == NULL) {\r
-            continue;\r
-        }\r
-        if (pElement->GetType() == PDFOBJ_NAME) {\r
-            if (cur_code < 256) {\r
-                pCharNames[cur_code] = ((CPDF_Name*)pElement)->GetString();\r
-            }\r
-            cur_code ++;\r
-        } else {\r
-            cur_code = pElement->GetInteger();\r
-        }\r
-    }\r
-}\r
-FX_BOOL CPDF_Font::IsStandardFont() const\r
-{\r
-    if (m_FontType != PDFFONT_TYPE1) {\r
-        return FALSE;\r
-    }\r
-    if (m_pFontFile != NULL) {\r
-        return FALSE;\r
-    }\r
-    if (((CPDF_Type1Font*)this)->GetBase14Font() < 0) {\r
-        return FALSE;\r
-    }\r
-    return TRUE;\r
-}\r
-extern FX_LPCSTR PDF_CharNameFromPredefinedCharSet(int encoding, FX_BYTE charcode);\r
-CPDF_SimpleFont::CPDF_SimpleFont()\r
-{\r
-    FXSYS_memset8(m_CharBBox, 0xff, sizeof m_CharBBox);\r
-    FXSYS_memset8(m_CharWidth, 0xff, sizeof m_CharWidth);\r
-    FXSYS_memset8(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);\r
-    FXSYS_memset8(m_ExtGID, 0xff, sizeof m_ExtGID);\r
-    m_pCharNames = NULL;\r
-    m_BaseEncoding = PDFFONT_ENCODING_BUILTIN;\r
-}\r
-CPDF_SimpleFont::~CPDF_SimpleFont()\r
-{\r
-    if (m_pCharNames) {\r
-        FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256);\r
-    }\r
-}\r
-int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL *pVertGlyph)\r
-{\r
-    if (pVertGlyph) {\r
-        *pVertGlyph = FALSE;\r
-    }\r
-    if (charcode > 0xff) {\r
-        return -1;\r
-    }\r
-    int index = m_GlyphIndex[(FX_BYTE)charcode];\r
-    if (index == 0xffff) {\r
-        return -1;\r
-    }\r
-    return index;\r
-}\r
-void CPDF_SimpleFont::LoadCharMetrics(int charcode)\r
-{\r
-    if (m_Font.m_Face == NULL) {\r
-        return;\r
-    }\r
-    if (charcode < 0 || charcode > 0xff) {\r
-        return;\r
-    }\r
-    int glyph_index = m_GlyphIndex[charcode];\r
-    if (glyph_index == 0xffff) {\r
-        if (m_pFontFile == NULL && charcode != 32) {\r
-            LoadCharMetrics(32);\r
-            m_CharBBox[charcode] = m_CharBBox[32];\r
-            if (m_bUseFontWidth) {\r
-                m_CharWidth[charcode] = m_CharWidth[32];\r
-            }\r
-        }\r
-        return;\r
-    }\r
-    int err = FXFT_Load_Glyph(m_Font.m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);\r
-    if (err) {\r
-        return;\r
-    }\r
-    m_CharBBox[charcode].Left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face), m_Font.m_Face);\r
-    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);\r
-    m_CharBBox[charcode].Top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face), m_Font.m_Face);\r
-    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);\r
-    if (m_bUseFontWidth) {\r
-        int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(m_Font.m_Face), m_Font.m_Face);\r
-        if (m_CharWidth[charcode] == 0xffff) {\r
-            m_CharWidth[charcode] = TT_Width;\r
-        } else if (TT_Width && !IsEmbedded()) {\r
-            m_CharBBox[charcode].Right = m_CharBBox[charcode].Right * m_CharWidth[charcode] / TT_Width;\r
-            m_CharBBox[charcode].Left = m_CharBBox[charcode].Left * m_CharWidth[charcode] / TT_Width;\r
-        }\r
-    }\r
-}\r
-int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level)\r
-{\r
-    if (charcode > 0xff) {\r
-        charcode = 0;\r
-    }\r
-    if (m_CharWidth[charcode] == 0xffff) {\r
-        LoadCharMetrics(charcode);\r
-        if (m_CharWidth[charcode] == 0xffff) {\r
-            m_CharWidth[charcode] = 0;\r
-        }\r
-    }\r
-    return (FX_INT16)m_CharWidth[charcode];\r
-}\r
-void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level)\r
-{\r
-    if (charcode > 0xff) {\r
-        charcode = 0;\r
-    }\r
-    if (m_CharBBox[charcode].Left == (FX_SHORT)0xffff) {\r
-        LoadCharMetrics(charcode);\r
-    }\r
-    rect.left = m_CharBBox[charcode].Left;\r
-    rect.right = m_CharBBox[charcode].Right;\r
-    rect.bottom = m_CharBBox[charcode].Bottom;\r
-    rect.top = m_CharBBox[charcode].Top;\r
-}\r
-FX_LPCSTR GetAdobeCharName(int iBaseEncoding, const CFX_ByteString* pCharNames, int charcode)\r
-{\r
-    ASSERT(charcode >= 0 && charcode < 256);\r
-    if (charcode < 0 || charcode >= 256) {\r
-        return NULL;\r
-    }\r
-    FX_LPCSTR name = NULL;\r
-    if (pCharNames) {\r
-        name = pCharNames[charcode];\r
-    }\r
-    if ((name == NULL || name[0] == 0) && iBaseEncoding) {\r
-        name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);\r
-    }\r
-    if (name == NULL || name[0] == 0) {\r
-        return NULL;\r
-    }\r
-    return name;\r
-}\r
-FX_BOOL CPDF_SimpleFont::LoadCommon()\r
-{\r
-    CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor"));\r
-    if (pFontDesc) {\r
-        LoadFontDescriptor(pFontDesc);\r
-    }\r
-    CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths"));\r
-    int width_start = 0, width_end = -1;\r
-    m_bUseFontWidth = TRUE;\r
-    if (pWidthArray) {\r
-        m_bUseFontWidth = FALSE;\r
-        if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("MissingWidth"))) {\r
-            int MissingWidth = pFontDesc->GetInteger(FX_BSTRC("MissingWidth"));\r
-            for (int i = 0; i < 256; i ++) {\r
-                m_CharWidth[i] = MissingWidth;\r
-            }\r
-        }\r
-        width_start = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"), 0);\r
-        width_end = m_pFontDict->GetInteger(FX_BSTRC("LastChar"), 0);\r
-        if (width_start >= 0 && width_start <= 255) {\r
-            if (width_end <= 0 || width_end >= width_start + (int)pWidthArray->GetCount()) {\r
-                width_end = width_start + pWidthArray->GetCount() - 1;\r
-            }\r
-            if (width_end > 255) {\r
-                width_end = 255;\r
-            }\r
-            for (int i = width_start; i <= width_end; i ++) {\r
-                m_CharWidth[i] = pWidthArray->GetInteger(i - width_start);\r
-            }\r
-        }\r
-    }\r
-    if (m_pFontFile == NULL) {\r
-        LoadSubstFont();\r
-    } else {\r
-        if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') {\r
-            m_BaseFont = m_BaseFont.Mid(8);\r
-        }\r
-    }\r
-    if (!(m_Flags & PDFFONT_SYMBOLIC)) {\r
-        m_BaseEncoding = PDFFONT_ENCODING_STANDARD;\r
-    }\r
-    CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding"));\r
-    LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL, m_Font.IsTTFont());\r
-    LoadGlyphMap();\r
-    if (m_pCharNames) {\r
-        FX_DELETE_VECTOR(m_pCharNames, CFX_ByteString, 256);\r
-        m_pCharNames = NULL;\r
-    }\r
-    if (m_Font.m_Face == NULL) {\r
-        return TRUE;\r
-    }\r
-    if (m_Flags & PDFFONT_ALLCAP) {\r
-        unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};\r
-        for (int range = 0; range < sizeof lowercases / 2; range ++) {\r
-            for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i ++) {\r
-                if (m_GlyphIndex[i] != 0xffff && m_pFontFile != NULL) {\r
-                    continue;\r
-                }\r
-                m_GlyphIndex[i] = m_GlyphIndex[i - 32];\r
-                if (m_CharWidth[i - 32]) {\r
-                    m_CharWidth[i] = m_CharWidth[i - 32];\r
-                    m_CharBBox[i] = m_CharBBox[i - 32];\r
-                }\r
-            }\r
-        }\r
-    }\r
-    CheckFontMetrics();\r
-    return TRUE;\r
-}\r
-void CPDF_SimpleFont::LoadSubstFont()\r
-{\r
-    if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) {\r
-        int width = 0, i;\r
-        for (i = 0; i < 256; i ++) {\r
-            if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) {\r
-                continue;\r
-            }\r
-            if (width == 0) {\r
-                width = m_CharWidth[i];\r
-            } else if (width != m_CharWidth[i]) {\r
-                break;\r
-            }\r
-        }\r
-        if (i == 256 && width) {\r
-            m_Flags |= PDFFONT_FIXEDPITCH;\r
-        }\r
-    }\r
-    int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);\r
-    m_Font.LoadSubst(m_BaseFont, m_FontType == PDFFONT_TRUETYPE, m_Flags, weight, m_ItalicAngle, 0);\r
-    if (m_Font.m_pSubstFont->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {\r
-    }\r
-}\r
-FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const\r
-{\r
-    return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&\r
-           m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS;\r
-}\r
-CPDF_Type1Font::CPDF_Type1Font()\r
-{\r
-    m_Base14Font = -1;\r
-}\r
-FX_BOOL CPDF_Type1Font::_Load()\r
-{\r
-    m_Base14Font = _PDF_GetStandardFontName(m_BaseFont);\r
-    if (m_Base14Font >= 0) {\r
-        CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor"));\r
-        if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("Flags"))) {\r
-            m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"));\r
-        } else {\r
-            m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC;\r
-        }\r
-        if (m_Base14Font < 4)\r
-            for (int i = 0; i < 256; i ++) {\r
-                m_CharWidth[i] = 600;\r
-            }\r
-        if (m_Base14Font == 12) {\r
-            m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;\r
-        } else if (m_Base14Font == 13) {\r
-            m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;\r
-        } else if (m_Flags & PDFFONT_NONSYMBOLIC) {\r
-            m_BaseEncoding = PDFFONT_ENCODING_STANDARD;\r
-        }\r
-    }\r
-    return LoadCommon();\r
-}\r
-static FX_BOOL FT_UseType1Charmap(FXFT_Face face)\r
-{\r
-    if (FXFT_Get_Face_CharmapCount(face) == 0) {\r
-        return FALSE;\r
-    }\r
-    if (FXFT_Get_Face_CharmapCount(face) == 1 &&\r
-            FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) {\r
-        return FALSE;\r
-    }\r
-    if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) {\r
-        FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);\r
-    } else {\r
-        FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);\r
-    }\r
-    return TRUE;\r
-}\r
-extern FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode);\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-#include "../../fxge/apple/apple_int.h"\r
-#endif\r
-int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode)\r
-{\r
-    if (charcode > 0xff) {\r
-        return -1;\r
-    }\r
-    int index = m_ExtGID[(FX_BYTE)charcode];\r
-    if (index == 0xffff) {\r
-        return -1;\r
-    }\r
-    return index;\r
-}\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-struct _GlyphNameMap {\r
-    FX_LPCSTR m_pStrAdobe;\r
-    FX_LPCSTR m_pStrUnicode;\r
-};\r
-static const _GlyphNameMap g_GlyphNameSubsts[] = {\r
-    {"ff", "uniFB00"},\r
-    {"fi", "uniFB01"},\r
-    {"fl", "uniFB02"},\r
-    {"ffi", "uniFB03"},\r
-    {"ffl", "uniFB04"}\r
-};\r
-extern "C" {\r
-    static int compareString(const void* key, const void* element)\r
-    {\r
-        return FXSYS_stricmp((FX_LPCSTR)key, ((_GlyphNameMap*)element)->m_pStrAdobe);\r
-    }\r
-}\r
-static FX_LPCSTR _GlyphNameRemap(FX_LPCSTR pStrAdobe)\r
-{\r
-    _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch(pStrAdobe, g_GlyphNameSubsts,\r
-                           sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), sizeof(_GlyphNameMap),\r
-                           compareString);\r
-    if (found) {\r
-        return found->m_pStrUnicode;\r
-    }\r
-    return NULL;\r
-}\r
-#endif\r
-void CPDF_Type1Font::LoadGlyphMap()\r
-{\r
-    if (m_Font.m_Face == NULL) {\r
-        return;\r
-    }\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-    FX_BOOL bCoreText = TRUE;\r
-    CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;\r
-    if (!m_Font.m_pPlatformFont) {\r
-        if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {\r
-            bCoreText = FALSE;\r
-        }\r
-        m_Font.m_pPlatformFont = quartz2d.CreateFont(m_Font.m_pFontData, m_Font.m_dwSize);\r
-        if (NULL == m_Font.m_pPlatformFont) {\r
-            bCoreText = FALSE;\r
-        }\r
-    }\r
-#endif\r
-    if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {\r
-        if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {\r
-            FX_BOOL bGotOne = FALSE;\r
-            for (int charcode = 0; charcode < 256; charcode ++) {\r
-                const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};\r
-                for (int j = 0; j < 4; j ++) {\r
-                    FX_WORD unicode = prefix[j] * 256 + charcode;\r
-                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-                    FX_CHAR name_glyph[256];\r
-                    FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);\r
-                    name_glyph[255] = 0;\r
-                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);\r
-                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);\r
-                    if (name_ct) {\r
-                        CFRelease(name_ct);\r
-                    }\r
-#endif\r
-                    if (m_GlyphIndex[charcode]) {\r
-                        bGotOne = TRUE;\r
-                        break;\r
-                    }\r
-                }\r
-            }\r
-            if (bGotOne) {\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-                if (!bCoreText) {\r
-                    FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);\r
-                }\r
-#endif\r
-                return;\r
-            }\r
-        }\r
-        FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE);\r
-        if (m_BaseEncoding == 0) {\r
-            m_BaseEncoding = PDFFONT_ENCODING_STANDARD;\r
-        }\r
-        for (int charcode = 0; charcode < 256; charcode ++) {\r
-            FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);\r
-            if (name == NULL) {\r
-                continue;\r
-            }\r
-            m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);\r
-            m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-            FX_CHAR name_glyph[256];\r
-            FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);\r
-            name_glyph[255] = 0;\r
-            CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);\r
-            m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);\r
-            if (name_ct) {\r
-                CFRelease(name_ct);\r
-            }\r
-#endif\r
-            if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) {\r
-                m_Encoding.m_Unicodes[charcode] = 0x20;\r
-                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 0x20);\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-                FX_CHAR name_glyph[256];\r
-                FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);\r
-                name_glyph[255] = 0;\r
-                CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);\r
-                m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);\r
-                if (name_ct) {\r
-                    CFRelease(name_ct);\r
-                }\r
-#endif\r
-            }\r
-        }\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-        if (!bCoreText) {\r
-            FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);\r
-        }\r
-#endif\r
-        return;\r
-    }\r
-    FT_UseType1Charmap(m_Font.m_Face);\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-    if (bCoreText) {\r
-        if (m_Flags & PDFFONT_SYMBOLIC) {\r
-            for (int charcode = 0; charcode < 256; charcode ++) {\r
-                FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);\r
-                if (name) {\r
-                    m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);\r
-                    m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);\r
-                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);\r
-                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);\r
-                    if (name_ct) {\r
-                        CFRelease(name_ct);\r
-                    }\r
-                } else {\r
-                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);\r
-                    FX_WCHAR unicode = 0;\r
-                    if (m_GlyphIndex[charcode]) {\r
-                        unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);\r
-                    }\r
-                    FX_CHAR name_glyph[256];\r
-                    FXSYS_memset32(name_glyph, 0, sizeof(name_glyph));\r
-                    FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);\r
-                    name_glyph[255] = 0;\r
-                    if (unicode == 0 && name_glyph[0] != 0) {\r
-                        unicode = PDF_UnicodeFromAdobeName(name_glyph);\r
-                    }\r
-                    m_Encoding.m_Unicodes[charcode] = unicode;\r
-                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);\r
-                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);\r
-                    if (name_ct) {\r
-                        CFRelease(name_ct);\r
-                    }\r
-                }\r
-            }\r
-            return;\r
-        }\r
-        FX_BOOL bUnicode = FALSE;\r
-        if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) {\r
-            bUnicode = TRUE;\r
-        }\r
-        for (int charcode = 0; charcode < 256; charcode ++) {\r
-            FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);\r
-            if (name == NULL) {\r
-                continue;\r
-            }\r
-            m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);\r
-            FX_LPCSTR pStrUnicode = _GlyphNameRemap(name);\r
-            if (pStrUnicode && 0 == FXFT_Get_Name_Index(m_Font.m_Face, (char*)name)) {\r
-                name = pStrUnicode;\r
-            }\r
-            m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);\r
-            CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);\r
-            m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);\r
-            if (name_ct) {\r
-                CFRelease(name_ct);\r
-            }\r
-            if (m_GlyphIndex[charcode] == 0) {\r
-                if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) {\r
-                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);\r
-                    FX_CHAR name_glyph[256];\r
-                    FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);\r
-                    name_glyph[255] = 0;\r
-                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);\r
-                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);\r
-                    if (name_ct) {\r
-                        CFRelease(name_ct);\r
-                    }\r
-                } else {\r
-                    m_Encoding.m_Unicodes[charcode] = 0x20;\r
-                    m_GlyphIndex[charcode] = bUnicode ? FXFT_Get_Char_Index(m_Font.m_Face, 0x20) : 0xffff;\r
-                    FX_CHAR name_glyph[256];\r
-                    FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);\r
-                    name_glyph[255] = 0;\r
-                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);\r
-                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);\r
-                    if (name_ct) {\r
-                        CFRelease(name_ct);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return;\r
-    }\r
-#endif\r
-    if (m_Flags & PDFFONT_SYMBOLIC) {\r
-        for (int charcode = 0; charcode < 256; charcode ++) {\r
-            FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);\r
-            if (name) {\r
-                m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);\r
-                m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);\r
-            } else {\r
-                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);\r
-                if (m_GlyphIndex[charcode]) {\r
-                    FX_WCHAR unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);\r
-                    if (unicode == 0) {\r
-                        FX_CHAR name_glyph[256];\r
-                        FXSYS_memset32(name_glyph, 0, sizeof(name_glyph));\r
-                        FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);\r
-                        name_glyph[255] = 0;\r
-                        if (name_glyph[0] != 0) {\r
-                            unicode = PDF_UnicodeFromAdobeName(name_glyph);\r
-                        }\r
-                    }\r
-                    m_Encoding.m_Unicodes[charcode] = unicode;\r
-                }\r
-            }\r
-        }\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-        if (!bCoreText) {\r
-            FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);\r
-        }\r
-#endif\r
-        return;\r
-    }\r
-    FX_BOOL bUnicode = FALSE;\r
-    if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) {\r
-        bUnicode = TRUE;\r
-    }\r
-    for (int charcode = 0; charcode < 256; charcode ++) {\r
-        FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);\r
-        if (name == NULL) {\r
-            continue;\r
-        }\r
-        m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);\r
-        m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);\r
-        if (m_GlyphIndex[charcode] == 0) {\r
-            if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) {\r
-                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);\r
-            } else {\r
-                m_Encoding.m_Unicodes[charcode] = 0x20;\r
-                m_GlyphIndex[charcode] = 0xffff;\r
-            }\r
-        }\r
-    }\r
-#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_\r
-    if (!bCoreText) {\r
-        FXSYS_memcpy32(m_ExtGID, m_GlyphIndex, 256);\r
-    }\r
-#endif\r
-}\r
-CPDF_FontEncoding::CPDF_FontEncoding()\r
-{\r
-    FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes));\r
-}\r
-int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const\r
-{\r
-    for (int i = 0; i < 256; i ++)\r
-        if (m_Unicodes[i] == unicode) {\r
-            return i;\r
-        }\r
-    return -1;\r
-}\r
-CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding)\r
-{\r
-    const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);\r
-    if (!pSrc) {\r
-        FXSYS_memset32(m_Unicodes, 0, sizeof(m_Unicodes));\r
-    } else\r
-        for (int i = 0; i < 256; i++) {\r
-            m_Unicodes[i] = pSrc[i];\r
-        }\r
-}\r
-FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const\r
-{\r
-    return FXSYS_memcmp32(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) == 0;\r
-}\r
-CPDF_Object* CPDF_FontEncoding::Realize()\r
-{\r
-    int predefined = 0;\r
-    for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; cs ++) {\r
-        const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs);\r
-        FX_BOOL match = TRUE;\r
-        for (int i = 0; i < 256; ++i) {\r
-            if (m_Unicodes[i] != pSrc[i]) {\r
-                match = FALSE;\r
-                break;\r
-            }\r
-        }\r
-        if (match) {\r
-            predefined = cs;\r
-            break;\r
-        }\r
-    }\r
-    if (predefined) {\r
-        if (predefined == PDFFONT_ENCODING_WINANSI) {\r
-            return CPDF_Name::Create("WinAnsiEncoding");\r
-        }\r
-        if (predefined == PDFFONT_ENCODING_MACROMAN) {\r
-            return CPDF_Name::Create("MacRomanEncoding");\r
-        }\r
-        if (predefined == PDFFONT_ENCODING_MACEXPERT) {\r
-            return CPDF_Name::Create("MacExpertEncoding");\r
-        }\r
-        return NULL;\r
-    }\r
-    CPDF_Dictionary* pDict = CPDF_Dictionary::Create();\r
-    pDict->SetAtName(FX_BSTRC("BaseEncoding"), FX_BSTRC("WinAnsiEncoding"));\r
-    const FX_WORD* pStandard = PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);\r
-    CPDF_Array* pDiff = CPDF_Array::Create();\r
-    for (int i = 0; i < 256; i ++) {\r
-        if (pStandard[i] == m_Unicodes[i]) {\r
-            continue;\r
-        }\r
-        pDiff->Add(CPDF_Number::Create(i));\r
-        pDiff->Add(CPDF_Name::Create(PDF_AdobeNameFromUnicode(m_Unicodes[i])));\r
-    }\r
-    pDict->SetAt(FX_BSTRC("Differences"), pDiff);\r
-    return pDict;\r
-}\r
-CPDF_TrueTypeFont::CPDF_TrueTypeFont()\r
-{\r
-}\r
-FX_BOOL CPDF_TrueTypeFont::_Load()\r
-{\r
-    return LoadCommon();\r
-}\r
-extern FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode);\r
-void CPDF_TrueTypeFont::LoadGlyphMap()\r
-{\r
-    if (m_Font.m_Face == NULL) {\r
-        return;\r
-    }\r
-    int baseEncoding = m_BaseEncoding;\r
-    if (m_pFontFile && m_Font.m_Face->num_charmaps > 0\r
-            && (baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI)\r
-            && (m_Flags & PDFFONT_SYMBOLIC)) {\r
-        FX_BOOL bSupportWin = FALSE;\r
-        FX_BOOL bSupportMac = FALSE;\r
-        for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.m_Face); i++) {\r
-            int platform_id = FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]);\r
-            if (platform_id == 0 || platform_id == 3) {\r
-                bSupportWin = TRUE;\r
-            } else if (platform_id == 0 || platform_id == 1) {\r
-                bSupportMac = TRUE;\r
-            }\r
-        }\r
-        if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) {\r
-            baseEncoding = bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN;\r
-        } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) {\r
-            baseEncoding = bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN;\r
-        }\r
-    }\r
-    if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI)\r
-            && m_pCharNames == NULL) || (m_Flags & PDFFONT_NONSYMBOLIC)) {\r
-        if (!FXFT_Has_Glyph_Names(m_Font.m_Face) && (!m_Font.m_Face->num_charmaps || !m_Font.m_Face->charmaps)) {\r
-            int nStartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"));\r
-            int charcode = 0;\r
-            for (; charcode < nStartChar; charcode ++) {\r
-                m_GlyphIndex[charcode] = 0;\r
-            }\r
-            FX_WORD nGlyph = charcode - nStartChar + 3;\r
-            for (; charcode < 256; charcode ++, nGlyph ++) {\r
-                m_GlyphIndex[charcode] = nGlyph;\r
-            }\r
-            return;\r
-        }\r
-        FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.m_Face, 3, 1);\r
-        FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE;\r
-        if (!bMSUnicode) {\r
-            if (m_Flags & PDFFONT_NONSYMBOLIC) {\r
-                bMacRoman = FT_UseTTCharmap(m_Font.m_Face, 1, 0);\r
-                bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.m_Face, 3, 0);\r
-            } else {\r
-                bMSSymbol = FT_UseTTCharmap(m_Font.m_Face, 3, 0);\r
-                bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.m_Face, 1, 0);\r
-            }\r
-        }\r
-        FX_BOOL bToUnicode = m_pFontDict->KeyExist(FX_BSTRC("ToUnicode"));\r
-        for (int charcode = 0; charcode < 256; charcode ++) {\r
-            FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode);\r
-            if (name == NULL) {\r
-                m_GlyphIndex[charcode] = m_pFontFile ? FXFT_Get_Char_Index(m_Font.m_Face, charcode) : -1;\r
-                continue;\r
-            }\r
-            m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);\r
-            if (bMSSymbol) {\r
-                const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};\r
-                for (int j = 0; j < 4; j ++) {\r
-                    FX_WORD unicode = prefix[j] * 256 + charcode;\r
-                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);\r
-                    if (m_GlyphIndex[charcode]) {\r
-                        break;\r
-                    }\r
-                }\r
-            } else if (m_Encoding.m_Unicodes[charcode]) {\r
-                if (bMSUnicode) {\r
-                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);\r
-                } else if (bMacRoman) {\r
-                    FX_DWORD maccode = FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]);\r
-                    if (!maccode) {\r
-                        m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char *)name);\r
-                    } else {\r
-                        m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, maccode);\r
-                    }\r
-                }\r
-            }\r
-            if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && name != NULL) {\r
-                if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) {\r
-                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 32);\r
-                } else {\r
-                    m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);\r
-                    if (m_GlyphIndex[charcode] == 0) {\r
-                        if (bToUnicode) {\r
-                            CFX_WideString wsUnicode = UnicodeFromCharCode(charcode);\r
-                            if (!wsUnicode.IsEmpty()) {\r
-                                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, wsUnicode[0]);\r
-                                m_Encoding.m_Unicodes[charcode] = wsUnicode[0];\r
-                            }\r
-                        }\r
-                        if (m_GlyphIndex[charcode] == 0) {\r
-                            m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return;\r
-    }\r
-    if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {\r
-        const FX_BYTE prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};\r
-        FX_BOOL bGotOne = FALSE;\r
-        for (int charcode = 0; charcode < 256; charcode ++) {\r
-            for (int j = 0; j < 4; j ++) {\r
-                FX_WORD unicode = prefix[j] * 256 + charcode;\r
-                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);\r
-                if (m_GlyphIndex[charcode]) {\r
-                    bGotOne = TRUE;\r
-                    break;\r
-                }\r
-            }\r
-        }\r
-        if (bGotOne) {\r
-            if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {\r
-                for (int charcode = 0; charcode < 256; charcode ++) {\r
-                    FX_LPCSTR name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode);\r
-                    if (name == NULL) {\r
-                        continue;\r
-                    }\r
-                    m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);\r
-                }\r
-            } else if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) {\r
-                for (int charcode = 0; charcode < 256; charcode ++) {\r
-                    m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);\r
-                }\r
-            }\r
-            return;\r
-        }\r
-    }\r
-    if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) {\r
-        FX_BOOL bGotOne = FALSE;\r
-        for (int charcode = 0; charcode < 256; charcode ++) {\r
-            m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);\r
-            m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);\r
-            if (m_GlyphIndex[charcode]) {\r
-                bGotOne = TRUE;\r
-            }\r
-        }\r
-        if (m_pFontFile || bGotOne) {\r
-            return;\r
-        }\r
-    }\r
-    if (FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE) == 0) {\r
-        FX_BOOL bGotOne = FALSE;\r
-        const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding);\r
-        for (int charcode = 0; charcode < 256; charcode ++) {\r
-            if (m_pFontFile == NULL) {\r
-                FX_LPCSTR name = GetAdobeCharName(0, m_pCharNames, charcode);\r
-                if (name != NULL) {\r
-                    m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);\r
-                } else if (pUnicodes) {\r
-                    m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode];\r
-                }\r
-            } else {\r
-                m_Encoding.m_Unicodes[charcode] = charcode;\r
-            }\r
-            m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);\r
-            if (m_GlyphIndex[charcode]) {\r
-                bGotOne = TRUE;\r
-            }\r
-        }\r
-        if (bGotOne) {\r
-            return;\r
-        }\r
-    }\r
-    for (int charcode = 0; charcode < 256; charcode ++) {\r
-        m_GlyphIndex[charcode] = charcode;\r
-    }\r
-}\r
-CPDF_Type3Font::CPDF_Type3Font()\r
-{\r
-    m_pPageResources = NULL;\r
-    FXSYS_memset32(m_CharWidthL, 0, sizeof m_CharWidthL);\r
-}\r
-CPDF_Type3Font::~CPDF_Type3Font()\r
-{\r
-    FX_POSITION pos = m_CacheMap.GetStartPosition();\r
-    while (pos) {\r
-        FX_LPVOID key, value;\r
-        m_CacheMap.GetNextAssoc(pos, key, value);\r
-        delete (CPDF_Type3Char*)value;\r
-    }\r
-    m_CacheMap.RemoveAll();\r
-    pos = m_DeletedMap.GetStartPosition();\r
-    while (pos) {\r
-        FX_LPVOID key, value;\r
-        m_DeletedMap.GetNextAssoc(pos, key, value);\r
-        delete (CPDF_Type3Char*)key;\r
-    }\r
-}\r
-FX_BOOL CPDF_Type3Font::_Load()\r
-{\r
-    m_pFontResources = m_pFontDict->GetDict(FX_BSTRC("Resources"));\r
-    CPDF_Array* pMatrix = m_pFontDict->GetArray(FX_BSTRC("FontMatrix"));\r
-    FX_FLOAT xscale = 1.0f, yscale = 1.0f;\r
-    if (pMatrix) {\r
-        m_FontMatrix = pMatrix->GetMatrix();\r
-        xscale = m_FontMatrix.a;\r
-        yscale = m_FontMatrix.d;\r
-    }\r
-    CPDF_Array* pBBox = m_pFontDict->GetArray(FX_BSTRC("FontBBox"));\r
-    if (pBBox) {\r
-        m_FontBBox.left = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000);\r
-        m_FontBBox.bottom = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000);\r
-        m_FontBBox.right = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000);\r
-        m_FontBBox.top = (FX_INT32)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 1000);\r
-    }\r
-    int StartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"));\r
-    CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths"));\r
-    if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {\r
-        FX_DWORD count = pWidthArray->GetCount();\r
-        if (count > 256) {\r
-            count = 256;\r
-        }\r
-        if (StartChar + count > 256) {\r
-            count = 256 - StartChar;\r
-        }\r
-        for (FX_DWORD i = 0; i < count; i ++) {\r
-            m_CharWidthL[StartChar + i] = FXSYS_round(FXSYS_Mul(pWidthArray->GetNumber(i), xscale) * 1000);\r
-        }\r
-    }\r
-    m_pCharProcs = m_pFontDict->GetDict(FX_BSTRC("CharProcs"));\r
-    CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding"));\r
-    if (pEncoding) {\r
-        LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);\r
-        if (m_pCharNames) {\r
-            for (int i = 0; i < 256; i ++) {\r
-                m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);\r
-                if (m_Encoding.m_Unicodes[i] == 0) {\r
-                    m_Encoding.m_Unicodes[i] = i;\r
-                }\r
-            }\r
-        }\r
-    }\r
-    return TRUE;\r
-}\r
-void CPDF_Type3Font::CheckType3FontMetrics()\r
-{\r
-    CheckFontMetrics();\r
-}\r
-CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level)\r
-{\r
-    if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_) {\r
-        return NULL;\r
-    }\r
-    CPDF_Type3Char* pChar = NULL;\r
-    if (m_CacheMap.Lookup((FX_LPVOID)(FX_UINTPTR)charcode, (FX_LPVOID&)pChar)) {\r
-        if (pChar->m_bPageRequired && m_pPageResources) {\r
-            delete pChar;\r
-            m_CacheMap.RemoveKey((FX_LPVOID)(FX_UINTPTR)charcode);\r
-            return LoadChar(charcode, level + 1);\r
-        }\r
-        return pChar;\r
-    }\r
-    FX_LPCSTR name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);\r
-    if (name == NULL) {\r
-        return NULL;\r
-    }\r
-    CPDF_Stream* pStream = (CPDF_Stream*)m_pCharProcs->GetElementValue(name);\r
-    if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {\r
-        return NULL;\r
-    }\r
-    pChar = FX_NEW CPDF_Type3Char;\r
-    pChar->m_pForm = FX_NEW CPDF_Form(m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources, pStream, NULL);\r
-    pChar->m_pForm->ParseContent(NULL, NULL, pChar, NULL, level + 1);\r
-    FX_FLOAT scale = m_FontMatrix.GetXUnit();\r
-    pChar->m_Width = (FX_INT32)(pChar->m_Width * scale + 0.5f);\r
-    FX_RECT &rcBBox = pChar->m_BBox;\r
-    CFX_FloatRect char_rect((FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,\r
-                            (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);\r
-    if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) {\r
-        char_rect = pChar->m_pForm->CalcBoundingBox();\r
-    }\r
-    char_rect.Transform(&m_FontMatrix);\r
-    rcBBox.left = FXSYS_round(char_rect.left * 1000);\r
-    rcBBox.right = FXSYS_round(char_rect.right * 1000);\r
-    rcBBox.top = FXSYS_round(char_rect.top * 1000);\r
-    rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);\r
-    m_CacheMap.SetAt((FX_LPVOID)(FX_UINTPTR)charcode, pChar);\r
-    if (pChar->m_pForm->CountObjects() == 0) {\r
-        delete pChar->m_pForm;\r
-        pChar->m_pForm = NULL;\r
-    }\r
-    return pChar;\r
-}\r
-int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level)\r
-{\r
-    if (charcode > 0xff) {\r
-        charcode = 0;\r
-    }\r
-    if (m_CharWidthL[charcode]) {\r
-        return m_CharWidthL[charcode];\r
-    }\r
-    CPDF_Type3Char* pChar = LoadChar(charcode, level);\r
-    if (pChar == NULL) {\r
-        return 0;\r
-    }\r
-    return pChar->m_Width;\r
-}\r
-void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level)\r
-{\r
-    CPDF_Type3Char* pChar = LoadChar(charcode, level);\r
-    if (pChar == NULL) {\r
-        rect.left = rect.right = rect.top = rect.bottom = 0;\r
-        return;\r
-    }\r
-    rect = pChar->m_BBox;\r
-}\r
-CPDF_Type3Char::CPDF_Type3Char()\r
-{\r
-    m_pForm = NULL;\r
-    m_pBitmap = NULL;\r
-    m_bPageRequired = FALSE;\r
-    m_bColored = FALSE;\r
-}\r
-CPDF_Type3Char::~CPDF_Type3Char()\r
-{\r
-    if (m_pForm) {\r
-        delete m_pForm;\r
-    }\r
-    if (m_pBitmap) {\r
-        delete m_pBitmap;\r
-    }\r
-}\r
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fpdfapi/fpdf_page.h"
+#include "../../../include/fpdfapi/fpdf_module.h"
+#include "../../../include/fpdfapi/fpdf_pageobj.h"
+#include "font_int.h"
+#include "../fpdf_page/pageint.h"
+#include "../../../include/fxge/fx_freetype.h"
+
+FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id)
+{
+    for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i ++) {
+        if (FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(face)[i]) == platform_id &&
+                FXFT_Get_Charmap_EncodingID(FXFT_Get_Face_Charmaps(face)[i]) == encoding_id) {
+            FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+extern const FX_WORD* PDF_UnicodesForPredefinedCharSet(int);
+CPDF_FontGlobals::CPDF_FontGlobals()
+    : m_pContrastRamps(NULL)
+{
+    FXSYS_memset(m_EmbeddedCharsets, 0, sizeof(m_EmbeddedCharsets));
+    FXSYS_memset(m_EmbeddedToUnicodes, 0, sizeof(m_EmbeddedToUnicodes));
+}
+CPDF_FontGlobals::~CPDF_FontGlobals()
+{
+    ClearAll();
+    if (m_pContrastRamps) {
+        FX_Free(m_pContrastRamps);
+    }
+}
+class CFX_StockFontArray
+{
+public:
+    CFX_StockFontArray()
+    {
+        FXSYS_memset(m_pStockFonts, 0, sizeof(m_pStockFonts));
+    }
+    ~CFX_StockFontArray()
+    {
+        for (int i = 0; i < FX_ArraySize(m_pStockFonts); i++) {
+            if (!m_pStockFonts[i])
+                continue;
+            CPDF_Dictionary* pFontDict = m_pStockFonts[i]->GetFontDict();
+            if (pFontDict)
+                pFontDict->Release();
+            delete m_pStockFonts[i];
+        }
+    }
+    CPDF_Font* GetFont(int index) const
+    {
+        if (index < 0 || index >= FX_ArraySize(m_pStockFonts))
+            return NULL;
+        return m_pStockFonts[index];
+    }
+    void SetFont(int index, CPDF_Font* font)
+    {
+        if (index < 0 || index >= FX_ArraySize(m_pStockFonts))
+            return;
+        delete m_pStockFonts[index];
+        m_pStockFonts[index] = font;
+    }
+private:
+    CPDF_Font* m_pStockFonts[14];
+};
+CPDF_Font* CPDF_FontGlobals::Find(void* key, int index)
+{
+    void* value = NULL;
+    if (!m_pStockMap.Lookup(key, value)) {
+        return NULL;
+    }
+    if (!value) {
+        return NULL;
+    }
+    return static_cast<CFX_StockFontArray*>(value)->GetFont(index);
+}
+void CPDF_FontGlobals::Set(void* key, int index, CPDF_Font* pFont)
+{
+    void* value = NULL;
+    CFX_StockFontArray* font_array = NULL;
+    if (m_pStockMap.Lookup(key, value)) {
+        font_array = static_cast<CFX_StockFontArray*>(value);
+    } else {
+        font_array = new CFX_StockFontArray();
+        m_pStockMap.SetAt(key, font_array);
+    }
+    font_array->SetFont(index, pFont);
+}
+void CPDF_FontGlobals::Clear(void* key)
+{
+    void* value = NULL;
+    if (!m_pStockMap.Lookup(key, value)) {
+        return;
+    }
+    delete static_cast<CFX_StockFontArray*>(value);
+    m_pStockMap.RemoveKey(key);
+}
+void CPDF_FontGlobals::ClearAll()
+{
+    FX_POSITION pos = m_pStockMap.GetStartPosition();
+    while (pos) {
+        void* key = NULL;
+        void* value = NULL;
+        m_pStockMap.GetNextAssoc(pos, key, value);
+        delete static_cast<CFX_StockFontArray*>(value);
+        m_pStockMap.RemoveKey(key);
+    }
+}
+CPDF_Font::CPDF_Font(int fonttype) : m_FontType(fonttype)
+{
+    m_FontBBox.left = m_FontBBox.right = m_FontBBox.top = m_FontBBox.bottom = 0;
+    m_StemV = m_Ascent = m_Descent = m_ItalicAngle = 0;
+    m_pFontFile = NULL;
+    m_Flags = 0;
+    m_pToUnicodeMap = NULL;
+    m_bToUnicodeLoaded = FALSE;
+    m_pCharMap = new CPDF_FontCharMap(this);
+}
+CPDF_Font::~CPDF_Font()
+{
+    delete m_pCharMap;
+    m_pCharMap = NULL;
+
+    delete m_pToUnicodeMap;
+    m_pToUnicodeMap = NULL;
+
+    if (m_pFontFile) {
+        m_pDocument->GetPageData()->ReleaseFontFileStreamAcc((CPDF_Stream*)m_pFontFile->GetStream());
+    }
+}
+FX_BOOL CPDF_Font::IsVertWriting() const
+{
+    FX_BOOL bVertWriting = FALSE;
+    CPDF_CIDFont* pCIDFont = GetCIDFont();
+    if (pCIDFont) {
+        bVertWriting = pCIDFont->IsVertWriting();
+    } else {
+        bVertWriting = m_Font.IsVertical();
+    }
+    return bVertWriting;
+}
+CFX_ByteString CPDF_Font::GetFontTypeName() const
+{
+    switch (m_FontType) {
+        case PDFFONT_TYPE1:
+            return FX_BSTRC("Type1");
+        case PDFFONT_TRUETYPE:
+            return FX_BSTRC("TrueType");
+        case PDFFONT_TYPE3:
+            return FX_BSTRC("Type3");
+        case PDFFONT_CIDFONT:
+            return FX_BSTRC("Type0");
+    }
+    return CFX_ByteString();
+}
+void CPDF_Font::AppendChar(CFX_ByteString& str, FX_DWORD charcode) const
+{
+    char buf[4];
+    int len = AppendChar(buf, charcode);
+    if (len == 1) {
+        str += buf[0];
+    } else {
+        str += CFX_ByteString(buf, len);
+    }
+}
+CFX_WideString CPDF_Font::UnicodeFromCharCode(FX_DWORD charcode) const
+{
+    if (!m_bToUnicodeLoaded) {
+        ((CPDF_Font*)this)->LoadUnicodeMap();
+    }
+    if (m_pToUnicodeMap) {
+        CFX_WideString wsRet = m_pToUnicodeMap->Lookup(charcode);
+        if (!wsRet.IsEmpty()) {
+            return wsRet;
+        }
+    }
+    FX_WCHAR unicode = _UnicodeFromCharCode(charcode);
+    if (unicode == 0) {
+        return CFX_WideString();
+    }
+    return unicode;
+}
+FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const
+{
+    if (!m_bToUnicodeLoaded) {
+        ((CPDF_Font*)this)->LoadUnicodeMap();
+    }
+    if (m_pToUnicodeMap) {
+        FX_DWORD charcode = m_pToUnicodeMap->ReverseLookup(unicode);
+        if (charcode) {
+            return charcode;
+        }
+    }
+    return _CharCodeFromUnicode(unicode);
+}
+CFX_WideString CPDF_Font::DecodeString(const CFX_ByteString& str) const
+{
+    CFX_WideString result;
+    int src_len = str.GetLength();
+    result.Reserve(src_len);
+    const FX_CHAR* src_buf = str;
+    int src_pos = 0;
+    while (src_pos < src_len) {
+        FX_DWORD charcode = GetNextChar(src_buf, src_len, src_pos);
+        CFX_WideString unicode = UnicodeFromCharCode(charcode);
+        if (!unicode.IsEmpty()) {
+            result += unicode;
+        } else {
+            result += (FX_WCHAR)charcode;
+        }
+    }
+    return result;
+}
+CFX_ByteString CPDF_Font::EncodeString(const CFX_WideString& str) const
+{
+    CFX_ByteString result;
+    int src_len = str.GetLength();
+    FX_CHAR* dest_buf = result.GetBuffer(src_len * 2);
+    const FX_WCHAR* src_buf = str.c_str();
+    int dest_pos = 0;
+    for (int src_pos = 0; src_pos < src_len; src_pos ++) {
+        FX_DWORD charcode = CharCodeFromUnicode(src_buf[src_pos]);
+        dest_pos += AppendChar(dest_buf + dest_pos, charcode);
+    }
+    result.ReleaseBuffer(dest_pos);
+    return result;
+}
+void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc)
+{
+    m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"), PDFFONT_NONSYMBOLIC);
+    int ItalicAngle = 0;
+    FX_BOOL bExistItalicAngle = FALSE;
+    if (pFontDesc->KeyExist(FX_BSTRC("ItalicAngle"))) {
+        ItalicAngle = pFontDesc->GetInteger(FX_BSTRC("ItalicAngle"));
+        bExistItalicAngle = TRUE;
+    }
+    if (ItalicAngle < 0) {
+        m_Flags |= PDFFONT_ITALIC;
+        m_ItalicAngle = ItalicAngle;
+    }
+    FX_BOOL bExistStemV = FALSE;
+    if (pFontDesc->KeyExist(FX_BSTRC("StemV"))) {
+        m_StemV = pFontDesc->GetInteger(FX_BSTRC("StemV"));
+        bExistStemV = TRUE;
+    }
+    FX_BOOL bExistAscent = FALSE;
+    if (pFontDesc->KeyExist(FX_BSTRC("Ascent"))) {
+        m_Ascent = pFontDesc->GetInteger(FX_BSTRC("Ascent"));
+        bExistAscent = TRUE;
+    }
+    FX_BOOL bExistDescent = FALSE;
+    if (pFontDesc->KeyExist(FX_BSTRC("Descent"))) {
+        m_Descent = pFontDesc->GetInteger(FX_BSTRC("Descent"));
+        bExistDescent = TRUE;
+    }
+    FX_BOOL bExistCapHeight = FALSE;
+    if (pFontDesc->KeyExist(FX_BSTRC("CapHeight"))) {
+        bExistCapHeight = TRUE;
+    }
+    if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && bExistStemV) {
+        m_Flags |= PDFFONT_USEEXTERNATTR;
+    }
+    if (m_Descent > 10) {
+        m_Descent = -m_Descent;
+    }
+    CPDF_Array* pBBox = pFontDesc->GetArray(FX_BSTRC("FontBBox"));
+    if (pBBox) {
+        m_FontBBox.left = pBBox->GetInteger(0);
+        m_FontBBox.bottom = pBBox->GetInteger(1);
+        m_FontBBox.right = pBBox->GetInteger(2);
+        m_FontBBox.top = pBBox->GetInteger(3);
+    }
+    CPDF_Stream* pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile"));
+    if (pFontFile == NULL) {
+        pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile2"));
+    }
+    if (pFontFile == NULL) {
+        pFontFile = pFontDesc->GetStream(FX_BSTRC("FontFile3"));
+    }
+    if (pFontFile) {
+        m_pFontFile = m_pDocument->LoadFontFile(pFontFile);
+        if (m_pFontFile == NULL) {
+            return;
+        }
+        const uint8_t* pFontData = m_pFontFile->GetData();
+        FX_DWORD dwFontSize = m_pFontFile->GetSize();
+        m_Font.LoadEmbedded(pFontData, dwFontSize);
+        if (m_Font.m_Face == NULL) {
+            m_pFontFile = NULL;
+        }
+    }
+}
+short TT2PDF(int m, FXFT_Face face)
+{
+    int upm = FXFT_Get_Face_UnitsPerEM(face);
+    if (upm == 0) {
+        return (short)m;
+    }
+    return (m * 1000 + upm / 2) / upm;
+}
+void CPDF_Font::CheckFontMetrics()
+{
+    if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 && m_FontBBox.right == 0) {
+        if (m_Font.m_Face) {
+            m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(m_Font.m_Face), m_Font.m_Face);
+            m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(m_Font.m_Face), m_Font.m_Face);
+            m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(m_Font.m_Face), m_Font.m_Face);
+            m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(m_Font.m_Face), m_Font.m_Face);
+            m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(m_Font.m_Face), m_Font.m_Face);
+            m_Descent = TT2PDF(FXFT_Get_Face_Descender(m_Font.m_Face), m_Font.m_Face);
+        } else {
+            FX_BOOL bFirst = TRUE;
+            for (int i = 0; i < 256; i ++) {
+                FX_RECT rect;
+                GetCharBBox(i, rect);
+                if (rect.left == rect.right) {
+                    continue;
+                }
+                if (bFirst) {
+                    m_FontBBox = rect;
+                    bFirst = FALSE;
+                } else {
+                    if (m_FontBBox.top < rect.top) {
+                        m_FontBBox.top = rect.top;
+                    }
+                    if (m_FontBBox.right < rect.right) {
+                        m_FontBBox.right = rect.right;
+                    }
+                    if (m_FontBBox.left > rect.left) {
+                        m_FontBBox.left = rect.left;
+                    }
+                    if (m_FontBBox.bottom > rect.bottom) {
+                        m_FontBBox.bottom = rect.bottom;
+                    }
+                }
+            }
+        }
+    }
+    if (m_Ascent == 0 && m_Descent == 0) {
+        FX_RECT rect;
+        GetCharBBox('A', rect);
+        if (rect.bottom == rect.top) {
+            m_Ascent = m_FontBBox.top;
+        } else {
+            m_Ascent = rect.top;
+        }
+        GetCharBBox('g', rect);
+        if (rect.bottom == rect.top) {
+            m_Descent = m_FontBBox.bottom;
+        } else {
+            m_Descent = rect.bottom;
+        }
+    }
+}
+void CPDF_Font::LoadUnicodeMap()
+{
+    m_bToUnicodeLoaded = TRUE;
+    CPDF_Stream* pStream = m_pFontDict->GetStream(FX_BSTRC("ToUnicode"));
+    if (pStream == NULL) {
+        return;
+    }
+    m_pToUnicodeMap = new CPDF_ToUnicodeMap;
+    m_pToUnicodeMap->Load(pStream);
+}
+int CPDF_Font::GetStringWidth(const FX_CHAR* pString, int size)
+{
+    int offset = 0;
+    int width = 0;
+    while (offset < size) {
+        FX_DWORD charcode = GetNextChar(pString, size, offset);
+        width += GetCharWidthF(charcode);
+    }
+    return width;
+}
+int CPDF_Font::GetCharTypeWidth(FX_DWORD charcode)
+{
+    if (m_Font.m_Face == NULL) {
+        return 0;
+    }
+    int glyph_index = GlyphFromCharCode(charcode);
+    if (glyph_index == 0xffff) {
+        return 0;
+    }
+    return m_Font.GetGlyphWidth(glyph_index);
+}
+int _PDF_GetStandardFontName(CFX_ByteString& name);
+CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, const CFX_ByteStringC& name)
+{
+    CFX_ByteString fontname(name);
+    int font_id = _PDF_GetStandardFontName(fontname);
+    if (font_id < 0) {
+        return NULL;
+    }
+    CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
+    CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id);
+    if (pFont) {
+        return pFont;
+    }
+    CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
+    pDict->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Font"));
+    pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Type1"));
+    pDict->SetAtName(FX_BSTRC("BaseFont"), fontname);
+    pDict->SetAtName(FX_BSTRC("Encoding"), FX_BSTRC("WinAnsiEncoding"));
+    pFont = CPDF_Font::CreateFontF(NULL, pDict);
+    pFontGlobals->Set(pDoc, font_id, pFont);
+    return pFont;
+}
+const uint8_t ChineseFontNames[][5] = {
+    {0xCB, 0xCE, 0xCC, 0xE5, 0x00},
+    {0xBF, 0xAC, 0xCC, 0xE5, 0x00},
+    {0xBA, 0xDA, 0xCC, 0xE5, 0x00},
+    {0xB7, 0xC2, 0xCB, 0xCE, 0x00},
+    {0xD0, 0xC2, 0xCB, 0xCE, 0x00}
+};
+CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, CPDF_Dictionary* pFontDict)
+{
+    CFX_ByteString type = pFontDict->GetString(FX_BSTRC("Subtype"));
+    CPDF_Font* pFont;
+    if (type == FX_BSTRC("TrueType")) {
+        {
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_WINDOWS_ || _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ || _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+            CFX_ByteString basefont = pFontDict->GetString(FX_BSTRC("BaseFont"));
+            CFX_ByteString tag = basefont.Left(4);
+            int i;
+            int count = sizeof(ChineseFontNames) / sizeof(ChineseFontNames[0]);
+            for (i = 0; i < count; ++i) {
+                if (tag == CFX_ByteString((const FX_CHAR*)ChineseFontNames[i])) {
+                    break;
+                }
+            }
+            if (i < count) {
+                CPDF_Dictionary* pFontDesc = pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
+                if (pFontDesc == NULL || !pFontDesc->KeyExist(FX_BSTRC("FontFile2"))) {
+                    pFont = new CPDF_CIDFont;
+                    pFont->m_pFontDict = pFontDict;
+                    pFont->m_pDocument = pDoc;
+                    if (!pFont->Load()) {
+                        delete pFont;
+                        return NULL;
+                    }
+                    return pFont;
+                }
+            }
+#endif
+        }
+        pFont = new CPDF_TrueTypeFont;
+    } else if (type == FX_BSTRC("Type3")) {
+        pFont = new CPDF_Type3Font;
+    } else if (type == FX_BSTRC("Type0")) {
+        pFont = new CPDF_CIDFont;
+    } else {
+        pFont = new CPDF_Type1Font;
+    }
+    pFont->m_pFontDict = pFontDict;
+    pFont->m_pDocument = pDoc;
+    if (!pFont->Load()) {
+        delete pFont;
+        return NULL;
+    }
+    return pFont;
+}
+FX_BOOL CPDF_Font::Load()
+{
+    if (m_pFontDict == NULL) {
+        return FALSE;
+    }
+    CFX_ByteString type = m_pFontDict->GetString(FX_BSTRC("Subtype"));
+    m_BaseFont = m_pFontDict->GetString(FX_BSTRC("BaseFont"));
+    if (type == FX_BSTRC("MMType1")) {
+        type = FX_BSTRC("Type1");
+    }
+    return _Load();
+}
+static CFX_WideString _FontMap_GetWideString(CFX_CharMap* pMap, const CFX_ByteString& bytestr)
+{
+    return ((CPDF_FontCharMap*)pMap)->m_pFont->DecodeString(bytestr);
+}
+static CFX_ByteString _FontMap_GetByteString(CFX_CharMap* pMap, const CFX_WideString& widestr)
+{
+    return ((CPDF_FontCharMap*)pMap)->m_pFont->EncodeString(widestr);
+}
+CPDF_FontCharMap::CPDF_FontCharMap(CPDF_Font* pFont)
+{
+    m_GetByteString = _FontMap_GetByteString;
+    m_GetWideString = _FontMap_GetWideString;
+    m_pFont = pFont;
+}
+CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode)
+{
+    FX_DWORD value;
+    if (m_Map.Lookup(charcode, value)) {
+        FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff);
+        if (unicode != 0xffff) {
+            return unicode;
+        }
+        const FX_WCHAR* buf = m_MultiCharBuf.GetBuffer();
+        FX_DWORD buf_len = m_MultiCharBuf.GetLength();
+        if (buf == NULL || buf_len == 0) {
+            return CFX_WideString();
+        }
+        FX_DWORD index = value >> 16;
+        if (index >= buf_len) {
+            return CFX_WideString();
+        }
+        FX_DWORD len = buf[index];
+        if (index + len < index || index + len >= buf_len) {
+            return CFX_WideString();
+        }
+        return CFX_WideString(buf + index + 1, len);
+    }
+    if (m_pBaseMap) {
+        return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode);
+    }
+    return CFX_WideString();
+}
+FX_DWORD CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode)
+{
+    FX_POSITION pos = m_Map.GetStartPosition();
+    while (pos) {
+        FX_DWORD key, value;
+        m_Map.GetNextAssoc(pos, key, value);
+        if ((FX_WCHAR)value == unicode) {
+            return key;
+        }
+    }
+    return 0;
+}
+static FX_DWORD _StringToCode(const CFX_ByteStringC& str)
+{
+    const FX_CHAR* buf = str.GetCStr();
+    int len = str.GetLength();
+    if (len == 0) {
+        return 0;
+    }
+    int result = 0;
+    if (buf[0] == '<') {
+        for (int i = 1; i < len; i ++) {
+            int digit;
+            if (buf[i] >= '0' && buf[i] <= '9') {
+                digit = buf[i] - '0';
+            } else if (buf[i] >= 'a' && buf[i] <= 'f') {
+                digit = buf[i] - 'a' + 10;
+            } else if (buf[i] >= 'A' && buf[i] <= 'F') {
+                digit = buf[i] - 'A' + 10;
+            } else {
+                break;
+            }
+            result = result * 16 + digit;
+        }
+        return result;
+    } else {
+        for (int i = 0; i < len; i ++) {
+            if (buf[i] < '0' || buf[i] > '9') {
+                break;
+            }
+            result = result * 10 + buf[i] - '0';
+        }
+    }
+    return result;
+}
+static CFX_WideString _StringDataAdd(CFX_WideString str)
+{
+    CFX_WideString ret;
+    int len = str.GetLength();
+    FX_WCHAR value = 1;
+    for (int i = len - 1; i >= 0 ; --i) {
+        FX_WCHAR ch = str[i] + value;
+        if (ch < str[i]) {
+            ret.Insert(0, 0);
+        } else {
+            ret.Insert(0, ch);
+            value = 0;
+        }
+    }
+    if (value) {
+        ret.Insert(0, value);
+    }
+    return ret;
+}
+static CFX_WideString _StringToWideString(const CFX_ByteStringC& str)
+{
+    const FX_CHAR* buf = str.GetCStr();
+    int len = str.GetLength();
+    if (len == 0) {
+        return CFX_WideString();
+    }
+    CFX_WideString result;
+    if (buf[0] == '<') {
+        int byte_pos = 0;
+        FX_WCHAR ch = 0;
+        for (int i = 1; i < len; i ++) {
+            int digit;
+            if (buf[i] >= '0' && buf[i] <= '9') {
+                digit = buf[i] - '0';
+            } else if (buf[i] >= 'a' && buf[i] <= 'f') {
+                digit = buf[i] - 'a' + 10;
+            } else if (buf[i] >= 'A' && buf[i] <= 'F') {
+                digit = buf[i] - 'A' + 10;
+            } else {
+                break;
+            }
+            ch = ch * 16 + digit;
+            byte_pos ++;
+            if (byte_pos == 4) {
+                result += ch;
+                byte_pos = 0;
+                ch = 0;
+            }
+        }
+        return result;
+    }
+    if (buf[0] == '(') {
+    }
+    return result;
+}
+void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream)
+{
+    int CIDSet = 0;
+    CPDF_StreamAcc stream;
+    stream.LoadAllData(pStream, FALSE);
+    CPDF_SimpleParser parser(stream.GetData(), stream.GetSize());
+    m_Map.EstimateSize(stream.GetSize() / 8, 1024);
+    while (1) {
+        CFX_ByteStringC word = parser.GetWord();
+        if (word.IsEmpty()) {
+            break;
+        }
+        if (word == FX_BSTRC("beginbfchar")) {
+            while (1) {
+                word = parser.GetWord();
+                if (word.IsEmpty() || word == FX_BSTRC("endbfchar")) {
+                    break;
+                }
+                FX_DWORD srccode = _StringToCode(word);
+                word = parser.GetWord();
+                CFX_WideString destcode = _StringToWideString(word);
+                int len = destcode.GetLength();
+                if (len == 0) {
+                    continue;
+                }
+                if (len == 1) {
+                    m_Map.SetAt(srccode, destcode.GetAt(0));
+                } else {
+                    m_Map.SetAt(srccode, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);
+                    m_MultiCharBuf.AppendChar(destcode.GetLength());
+                    m_MultiCharBuf << destcode;
+                }
+            }
+        } else if (word == FX_BSTRC("beginbfrange")) {
+            while (1) {
+                CFX_ByteString low, high;
+                low = parser.GetWord();
+                if (low.IsEmpty() || low == FX_BSTRC("endbfrange")) {
+                    break;
+                }
+                high = parser.GetWord();
+                FX_DWORD lowcode = _StringToCode(low);
+                FX_DWORD highcode = (lowcode & 0xffffff00) | (_StringToCode(high) & 0xff);
+                if (highcode == (FX_DWORD) - 1) {
+                    break;
+                }
+                CFX_ByteString start = parser.GetWord();
+                if (start == FX_BSTRC("[")) {
+                    for (FX_DWORD code = lowcode; code <= highcode; code ++) {
+                        CFX_ByteString dest = parser.GetWord();
+                        CFX_WideString destcode = _StringToWideString(dest);
+                        int len = destcode.GetLength();
+                        if (len == 0) {
+                            continue;
+                        }
+                        if (len == 1) {
+                            m_Map.SetAt(code, destcode.GetAt(0));
+                        } else {
+                            m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);
+                            m_MultiCharBuf.AppendChar(destcode.GetLength());
+                            m_MultiCharBuf << destcode;
+                        }
+                    }
+                    parser.GetWord();
+                } else {
+                    CFX_WideString destcode = _StringToWideString(start);
+                    int len = destcode.GetLength();
+                    FX_DWORD value = 0;
+                    if (len == 1) {
+                        value = _StringToCode(start);
+                        for (FX_DWORD code = lowcode; code <= highcode; code ++) {
+                            m_Map.SetAt(code, value++);
+                        }
+                    } else {
+                        for (FX_DWORD code = lowcode; code <= highcode; code ++) {
+                            CFX_WideString retcode;
+                            if (code == lowcode) {
+                                retcode = destcode;
+                            } else {
+                                retcode = _StringDataAdd(destcode);
+                            }
+                            m_Map.SetAt(code, m_MultiCharBuf.GetLength() * 0x10000 + 0xffff);
+                            m_MultiCharBuf.AppendChar(retcode.GetLength());
+                            m_MultiCharBuf << retcode;
+                            destcode = retcode;
+                        }
+                    }
+                }
+            }
+        } else if (word == FX_BSTRC("/Adobe-Korea1-UCS2")) {
+            CIDSet = CIDSET_KOREA1;
+        } else if (word == FX_BSTRC("/Adobe-Japan1-UCS2")) {
+            CIDSet = CIDSET_JAPAN1;
+        } else if (word == FX_BSTRC("/Adobe-CNS1-UCS2")) {
+            CIDSet = CIDSET_CNS1;
+        } else if (word == FX_BSTRC("/Adobe-GB1-UCS2")) {
+            CIDSet = CIDSET_GB1;
+        }
+    }
+    if (CIDSet) {
+        m_pBaseMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetCID2UnicodeMap(CIDSet, FALSE);
+    } else {
+        m_pBaseMap = NULL;
+    }
+}
+static FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value)
+{
+    if (value == FX_BSTRC("WinAnsiEncoding")) {
+        basemap = PDFFONT_ENCODING_WINANSI;
+    } else if (value == FX_BSTRC("MacRomanEncoding")) {
+        basemap = PDFFONT_ENCODING_MACROMAN;
+    } else if (value == FX_BSTRC("MacExpertEncoding")) {
+        basemap = PDFFONT_ENCODING_MACEXPERT;
+    } else if (value == FX_BSTRC("PDFDocEncoding")) {
+        basemap = PDFFONT_ENCODING_PDFDOC;
+    } else {
+        return FALSE;
+    }
+    return TRUE;
+}
+void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, int& iBaseEncoding, CFX_ByteString*& pCharNames,
+                                FX_BOOL bEmbedded, FX_BOOL bTrueType)
+{
+    if (pEncoding == NULL) {
+        if (m_BaseFont == FX_BSTRC("Symbol")) {
+            iBaseEncoding = bTrueType ? PDFFONT_ENCODING_MS_SYMBOL : PDFFONT_ENCODING_ADOBE_SYMBOL;
+        } else if (!bEmbedded && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
+            iBaseEncoding = PDFFONT_ENCODING_WINANSI;
+        }
+        return;
+    }
+    if (pEncoding->GetType() == PDFOBJ_NAME) {
+        if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) {
+            return;
+        }
+        if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == FX_BSTRC("Symbol")) {
+            if (!bTrueType) {
+                iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
+            }
+            return;
+        }
+        CFX_ByteString bsEncoding = pEncoding->GetString();
+        if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0) {
+            bsEncoding = FX_BSTRC("WinAnsiEncoding");
+        }
+        GetPredefinedEncoding(iBaseEncoding, bsEncoding);
+        return;
+    }
+    if (pEncoding->GetType() != PDFOBJ_DICTIONARY) {
+        return;
+    }
+    CPDF_Dictionary* pDict = (CPDF_Dictionary*)pEncoding;
+    if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) {
+        CFX_ByteString bsEncoding = pDict->GetString(FX_BSTRC("BaseEncoding"));
+        if (bsEncoding.Compare(FX_BSTRC("MacExpertEncoding")) == 0 && bTrueType) {
+            bsEncoding = FX_BSTRC("WinAnsiEncoding");
+        }
+        GetPredefinedEncoding(iBaseEncoding, bsEncoding);
+    }
+    if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) {
+        iBaseEncoding = PDFFONT_ENCODING_STANDARD;
+    }
+    CPDF_Array* pDiffs = pDict->GetArray(FX_BSTRC("Differences"));
+    if (pDiffs == NULL) {
+        return;
+    }
+    pCharNames = new CFX_ByteString[256];
+    FX_DWORD cur_code = 0;
+    for (FX_DWORD i = 0; i < pDiffs->GetCount(); i ++) {
+        CPDF_Object* pElement = pDiffs->GetElementValue(i);
+        if (pElement == NULL) {
+            continue;
+        }
+        if (pElement->GetType() == PDFOBJ_NAME) {
+            if (cur_code < 256) {
+                pCharNames[cur_code] = ((CPDF_Name*)pElement)->GetString();
+            }
+            cur_code ++;
+        } else {
+            cur_code = pElement->GetInteger();
+        }
+    }
+}
+FX_BOOL CPDF_Font::IsStandardFont() const
+{
+    if (m_FontType != PDFFONT_TYPE1) {
+        return FALSE;
+    }
+    if (m_pFontFile != NULL) {
+        return FALSE;
+    }
+    if (((CPDF_Type1Font*)this)->GetBase14Font() < 0) {
+        return FALSE;
+    }
+    return TRUE;
+}
+extern const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding, uint8_t charcode);
+CPDF_SimpleFont::CPDF_SimpleFont(int fonttype) : CPDF_Font(fonttype)
+{
+    FXSYS_memset(m_CharBBox, 0xff, sizeof m_CharBBox);
+    FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth);
+    FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex);
+    FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID);
+    m_pCharNames = NULL;
+    m_BaseEncoding = PDFFONT_ENCODING_BUILTIN;
+}
+CPDF_SimpleFont::~CPDF_SimpleFont()
+{
+    delete[] m_pCharNames;
+}
+int CPDF_SimpleFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL *pVertGlyph)
+{
+    if (pVertGlyph) {
+        *pVertGlyph = FALSE;
+    }
+    if (charcode > 0xff) {
+        return -1;
+    }
+    int index = m_GlyphIndex[(uint8_t)charcode];
+    if (index == 0xffff) {
+        return -1;
+    }
+    return index;
+}
+void CPDF_SimpleFont::LoadCharMetrics(int charcode)
+{
+    if (m_Font.m_Face == NULL) {
+        return;
+    }
+    if (charcode < 0 || charcode > 0xff) {
+        return;
+    }
+    int glyph_index = m_GlyphIndex[charcode];
+    if (glyph_index == 0xffff) {
+        if (m_pFontFile == NULL && charcode != 32) {
+            LoadCharMetrics(32);
+            m_CharBBox[charcode] = m_CharBBox[32];
+            if (m_bUseFontWidth) {
+                m_CharWidth[charcode] = m_CharWidth[32];
+            }
+        }
+        return;
+    }
+    int err = FXFT_Load_Glyph(m_Font.m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
+    if (err) {
+        return;
+    }
+    m_CharBBox[charcode].Left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(m_Font.m_Face), m_Font.m_Face);
+    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);
+    m_CharBBox[charcode].Top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(m_Font.m_Face), m_Font.m_Face);
+    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);
+    if (m_bUseFontWidth) {
+        int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(m_Font.m_Face), m_Font.m_Face);
+        if (m_CharWidth[charcode] == 0xffff) {
+            m_CharWidth[charcode] = TT_Width;
+        } else if (TT_Width && !IsEmbedded()) {
+            m_CharBBox[charcode].Right = m_CharBBox[charcode].Right * m_CharWidth[charcode] / TT_Width;
+            m_CharBBox[charcode].Left = m_CharBBox[charcode].Left * m_CharWidth[charcode] / TT_Width;
+        }
+    }
+}
+int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level)
+{
+    if (charcode > 0xff) {
+        charcode = 0;
+    }
+    if (m_CharWidth[charcode] == 0xffff) {
+        LoadCharMetrics(charcode);
+        if (m_CharWidth[charcode] == 0xffff) {
+            m_CharWidth[charcode] = 0;
+        }
+    }
+    return (int16_t)m_CharWidth[charcode];
+}
+void CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level)
+{
+    if (charcode > 0xff) {
+        charcode = 0;
+    }
+    if (m_CharBBox[charcode].Left == (int16_t)0xffff) {
+        LoadCharMetrics(charcode);
+    }
+    rect.left = m_CharBBox[charcode].Left;
+    rect.right = m_CharBBox[charcode].Right;
+    rect.bottom = m_CharBBox[charcode].Bottom;
+    rect.top = m_CharBBox[charcode].Top;
+}
+const FX_CHAR* GetAdobeCharName(int iBaseEncoding, const CFX_ByteString* pCharNames, int charcode)
+{
+    ASSERT(charcode >= 0 && charcode < 256);
+    if (charcode < 0 || charcode >= 256) {
+        return NULL;
+    }
+    const FX_CHAR* name = NULL;
+    if (pCharNames) {
+        name = pCharNames[charcode];
+    }
+    if ((name == NULL || name[0] == 0) && iBaseEncoding) {
+        name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode);
+    }
+    if (name == NULL || name[0] == 0) {
+        return NULL;
+    }
+    return name;
+}
+FX_BOOL CPDF_SimpleFont::LoadCommon()
+{
+    CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
+    if (pFontDesc) {
+        LoadFontDescriptor(pFontDesc);
+    }
+    CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths"));
+    int width_start = 0, width_end = -1;
+    m_bUseFontWidth = TRUE;
+    if (pWidthArray) {
+        m_bUseFontWidth = FALSE;
+        if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("MissingWidth"))) {
+            int MissingWidth = pFontDesc->GetInteger(FX_BSTRC("MissingWidth"));
+            for (int i = 0; i < 256; i ++) {
+                m_CharWidth[i] = MissingWidth;
+            }
+        }
+        width_start = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"), 0);
+        width_end = m_pFontDict->GetInteger(FX_BSTRC("LastChar"), 0);
+        if (width_start >= 0 && width_start <= 255) {
+            if (width_end <= 0 || width_end >= width_start + (int)pWidthArray->GetCount()) {
+                width_end = width_start + pWidthArray->GetCount() - 1;
+            }
+            if (width_end > 255) {
+                width_end = 255;
+            }
+            for (int i = width_start; i <= width_end; i ++) {
+                m_CharWidth[i] = pWidthArray->GetInteger(i - width_start);
+            }
+        }
+    }
+    if (m_pFontFile == NULL) {
+        LoadSubstFont();
+    } else {
+        if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') {
+            m_BaseFont = m_BaseFont.Mid(8);
+        }
+    }
+    if (!(m_Flags & PDFFONT_SYMBOLIC)) {
+        m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
+    }
+    CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding"));
+    LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL, m_Font.IsTTFont());
+    LoadGlyphMap();
+    delete[] m_pCharNames;
+    m_pCharNames = NULL;
+    if (m_Font.m_Face == NULL) {
+        return TRUE;
+    }
+    if (m_Flags & PDFFONT_ALLCAP) {
+        unsigned char lowercases[] = {'a', 'z', 0xe0, 0xf6, 0xf8, 0xfd};
+        for (size_t range = 0; range < sizeof lowercases / 2; range ++) {
+            for (int i = lowercases[range * 2]; i <= lowercases[range * 2 + 1]; i ++) {
+                if (m_GlyphIndex[i] != 0xffff && m_pFontFile != NULL) {
+                    continue;
+                }
+                m_GlyphIndex[i] = m_GlyphIndex[i - 32];
+                if (m_CharWidth[i - 32]) {
+                    m_CharWidth[i] = m_CharWidth[i - 32];
+                    m_CharBBox[i] = m_CharBBox[i - 32];
+                }
+            }
+        }
+    }
+    CheckFontMetrics();
+    return TRUE;
+}
+void CPDF_SimpleFont::LoadSubstFont()
+{
+    if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) {
+        int width = 0, i;
+        for (i = 0; i < 256; i ++) {
+            if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) {
+                continue;
+            }
+            if (width == 0) {
+                width = m_CharWidth[i];
+            } else if (width != m_CharWidth[i]) {
+                break;
+            }
+        }
+        if (i == 256 && width) {
+            m_Flags |= PDFFONT_FIXEDPITCH;
+        }
+    }
+    int weight = m_StemV < 140 ? m_StemV * 5 : (m_StemV * 4 + 140);
+    m_Font.LoadSubst(m_BaseFont, IsFontType(PDFFONT_TRUETYPE), m_Flags, weight, m_ItalicAngle, 0);
+    if (m_Font.m_pSubstFont->m_SubstFlags & FXFONT_SUBST_NONSYMBOL) {
+    }
+}
+FX_BOOL CPDF_SimpleFont::IsUnicodeCompatible() const
+{
+    return m_BaseEncoding != PDFFONT_ENCODING_BUILTIN && m_BaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL &&
+           m_BaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS;
+}
+CPDF_Type1Font::CPDF_Type1Font() : CPDF_SimpleFont(PDFFONT_TYPE1)
+{
+    m_Base14Font = -1;
+}
+FX_BOOL CPDF_Type1Font::_Load()
+{
+    m_Base14Font = _PDF_GetStandardFontName(m_BaseFont);
+    if (m_Base14Font >= 0) {
+        CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
+        if (pFontDesc && pFontDesc->KeyExist(FX_BSTRC("Flags"))) {
+            m_Flags = pFontDesc->GetInteger(FX_BSTRC("Flags"));
+        } else {
+            m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC;
+        }
+        if (m_Base14Font < 4)
+            for (int i = 0; i < 256; i ++) {
+                m_CharWidth[i] = 600;
+            }
+        if (m_Base14Font == 12) {
+            m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL;
+        } else if (m_Base14Font == 13) {
+            m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS;
+        } else if (m_Flags & PDFFONT_NONSYMBOLIC) {
+            m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
+        }
+    }
+    return LoadCommon();
+}
+static FX_BOOL FT_UseType1Charmap(FXFT_Face face)
+{
+    if (FXFT_Get_Face_CharmapCount(face) == 0) {
+        return FALSE;
+    }
+    if (FXFT_Get_Face_CharmapCount(face) == 1 &&
+            FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) {
+        return FALSE;
+    }
+    if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == FXFT_ENCODING_UNICODE) {
+        FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]);
+    } else {
+        FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]);
+    }
+    return TRUE;
+}
+extern FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode);
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+#include "../../fxge/apple/apple_int.h"
+#endif
+int CPDF_Type1Font::GlyphFromCharCodeExt(FX_DWORD charcode)
+{
+    if (charcode > 0xff) {
+        return -1;
+    }
+    int index = m_ExtGID[(uint8_t)charcode];
+    if (index == 0xffff) {
+        return -1;
+    }
+    return index;
+}
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+struct _GlyphNameMap {
+    const FX_CHAR* m_pStrAdobe;
+    const FX_CHAR* m_pStrUnicode;
+};
+static const _GlyphNameMap g_GlyphNameSubsts[] = {
+    {"ff", "uniFB00"},
+    {"fi", "uniFB01"},
+    {"fl", "uniFB02"},
+    {"ffi", "uniFB03"},
+    {"ffl", "uniFB04"}
+};
+extern "C" {
+    static int compareString(const void* key, const void* element)
+    {
+        return FXSYS_stricmp((const FX_CHAR*)key, ((_GlyphNameMap*)element)->m_pStrAdobe);
+    }
+}
+static const FX_CHAR* _GlyphNameRemap(const FX_CHAR* pStrAdobe)
+{
+    _GlyphNameMap* found = (_GlyphNameMap*)FXSYS_bsearch(pStrAdobe, g_GlyphNameSubsts,
+                           sizeof g_GlyphNameSubsts / sizeof(_GlyphNameMap), sizeof(_GlyphNameMap),
+                           compareString);
+    if (found) {
+        return found->m_pStrUnicode;
+    }
+    return NULL;
+}
+#endif
+void CPDF_Type1Font::LoadGlyphMap()
+{
+    if (m_Font.m_Face == NULL) {
+        return;
+    }
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+    FX_BOOL bCoreText = TRUE;
+    CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
+    if (!m_Font.m_pPlatformFont) {
+        if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
+            bCoreText = FALSE;
+        }
+        m_Font.m_pPlatformFont = quartz2d.CreateFont(m_Font.m_pFontData, m_Font.m_dwSize);
+        if (NULL == m_Font.m_pPlatformFont) {
+            bCoreText = FALSE;
+        }
+    }
+#endif
+    if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) {
+        if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {
+            FX_BOOL bGotOne = FALSE;
+            for (int charcode = 0; charcode < 256; charcode ++) {
+                const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
+                for (int j = 0; j < 4; j ++) {
+                    FX_WORD unicode = prefix[j] * 256 + charcode;
+                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+                    FX_CHAR name_glyph[256];
+                    FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
+                    name_glyph[255] = 0;
+                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
+                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
+                    if (name_ct) {
+                        CFRelease(name_ct);
+                    }
+#endif
+                    if (m_GlyphIndex[charcode]) {
+                        bGotOne = TRUE;
+                        break;
+                    }
+                }
+            }
+            if (bGotOne) {
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+                if (!bCoreText) {
+                    FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
+                }
+#endif
+                return;
+            }
+        }
+        FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE);
+        if (m_BaseEncoding == 0) {
+            m_BaseEncoding = PDFFONT_ENCODING_STANDARD;
+        }
+        for (int charcode = 0; charcode < 256; charcode ++) {
+            const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+            if (name == NULL) {
+                continue;
+            }
+            m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+            m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+            FX_CHAR name_glyph[256];
+            FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
+            name_glyph[255] = 0;
+            CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
+            m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
+            if (name_ct) {
+                CFRelease(name_ct);
+            }
+#endif
+            if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) {
+                m_Encoding.m_Unicodes[charcode] = 0x20;
+                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 0x20);
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+                FX_CHAR name_glyph[256];
+                FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
+                name_glyph[255] = 0;
+                CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
+                m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
+                if (name_ct) {
+                    CFRelease(name_ct);
+                }
+#endif
+            }
+        }
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+        if (!bCoreText) {
+            FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
+        }
+#endif
+        return;
+    }
+    FT_UseType1Charmap(m_Font.m_Face);
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+    if (bCoreText) {
+        if (m_Flags & PDFFONT_SYMBOLIC) {
+            for (int charcode = 0; charcode < 256; charcode ++) {
+                const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+                if (name) {
+                    m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+                    m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
+                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
+                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
+                    if (name_ct) {
+                        CFRelease(name_ct);
+                    }
+                } else {
+                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
+                    FX_WCHAR unicode = 0;
+                    if (m_GlyphIndex[charcode]) {
+                        unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
+                    }
+                    FX_CHAR name_glyph[256];
+                    FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
+                    FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
+                    name_glyph[255] = 0;
+                    if (unicode == 0 && name_glyph[0] != 0) {
+                        unicode = PDF_UnicodeFromAdobeName(name_glyph);
+                    }
+                    m_Encoding.m_Unicodes[charcode] = unicode;
+                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
+                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
+                    if (name_ct) {
+                        CFRelease(name_ct);
+                    }
+                }
+            }
+            return;
+        }
+        FX_BOOL bUnicode = FALSE;
+        if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) {
+            bUnicode = TRUE;
+        }
+        for (int charcode = 0; charcode < 256; charcode ++) {
+            const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+            if (name == NULL) {
+                continue;
+            }
+            m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+            const FX_CHAR* pStrUnicode = _GlyphNameRemap(name);
+            if (pStrUnicode && 0 == FXFT_Get_Name_Index(m_Font.m_Face, (char*)name)) {
+                name = pStrUnicode;
+            }
+            m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
+            CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull);
+            m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
+            if (name_ct) {
+                CFRelease(name_ct);
+            }
+            if (m_GlyphIndex[charcode] == 0) {
+                if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) {
+                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
+                    FX_CHAR name_glyph[256];
+                    FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
+                    name_glyph[255] = 0;
+                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
+                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
+                    if (name_ct) {
+                        CFRelease(name_ct);
+                    }
+                } else {
+                    m_Encoding.m_Unicodes[charcode] = 0x20;
+                    m_GlyphIndex[charcode] = bUnicode ? FXFT_Get_Char_Index(m_Font.m_Face, 0x20) : 0xffff;
+                    FX_CHAR name_glyph[256];
+                    FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
+                    name_glyph[255] = 0;
+                    CFStringRef name_ct = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name_glyph, kCFStringEncodingASCII, kCFAllocatorNull);
+                    m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.m_pPlatformFont, name_ct);
+                    if (name_ct) {
+                        CFRelease(name_ct);
+                    }
+                }
+            }
+        }
+        return;
+    }
+#endif
+    if (m_Flags & PDFFONT_SYMBOLIC) {
+        for (int charcode = 0; charcode < 256; charcode ++) {
+            const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+            if (name) {
+                m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+                m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
+            } else {
+                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
+                if (m_GlyphIndex[charcode]) {
+                    FX_WCHAR unicode = FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode);
+                    if (unicode == 0) {
+                        FX_CHAR name_glyph[256];
+                        FXSYS_memset(name_glyph, 0, sizeof(name_glyph));
+                        FXFT_Get_Glyph_Name(m_Font.m_Face, m_GlyphIndex[charcode], name_glyph, 256);
+                        name_glyph[255] = 0;
+                        if (name_glyph[0] != 0) {
+                            unicode = PDF_UnicodeFromAdobeName(name_glyph);
+                        }
+                    }
+                    m_Encoding.m_Unicodes[charcode] = unicode;
+                }
+            }
+        }
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+        if (!bCoreText) {
+            FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
+        }
+#endif
+        return;
+    }
+    FX_BOOL bUnicode = FALSE;
+    if (0 == FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE)) {
+        bUnicode = TRUE;
+    }
+    for (int charcode = 0; charcode < 256; charcode ++) {
+        const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+        if (name == NULL) {
+            continue;
+        }
+        m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+        m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
+        if (m_GlyphIndex[charcode] == 0) {
+            if (FXSYS_strcmp(name, ".notdef") != 0 && FXSYS_strcmp(name, "space") != 0) {
+                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode);
+            } else {
+                m_Encoding.m_Unicodes[charcode] = 0x20;
+                m_GlyphIndex[charcode] = 0xffff;
+            }
+        }
+    }
+#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
+    if (!bCoreText) {
+        FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256);
+    }
+#endif
+}
+CPDF_FontEncoding::CPDF_FontEncoding()
+{
+    FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
+}
+int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const
+{
+    for (int i = 0; i < 256; i ++)
+        if (m_Unicodes[i] == unicode) {
+            return i;
+        }
+    return -1;
+}
+CPDF_FontEncoding::CPDF_FontEncoding(int PredefinedEncoding)
+{
+    const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(PredefinedEncoding);
+    if (!pSrc) {
+        FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes));
+    } else
+        for (int i = 0; i < 256; i++) {
+            m_Unicodes[i] = pSrc[i];
+        }
+}
+FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const
+{
+    return FXSYS_memcmp(m_Unicodes, pAnother->m_Unicodes, sizeof(m_Unicodes)) == 0;
+}
+CPDF_Object* CPDF_FontEncoding::Realize()
+{
+    int predefined = 0;
+    for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; cs ++) {
+        const FX_WORD* pSrc = PDF_UnicodesForPredefinedCharSet(cs);
+        FX_BOOL match = TRUE;
+        for (int i = 0; i < 256; ++i) {
+            if (m_Unicodes[i] != pSrc[i]) {
+                match = FALSE;
+                break;
+            }
+        }
+        if (match) {
+            predefined = cs;
+            break;
+        }
+    }
+    if (predefined) {
+        if (predefined == PDFFONT_ENCODING_WINANSI) {
+            return CPDF_Name::Create("WinAnsiEncoding");
+        }
+        if (predefined == PDFFONT_ENCODING_MACROMAN) {
+            return CPDF_Name::Create("MacRomanEncoding");
+        }
+        if (predefined == PDFFONT_ENCODING_MACEXPERT) {
+            return CPDF_Name::Create("MacExpertEncoding");
+        }
+        return NULL;
+    }
+    CPDF_Dictionary* pDict = CPDF_Dictionary::Create();
+    pDict->SetAtName(FX_BSTRC("BaseEncoding"), FX_BSTRC("WinAnsiEncoding"));
+    const FX_WORD* pStandard = PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI);
+    CPDF_Array* pDiff = CPDF_Array::Create();
+    for (int i = 0; i < 256; i ++) {
+        if (pStandard[i] == m_Unicodes[i]) {
+            continue;
+        }
+        pDiff->Add(CPDF_Number::Create(i));
+        pDiff->Add(CPDF_Name::Create(PDF_AdobeNameFromUnicode(m_Unicodes[i])));
+    }
+    pDict->SetAt(FX_BSTRC("Differences"), pDiff);
+    return pDict;
+}
+CPDF_TrueTypeFont::CPDF_TrueTypeFont() : CPDF_SimpleFont(PDFFONT_TRUETYPE)
+{
+}
+FX_BOOL CPDF_TrueTypeFont::_Load()
+{
+    return LoadCommon();
+}
+extern FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode);
+void CPDF_TrueTypeFont::LoadGlyphMap()
+{
+    if (m_Font.m_Face == NULL) {
+        return;
+    }
+    int baseEncoding = m_BaseEncoding;
+    if (m_pFontFile && m_Font.m_Face->num_charmaps > 0
+            && (baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI)
+            && (m_Flags & PDFFONT_SYMBOLIC)) {
+        FX_BOOL bSupportWin = FALSE;
+        FX_BOOL bSupportMac = FALSE;
+        for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.m_Face); i++) {
+            int platform_id = FXFT_Get_Charmap_PlatformID(FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]);
+            if (platform_id == 0 || platform_id == 3) {
+                bSupportWin = TRUE;
+            } else if (platform_id == 0 || platform_id == 1) {
+                bSupportMac = TRUE;
+            }
+        }
+        if (baseEncoding == PDFFONT_ENCODING_WINANSI && !bSupportWin) {
+            baseEncoding = bSupportMac ? PDFFONT_ENCODING_MACROMAN : PDFFONT_ENCODING_BUILTIN;
+        } else if (baseEncoding == PDFFONT_ENCODING_MACROMAN && !bSupportMac) {
+            baseEncoding = bSupportWin ? PDFFONT_ENCODING_WINANSI : PDFFONT_ENCODING_BUILTIN;
+        }
+    }
+    if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI)
+            && m_pCharNames == NULL) || (m_Flags & PDFFONT_NONSYMBOLIC)) {
+        if (!FXFT_Has_Glyph_Names(m_Font.m_Face) && (!m_Font.m_Face->num_charmaps || !m_Font.m_Face->charmaps)) {
+            int nStartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"));
+            if(nStartChar < 0 || nStartChar > 255)
+                return;
+
+            int charcode = 0;
+            for (; charcode < nStartChar; charcode ++) {
+                m_GlyphIndex[charcode] = 0;
+            }
+            FX_WORD nGlyph = charcode - nStartChar + 3;
+            for (; charcode < 256; charcode ++, nGlyph ++) {
+                m_GlyphIndex[charcode] = nGlyph;
+            }
+            return;
+        }
+        FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.m_Face, 3, 1);
+        FX_BOOL bMacRoman = FALSE, bMSSymbol = FALSE;
+        if (!bMSUnicode) {
+            if (m_Flags & PDFFONT_NONSYMBOLIC) {
+                bMacRoman = FT_UseTTCharmap(m_Font.m_Face, 1, 0);
+                bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.m_Face, 3, 0);
+            } else {
+                bMSSymbol = FT_UseTTCharmap(m_Font.m_Face, 3, 0);
+                bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.m_Face, 1, 0);
+            }
+        }
+        FX_BOOL bToUnicode = m_pFontDict->KeyExist(FX_BSTRC("ToUnicode"));
+        for (int charcode = 0; charcode < 256; charcode ++) {
+            const FX_CHAR* name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
+            if (name == NULL) {
+                m_GlyphIndex[charcode] = m_pFontFile ? FXFT_Get_Char_Index(m_Font.m_Face, charcode) : -1;
+                continue;
+            }
+            m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+            if (bMSSymbol) {
+                const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
+                for (int j = 0; j < 4; j ++) {
+                    FX_WORD unicode = prefix[j] * 256 + charcode;
+                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
+                    if (m_GlyphIndex[charcode]) {
+                        break;
+                    }
+                }
+            } else if (m_Encoding.m_Unicodes[charcode]) {
+                if (bMSUnicode) {
+                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);
+                } else if (bMacRoman) {
+                    FX_DWORD maccode = FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]);
+                    if (!maccode) {
+                        m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char *)name);
+                    } else {
+                        m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, maccode);
+                    }
+                }
+            }
+            if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && name != NULL) {
+                if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) {
+                    m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, 32);
+                } else {
+                    m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.m_Face, (char*)name);
+                    if (m_GlyphIndex[charcode] == 0) {
+                        if (bToUnicode) {
+                            CFX_WideString wsUnicode = UnicodeFromCharCode(charcode);
+                            if (!wsUnicode.IsEmpty()) {
+                                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, wsUnicode[0]);
+                                m_Encoding.m_Unicodes[charcode] = wsUnicode[0];
+                            }
+                        }
+                        if (m_GlyphIndex[charcode] == 0) {
+                            m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
+                        }
+                    }
+                }
+            }
+        }
+        return;
+    }
+    if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) {
+        const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
+        FX_BOOL bGotOne = FALSE;
+        for (int charcode = 0; charcode < 256; charcode ++) {
+            for (int j = 0; j < 4; j ++) {
+                FX_WORD unicode = prefix[j] * 256 + charcode;
+                m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
+                if (m_GlyphIndex[charcode]) {
+                    bGotOne = TRUE;
+                    break;
+                }
+            }
+        }
+        if (bGotOne) {
+            if (baseEncoding != PDFFONT_ENCODING_BUILTIN) {
+                for (int charcode = 0; charcode < 256; charcode ++) {
+                    const FX_CHAR* name = GetAdobeCharName(baseEncoding, m_pCharNames, charcode);
+                    if (name == NULL) {
+                        continue;
+                    }
+                    m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+                }
+            } else if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) {
+                for (int charcode = 0; charcode < 256; charcode ++) {
+                    m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
+                }
+            }
+            return;
+        }
+    }
+    if (FT_UseTTCharmap(m_Font.m_Face, 1, 0)) {
+        FX_BOOL bGotOne = FALSE;
+        for (int charcode = 0; charcode < 256; charcode ++) {
+            m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, charcode);
+            m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode);
+            if (m_GlyphIndex[charcode]) {
+                bGotOne = TRUE;
+            }
+        }
+        if (m_pFontFile || bGotOne) {
+            return;
+        }
+    }
+    if (FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE) == 0) {
+        FX_BOOL bGotOne = FALSE;
+        const FX_WORD* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding);
+        for (int charcode = 0; charcode < 256; charcode ++) {
+            if (m_pFontFile == NULL) {
+                const FX_CHAR* name = GetAdobeCharName(0, m_pCharNames, charcode);
+                if (name != NULL) {
+                    m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name);
+                } else if (pUnicodes) {
+                    m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode];
+                }
+            } else {
+                m_Encoding.m_Unicodes[charcode] = charcode;
+            }
+            m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.m_Face, m_Encoding.m_Unicodes[charcode]);
+            if (m_GlyphIndex[charcode]) {
+                bGotOne = TRUE;
+            }
+        }
+        if (bGotOne) {
+            return;
+        }
+    }
+    for (int charcode = 0; charcode < 256; charcode ++) {
+        m_GlyphIndex[charcode] = charcode;
+    }
+}
+CPDF_Type3Font::CPDF_Type3Font() : CPDF_SimpleFont(PDFFONT_TYPE3)
+{
+    m_pPageResources = NULL;
+    FXSYS_memset(m_CharWidthL, 0, sizeof m_CharWidthL);
+}
+CPDF_Type3Font::~CPDF_Type3Font()
+{
+    FX_POSITION pos = m_CacheMap.GetStartPosition();
+    while (pos) {
+        void* key;
+        void* value;
+        m_CacheMap.GetNextAssoc(pos, key, value);
+        delete (CPDF_Type3Char*)value;
+    }
+    m_CacheMap.RemoveAll();
+    pos = m_DeletedMap.GetStartPosition();
+    while (pos) {
+        void* key;
+        void* value;
+        m_DeletedMap.GetNextAssoc(pos, key, value);
+        delete (CPDF_Type3Char*)key;
+    }
+}
+FX_BOOL CPDF_Type3Font::_Load()
+{
+    m_pFontResources = m_pFontDict->GetDict(FX_BSTRC("Resources"));
+    CPDF_Array* pMatrix = m_pFontDict->GetArray(FX_BSTRC("FontMatrix"));
+    FX_FLOAT xscale = 1.0f, yscale = 1.0f;
+    if (pMatrix) {
+        m_FontMatrix = pMatrix->GetMatrix();
+        xscale = m_FontMatrix.a;
+        yscale = m_FontMatrix.d;
+    }
+    CPDF_Array* pBBox = m_pFontDict->GetArray(FX_BSTRC("FontBBox"));
+    if (pBBox) {
+        m_FontBBox.left = (int32_t)(FXSYS_Mul(pBBox->GetNumber(0), xscale) * 1000);
+        m_FontBBox.bottom = (int32_t)(FXSYS_Mul(pBBox->GetNumber(1), yscale) * 1000);
+        m_FontBBox.right = (int32_t)(FXSYS_Mul(pBBox->GetNumber(2), xscale) * 1000);
+        m_FontBBox.top = (int32_t)(FXSYS_Mul(pBBox->GetNumber(3), yscale) * 1000);
+    }
+    int StartChar = m_pFontDict->GetInteger(FX_BSTRC("FirstChar"));
+    CPDF_Array* pWidthArray = m_pFontDict->GetArray(FX_BSTRC("Widths"));
+    if (pWidthArray && (StartChar >= 0 && StartChar < 256)) {
+        FX_DWORD count = pWidthArray->GetCount();
+        if (count > 256) {
+            count = 256;
+        }
+        if (StartChar + count > 256) {
+            count = 256 - StartChar;
+        }
+        for (FX_DWORD i = 0; i < count; i ++) {
+            m_CharWidthL[StartChar + i] = FXSYS_round(FXSYS_Mul(pWidthArray->GetNumber(i), xscale) * 1000);
+        }
+    }
+    m_pCharProcs = m_pFontDict->GetDict(FX_BSTRC("CharProcs"));
+    CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding"));
+    if (pEncoding) {
+        LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, FALSE, FALSE);
+        if (m_pCharNames) {
+            for (int i = 0; i < 256; i ++) {
+                m_Encoding.m_Unicodes[i] = PDF_UnicodeFromAdobeName(m_pCharNames[i]);
+                if (m_Encoding.m_Unicodes[i] == 0) {
+                    m_Encoding.m_Unicodes[i] = i;
+                }
+            }
+        }
+    }
+    return TRUE;
+}
+void CPDF_Type3Font::CheckType3FontMetrics()
+{
+    CheckFontMetrics();
+}
+CPDF_Type3Char* CPDF_Type3Font::LoadChar(FX_DWORD charcode, int level)
+{
+    if (level >= _FPDF_MAX_TYPE3_FORM_LEVEL_) {
+        return NULL;
+    }
+    CPDF_Type3Char* pChar = NULL;
+    if (m_CacheMap.Lookup((void*)(uintptr_t)charcode, (void*&)pChar)) {
+        if (pChar->m_bPageRequired && m_pPageResources) {
+            delete pChar;
+            m_CacheMap.RemoveKey((void*)(uintptr_t)charcode);
+            return LoadChar(charcode, level + 1);
+        }
+        return pChar;
+    }
+    const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode);
+    if (name == NULL) {
+        return NULL;
+    }
+    CPDF_Stream* pStream = (CPDF_Stream*)(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : NULL);
+    if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
+        return NULL;
+    }
+    pChar = new CPDF_Type3Char;
+    pChar->m_pForm = new CPDF_Form(m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources, pStream, NULL);
+    pChar->m_pForm->ParseContent(NULL, NULL, pChar, NULL, level + 1);
+    FX_FLOAT scale = m_FontMatrix.GetXUnit();
+    pChar->m_Width = (int32_t)(pChar->m_Width * scale + 0.5f);
+    FX_RECT &rcBBox = pChar->m_BBox;
+    CFX_FloatRect char_rect((FX_FLOAT)rcBBox.left / 1000.0f, (FX_FLOAT)rcBBox.bottom / 1000.0f,
+                            (FX_FLOAT)rcBBox.right / 1000.0f, (FX_FLOAT)rcBBox.top / 1000.0f);
+    if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) {
+        char_rect = pChar->m_pForm->CalcBoundingBox();
+    }
+    char_rect.Transform(&m_FontMatrix);
+    rcBBox.left = FXSYS_round(char_rect.left * 1000);
+    rcBBox.right = FXSYS_round(char_rect.right * 1000);
+    rcBBox.top = FXSYS_round(char_rect.top * 1000);
+    rcBBox.bottom = FXSYS_round(char_rect.bottom * 1000);
+    m_CacheMap.SetAt((void*)(uintptr_t)charcode, pChar);
+    if (pChar->m_pForm->CountObjects() == 0) {
+        delete pChar->m_pForm;
+        pChar->m_pForm = NULL;
+    }
+    return pChar;
+}
+int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level)
+{
+    if (charcode > 0xff) {
+        charcode = 0;
+    }
+    if (m_CharWidthL[charcode]) {
+        return m_CharWidthL[charcode];
+    }
+    CPDF_Type3Char* pChar = LoadChar(charcode, level);
+    if (pChar == NULL) {
+        return 0;
+    }
+    return pChar->m_Width;
+}
+void CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level)
+{
+    CPDF_Type3Char* pChar = LoadChar(charcode, level);
+    if (pChar == NULL) {
+        rect.left = rect.right = rect.top = rect.bottom = 0;
+        return;
+    }
+    rect = pChar->m_BBox;
+}
+CPDF_Type3Char::CPDF_Type3Char()
+{
+    m_pForm = NULL;
+    m_pBitmap = NULL;
+    m_bPageRequired = FALSE;
+    m_bColored = FALSE;
+}
+CPDF_Type3Char::~CPDF_Type3Char()
+{
+    if (m_pForm) {
+        delete m_pForm;
+    }
+    if (m_pBitmap) {
+        delete m_pBitmap;
+    }
+}