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
GlyphNameRemap(const char * pStrAdobe)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
FT_UseType1Charmap(FXFT_Face face)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
CPDF_Type1Font()63 CPDF_Type1Font::CPDF_Type1Font() : m_Base14Font(-1) {}
64
IsType1Font() const65 bool CPDF_Type1Font::IsType1Font() const {
66 return true;
67 }
68
AsType1Font() const69 const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const {
70 return this;
71 }
72
AsType1Font()73 CPDF_Type1Font* CPDF_Type1Font::AsType1Font() {
74 return this;
75 }
76
Load()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
GlyphFromCharCodeExt(uint32_t charcode)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
LoadGlyphMap()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_
SetExtGID(const char * name,int charcode)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
CalcExtGID(int charcode)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