From bc5e6d289ed40efec2b0e03427e8fc2947bf53e3 Mon Sep 17 00:00:00 2001 From: dsinclair Date: Tue, 4 Oct 2016 11:08:49 -0700 Subject: Move core/fpdfapi/fpdf_font to core/fpdfapi/font BUG=pdfium:603 Review-Url: https://codereview.chromium.org/2392773003 --- core/fpdfapi/font/cpdf_type1font.cpp | 398 +++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 core/fpdfapi/font/cpdf_type1font.cpp (limited to 'core/fpdfapi/font/cpdf_type1font.cpp') diff --git a/core/fpdfapi/font/cpdf_type1font.cpp b/core/fpdfapi/font/cpdf_type1font.cpp new file mode 100644 index 0000000000..7848af5dee --- /dev/null +++ b/core/fpdfapi/font/cpdf_type1font.cpp @@ -0,0 +1,398 @@ +// 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/font/cpdf_type1font.h" + +#include "core/fpdfapi/font/font_int.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fxge/cfx_gemodule.h" +#include "core/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"}, + {"ffi", "uniFB03"}, + {"ffl", "uniFB04"}, + {"fi", "uniFB01"}, + {"fl", "uniFB02"}}; + +int compareString(const void* key, const void* element) { + return FXSYS_stricmp(static_cast(key), + static_cast(element)->m_pStrAdobe); +} + +const FX_CHAR* GlyphNameRemap(const FX_CHAR* pStrAdobe) { + const GlyphNameMap* found = static_cast(FXSYS_bsearch( + pStrAdobe, g_GlyphNameSubsts, FX_ArraySize(g_GlyphNameSubsts), + sizeof(GlyphNameMap), compareString)); + return found ? found->m_pStrUnicode : nullptr; +} + +#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; +} + +bool CPDF_Type1Font::Load() { + m_Base14Font = PDF_GetStandardFontName(&m_BaseFont); + if (m_Base14Font >= 0) { + CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor"); + if (pFontDesc && pFontDesc->KeyExist("Flags")) + m_Flags = pFontDesc->GetIntegerFor("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(uint32_t 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_ + bool bCoreText = true; + CQuartz2D& quartz2d = + static_cast(CFX_GEModule::Get()->GetPlatformData()) + ->m_quartz2d; + if (!m_Font.GetPlatformFont()) { + if (m_Font.GetPsName() == "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_CharNames, 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_CharNames, 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_CharNames, 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 // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (m_Flags & PDFFONT_SYMBOLIC) { + for (int charcode = 0; charcode < 256; charcode++) { + const FX_CHAR* name = + GetAdobeCharName(m_BaseEncoding, m_CharNames, 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_CharNames, 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 +} -- cgit v1.2.3