• 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 "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