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