| Index: core/src/fpdfapi/fpdf_font/fpdf_font.cpp | 
| diff --git a/core/src/fpdfapi/fpdf_font/fpdf_font.cpp b/core/src/fpdfapi/fpdf_font/fpdf_font.cpp | 
| index 8037a8c674e811202d43d3c91bcff16a5e1df452..0107000dd9725f91c5587694f7135d5965fd48f2 100644 | 
| --- a/core/src/fpdfapi/fpdf_font/fpdf_font.cpp | 
| +++ b/core/src/fpdfapi/fpdf_font/fpdf_font.cpp | 
| @@ -12,1735 +12,1786 @@ | 
| #include "../fpdf_page/pageint.h" | 
| #include "font_int.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; | 
| -} | 
| -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]; | 
| +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; | 
| +} | 
| +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) | 
| -{ | 
| +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; | 
| -    if (!m_pStockMap.Lookup(key, value)) { | 
| -        return; | 
| -    } | 
| +    m_pStockMap.GetNextAssoc(pos, key, value); | 
| 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; | 
| +  } | 
| +} | 
| +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; | 
| +  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]; | 
| +  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 { | 
| -        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; | 
| -                    } | 
| -                } | 
| -            } | 
| -        } | 
| +      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; | 
| } | 
| -    if (m_Ascent == 0 && m_Descent == 0) { | 
| +    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('A', rect); | 
| -        if (rect.bottom == rect.top) { | 
| -            m_Ascent = m_FontBBox.top; | 
| -        } else { | 
| -            m_Ascent = rect.top; | 
| +        GetCharBBox(i, rect); | 
| +        if (rect.left == rect.right) { | 
| +          continue; | 
| } | 
| -        GetCharBBox('g', rect); | 
| -        if (rect.bottom == rect.top) { | 
| -            m_Descent = m_FontBBox.bottom; | 
| +        if (bFirst) { | 
| +          m_FontBBox = rect; | 
| +          bFirst = FALSE; | 
| } 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; | 
| +          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; | 
| } | 
| -    return m_Font.GetGlyphWidth(glyph_index); | 
| +    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; | 
| -    } | 
| +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; | 
| -} | 
| -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(); | 
| +  } | 
| +  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; | 
| } | 
| -        return CFX_WideString(buf + index + 1, len); | 
| -    } | 
| -    if (m_pBaseMap) { | 
| -        return m_pBaseMap->UnicodeFromCID((FX_WORD)charcode); | 
| +      } | 
| +#endif | 
| } | 
| -    return CFX_WideString(); | 
| +    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_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; | 
| -        } | 
| -    } | 
| +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; | 
| -} | 
| -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; | 
| +  } | 
| +  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; | 
| } | 
| -    for (int i = 0; i < len; i ++) { | 
| -        if (buf[i] < '0' || buf[i] > '9') { | 
| -            break; | 
| -        } | 
| -        result = result * 10 + buf[i] - '0'; | 
| +    return result; | 
| +  } | 
| +  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; | 
| -} | 
| -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); | 
| +  } | 
| +  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 { | 
| -            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; | 
| +          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; | 
| } | 
| -            ch = ch * 16 + digit; | 
| -            byte_pos ++; | 
| -            if (byte_pos == 4) { | 
| -                result += ch; | 
| -                byte_pos = 0; | 
| -                ch = 0; | 
| +            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; | 
| } | 
| -        } | 
| -        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; | 
| -                } | 
| +          } | 
| +          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 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 { | 
| +            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 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 { | 
| -        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; | 
| +      cur_code = pElement->GetInteger(); | 
| } | 
| -    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; | 
| -} | 
| -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; | 
| -    } | 
| +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; | 
| +} | 
| +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) { | 
| -        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(); | 
| +      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; | 
| -} | 
| -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]); | 
| +  } | 
| +  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 { | 
| -        FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); | 
| -    } | 
| -    return TRUE; | 
| +      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_ | 
| +#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; | 
| +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_ | 
| +#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"} | 
| +  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 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; | 
| +} | 
| +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); | 
| -                    } | 
| +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 (m_GlyphIndex[charcode]) { | 
| -                        bGotOne = TRUE; | 
| -                        break; | 
| -                    } | 
| -                } | 
| -            } | 
| -            if (bGotOne) { | 
| -#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_ | 
| -                if (!bCoreText) { | 
| -                    FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); | 
| -                } | 
| +  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 | 
| -                return; | 
| -            } | 
| +          if (m_GlyphIndex[charcode]) { | 
| +            bGotOne = TRUE; | 
| +            break; | 
| +          } | 
| } | 
| -        FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE); | 
| -        if (m_BaseEncoding == 0) { | 
| -            m_BaseEncoding = PDFFONT_ENCODING_STANDARD; | 
| +      } | 
| +      if (bGotOne) { | 
| +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 
| +        if (!bCoreText) { | 
| +          FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); | 
| } | 
| -        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); | 
| -                } | 
| +        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 _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_ | 
| -        if (!bCoreText) { | 
| -            FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); | 
| +      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 | 
| -        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; | 
| +#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); | 
| -            } 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; | 
| +      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; | 
| -        } | 
| +      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); | 
| -        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; | 
| +        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 _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 
| if (!bCoreText) { | 
| -        FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); | 
| +      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]; | 
| -        } | 
| +CPDF_FontEncoding::CPDF_FontEncoding() { | 
| +  FXSYS_memset(m_Unicodes, 0, sizeof(m_Unicodes)); | 
| } | 
| -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]))); | 
| +int CPDF_FontEncoding::CharCodeFromUnicode(FX_WCHAR unicode) const { | 
| +  for (int i = 0; i < 256; i++) | 
| +    if (m_Unicodes[i] == unicode) { | 
| +      return i; | 
| } | 
| -    pDict->SetAt(FX_BSTRC("Differences"), pDiff); | 
| -    return pDict; | 
| +  return -1; | 
| } | 
| -CPDF_TrueTypeFont::CPDF_TrueTypeFont() : CPDF_SimpleFont(PDFFONT_TRUETYPE) | 
| -{ | 
| -} | 
| -FX_BOOL CPDF_TrueTypeFont::_Load() | 
| -{ | 
| -    return LoadCommon(); | 
| -} | 
| -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; | 
| -        } | 
| +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"); | 
| } | 
| -    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 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(); | 
| +} | 
| +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; | 
| -    } | 
| -    if (FT_UseTTCharmap(m_Font.m_Face, 3, 0)) { | 
| + | 
| +      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}; | 
| -        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; | 
| +        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 (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; | 
| -                } | 
| +            if (m_GlyphIndex[charcode] == 0) { | 
| +              m_GlyphIndex[charcode] = | 
| +                  FXFT_Get_Char_Index(m_Font.m_Face, charcode); | 
| } | 
| -        } | 
| -    } | 
| -    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; | 
| +  } | 
| +  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; | 
| -} | 
| -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() | 
| -{ | 
| -    delete m_pForm; | 
| -    delete m_pBitmap; | 
| +  } | 
| +  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() { | 
| +  delete m_pForm; | 
| +  delete m_pBitmap; | 
| } | 
|  |