Index: core/fpdfapi/fpdf_font/cpdf_type1font.cpp |
diff --git a/core/fpdfapi/fpdf_font/cpdf_type1font.cpp b/core/fpdfapi/fpdf_font/cpdf_type1font.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5a6ee34362f52d0cec00827adcdb2f285ded39b5 |
--- /dev/null |
+++ b/core/fpdfapi/fpdf_font/cpdf_type1font.cpp |
@@ -0,0 +1,403 @@ |
+// Copyright 2016 PDFium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
+ |
+#include "core/fpdfapi/fpdf_font/cpdf_type1font.h" |
+ |
+#include "core/fpdfapi/fpdf_font/font_int.h" |
+#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
+#include "core/include/fxge/fx_freetype.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 // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
+ |
+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 |
+ |
+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 |
+} |