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_truetypefont.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_truetypefont.h"
8
9#include <algorithm>
10#include <utility>
11
12#include "core/fpdfapi/parser/cpdf_dictionary.h"
13#include "core/fxge/fx_font.h"
14
15namespace {
16
17constexpr uint8_t kPrefix[4] = {0x00, 0xf0, 0xf1, 0xf2};
18
19uint16_t GetGlyphIndexForMSSymbol(const RetainPtr<CFX_Face>& face,
20 uint32_t charcode) {
21 for (uint8_t c : kPrefix) {
22 uint16_t unicode = c * 256 + charcode;
23 uint16_t val = face->GetCharIndex(unicode);
24 if (val)
25 return val;
26 }
27 return 0;
28}
29
30bool IsWinAnsiOrMacRomanEncoding(FontEncoding encoding) {
31 return encoding == FontEncoding::kWinAnsi ||
32 encoding == FontEncoding::kMacRoman;
33}
34
35} // namespace
36
37CPDF_TrueTypeFont::CPDF_TrueTypeFont(CPDF_Document* pDocument,
38 RetainPtr<CPDF_Dictionary> pFontDict)
39 : CPDF_SimpleFont(pDocument, std::move(pFontDict)) {}
40
41CPDF_TrueTypeFont::~CPDF_TrueTypeFont() = default;
42
43bool CPDF_TrueTypeFont::IsTrueTypeFont() const {
44 return true;
45}
46
47const CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() const {
48 return this;
49}
50
51CPDF_TrueTypeFont* CPDF_TrueTypeFont::AsTrueTypeFont() {
52 return this;
53}
54
55bool CPDF_TrueTypeFont::Load() {
56 return LoadCommon();
57}
58
59void CPDF_TrueTypeFont::LoadGlyphMap() {
60 RetainPtr<CFX_Face> face = m_Font.GetFace();
61 if (!face) {
62 return;
63 }
64
65 const FontEncoding base_encoding = DetermineEncoding();
66 if ((IsWinAnsiOrMacRomanEncoding(base_encoding) && m_CharNames.empty()) ||
67 FontStyleIsNonSymbolic(m_Flags)) {
68 if (m_Font.GetFace()->HasGlyphNames() && face->GetCharMapCount() == 0) {
69 SetGlyphIndicesFromFirstChar();
70 return;
71 }
72
73 const CharmapType charmap_type = DetermineCharmapType();
74 bool bToUnicode = m_pFontDict->KeyExist("ToUnicode");
75 for (uint32_t charcode = 0; charcode < 256; charcode++) {
76 const char* name = GetAdobeCharName(base_encoding, m_CharNames, charcode);
77 if (!name) {
78 m_GlyphIndex[charcode] =
79 m_pFontFile ? face->GetCharIndex(charcode) : -1;
80 continue;
81 }
82 m_Encoding.SetUnicode(charcode, UnicodeFromAdobeName(name));
83 if (charmap_type == CharmapType::kMSSymbol) {
84 m_GlyphIndex[charcode] = GetGlyphIndexForMSSymbol(face, charcode);
85 } else if (m_Encoding.UnicodeFromCharCode(charcode)) {
86 if (charmap_type == CharmapType::kMSUnicode) {
87 m_GlyphIndex[charcode] =
88 face->GetCharIndex(m_Encoding.UnicodeFromCharCode(charcode));
89 } else if (charmap_type == CharmapType::kMacRoman) {
90 uint32_t maccode = CharCodeFromUnicodeForEncoding(
91 fxge::FontEncoding::kAppleRoman,
92 m_Encoding.UnicodeFromCharCode(charcode));
93 if (!maccode) {
94 m_GlyphIndex[charcode] = face->GetNameIndex((FT_String*)name);
95 } else {
96 m_GlyphIndex[charcode] = face->GetCharIndex(maccode);
97 }
98 }
99 }
100 if ((m_GlyphIndex[charcode] != 0 && m_GlyphIndex[charcode] != 0xffff) ||
101 !name) {
102 continue;
103 }
104 if (strcmp(name, ".notdef") == 0) {
105 m_GlyphIndex[charcode] = face->GetCharIndex(32);
106 continue;
107 }
108 m_GlyphIndex[charcode] = face->GetNameIndex((FT_String*)name);
109 if (m_GlyphIndex[charcode] != 0 || !bToUnicode)
110 continue;
111
112 WideString wsUnicode = UnicodeFromCharCode(charcode);
113 if (!wsUnicode.IsEmpty()) {
114 m_GlyphIndex[charcode] = face->GetCharIndex(wsUnicode[0]);
115 m_Encoding.SetUnicode(charcode, wsUnicode[0]);
116 }
117 }
118 return;
119 }
120 if (UseTTCharmapMSSymbol(face)) {
121 for (uint32_t charcode = 0; charcode < 256; charcode++)
122 m_GlyphIndex[charcode] = GetGlyphIndexForMSSymbol(face, charcode);
123 if (HasAnyGlyphIndex()) {
124 if (base_encoding != FontEncoding::kBuiltin) {
125 for (uint32_t charcode = 0; charcode < 256; charcode++) {
126 const char* name =
127 GetAdobeCharName(base_encoding, m_CharNames, charcode);
128 if (name)
129 m_Encoding.SetUnicode(charcode, UnicodeFromAdobeName(name));
130 }
131 } else if (UseTTCharmapMacRoman(face)) {
132 for (uint32_t charcode = 0; charcode < 256; charcode++) {
133 m_Encoding.SetUnicode(charcode,
134 UnicodeFromAppleRomanCharCode(charcode));
135 }
136 }
137 return;
138 }
139 }
140 if (UseTTCharmapMacRoman(face)) {
141 for (uint32_t charcode = 0; charcode < 256; charcode++) {
142 m_GlyphIndex[charcode] = face->GetCharIndex(charcode);
143 m_Encoding.SetUnicode(charcode, UnicodeFromAppleRomanCharCode(charcode));
144 }
145 if (m_pFontFile || HasAnyGlyphIndex())
146 return;
147 }
148 if (m_Font.GetFace()->SelectCharMap(fxge::FontEncoding::kUnicode)) {
149 pdfium::span<const uint16_t> unicodes =
150 UnicodesForPredefinedCharSet(base_encoding);
151 for (uint32_t charcode = 0; charcode < 256; charcode++) {
152 if (m_pFontFile) {
153 m_Encoding.SetUnicode(charcode, charcode);
154 } else {
155 const char* name =
156 GetAdobeCharName(FontEncoding::kBuiltin, m_CharNames, charcode);
157 if (name) {
158 m_Encoding.SetUnicode(charcode, UnicodeFromAdobeName(name));
159 } else if (!unicodes.empty()) {
160 m_Encoding.SetUnicode(charcode, unicodes[charcode]);
161 }
162 }
163 m_GlyphIndex[charcode] =
164 face->GetCharIndex(m_Encoding.UnicodeFromCharCode(charcode));
165 }
166 if (HasAnyGlyphIndex())
167 return;
168 }
169 for (int charcode = 0; charcode < 256; charcode++)
170 m_GlyphIndex[charcode] = charcode;
171}
172
173bool CPDF_TrueTypeFont::HasAnyGlyphIndex() const {
174 for (uint32_t charcode = 0; charcode < kInternalTableSize; charcode++) {
175 if (m_GlyphIndex[charcode])
176 return true;
177 }
178 return false;
179}
180
181CPDF_TrueTypeFont::CharmapType CPDF_TrueTypeFont::DetermineCharmapType() const {
182 if (UseTTCharmapMSUnicode(m_Font.GetFace())) {
183 return CharmapType::kMSUnicode;
184 }
185
187 if (UseTTCharmapMacRoman(m_Font.GetFace())) {
188 return CharmapType::kMacRoman;
189 }
190 if (UseTTCharmapMSSymbol(m_Font.GetFace())) {
191 return CharmapType::kMSSymbol;
192 }
193 } else {
194 if (UseTTCharmapMSSymbol(m_Font.GetFace())) {
195 return CharmapType::kMSSymbol;
196 }
197 if (UseTTCharmapMacRoman(m_Font.GetFace())) {
198 return CharmapType::kMacRoman;
199 }
200 }
201 return CharmapType::kOther;
202}
203
204FontEncoding CPDF_TrueTypeFont::DetermineEncoding() const {
205 if (!m_pFontFile || !FontStyleIsSymbolic(m_Flags) ||
206 !IsWinAnsiOrMacRomanEncoding(m_BaseEncoding)) {
207 return m_BaseEncoding;
208 }
209
210 // Not null - caller checked.
211 RetainPtr<CFX_Face> face = m_Font.GetFace();
212 const size_t num_charmaps = face->GetCharMapCount();
213 if (num_charmaps == 0) {
214 return m_BaseEncoding;
215 }
216
217 bool support_win = false;
218 bool support_mac = false;
219 for (size_t i = 0; i < num_charmaps; i++) {
220 int platform_id = face->GetCharMapPlatformIdByIndex(i);
221 if (platform_id == kNamePlatformAppleUnicode ||
222 platform_id == kNamePlatformWindows) {
223 support_win = true;
224 } else if (platform_id == kNamePlatformMac) {
225 support_mac = true;
226 }
227 if (support_win && support_mac)
228 break;
229 }
230
231 if (m_BaseEncoding == FontEncoding::kWinAnsi && !support_win)
232 return support_mac ? FontEncoding::kMacRoman : FontEncoding::kBuiltin;
233 if (m_BaseEncoding == FontEncoding::kMacRoman && !support_mac)
234 return support_win ? FontEncoding::kWinAnsi : FontEncoding::kBuiltin;
235 return m_BaseEncoding;
236}
237
238void CPDF_TrueTypeFont::SetGlyphIndicesFromFirstChar() {
239 int start_char = m_pFontDict->GetIntegerFor("FirstChar");
240 if (start_char < 0 || start_char > 255)
241 return;
242
243 auto* it = std::begin(m_GlyphIndex);
244 std::fill(it, it + start_char, 0);
245 uint16_t glyph = 3;
246 for (int charcode = start_char; charcode < 256; charcode++, glyph++)
247 m_GlyphIndex[charcode] = glyph;
248}
static bool UseTTCharmapMSSymbol(const RetainPtr< CFX_Face > &face)
Definition cpdf_font.h:149
static bool UseTTCharmapMacRoman(const RetainPtr< CFX_Face > &face)
Definition cpdf_font.h:152
int m_Flags
Definition cpdf_font.h:178
FontEncoding m_BaseEncoding
WideString UnicodeFromCharCode(uint32_t charcode) const override
bool IsTrueTypeFont() const override
void LoadGlyphMap() override
CPDF_TrueTypeFont * AsTrueTypeFont() override
const CPDF_TrueTypeFont * AsTrueTypeFont() const override
~CPDF_TrueTypeFont() override
bool IsEmpty() const
Definition widestring.h:118
FontEncoding
constexpr uint16_t kNamePlatformMac
Definition fx_font.h:43
bool FontStyleIsNonSymbolic(uint32_t style)
Definition fx_font.h:71
constexpr uint16_t kNamePlatformAppleUnicode
Definition fx_font.h:42
constexpr uint16_t kNamePlatformWindows
Definition fx_font.h:44