Index: core/fpdfapi/fpdf_font/fpdf_font.cpp |
diff --git a/core/fpdfapi/fpdf_font/fpdf_font.cpp b/core/fpdfapi/fpdf_font/fpdf_font.cpp |
index 8dc91616f9933d7bb0aef53a4f701cd59b014828..c0c6f520f44f3b81b896eb040d6c0f822f885010 100644 |
--- a/core/fpdfapi/fpdf_font/fpdf_font.cpp |
+++ b/core/fpdfapi/fpdf_font/fpdf_font.cpp |
@@ -14,87 +14,12 @@ |
#include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" |
#include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" |
#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h" |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
#include "core/fpdfapi/include/cpdf_modulemgr.h" |
#include "core/fxcrt/include/fx_ext.h" |
-#include "core/include/fpdfapi/fpdf_resource.h" |
#include "core/include/fxge/fx_freetype.h" |
#include "third_party/base/stl_util.h" |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
-#include "core/fxge/apple/apple_int.h" |
-#endif |
- |
-namespace { |
- |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
-struct GlyphNameMap { |
- const FX_CHAR* m_pStrAdobe; |
- const FX_CHAR* m_pStrUnicode; |
-}; |
- |
-const GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"}, |
- {"fi", "uniFB01"}, |
- {"fl", "uniFB02"}, |
- {"ffi", "uniFB03"}, |
- {"ffl", "uniFB04"}}; |
- |
-int compareString(const void* key, const void* element) { |
- return FXSYS_stricmp((const FX_CHAR*)key, |
- ((GlyphNameMap*)element)->m_pStrAdobe); |
-} |
- |
-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 |
- |
-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}}; |
- |
-FX_BOOL GetPredefinedEncoding(int& basemap, const CFX_ByteString& value) { |
- if (value == "WinAnsiEncoding") { |
- basemap = PDFFONT_ENCODING_WINANSI; |
- } else if (value == "MacRomanEncoding") { |
- basemap = PDFFONT_ENCODING_MACROMAN; |
- } else if (value == "MacExpertEncoding") { |
- basemap = PDFFONT_ENCODING_MACEXPERT; |
- } else if (value == "PDFDocEncoding") { |
- basemap = PDFFONT_ENCODING_PDFDOC; |
- } else { |
- return FALSE; |
- } |
- return TRUE; |
-} |
- |
-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; |
-} |
- |
-} // namespace |
- |
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]) == |
@@ -156,356 +81,15 @@ void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) { |
m_StockMap.erase(pDoc); |
} |
-CPDF_Font::CPDF_Font() |
- : m_pFontFile(nullptr), |
- m_pFontDict(nullptr), |
- m_pToUnicodeMap(nullptr), |
- m_bToUnicodeLoaded(FALSE), |
- m_Flags(0), |
- m_StemV(0), |
- m_Ascent(0), |
- m_Descent(0), |
- m_ItalicAngle(0) {} |
- |
-CPDF_Font::~CPDF_Font() { |
- delete m_pToUnicodeMap; |
- m_pToUnicodeMap = NULL; |
- |
- if (m_pFontFile) { |
- m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( |
- const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream())); |
- } |
-} |
- |
-bool CPDF_Font::IsType1Font() const { |
- return false; |
-} |
- |
-bool CPDF_Font::IsTrueTypeFont() const { |
- return false; |
-} |
- |
-bool CPDF_Font::IsType3Font() const { |
- return false; |
-} |
- |
-bool CPDF_Font::IsCIDFont() const { |
- return false; |
-} |
- |
-const CPDF_Type1Font* CPDF_Font::AsType1Font() const { |
- return nullptr; |
-} |
- |
-CPDF_Type1Font* CPDF_Font::AsType1Font() { |
- return nullptr; |
-} |
- |
-const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const { |
- return nullptr; |
-} |
- |
-CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() { |
- return nullptr; |
-} |
- |
-const CPDF_Type3Font* CPDF_Font::AsType3Font() const { |
- return nullptr; |
-} |
- |
-CPDF_Type3Font* CPDF_Font::AsType3Font() { |
- return nullptr; |
-} |
- |
-const CPDF_CIDFont* CPDF_Font::AsCIDFont() const { |
- return nullptr; |
-} |
- |
-CPDF_CIDFont* CPDF_Font::AsCIDFont() { |
- return nullptr; |
-} |
- |
-FX_BOOL CPDF_Font::IsUnicodeCompatible() const { |
- return FALSE; |
-} |
- |
-int CPDF_Font::CountChar(const FX_CHAR* pString, int size) const { |
- return size; |
-} |
- |
-int CPDF_Font::GetCharSize(FX_DWORD charcode) const { |
- return 1; |
-} |
- |
-int CPDF_Font::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph) { |
- ASSERT(false); |
- return 0; |
-} |
- |
-int CPDF_Font::GlyphFromCharCodeExt(FX_DWORD charcode) { |
- return GlyphFromCharCode(charcode); |
-} |
- |
-FX_BOOL CPDF_Font::IsVertWriting() const { |
- FX_BOOL bVertWriting = FALSE; |
- const CPDF_CIDFont* pCIDFont = AsCIDFont(); |
- if (pCIDFont) { |
- bVertWriting = pCIDFont->IsVertWriting(); |
- } else { |
- bVertWriting = m_Font.IsVertical(); |
- } |
- return bVertWriting; |
-} |
- |
-int CPDF_Font::AppendChar(FX_CHAR* buf, FX_DWORD charcode) const { |
- *buf = (FX_CHAR)charcode; |
- return 1; |
-} |
- |
-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) |
- return m_pToUnicodeMap->Lookup(charcode); |
- return CFX_WideString(); |
-} |
- |
-FX_DWORD CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const { |
- if (!m_bToUnicodeLoaded) |
- ((CPDF_Font*)this)->LoadUnicodeMap(); |
- |
- if (m_pToUnicodeMap) |
- return m_pToUnicodeMap->ReverseLookup(unicode); |
- return 0; |
-} |
- |
-void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) { |
- m_Flags = pFontDesc->GetIntegerBy("Flags", PDFFONT_NONSYMBOLIC); |
- int ItalicAngle = 0; |
- FX_BOOL bExistItalicAngle = FALSE; |
- if (pFontDesc->KeyExist("ItalicAngle")) { |
- ItalicAngle = pFontDesc->GetIntegerBy("ItalicAngle"); |
- bExistItalicAngle = TRUE; |
- } |
- if (ItalicAngle < 0) { |
- m_Flags |= PDFFONT_ITALIC; |
- m_ItalicAngle = ItalicAngle; |
- } |
- FX_BOOL bExistStemV = FALSE; |
- if (pFontDesc->KeyExist("StemV")) { |
- m_StemV = pFontDesc->GetIntegerBy("StemV"); |
- bExistStemV = TRUE; |
- } |
- FX_BOOL bExistAscent = FALSE; |
- if (pFontDesc->KeyExist("Ascent")) { |
- m_Ascent = pFontDesc->GetIntegerBy("Ascent"); |
- bExistAscent = TRUE; |
- } |
- FX_BOOL bExistDescent = FALSE; |
- if (pFontDesc->KeyExist("Descent")) { |
- m_Descent = pFontDesc->GetIntegerBy("Descent"); |
- bExistDescent = TRUE; |
- } |
- FX_BOOL bExistCapHeight = FALSE; |
- if (pFontDesc->KeyExist("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->GetArrayBy("FontBBox"); |
- if (pBBox) { |
- m_FontBBox.left = pBBox->GetIntegerAt(0); |
- m_FontBBox.bottom = pBBox->GetIntegerAt(1); |
- m_FontBBox.right = pBBox->GetIntegerAt(2); |
- m_FontBBox.top = pBBox->GetIntegerAt(3); |
- } |
- |
- CPDF_Stream* pFontFile = pFontDesc->GetStreamBy("FontFile"); |
- if (!pFontFile) |
- pFontFile = pFontDesc->GetStreamBy("FontFile2"); |
- if (!pFontFile) |
- pFontFile = pFontDesc->GetStreamBy("FontFile3"); |
- if (!pFontFile) |
- return; |
- |
- m_pFontFile = m_pDocument->LoadFontFile(pFontFile); |
- if (!m_pFontFile) |
- return; |
- const uint8_t* pFontData = m_pFontFile->GetData(); |
- FX_DWORD dwFontSize = m_pFontFile->GetSize(); |
- if (!m_Font.LoadEmbedded(pFontData, dwFontSize)) { |
- m_pDocument->GetPageData()->ReleaseFontFileStreamAcc( |
- const_cast<CPDF_Stream*>(m_pFontFile->GetStream()->AsStream())); |
- m_pFontFile = nullptr; |
- } |
-} |
short TT2PDF(int m, FXFT_Face face) { |
int upm = FXFT_Get_Face_UnitsPerEM(face); |
- if (upm == 0) { |
+ 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) { |
- FXFT_Face face = m_Font.GetFace(); |
- if (face) { |
- m_FontBBox.left = TT2PDF(FXFT_Get_Face_xMin(face), face); |
- m_FontBBox.bottom = TT2PDF(FXFT_Get_Face_yMin(face), face); |
- m_FontBBox.right = TT2PDF(FXFT_Get_Face_xMax(face), face); |
- m_FontBBox.top = TT2PDF(FXFT_Get_Face_yMax(face), face); |
- m_Ascent = TT2PDF(FXFT_Get_Face_Ascender(face), face); |
- m_Descent = TT2PDF(FXFT_Get_Face_Descender(face), face); |
- } else { |
- FX_BOOL bFirst = TRUE; |
- for (int i = 0; i < 256; i++) { |
- FX_RECT rect = GetCharBBox(i); |
- if (rect.left == rect.right) { |
- continue; |
- } |
- if (bFirst) { |
- m_FontBBox = rect; |
- bFirst = FALSE; |
- } else { |
- if (m_FontBBox.top < rect.top) { |
- m_FontBBox.top = rect.top; |
- } |
- if (m_FontBBox.right < rect.right) { |
- m_FontBBox.right = rect.right; |
- } |
- if (m_FontBBox.left > rect.left) { |
- m_FontBBox.left = rect.left; |
- } |
- if (m_FontBBox.bottom > rect.bottom) { |
- m_FontBBox.bottom = rect.bottom; |
- } |
- } |
- } |
- } |
- } |
- if (m_Ascent == 0 && m_Descent == 0) { |
- FX_RECT rect = GetCharBBox('A'); |
- m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top; |
- rect = GetCharBBox('g'); |
- m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom; |
- } |
-} |
- |
-void CPDF_Font::LoadUnicodeMap() { |
- m_bToUnicodeLoaded = TRUE; |
- CPDF_Stream* pStream = m_pFontDict->GetStreamBy("ToUnicode"); |
- if (!pStream) { |
- 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; |
-} |
- |
-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 nullptr; |
- } |
- CPDF_FontGlobals* pFontGlobals = |
- CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); |
- CPDF_Font* pFont = pFontGlobals->Find(pDoc, font_id); |
- if (pFont) { |
- return pFont; |
- } |
- CPDF_Dictionary* pDict = new CPDF_Dictionary; |
- pDict->SetAtName("Type", "Font"); |
- pDict->SetAtName("Subtype", "Type1"); |
- pDict->SetAtName("BaseFont", fontname); |
- pDict->SetAtName("Encoding", "WinAnsiEncoding"); |
- pFont = CPDF_Font::CreateFontF(NULL, pDict); |
- pFontGlobals->Set(pDoc, font_id, pFont); |
- return pFont; |
-} |
- |
-CPDF_Font* CPDF_Font::CreateFontF(CPDF_Document* pDoc, |
- CPDF_Dictionary* pFontDict) { |
- CFX_ByteString type = pFontDict->GetStringBy("Subtype"); |
- CPDF_Font* pFont; |
- if (type == "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->GetStringBy("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->GetDictBy("FontDescriptor"); |
- if (!pFontDesc || !pFontDesc->KeyExist("FontFile2")) { |
- pFont = new CPDF_CIDFont; |
- pFont->m_pFontDict = pFontDict; |
- pFont->m_pDocument = pDoc; |
- pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont"); |
- if (!pFont->Load()) { |
- delete pFont; |
- return NULL; |
- } |
- return pFont; |
- } |
- } |
-#endif |
- } |
- pFont = new CPDF_TrueTypeFont; |
- } else if (type == "Type3") { |
- pFont = new CPDF_Type3Font; |
- } else if (type == "Type0") { |
- pFont = new CPDF_CIDFont; |
- } else { |
- pFont = new CPDF_Type1Font; |
- } |
- pFont->m_pFontDict = pFontDict; |
- pFont->m_pDocument = pDoc; |
- pFont->m_BaseFont = pFontDict->GetStringBy("BaseFont"); |
- if (!pFont->Load()) { |
- delete pFont; |
- return NULL; |
- } |
- return pFont; |
-} |
CFX_WideString CPDF_ToUnicodeMap::Lookup(FX_DWORD charcode) { |
auto it = m_Map.find(charcode); |
@@ -716,1098 +300,3 @@ void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) { |
m_pBaseMap = NULL; |
} |
} |
- |
-FX_DWORD CPDF_Font::GetNextChar(const FX_CHAR* pString, |
- int nStrLen, |
- int& offset) const { |
- if (offset < 0 || nStrLen < 1) { |
- return 0; |
- } |
- uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1]; |
- return static_cast<FX_DWORD>(ch); |
-} |
- |
-void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, |
- int& iBaseEncoding, |
- CFX_ByteString*& pCharNames, |
- FX_BOOL bEmbedded, |
- FX_BOOL bTrueType) { |
- if (!pEncoding) { |
- if (m_BaseFont == "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->IsName()) { |
- if (iBaseEncoding == PDFFONT_ENCODING_ADOBE_SYMBOL || |
- iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) { |
- return; |
- } |
- if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") { |
- if (!bTrueType) { |
- iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; |
- } |
- return; |
- } |
- CFX_ByteString bsEncoding = pEncoding->GetString(); |
- if (bsEncoding.Compare("MacExpertEncoding") == 0) { |
- bsEncoding = "WinAnsiEncoding"; |
- } |
- GetPredefinedEncoding(iBaseEncoding, bsEncoding); |
- return; |
- } |
- |
- CPDF_Dictionary* pDict = pEncoding->AsDictionary(); |
- if (!pDict) |
- return; |
- |
- if (iBaseEncoding != PDFFONT_ENCODING_ADOBE_SYMBOL && |
- iBaseEncoding != PDFFONT_ENCODING_ZAPFDINGBATS) { |
- CFX_ByteString bsEncoding = pDict->GetStringBy("BaseEncoding"); |
- if (bsEncoding.Compare("MacExpertEncoding") == 0 && bTrueType) { |
- bsEncoding = "WinAnsiEncoding"; |
- } |
- GetPredefinedEncoding(iBaseEncoding, bsEncoding); |
- } |
- if ((!bEmbedded || bTrueType) && iBaseEncoding == PDFFONT_ENCODING_BUILTIN) { |
- iBaseEncoding = PDFFONT_ENCODING_STANDARD; |
- } |
- CPDF_Array* pDiffs = pDict->GetArrayBy("Differences"); |
- if (!pDiffs) { |
- 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) |
- continue; |
- |
- if (CPDF_Name* pName = pElement->AsName()) { |
- if (cur_code < 256) |
- pCharNames[cur_code] = pName->GetString(); |
- cur_code++; |
- } else { |
- cur_code = pElement->GetInteger(); |
- } |
- } |
-} |
- |
-FX_BOOL CPDF_Font::IsStandardFont() const { |
- if (!IsType1Font()) |
- return FALSE; |
- if (m_pFontFile) |
- return FALSE; |
- if (AsType1Font()->GetBase14Font() < 0) |
- return FALSE; |
- return TRUE; |
-} |
- |
-CPDF_SimpleFont::CPDF_SimpleFont() |
- : m_pCharNames(nullptr), m_BaseEncoding(PDFFONT_ENCODING_BUILTIN) { |
- FXSYS_memset(m_CharWidth, 0xff, sizeof m_CharWidth); |
- FXSYS_memset(m_GlyphIndex, 0xff, sizeof m_GlyphIndex); |
- FXSYS_memset(m_ExtGID, 0xff, sizeof m_ExtGID); |
-} |
- |
-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.GetFace()) |
- return; |
- |
- if (charcode < 0 || charcode > 0xff) { |
- return; |
- } |
- int glyph_index = m_GlyphIndex[charcode]; |
- if (glyph_index == 0xffff) { |
- if (!m_pFontFile && charcode != 32) { |
- LoadCharMetrics(32); |
- m_CharBBox[charcode] = m_CharBBox[32]; |
- if (m_bUseFontWidth) { |
- m_CharWidth[charcode] = m_CharWidth[32]; |
- } |
- } |
- return; |
- } |
- FXFT_Face face = m_Font.GetFace(); |
- int err = FXFT_Load_Glyph( |
- face, glyph_index, |
- FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); |
- if (err) { |
- return; |
- } |
- m_CharBBox[charcode] = FX_SMALL_RECT( |
- TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face), |
- TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face), |
- TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face), |
- face), |
- TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face), |
- face)); |
- |
- if (m_bUseFontWidth) { |
- int TT_Width = TT2PDF(FXFT_Get_Glyph_HoriAdvance(face), face); |
- if (m_CharWidth[charcode] == 0xffff) { |
- m_CharWidth[charcode] = TT_Width; |
- } else if (TT_Width && !IsEmbedded()) { |
- m_CharBBox[charcode].right = |
- m_CharBBox[charcode].right * m_CharWidth[charcode] / TT_Width; |
- m_CharBBox[charcode].left = |
- m_CharBBox[charcode].left * m_CharWidth[charcode] / TT_Width; |
- } |
- } |
-} |
- |
-int CPDF_SimpleFont::GetCharWidthF(FX_DWORD charcode, int level) { |
- if (charcode > 0xff) { |
- charcode = 0; |
- } |
- if (m_CharWidth[charcode] == 0xffff) { |
- LoadCharMetrics(charcode); |
- if (m_CharWidth[charcode] == 0xffff) { |
- m_CharWidth[charcode] = 0; |
- } |
- } |
- return (int16_t)m_CharWidth[charcode]; |
-} |
- |
-FX_RECT CPDF_SimpleFont::GetCharBBox(FX_DWORD charcode, int level) { |
- if (charcode > 0xff) |
- charcode = 0; |
- |
- if (m_CharBBox[charcode].left == FX_SMALL_RECT::kInvalid) |
- LoadCharMetrics(charcode); |
- |
- return FX_RECT(m_CharBBox[charcode]); |
-} |
- |
-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 || name[0] == 0) && iBaseEncoding) { |
- name = PDF_CharNameFromPredefinedCharSet(iBaseEncoding, charcode); |
- } |
- return name && name[0] ? name : nullptr; |
-} |
- |
-FX_BOOL CPDF_SimpleFont::LoadCommon() { |
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor"); |
- if (pFontDesc) { |
- LoadFontDescriptor(pFontDesc); |
- } |
- CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("Widths"); |
- int width_start = 0, width_end = -1; |
- m_bUseFontWidth = TRUE; |
- if (pWidthArray) { |
- m_bUseFontWidth = FALSE; |
- if (pFontDesc && pFontDesc->KeyExist("MissingWidth")) { |
- int MissingWidth = pFontDesc->GetIntegerBy("MissingWidth"); |
- for (int i = 0; i < 256; i++) { |
- m_CharWidth[i] = MissingWidth; |
- } |
- } |
- width_start = m_pFontDict->GetIntegerBy("FirstChar", 0); |
- width_end = m_pFontDict->GetIntegerBy("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->GetIntegerAt(i - width_start); |
- } |
- } |
- } |
- if (m_pFontFile) { |
- if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') { |
- m_BaseFont = m_BaseFont.Mid(8); |
- } |
- } else { |
- LoadSubstFont(); |
- } |
- if (!(m_Flags & PDFFONT_SYMBOLIC)) { |
- m_BaseEncoding = PDFFONT_ENCODING_STANDARD; |
- } |
- CPDF_Object* pEncoding = m_pFontDict->GetElementValue("Encoding"); |
- LoadPDFEncoding(pEncoding, m_BaseEncoding, m_pCharNames, m_pFontFile != NULL, |
- m_Font.IsTTFont()); |
- LoadGlyphMap(); |
- delete[] m_pCharNames; |
- m_pCharNames = NULL; |
- if (!m_Font.GetFace()) |
- 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) { |
- 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, IsTrueTypeFont(), m_Flags, weight, m_ItalicAngle, |
- 0); |
- if (m_Font.GetSubstFont()->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; |
-} |
- |
-CFX_WideString CPDF_SimpleFont::UnicodeFromCharCode(FX_DWORD charcode) const { |
- CFX_WideString unicode = CPDF_Font::UnicodeFromCharCode(charcode); |
- if (!unicode.IsEmpty()) |
- return unicode; |
- FX_WCHAR ret = m_Encoding.UnicodeFromCharCode((uint8_t)charcode); |
- if (ret == 0) |
- return CFX_WideString(); |
- return ret; |
-} |
- |
-FX_DWORD CPDF_SimpleFont::CharCodeFromUnicode(FX_WCHAR unicode) const { |
- FX_DWORD ret = CPDF_Font::CharCodeFromUnicode(unicode); |
- if (ret) |
- return ret; |
- return m_Encoding.CharCodeFromUnicode(unicode); |
-} |
- |
-CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {} |
- |
-bool CPDF_Type1Font::IsType1Font() const { |
- return true; |
-} |
- |
-const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const { |
- return this; |
-} |
- |
-CPDF_Type1Font* CPDF_Type1Font::AsType1Font() { |
- return this; |
-} |
- |
-FX_BOOL CPDF_Type1Font::Load() { |
- m_Base14Font = PDF_GetStandardFontName(&m_BaseFont); |
- if (m_Base14Font >= 0) { |
- CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictBy("FontDescriptor"); |
- if (pFontDesc && pFontDesc->KeyExist("Flags")) |
- m_Flags = pFontDesc->GetIntegerBy("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(); |
-} |
- |
-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; |
-} |
- |
-void CPDF_Type1Font::LoadGlyphMap() { |
- if (!m_Font.GetFace()) |
- return; |
- |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- FX_BOOL bCoreText = TRUE; |
- CQuartz2D& quartz2d = |
- ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; |
- if (!m_Font.GetPlatformFont()) { |
- if (m_Font.GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { |
- bCoreText = FALSE; |
- } |
- m_Font.SetPlatformFont( |
- quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize())); |
- if (!m_Font.GetPlatformFont()) { |
- bCoreText = FALSE; |
- } |
- } |
-#endif |
- if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) { |
- if (FT_UseTTCharmap(m_Font.GetFace(), 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++) { |
- uint16_t unicode = prefix[j] * 256 + charcode; |
- m_GlyphIndex[charcode] = |
- FXFT_Get_Char_Index(m_Font.GetFace(), unicode); |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- FX_CHAR name_glyph[256]; |
- FXFT_Get_Glyph_Name(m_Font.GetFace(), 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.GetPlatformFont(), name_ct); |
- if (name_ct) { |
- CFRelease(name_ct); |
- } |
-#endif |
- if (m_GlyphIndex[charcode]) { |
- bGotOne = TRUE; |
- break; |
- } |
- } |
- } |
- if (bGotOne) { |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- if (!bCoreText) { |
- FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); |
- } |
-#endif |
- return; |
- } |
- } |
- FXFT_Select_Charmap(m_Font.GetFace(), 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) { |
- continue; |
- } |
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index( |
- m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- FX_CHAR name_glyph[256]; |
- FXFT_Get_Glyph_Name(m_Font.GetFace(), 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.GetPlatformFont(), 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.GetFace(), 0x20); |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- FX_CHAR name_glyph[256]; |
- FXFT_Get_Glyph_Name(m_Font.GetFace(), 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.GetPlatformFont(), name_ct); |
- if (name_ct) { |
- CFRelease(name_ct); |
- } |
-#endif |
- } |
- } |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- if (!bCoreText) { |
- FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); |
- } |
-#endif |
- return; |
- } |
- FT_UseType1Charmap(m_Font.GetFace()); |
-#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.GetFace(), (char*)name); |
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy( |
- kCFAllocatorDefault, name, kCFStringEncodingASCII, |
- kCFAllocatorNull); |
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
- (CGFontRef)m_Font.GetPlatformFont(), name_ct); |
- if (name_ct) { |
- CFRelease(name_ct); |
- } |
- } else { |
- m_GlyphIndex[charcode] = |
- FXFT_Get_Char_Index(m_Font.GetFace(), 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.GetFace(), 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.GetPlatformFont(), name_ct); |
- if (name_ct) { |
- CFRelease(name_ct); |
- } |
- } |
- } |
- return; |
- } |
- FX_BOOL bUnicode = FALSE; |
- if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { |
- bUnicode = TRUE; |
- } |
- for (int charcode = 0; charcode < 256; charcode++) { |
- const FX_CHAR* name = |
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); |
- if (!name) { |
- continue; |
- } |
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
- const FX_CHAR* pStrUnicode = GlyphNameRemap(name); |
- if (pStrUnicode && |
- 0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) { |
- name = pStrUnicode; |
- } |
- m_GlyphIndex[charcode] = |
- FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); |
- CFStringRef name_ct = CFStringCreateWithCStringNoCopy( |
- kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull); |
- m_ExtGID[charcode] = CGFontGetGlyphWithGlyphName( |
- (CGFontRef)m_Font.GetPlatformFont(), 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.GetFace(), |
- bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); |
- FX_CHAR name_glyph[256]; |
- FXFT_Get_Glyph_Name(m_Font.GetFace(), 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.GetPlatformFont(), 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.GetFace(), 0x20) : 0xffff; |
- FX_CHAR name_glyph[256]; |
- FXFT_Get_Glyph_Name(m_Font.GetFace(), 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.GetPlatformFont(), 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.GetFace(), (char*)name); |
- } else { |
- m_GlyphIndex[charcode] = |
- FXFT_Get_Char_Index(m_Font.GetFace(), 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.GetFace(), m_GlyphIndex[charcode], |
- name_glyph, 256); |
- name_glyph[255] = 0; |
- if (name_glyph[0] != 0) { |
- unicode = PDF_UnicodeFromAdobeName(name_glyph); |
- } |
- } |
- m_Encoding.m_Unicodes[charcode] = unicode; |
- } |
- } |
- } |
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
- if (!bCoreText) { |
- FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); |
- } |
-#endif |
- return; |
- } |
- FX_BOOL bUnicode = FALSE; |
- if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { |
- bUnicode = TRUE; |
- } |
- for (int charcode = 0; charcode < 256; charcode++) { |
- const FX_CHAR* name = |
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); |
- if (!name) { |
- continue; |
- } |
- m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); |
- m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (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.GetFace(), |
- 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 uint16_t* 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 uint16_t* 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 new CPDF_Name("WinAnsiEncoding"); |
- } |
- if (predefined == PDFFONT_ENCODING_MACROMAN) { |
- return new CPDF_Name("MacRomanEncoding"); |
- } |
- if (predefined == PDFFONT_ENCODING_MACEXPERT) { |
- return new CPDF_Name("MacExpertEncoding"); |
- } |
- return NULL; |
- } |
- const uint16_t* pStandard = |
- PDF_UnicodesForPredefinedCharSet(PDFFONT_ENCODING_WINANSI); |
- CPDF_Array* pDiff = new CPDF_Array; |
- for (int i = 0; i < 256; i++) { |
- if (pStandard[i] == m_Unicodes[i]) { |
- continue; |
- } |
- pDiff->Add(new CPDF_Number(i)); |
- pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i]))); |
- } |
- |
- CPDF_Dictionary* pDict = new CPDF_Dictionary; |
- pDict->SetAtName("BaseEncoding", "WinAnsiEncoding"); |
- pDict->SetAt("Differences", pDiff); |
- return pDict; |
-} |
- |
-CPDF_TrueTypeFont::CPDF_TrueTypeFont() {} |
- |
-bool CPDF_TrueTypeFont::IsTrueTypeFont() const { |
- return true; |
-} |
- |
-const CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() const { |
- return this; |
-} |
- |
-CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() { |
- return this; |
-} |
- |
-FX_BOOL CPDF_TrueTypeFont::Load() { |
- return LoadCommon(); |
-} |
- |
-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_pCharNames) || |
- (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->GetIntegerBy("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; |
- } |
- FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.GetFace(), 3, 1); |
- FX_BOOL bMacRoman = FALSE, 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_pCharNames, 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) { |
- const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; |
- for (int j = 0; j < 4; j++) { |
- uint16_t unicode = prefix[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) { |
- 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.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)) { |
- 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++) { |
- uint16_t unicode = prefix[j] * 256 + charcode; |
- m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 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) { |
- continue; |
- } |
- 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)) { |
- FX_BOOL bGotOne = 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]) { |
- bGotOne = TRUE; |
- } |
- } |
- if (m_pFontFile || bGotOne) { |
- return; |
- } |
- } |
- if (FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE) == 0) { |
- FX_BOOL bGotOne = 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_pCharNames, 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]) { |
- bGotOne = TRUE; |
- } |
- } |
- if (bGotOne) { |
- return; |
- } |
- } |
- for (int charcode = 0; charcode < 256; charcode++) { |
- m_GlyphIndex[charcode] = charcode; |
- } |
-} |
- |
-CPDF_Type3Font::CPDF_Type3Font() |
- : m_pCharProcs(nullptr), |
- m_pPageResources(nullptr), |
- m_pFontResources(nullptr) { |
- FXSYS_memset(m_CharWidthL, 0, sizeof(m_CharWidthL)); |
-} |
- |
-CPDF_Type3Font::~CPDF_Type3Font() { |
- for (auto it : m_CacheMap) |
- delete it.second; |
-} |
- |
-bool CPDF_Type3Font::IsType3Font() const { |
- return true; |
-} |
- |
-const CPDF_Type3Font* CPDF_Type3Font::AsType3Font() const { |
- return this; |
-} |
- |
-CPDF_Type3Font* CPDF_Type3Font::AsType3Font() { |
- return this; |
-} |
- |
-FX_BOOL CPDF_Type3Font::Load() { |
- m_pFontResources = m_pFontDict->GetDictBy("Resources"); |
- CPDF_Array* pMatrix = m_pFontDict->GetArrayBy("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->GetArrayBy("FontBBox"); |
- if (pBBox) { |
- m_FontBBox.left = (int32_t)(pBBox->GetNumberAt(0) * xscale * 1000); |
- m_FontBBox.bottom = (int32_t)(pBBox->GetNumberAt(1) * yscale * 1000); |
- m_FontBBox.right = (int32_t)(pBBox->GetNumberAt(2) * xscale * 1000); |
- m_FontBBox.top = (int32_t)(pBBox->GetNumberAt(3) * yscale * 1000); |
- } |
- int StartChar = m_pFontDict->GetIntegerBy("FirstChar"); |
- CPDF_Array* pWidthArray = m_pFontDict->GetArrayBy("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(pWidthArray->GetNumberAt(i) * xscale * 1000); |
- } |
- } |
- m_pCharProcs = m_pFontDict->GetDictBy("CharProcs"); |
- CPDF_Object* pEncoding = m_pFontDict->GetElementValue("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 nullptr; |
- |
- auto it = m_CacheMap.find(charcode); |
- if (it != m_CacheMap.end()) |
- return it->second; |
- |
- const FX_CHAR* name = |
- GetAdobeCharName(m_BaseEncoding, m_pCharNames, charcode); |
- if (!name) |
- return nullptr; |
- |
- CPDF_Stream* pStream = |
- ToStream(m_pCharProcs ? m_pCharProcs->GetElementValue(name) : nullptr); |
- if (!pStream) |
- return nullptr; |
- |
- std::unique_ptr<CPDF_Type3Char> pNewChar(new CPDF_Type3Char(new CPDF_Form( |
- m_pDocument, m_pFontResources ? m_pFontResources : m_pPageResources, |
- pStream, nullptr))); |
- |
- // This can trigger recursion into this method. The content of |m_CacheMap| |
- // can change as a result. Thus after it returns, check the cache again for |
- // a cache hit. |
- pNewChar->m_pForm->ParseContent(nullptr, nullptr, pNewChar.get(), nullptr, |
- level + 1); |
- it = m_CacheMap.find(charcode); |
- if (it != m_CacheMap.end()) |
- return it->second; |
- |
- FX_FLOAT scale = m_FontMatrix.GetXUnit(); |
- pNewChar->m_Width = (int32_t)(pNewChar->m_Width * scale + 0.5f); |
- FX_RECT& rcBBox = pNewChar->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 = pNewChar->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); |
- |
- ASSERT(!pdfium::ContainsKey(m_CacheMap, charcode)); |
- CPDF_Type3Char* pCachedChar = pNewChar.release(); |
- m_CacheMap[charcode] = pCachedChar; |
- if (pCachedChar->m_pForm->GetPageObjectList()->empty()) { |
- delete pCachedChar->m_pForm; |
- pCachedChar->m_pForm = nullptr; |
- } |
- return pCachedChar; |
-} |
- |
-int CPDF_Type3Font::GetCharWidthF(FX_DWORD charcode, int level) { |
- if (charcode >= FX_ArraySize(m_CharWidthL)) |
- charcode = 0; |
- |
- if (m_CharWidthL[charcode]) |
- return m_CharWidthL[charcode]; |
- |
- const CPDF_Type3Char* pChar = LoadChar(charcode, level); |
- return pChar ? pChar->m_Width : 0; |
-} |
- |
-FX_RECT CPDF_Type3Font::GetCharBBox(FX_DWORD charcode, int level) { |
- const CPDF_Type3Char* pChar = LoadChar(charcode, level); |
- return pChar ? pChar->m_BBox : FX_RECT(); |
-} |
- |
-CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm) |
- : m_pForm(pForm), m_pBitmap(nullptr), m_bColored(FALSE) {} |
- |
-CPDF_Type3Char::~CPDF_Type3Char() { |
- delete m_pForm; |
- delete m_pBitmap; |
-} |