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 <iterator>
11#include <utility>
12
13#include "build/build_config.h"
14#include "core/fpdfapi/parser/cpdf_dictionary.h"
15#include "core/fxcrt/fx_system.h"
16#include "core/fxcrt/span_util.h"
17#include "core/fxge/cfx_fontmapper.h"
18#include "core/fxge/cfx_gemodule.h"
19#include "core/fxge/freetype/fx_freetype.h"
20#include "core/fxge/fx_font.h"
21
22#if BUILDFLAG(IS_APPLE)
23#include <CoreFoundation/CFString.h>
24#include <CoreGraphics/CoreGraphics.h>
25#endif // BUILDFLAG(IS_APPLE)
26
27namespace {
28
29#if BUILDFLAG(IS_APPLE)
30struct GlyphNameMap {
31 const char* m_pStrAdobe; // Raw, POD struct.
32 const char* m_pStrUnicode; // Raw, POD struct.
33};
34
35const GlyphNameMap kGlyphNameSubsts[] = {{"ff", "uniFB00"},
36 {"ffi", "uniFB03"},
37 {"ffl", "uniFB04"},
38 {"fi", "uniFB01"},
39 {"fl", "uniFB02"}};
40
41const char* GlyphNameRemap(const char* pStrAdobe) {
42 for (const auto& element : kGlyphNameSubsts) {
43 if (!FXSYS_stricmp(element.m_pStrAdobe, pStrAdobe))
44 return element.m_pStrUnicode;
45 }
46 return nullptr;
47}
48
49#endif // BUILDFLAG(IS_APPLE)
50
51bool UseType1Charmap(const RetainPtr<CFX_Face>& face) {
52 size_t num_charmaps = face->GetCharMapCount();
53 if (num_charmaps == 0) {
54 return false;
55 }
56
57 bool is_first_charmap_unicode =
58 face->GetCharMapEncodingByIndex(0) == fxge::FontEncoding::kUnicode;
59 if (num_charmaps == 1 && is_first_charmap_unicode) {
60 return false;
61 }
62
63 int index = is_first_charmap_unicode ? 1 : 0;
64 face->SetCharMapByIndex(index);
65 return true;
66}
67
68} // namespace
69
70CPDF_Type1Font::CPDF_Type1Font(CPDF_Document* pDocument,
71 RetainPtr<CPDF_Dictionary> pFontDict)
72 : CPDF_SimpleFont(pDocument, std::move(pFontDict)) {
73#if BUILDFLAG(IS_APPLE)
74 memset(m_ExtGID, 0xff, sizeof(m_ExtGID));
75#endif
76}
77
78CPDF_Type1Font::~CPDF_Type1Font() = default;
79
80bool CPDF_Type1Font::IsType1Font() const {
81 return true;
82}
83
84const CPDF_Type1Font* CPDF_Type1Font::AsType1Font() const {
85 return this;
86}
87
88CPDF_Type1Font* CPDF_Type1Font::AsType1Font() {
89 return this;
90}
91
92bool CPDF_Type1Font::Load() {
93 m_Base14Font = CFX_FontMapper::GetStandardFontName(&m_BaseFontName);
94 if (!IsBase14Font())
95 return LoadCommon();
96
97 RetainPtr<const CPDF_Dictionary> pFontDesc =
98 m_pFontDict->GetDictFor("FontDescriptor");
99 if (pFontDesc && pFontDesc->KeyExist("Flags")) {
100 m_Flags = pFontDesc->GetIntegerFor("Flags");
101 } else if (IsSymbolicFont()) {
103 } else {
105 }
106 if (IsFixedFont()) {
107 std::fill(std::begin(m_CharWidth), std::end(m_CharWidth), 600);
108 }
109 if (m_Base14Font == CFX_FontMapper::kSymbol)
111 else if (m_Base14Font == CFX_FontMapper::kDingbats)
115 return LoadCommon();
116}
117
118#if BUILDFLAG(IS_APPLE)
119int CPDF_Type1Font::GlyphFromCharCodeExt(uint32_t charcode) {
120 if (charcode > 0xff)
121 return -1;
122
123 int index = m_ExtGID[static_cast<uint8_t>(charcode)];
124 return index != 0xffff ? index : -1;
125}
126#endif
127
128void CPDF_Type1Font::LoadGlyphMap() {
129 RetainPtr<CFX_Face> face = m_Font.GetFace();
130 if (!face) {
131 return;
132 }
133
134#if BUILDFLAG(IS_APPLE)
135 bool bCoreText = true;
136 if (!m_Font.GetPlatformFont()) {
137 if (m_Font.GetPsName() == "DFHeiStd-W5")
138 bCoreText = false;
139
140 auto* pPlatform = CFX_GEModule::Get()->GetPlatform();
141 pdfium::span<const uint8_t> span = m_Font.GetFontSpan();
142 m_Font.SetPlatformFont(pPlatform->CreatePlatformFont(span));
143 if (!m_Font.GetPlatformFont())
144 bCoreText = false;
145 }
146#endif
147 if (!IsEmbedded() && !IsSymbolicFont() && m_Font.IsTTFont()) {
148 if (UseTTCharmapMSSymbol(face)) {
149 bool bGotOne = false;
150 for (uint32_t charcode = 0; charcode < kInternalTableSize; charcode++) {
151 const uint8_t prefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
152 for (int j = 0; j < 4; j++) {
153 uint16_t unicode = prefix[j] * 256 + charcode;
154 m_GlyphIndex[charcode] = face->GetCharIndex(unicode);
155#if BUILDFLAG(IS_APPLE)
156 CalcExtGID(charcode);
157#endif
158 if (m_GlyphIndex[charcode]) {
159 bGotOne = true;
160 break;
161 }
162 }
163 }
164 if (bGotOne) {
165#if BUILDFLAG(IS_APPLE)
166 if (!bCoreText)
167 memcpy(m_ExtGID, m_GlyphIndex, sizeof(m_ExtGID));
168#endif
169 return;
170 }
171 }
172 face->SelectCharMap(fxge::FontEncoding::kUnicode);
175
176 for (uint32_t charcode = 0; charcode < kInternalTableSize; charcode++) {
177 const char* name =
178 GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
179 if (!name)
180 continue;
181
182 m_Encoding.SetUnicode(charcode, UnicodeFromAdobeName(name));
183 m_GlyphIndex[charcode] =
184 face->GetCharIndex(m_Encoding.UnicodeFromCharCode(charcode));
185#if BUILDFLAG(IS_APPLE)
186 CalcExtGID(charcode);
187#endif
188 if (m_GlyphIndex[charcode] == 0 && strcmp(name, ".notdef") == 0) {
189 m_Encoding.SetUnicode(charcode, 0x20);
190 m_GlyphIndex[charcode] = face->GetCharIndex(0x20);
191#if BUILDFLAG(IS_APPLE)
192 CalcExtGID(charcode);
193#endif
194 }
195 }
196#if BUILDFLAG(IS_APPLE)
197 if (!bCoreText) {
198 fxcrt::spancpy(pdfium::make_span(m_ExtGID),
199 pdfium::make_span(m_GlyphIndex));
200 }
201#endif
202 return;
203 }
204 UseType1Charmap(face);
205#if BUILDFLAG(IS_APPLE)
206 if (bCoreText) {
207 if (FontStyleIsSymbolic(m_Flags)) {
208 for (uint32_t charcode = 0; charcode < kInternalTableSize; charcode++) {
209 const char* name =
210 GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode);
211 if (name) {
212 m_Encoding.SetUnicode(charcode, UnicodeFromAdobeName(name));
213 m_GlyphIndex[charcode] = m_Font.GetFace()->GetNameIndex((FT_String*)name);
214 SetExtGID(name, charcode);
215 } else {
216 m_GlyphIndex[charcode] = face->GetCharIndex(charcode);
217 char name_glyph[kInternalTableSize] = {};
218 FT_Get_Glyph_Name(m_Font.GetFaceRec(), m_GlyphIndex[charcode],
219 name_glyph, sizeof(name_glyph));
220 name_glyph[kInternalTableSize - 1] = 0;
221 const wchar_t unicode =
222 name_glyph[0] != 0 ? UnicodeFromAdobeName(name_glyph) : 0;
223 m_Encoding.SetUnicode(charcode, unicode);
224 SetExtGID(name_glyph, 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 char name_glyph[kInternalTableSize] = {};
273 FT_Get_Glyph_Name(m_Font.GetFaceRec(), m_GlyphIndex[charcode],
274 name_glyph, sizeof(name_glyph));
275 name_glyph[kInternalTableSize - 1] = 0;
276 const wchar_t unicode =
277 name_glyph[0] != 0 ? UnicodeFromAdobeName(name_glyph) : 0;
278 m_Encoding.SetUnicode(charcode, unicode);
279 }
280 }
281 }
282#if BUILDFLAG(IS_APPLE)
283 if (!bCoreText)
284 memcpy(m_ExtGID, m_GlyphIndex, sizeof(m_ExtGID));
285#endif
286 return;
287 }
288
289 bool bUnicode = face->SelectCharMap(fxge::FontEncoding::kUnicode);
290 for (size_t charcode = 0; charcode < kInternalTableSize; charcode++) {
291 const char* name = GetAdobeCharName(m_BaseEncoding, m_CharNames,
292 static_cast<uint32_t>(charcode));
293 if (!name)
294 continue;
295
296 m_Encoding.SetUnicode(charcode, UnicodeFromAdobeName(name));
297 m_GlyphIndex[charcode] = m_Font.GetFace()->GetNameIndex((FT_String*)name);
298 if (m_GlyphIndex[charcode] != 0)
299 continue;
300
301 if (strcmp(name, ".notdef") != 0 && strcmp(name, "space") != 0) {
302 m_GlyphIndex[charcode] =
303 face->GetCharIndex(bUnicode ? m_Encoding.UnicodeFromCharCode(charcode)
304 : static_cast<uint32_t>(charcode));
305 } else {
306 m_Encoding.SetUnicode(charcode, 0x20);
307 m_GlyphIndex[charcode] = 0xffff;
308 }
309 }
310#if BUILDFLAG(IS_APPLE)
311 if (!bCoreText)
312 memcpy(m_ExtGID, m_GlyphIndex, sizeof(m_ExtGID));
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 char name_glyph[kInternalTableSize] = {};
338 FT_Get_Glyph_Name(m_Font.GetFaceRec(), m_GlyphIndex[charcode], name_glyph,
339 sizeof(name_glyph));
340 name_glyph[kInternalTableSize - 1] = 0;
341 SetExtGID(name_glyph, charcode);
342}
343#endif // BUILDFLAG(IS_APPLE)
static bool UseTTCharmapMSSymbol(const RetainPtr< CFX_Face > &face)
Definition cpdf_font.h:149
int m_Flags
Definition cpdf_font.h:178
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:32
bool FontStyleIsNonSymbolic(uint32_t style)
Definition fx_font.h:71
bool FontStyleIsSymbolic(uint32_t style)
Definition fx_font.h:68
#define FXFONT_SYMBOLIC
Definition fx_font.h:30