// 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 }