1 // Copyright 2016 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "core/fpdfapi/font/cpdf_type1font.h" 8 9 #include "core/fpdfapi/font/font_int.h" 10 #include "core/fpdfapi/parser/cpdf_dictionary.h" 11 #include "core/fxge/cfx_gemodule.h" 12 #include "core/fxge/fx_freetype.h" 13 14 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 15 #include "core/fxge/apple/apple_int.h" 16 #endif 17 18 namespace { 19 20 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 21 struct GlyphNameMap { 22 const FX_CHAR* m_pStrAdobe; 23 const FX_CHAR* m_pStrUnicode; 24 }; 25 26 const GlyphNameMap g_GlyphNameSubsts[] = {{"ff", "uniFB00"}, 27 {"ffi", "uniFB03"}, 28 {"ffl", "uniFB04"}, 29 {"fi", "uniFB01"}, 30 {"fl", "uniFB02"}}; 31 32 int compareString(const void* key, const void* element) { 33 return FXSYS_stricmp(static_cast<const FX_CHAR*>(key), 34 static_cast<const GlyphNameMap*>(element)->m_pStrAdobe); 35 } 36 37 const FX_CHAR* GlyphNameRemap(const FX_CHAR* pStrAdobe) { 38 const GlyphNameMap* found = static_cast<const GlyphNameMap*>(FXSYS_bsearch( 39 pStrAdobe, g_GlyphNameSubsts, FX_ArraySize(g_GlyphNameSubsts), 40 sizeof(GlyphNameMap), compareString)); 41 return found ? found->m_pStrUnicode : nullptr; 42 } 43 44 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 45 46 bool FT_UseType1Charmap(FXFT_Face face) { 47 if (FXFT_Get_Face_CharmapCount(face) == 0) { 48 return false; 49 } 50 if (FXFT_Get_Face_CharmapCount(face) == 1 && 51 FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == 52 FXFT_ENCODING_UNICODE) { 53 return false; 54 } 55 if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[0]) == 56 FXFT_ENCODING_UNICODE) { 57 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[1]); 58 } else { 59 FXFT_Set_Charmap(face, FXFT_Get_Face_Charmaps(face)[0]); 60 } 61 return true; 62 } 63 64 } // namespace 65 66 CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {} 67 68 bool CPDF_Type1Font::IsType1Font() const { 69 return true; 70 } 71 72 const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const { 73 return this; 74 } 75 76 CPDF_Type1Font* CPDF_Type1Font::AsType1Font() { 77 return this; 78 } 79 80 bool CPDF_Type1Font::Load() { 81 m_Base14Font = PDF_GetStandardFontName(&m_BaseFont); 82 if (m_Base14Font >= 0) { 83 CPDF_Dictionary* pFontDesc = m_pFontDict->GetDictFor("FontDescriptor"); 84 if (pFontDesc && pFontDesc->KeyExist("Flags")) 85 m_Flags = pFontDesc->GetIntegerFor("Flags"); 86 else 87 m_Flags = m_Base14Font >= 12 ? FXFONT_SYMBOLIC : FXFONT_NONSYMBOLIC; 88 89 if (m_Base14Font < 4) { 90 for (int i = 0; i < 256; i++) 91 m_CharWidth[i] = 600; 92 } 93 if (m_Base14Font == 12) 94 m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; 95 else if (m_Base14Font == 13) 96 m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS; 97 else if (m_Flags & FXFONT_NONSYMBOLIC) 98 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; 99 } 100 return LoadCommon(); 101 } 102 103 int CPDF_Type1Font::GlyphFromCharCodeExt(uint32_t charcode) { 104 if (charcode > 0xff) { 105 return -1; 106 } 107 int index = m_ExtGID[(uint8_t)charcode]; 108 if (index == 0xffff) { 109 return -1; 110 } 111 return index; 112 } 113 114 void CPDF_Type1Font::LoadGlyphMap() { 115 if (!m_Font.GetFace()) 116 return; 117 118 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 119 bool bCoreText = true; 120 CQuartz2D& quartz2d = 121 static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData()) 122 ->m_quartz2d; 123 if (!m_Font.GetPlatformFont()) { 124 if (m_Font.GetPsName() == "DFHeiStd-W5") 125 bCoreText = false; 126 127 m_Font.SetPlatformFont( 128 quartz2d.CreateFont(m_Font.GetFontData(), m_Font.GetSize())); 129 if (!m_Font.GetPlatformFont()) 130 bCoreText = false; 131 } 132 #endif 133 if (!IsEmbedded() && (m_Base14Font < 12) && m_Font.IsTTFont()) { 134 if (FT_UseTTCharmap(m_Font.GetFace(), 3, 0)) { 135 bool bGotOne = false; 136 for (int charcode = 0; charcode < 256; charcode++) { 137 const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2}; 138 for (int j = 0; j < 4; j++) { 139 uint16_t unicode = prefix[j] * 256 + charcode; 140 m_GlyphIndex[charcode] = 141 FXFT_Get_Char_Index(m_Font.GetFace(), unicode); 142 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 143 CalcExtGID(charcode); 144 #endif 145 if (m_GlyphIndex[charcode]) { 146 bGotOne = true; 147 break; 148 } 149 } 150 } 151 if (bGotOne) { 152 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 153 if (!bCoreText) 154 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); 155 #endif 156 return; 157 } 158 } 159 FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE); 160 if (m_BaseEncoding == 0) { 161 m_BaseEncoding = PDFFONT_ENCODING_STANDARD; 162 } 163 for (int charcode = 0; charcode < 256; charcode++) { 164 const FX_CHAR* name = 165 GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); 166 if (!name) 167 continue; 168 169 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 170 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( 171 m_Font.GetFace(), m_Encoding.m_Unicodes[charcode]); 172 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 173 CalcExtGID(charcode); 174 #endif 175 if (m_GlyphIndex[charcode] == 0 && FXSYS_strcmp(name, ".notdef") == 0) { 176 m_Encoding.m_Unicodes[charcode] = 0x20; 177 m_GlyphIndex[charcode] = FXFT_Get_Char_Index(m_Font.GetFace(), 0x20); 178 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 179 CalcExtGID(charcode); 180 #endif 181 } 182 } 183 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 184 if (!bCoreText) 185 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); 186 #endif 187 return; 188 } 189 FT_UseType1Charmap(m_Font.GetFace()); 190 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 191 if (bCoreText) { 192 if (m_Flags & FXFONT_SYMBOLIC) { 193 for (int charcode = 0; charcode < 256; charcode++) { 194 const FX_CHAR* name = 195 GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); 196 if (name) { 197 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 198 m_GlyphIndex[charcode] = 199 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 200 SetExtGID(name, charcode); 201 } else { 202 m_GlyphIndex[charcode] = 203 FXFT_Get_Char_Index(m_Font.GetFace(), charcode); 204 FX_WCHAR unicode = 0; 205 if (m_GlyphIndex[charcode]) { 206 unicode = 207 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); 208 } 209 FX_CHAR name_glyph[256]; 210 FXSYS_memset(name_glyph, 0, sizeof(name_glyph)); 211 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], 212 name_glyph, 256); 213 name_glyph[255] = 0; 214 if (unicode == 0 && name_glyph[0] != 0) { 215 unicode = PDF_UnicodeFromAdobeName(name_glyph); 216 } 217 m_Encoding.m_Unicodes[charcode] = unicode; 218 SetExtGID(name_glyph, charcode); 219 } 220 } 221 return; 222 } 223 bool bUnicode = false; 224 if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { 225 bUnicode = true; 226 } 227 for (int charcode = 0; charcode < 256; charcode++) { 228 const FX_CHAR* name = 229 GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); 230 if (!name) { 231 continue; 232 } 233 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 234 const FX_CHAR* pStrUnicode = GlyphNameRemap(name); 235 if (pStrUnicode && 236 0 == FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name)) { 237 name = pStrUnicode; 238 } 239 m_GlyphIndex[charcode] = 240 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 241 SetExtGID(name, charcode); 242 if (m_GlyphIndex[charcode] == 0) { 243 if (FXSYS_strcmp(name, ".notdef") != 0 && 244 FXSYS_strcmp(name, "space") != 0) { 245 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( 246 m_Font.GetFace(), 247 bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); 248 CalcExtGID(charcode); 249 } else { 250 m_Encoding.m_Unicodes[charcode] = 0x20; 251 m_GlyphIndex[charcode] = 252 bUnicode ? FXFT_Get_Char_Index(m_Font.GetFace(), 0x20) : 0xffff; 253 CalcExtGID(charcode); 254 } 255 } 256 } 257 return; 258 } 259 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 260 if (m_Flags & FXFONT_SYMBOLIC) { 261 for (int charcode = 0; charcode < 256; charcode++) { 262 const FX_CHAR* name = 263 GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); 264 if (name) { 265 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 266 m_GlyphIndex[charcode] = 267 FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 268 } else { 269 m_GlyphIndex[charcode] = 270 FXFT_Get_Char_Index(m_Font.GetFace(), charcode); 271 if (m_GlyphIndex[charcode]) { 272 FX_WCHAR unicode = 273 FT_UnicodeFromCharCode(PDFFONT_ENCODING_STANDARD, charcode); 274 if (unicode == 0) { 275 FX_CHAR name_glyph[256]; 276 FXSYS_memset(name_glyph, 0, sizeof(name_glyph)); 277 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], 278 name_glyph, 256); 279 name_glyph[255] = 0; 280 if (name_glyph[0] != 0) { 281 unicode = PDF_UnicodeFromAdobeName(name_glyph); 282 } 283 } 284 m_Encoding.m_Unicodes[charcode] = unicode; 285 } 286 } 287 } 288 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 289 if (!bCoreText) 290 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); 291 292 #endif 293 return; 294 } 295 bool bUnicode = false; 296 if (0 == FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE)) { 297 bUnicode = true; 298 } 299 for (int charcode = 0; charcode < 256; charcode++) { 300 const FX_CHAR* name = 301 GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); 302 if (!name) { 303 continue; 304 } 305 m_Encoding.m_Unicodes[charcode] = PDF_UnicodeFromAdobeName(name); 306 m_GlyphIndex[charcode] = FXFT_Get_Name_Index(m_Font.GetFace(), (char*)name); 307 if (m_GlyphIndex[charcode] == 0) { 308 if (FXSYS_strcmp(name, ".notdef") != 0 && 309 FXSYS_strcmp(name, "space") != 0) { 310 m_GlyphIndex[charcode] = FXFT_Get_Char_Index( 311 m_Font.GetFace(), 312 bUnicode ? m_Encoding.m_Unicodes[charcode] : charcode); 313 } else { 314 m_Encoding.m_Unicodes[charcode] = 0x20; 315 m_GlyphIndex[charcode] = 0xffff; 316 } 317 } 318 } 319 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 320 if (!bCoreText) 321 FXSYS_memcpy(m_ExtGID, m_GlyphIndex, 256); 322 #endif 323 } 324 325 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 326 void CPDF_Type1Font::SetExtGID(const FX_CHAR* name, int charcode) { 327 CFStringRef name_ct = CFStringCreateWithCStringNoCopy( 328 kCFAllocatorDefault, name, kCFStringEncodingASCII, kCFAllocatorNull); 329 m_ExtGID[charcode] = 330 CGFontGetGlyphWithGlyphName((CGFontRef)m_Font.GetPlatformFont(), name_ct); 331 if (name_ct) 332 CFRelease(name_ct); 333 } 334 335 void CPDF_Type1Font::CalcExtGID(int charcode) { 336 FX_CHAR name_glyph[256]; 337 FXFT_Get_Glyph_Name(m_Font.GetFace(), m_GlyphIndex[charcode], name_glyph, 338 256); 339 name_glyph[255] = 0; 340 SetExtGID(name_glyph, charcode); 341 } 342 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 343