summaryrefslogtreecommitdiff
path: root/core/fpdfapi/fpdf_font/cpdf_type1font.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/fpdf_font/cpdf_type1font.cpp')
-rw-r--r--core/fpdfapi/fpdf_font/cpdf_type1font.cpp403
1 files changed, 403 insertions, 0 deletions
diff --git a/core/fpdfapi/fpdf_font/cpdf_type1font.cpp b/core/fpdfapi/fpdf_font/cpdf_type1font.cpp
new file mode 100644
index 0000000000..5a6ee34362
--- /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
+}