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