Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cpdf_type1font.cpp
Go to the documentation of this file.
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
29namespace {
30
31#if BUILDFLAG(IS_APPLE)
32struct GlyphNameMap {
33 const char* m_pStrAdobe; // Raw, POD struct.
34 const char* m_pStrUnicode; // Raw, POD struct.
35};
36
37const GlyphNameMap kGlyphNameSubsts[] = {{"ff", "uniFB00"},
38 {"ffi", "uniFB03"},
39 {"ffl", "uniFB04"},
40 {"fi", "uniFB01"},
41 {"fl", "uniFB02"}};
42
43const 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
53bool 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
72CPDF_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
80CPDF_Type1Font::~CPDF_Type1Font() = default;
81
82bool CPDF_Type1Font::IsType1Font() const {
83 return true;
84}
85
86const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const {
87 return this;
88}
89
90CPDF_Type1Font* CPDF_Type1Font::AsType1Font() {
91 return this;
92}
93
94bool 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()) {
105 } else {
107 }
108 if (IsFixedFont()) {
109 std::fill(std::begin(m_CharWidth), std::end(m_CharWidth), 600);
110 }
111 if (m_Base14Font == CFX_FontMapper::kSymbol)
113 else if (m_Base14Font == CFX_FontMapper::kDingbats)
117 return LoadCommon();
118}
119
120#if BUILDFLAG(IS_APPLE)
121int 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
130void 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);
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((FT_String*)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((FT_String*)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)
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((FT_String*)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((FT_String*)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
316bool CPDF_Type1Font::IsSymbolicFont() const {
317 return m_Base14Font.has_value() &&
318 CFX_FontMapper::IsSymbolicFont(m_Base14Font.value());
319}
320
321bool CPDF_Type1Font::IsFixedFont() const {
322 return m_Base14Font.has_value() &&
323 CFX_FontMapper::IsFixedFont(m_Base14Font.value());
324}
325
326#if BUILDFLAG(IS_APPLE)
327void 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
336void 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)
fxcrt::ByteString ByteString
Definition bytestring.h:180
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
static bool UseTTCharmapMSSymbol(const RetainPtr< CFX_Face > &face)
Definition cpdf_font.h:144
int m_Flags
Definition cpdf_font.h:174
FontEncoding m_BaseEncoding
void LoadGlyphMap() override
CPDF_Type1Font * AsType1Font() override
const CPDF_Type1Font * AsType1Font() const override
bool IsBase14Font() const
~CPDF_Type1Font() override
bool Load() override
bool IsType1Font() const override
FontEncoding
#define FXFONT_NONSYMBOLIC
Definition fx_font.h:34
bool FontStyleIsNonSymbolic(uint32_t style)
Definition fx_font.h:73
bool FontStyleIsSymbolic(uint32_t style)
Definition fx_font.h:70
#define FXFONT_SYMBOLIC
Definition fx_font.h:32