FX_DWORD CFX_UnicodeEncodingEx::GlyphFromCharCode(FX_DWORD charcode) { FXFT_Face face = m_pFont->GetFace(); FT_UInt nIndex = FXFT_Get_Char_Index(face, charcode); if (nIndex > 0) { return nIndex; } int nmaps = FXFT_Get_Face_CharmapCount(face); int m = 0; while (m < nmaps) { int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]); if (m_nEncodingID == nEncodingID) { continue; } int error = FXFT_Select_Charmap(face, nEncodingID); if (error) { continue; } nIndex = FXFT_Get_Char_Index(face, charcode); if (nIndex > 0) { m_nEncodingID = nEncodingID; return nIndex; } } FXFT_Select_Charmap(face, m_nEncodingID); return 0; }
int CPDF_CIDFont::GetGlyphIndex(uint32_t unicode, bool* pVertGlyph) { if (pVertGlyph) *pVertGlyph = false; FXFT_Face face = m_Font.GetFace(); int index = FXFT_Get_Char_Index(face, unicode); if (unicode == 0x2502) return index; if (!index || !IsVertWriting()) return index; if (m_pTTGSUBTable) return GetVerticalGlyph(index, pVertGlyph); if (!m_Font.GetSubData()) { unsigned long length = 0; int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, nullptr, &length); if (!error) m_Font.SetSubData(FX_Alloc(uint8_t, length)); } int error = FXFT_Load_Sfnt_Table(face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, m_Font.GetSubData(), nullptr); if (error || !m_Font.GetSubData()) return index; m_pTTGSUBTable = pdfium::MakeUnique<CFX_CTTGSUBTable>(); m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.GetSubData()); return GetVerticalGlyph(index, pVertGlyph); }
FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode) { FXFT_Face face = m_pFont->GetFace(); if (!face) return charcode; if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0) return FXFT_Get_Char_Index(face, charcode); if (m_pFont->GetSubstFont() && m_pFont->GetSubstFont()->m_Charset == 2) { FX_DWORD index = 0; if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0) index = FXFT_Get_Char_Index(face, charcode); if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN)) return FXFT_Get_Char_Index(face, charcode); } return charcode; }
FX_INT32 CFPF_SkiaFont::GetGlyphIndex(FX_WCHAR wUnicode) { if (!m_Face) { return wUnicode; } if (FXFT_Select_Charmap(m_Face, FXFT_ENCODING_UNICODE)) { return 0; } return FXFT_Get_Char_Index(m_Face, wUnicode); }
int CPDF_Font::FallbackGlyphFromCharcode(int fallbackFont, uint32_t charcode) { if (fallbackFont < 0 || fallbackFont >= pdfium::CollectionSize<int>(m_FontFallbacks)) { return -1; } int glyph = FXFT_Get_Char_Index(m_FontFallbacks[fallbackFont]->GetFace(), charcode); if (glyph == 0 || glyph == 0xffff) return -1; return glyph; }
bool CFGAS_FontMgr::VerifyUnicode(CFGAS_GEFont* pFont, FX_WCHAR wcUnicode) { if (!pFont) return false; FXFT_Face pFace = pFont->GetDevFont()->GetFace(); FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace); if (FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE) != 0) return false; if (FXFT_Get_Char_Index(pFace, wcUnicode) == 0) { FXFT_Set_Charmap(pFace, charmap); return false; } return true; }
FX_BOOL CFGAS_FontMgrImp::VerifyUnicode(CFX_FontDescriptor* pDesc, FX_WCHAR wcUnicode) { IFX_FileRead* pFileRead = CreateFontStream(pDesc->m_wsFaceName.UTF8Encode()); if (!pFileRead) return FALSE; FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex); FT_Error retCharmap = FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE); FT_Error retIndex = FXFT_Get_Char_Index(pFace, wcUnicode); pFileRead->Release(); if (!pFace) return FALSE; if (FXFT_Get_Face_External_Stream(pFace)) FXFT_Clear_Face_External_Stream(pFace); FXFT_Done_Face(pFace); return !retCharmap && retIndex; }
FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCodeEx(FX_DWORD charcode, int encoding) { FXFT_Face face = m_pFont->GetFace(); if (!face) { return charcode; } if (encoding == ENCODING_UNICODE) { return GlyphFromCharCode(charcode); } else { int nmaps = FXFT_Get_Face_CharmapCount(m_pFont->m_Face); int i = 0; while (i < nmaps) { int encoding = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i++]); if (encoding != FXFT_ENCODING_UNICODE) { FXFT_Select_Charmap(face, encoding); break; } } } return FXFT_Get_Char_Index(face, charcode); }
void CPDF_TrueTypeFont::LoadGlyphMap() { if (!m_Font.GetFace()) return; int baseEncoding = m_BaseEncoding; if (m_pFontFile && m_Font.GetFace()->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.GetFace()); i++) { int platform_id = FXFT_Get_Charmap_PlatformID( FXFT_Get_Face_Charmaps(m_Font.GetFace())[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_CharNames.empty()) || (m_Flags & PDFFONT_NONSYMBOLIC)) { if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) && (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) { int nStartChar = m_pFontDict->GetIntegerFor("FirstChar"); if (nStartChar < 0 || nStartChar > 255) return; int charcode = 0; for (; charcode < nStartChar; charcode++) { m_GlyphIndex[charcode] = 0; } uint16_t nGlyph = charcode - nStartChar + 3; for (; charcode < 256; charcode++, nGlyph++) { m_GlyphIndex[charcode] = nGlyph; } return; } bool bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1); bool bMacRoman = false; bool bMSSymbol = false; if (!bMSUnicode) { if (m_Flags & PDFFONT_NONSYMBOLIC) { bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0); bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0); } else { bMSSymbol = FT_UseTTCharmap(m_Font.GetFace(), 3, 0); bMacRoman = !bMSSymbol && FT_UseTTCharmap(m_Font.GetFace(), 1, 0); } } FX_BOOL bToUnicode = m_pFontDict->KeyExist("ToUnicode"); for (int charcode = 0; charcode < 256; charcode++) { const FX_CHAR* name = GetAdobeCharName(baseEncoding, m_CharNames, charcode); if (!name) { m_GlyphIndex[charcode] = m_pFontFile ? FXFT_Get_Char_Index(m_Font.GetFace(), charcode) : -1; continue; } m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); if (bMSSymbol) { for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) { uint16_t unicode = kPrefix[j] * 256 + charcode; m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode); if (m_GlyphIndex[charcode]) { break; } } } else if (m_Encoding.m_Unicodes[charcode]) { if (bMSUnicode) { m_GlyphIndex[charcode] = FXFT_Get_Char_Index( m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); } else if (bMacRoman) { uint32_t maccode = FT_CharCodeFromUnicode( FXFT_ENCODING_APPLE_ROMAN, m_Encoding.m_Unicodes[charcode]); if (!maccode) { m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); } else { m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), maccode); } } } if ((m_GlyphIndex[charcode] == 0 || m_GlyphIndex[charcode] == 0xffff) && name) { if (name[0] == '.' && FXSYS_strcmp(name, ".notdef") == 0) { m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 32); } else { m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (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.GetFace(), wsUnicode[0]); m_Encoding.m_Unicodes[charcode] = wsUnicode[0]; } } if (m_GlyphIndex[charcode] == 0) { m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode); } } } } } return; } if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { bool bFound = false; for (int charcode = 0; charcode < 256; charcode++) { for (size_t j = 0; j < FX_ArraySize(kPrefix); j++) { uint16_t unicode = kPrefix[j] * 256 + charcode; m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), unicode); if (m_GlyphIndex[charcode]) { bFound = true; break; } } } if (bFound) { if (baseEncoding != PDFFONT_ENCODING_BUILTIN) { for (int charcode = 0; charcode < 256; charcode++) { const FX_CHAR* name = GetAdobeCharName(baseEncoding, m_CharNames, charcode); if (name) m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); } } else if (FT_UseTTCharmap(m_Font.GetFace(), 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.GetFace(), 1, 0)) { bool bFound = false; for (int charcode = 0; charcode < 256; charcode++) { m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), charcode); m_Encoding.m_Unicodes[charcode] = FT_UnicodeFromCharCode(FXFT_ENCODING_APPLE_ROMAN, charcode); if (m_GlyphIndex[charcode]) { bFound = true; } } if (m_pFontFile || bFound) return; } if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) { bool bFound = false; const uint16_t* pUnicodes = PDF_UnicodesForPredefinedCharSet(baseEncoding); for (int charcode = 0; charcode < 256; charcode++) { if (m_pFontFile) { m_Encoding.m_Unicodes[charcode] = charcode; } else { const FX_CHAR* name = GetAdobeCharName(0, m_CharNames, charcode); if (name) m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); else if (pUnicodes) m_Encoding.m_Unicodes[charcode] = pUnicodes[charcode]; } m_GlyphIndex[charcode] = FXFT_Get_Char_Index( m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); if (m_GlyphIndex[charcode]) bFound = true; } if (bFound) return; } for (int charcode = 0; charcode < 256; charcode++) m_GlyphIndex[charcode] = charcode; }
int CPDF_CIDFont::GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) { if (pVertGlyph) *pVertGlyph = false; if (!m_pFontFile && !m_pStreamAcc) { uint16_t cid = CIDFromCharCode(charcode); FX_WCHAR unicode = 0; if (m_bCIDIsGID) { #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ return cid; #else if (m_Flags & FXFONT_SYMBOLIC) return cid; CFX_WideString uni_str = UnicodeFromCharCode(charcode); if (uni_str.IsEmpty()) return cid; unicode = uni_str.GetAt(0); #endif } else { if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded()) unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid); if (unicode == 0) unicode = GetUnicodeFromCharCode(charcode); if (unicode == 0) { CFX_WideString unicode_str = UnicodeFromCharCode(charcode); if (!unicode_str.IsEmpty()) unicode = unicode_str.GetAt(0); } } FXFT_Face face = m_Font.GetFace(); if (unicode == 0) { if (!m_bAdobeCourierStd) return charcode ? static_cast<int>(charcode) : -1; charcode += 31; bool bMSUnicode = FT_UseTTCharmap(face, 3, 1); bool bMacRoman = !bMSUnicode && FT_UseTTCharmap(face, 1, 0); int iBaseEncoding = PDFFONT_ENCODING_STANDARD; if (bMSUnicode) iBaseEncoding = PDFFONT_ENCODING_WINANSI; else if (bMacRoman) iBaseEncoding = PDFFONT_ENCODING_MACROMAN; const FX_CHAR* name = GetAdobeCharName( iBaseEncoding, std::vector<CFX_ByteString>(), charcode); if (!name) return charcode ? static_cast<int>(charcode) : -1; int index = 0; uint16_t name_unicode = PDF_UnicodeFromAdobeName(name); if (!name_unicode) return charcode ? static_cast<int>(charcode) : -1; if (iBaseEncoding == PDFFONT_ENCODING_STANDARD) return FXFT_Get_Char_Index(face, name_unicode); if (iBaseEncoding == PDFFONT_ENCODING_WINANSI) { index = FXFT_Get_Char_Index(face, name_unicode); } else { ASSERT(iBaseEncoding == PDFFONT_ENCODING_MACROMAN); uint32_t maccode = FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, name_unicode); index = maccode ? FXFT_Get_Char_Index(face, maccode) : FXFT_Get_Name_Index(face, const_cast<char*>(name)); } if (index == 0 || index == 0xffff) return charcode ? static_cast<int>(charcode) : -1; return index; } if (m_Charset == CIDSET_JAPAN1) { if (unicode == '\\') { unicode = '/'; #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ } else if (unicode == 0xa5) { unicode = 0x5c; #endif } } if (!face) return unicode; int err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE); if (err) { int i; for (i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) { uint32_t ret = FT_CharCodeFromUnicode( FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]), static_cast<FX_WCHAR>(charcode)); if (ret == 0) continue; FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[i]); unicode = static_cast<FX_WCHAR>(ret); break; } if (i == FXFT_Get_Face_CharmapCount(face) && i) { FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); unicode = static_cast<FX_WCHAR>(charcode); } } if (FXFT_Get_Face_Charmap(face)) { int index = GetGlyphIndex(unicode, pVertGlyph); return index != 0 ? index : -1; } return unicode; } if (!m_Font.GetFace()) return -1; uint16_t cid = CIDFromCharCode(charcode); if (!m_pStreamAcc) { if (m_bType1) return cid; if (m_pFontFile && !m_pCMap->m_pMapping) return cid; if (m_pCMap->m_Coding == CIDCODING_UNKNOWN || !FXFT_Get_Face_Charmap(m_Font.GetFace())) { return cid; } if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.GetFace())) == FXFT_ENCODING_UNICODE) { CFX_WideString unicode_str = UnicodeFromCharCode(charcode); if (unicode_str.IsEmpty()) return -1; charcode = unicode_str.GetAt(0); } return GetGlyphIndex(charcode, pVertGlyph); } uint32_t byte_pos = cid * 2; if (byte_pos + 2 > m_pStreamAcc->GetSize()) return -1; const uint8_t* pdata = m_pStreamAcc->GetData() + byte_pos; return pdata[0] * 256 + pdata[1]; }