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