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