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