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