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
compareString(const void * key,const void * element)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
GlyphNameRemap(const FX_CHAR * pStrAdobe)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
FT_UseType1Charmap(FXFT_Face face)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
CPDF_Type1Font()66 CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {}
67
IsType1Font() const68 bool CPDF_Type1Font::IsType1Font() const {
69 return true;
70 }
71
AsType1Font() const72 const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const {
73 return this;
74 }
75
AsType1Font()76 CPDF_Type1Font* CPDF_Type1Font::AsType1Font() {
77 return this;
78 }
79
Load()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
GlyphFromCharCodeExt(uint32_t charcode)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
LoadGlyphMap()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_
SetExtGID(const FX_CHAR * name,int charcode)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
CalcExtGID(int charcode)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