• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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