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_font.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_font.h"
8
9#include <algorithm>
10#include <array>
11#include <memory>
12#include <utility>
13#include <vector>
14
15#include "build/build_config.h"
16#include "constants/font_encodings.h"
17#include "core/fpdfapi/font/cpdf_cidfont.h"
18#include "core/fpdfapi/font/cpdf_fontencoding.h"
19#include "core/fpdfapi/font/cpdf_fontglobals.h"
20#include "core/fpdfapi/font/cpdf_tounicodemap.h"
21#include "core/fpdfapi/font/cpdf_truetypefont.h"
22#include "core/fpdfapi/font/cpdf_type1font.h"
23#include "core/fpdfapi/font/cpdf_type3font.h"
24#include "core/fpdfapi/parser/cpdf_array.h"
25#include "core/fpdfapi/parser/cpdf_dictionary.h"
26#include "core/fpdfapi/parser/cpdf_document.h"
27#include "core/fpdfapi/parser/cpdf_name.h"
28#include "core/fpdfapi/parser/cpdf_stream.h"
29#include "core/fpdfapi/parser/cpdf_stream_acc.h"
30#include "core/fxcrt/check.h"
31#include "core/fxcrt/fx_codepage.h"
32#include "core/fxcrt/fx_safe_types.h"
33#include "core/fxcrt/stl_util.h"
34#include "core/fxge/cfx_fontmapper.h"
35#include "core/fxge/cfx_substfont.h"
36#include "core/fxge/fx_font.h"
37
38namespace {
39
40constexpr std::array<const char*, 5> kChineseFontNames = {{
41 "\xCB\xCE\xCC\xE5",
42 "\xBF\xAC\xCC\xE5",
43 "\xBA\xDA\xCC\xE5",
44 "\xB7\xC2\xCB\xCE",
45 "\xD0\xC2\xCB\xCE",
46}};
47
48} // namespace
49
55
57 if (!m_bWillBeDestroyed && m_pFontFile) {
58 m_pDocument->MaybePurgeFontFileStreamAcc(std::move(m_pFontFile));
59 }
60}
61
62bool CPDF_Font::IsType1Font() const {
63 return false;
64}
65
67 return false;
68}
69
70bool CPDF_Font::IsType3Font() const {
71 return false;
72}
73
74bool CPDF_Font::IsCIDFont() const {
75 return false;
76}
77
78const CPDF_Type1Font* CPDF_Font::AsType1Font() const {
79 return nullptr;
80}
81
82CPDF_Type1Font* CPDF_Font::AsType1Font() {
83 return nullptr;
84}
85
86const CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() const {
87 return nullptr;
88}
89
90CPDF_TrueTypeFont* CPDF_Font::AsTrueTypeFont() {
91 return nullptr;
92}
93
94const CPDF_Type3Font* CPDF_Font::AsType3Font() const {
95 return nullptr;
96}
97
98CPDF_Type3Font* CPDF_Font::AsType3Font() {
99 return nullptr;
100}
101
102const CPDF_CIDFont* CPDF_Font::AsCIDFont() const {
103 return nullptr;
104}
105
106CPDF_CIDFont* CPDF_Font::AsCIDFont() {
107 return nullptr;
108}
109
111 return pString.GetLength();
112}
113
114#if BUILDFLAG(IS_APPLE)
115int CPDF_Font::GlyphFromCharCodeExt(uint32_t charcode) {
116 return GlyphFromCharCode(charcode, nullptr);
117}
118#endif
119
123
125 const CPDF_CIDFont* pCIDFont = AsCIDFont();
126 return pCIDFont ? pCIDFont->IsVertWriting() : m_Font.IsVertical();
127}
128
129void CPDF_Font::AppendChar(ByteString* str, uint32_t charcode) const {
130 *str += static_cast<char>(charcode);
131}
132
133WideString CPDF_Font::UnicodeFromCharCode(uint32_t charcode) const {
136
137 return m_pToUnicodeMap ? m_pToUnicodeMap->Lookup(charcode) : WideString();
138}
139
140uint32_t CPDF_Font::CharCodeFromUnicode(wchar_t unicode) const {
143
144 return m_pToUnicodeMap ? m_pToUnicodeMap->ReverseLookup(unicode) : 0;
145}
146
148 return true;
149}
150
153 int ItalicAngle = 0;
154 bool bExistItalicAngle = false;
155 if (pFontDesc->KeyExist("ItalicAngle")) {
156 ItalicAngle = pFontDesc->GetIntegerFor("ItalicAngle");
157 bExistItalicAngle = true;
158 }
159 if (ItalicAngle < 0) {
161 m_ItalicAngle = ItalicAngle;
162 }
163 bool bExistStemV = false;
164 if (pFontDesc->KeyExist("StemV")) {
165 m_StemV = pFontDesc->GetIntegerFor("StemV");
166 bExistStemV = true;
167 }
168 bool bExistAscent = false;
169 if (pFontDesc->KeyExist("Ascent")) {
170 m_Ascent = pFontDesc->GetIntegerFor("Ascent");
171 bExistAscent = true;
172 }
173 bool bExistDescent = false;
174 if (pFontDesc->KeyExist("Descent")) {
175 m_Descent = pFontDesc->GetIntegerFor("Descent");
176 bExistDescent = true;
177 }
178 bool bExistCapHeight = false;
179 if (pFontDesc->KeyExist("CapHeight"))
180 bExistCapHeight = true;
181 if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent &&
182 bExistStemV) {
184 }
185 if (m_Descent > 10)
187 RetainPtr<const CPDF_Array> pBBox = pFontDesc->GetArrayFor("FontBBox");
188 if (pBBox) {
189 m_FontBBox.left = pBBox->GetIntegerAt(0);
190 m_FontBBox.bottom = pBBox->GetIntegerAt(1);
191 m_FontBBox.right = pBBox->GetIntegerAt(2);
192 m_FontBBox.top = pBBox->GetIntegerAt(3);
193 }
194
195 RetainPtr<const CPDF_Stream> pFontFile = pFontDesc->GetStreamFor("FontFile");
196 if (!pFontFile)
197 pFontFile = pFontDesc->GetStreamFor("FontFile2");
198 if (!pFontFile)
199 pFontFile = pFontDesc->GetStreamFor("FontFile3");
200 if (!pFontFile)
201 return;
202
203 const uint64_t key = pFontFile->KeyForCache();
204 m_pFontFile = m_pDocument->GetFontFileStreamAcc(std::move(pFontFile));
205 if (!m_pFontFile)
206 return;
207
208 if (!m_Font.LoadEmbedded(m_pFontFile->GetSpan(), IsVertWriting(), key))
209 m_pDocument->MaybePurgeFontFileStreamAcc(std::move(m_pFontFile));
210}
211
213 if (m_FontBBox.top == 0 && m_FontBBox.bottom == 0 && m_FontBBox.left == 0 &&
214 m_FontBBox.right == 0) {
215 RetainPtr<CFX_Face> face = m_Font.GetFace();
216 if (face) {
217 // Note that `m_FontBBox` is deliberately flipped.
218 const FX_RECT raw_bbox = face->GetBBox();
219 const uint16_t upem = face->GetUnitsPerEm();
224 m_Ascent = NormalizeFontMetric(face->GetAscender(), upem);
225 m_Descent = NormalizeFontMetric(face->GetDescender(), upem);
226 } else {
227 bool bFirst = true;
228 for (int i = 0; i < 256; i++) {
229 FX_RECT rect = GetCharBBox(i);
230 if (rect.left == rect.right) {
231 continue;
232 }
233 if (bFirst) {
234 m_FontBBox = rect;
235 bFirst = false;
236 } else {
241 }
242 }
243 }
244 }
245 if (m_Ascent == 0 && m_Descent == 0) {
246 FX_RECT rect = GetCharBBox('A');
247 m_Ascent = rect.bottom == rect.top ? m_FontBBox.top : rect.top;
248 rect = GetCharBBox('g');
249 m_Descent = rect.bottom == rect.top ? m_FontBBox.bottom : rect.bottom;
250 }
251}
252
254 m_bToUnicodeLoaded = true;
255 RetainPtr<const CPDF_Stream> pStream = m_pFontDict->GetStreamFor("ToUnicode");
256 if (!pStream)
257 return;
258
259 m_pToUnicodeMap = std::make_unique<CPDF_ToUnicodeMap>(std::move(pStream));
260}
261
263 size_t offset = 0;
264 int width = 0;
265 while (offset < pString.GetLength())
266 width += GetCharWidthF(GetNextChar(pString, &offset));
267 return width;
268}
269
270// static
272 ByteStringView name) {
273 ByteString fontname(name);
274 std::optional<CFX_FontMapper::StandardFont> font_id =
275 CFX_FontMapper::GetStandardFontName(&fontname);
276 if (!font_id.has_value())
277 return nullptr;
278
279 auto* pFontGlobals = CPDF_FontGlobals::GetInstance();
280 RetainPtr<CPDF_Font> pFont = pFontGlobals->Find(pDoc, font_id.value());
281 if (pFont)
282 return pFont;
283
284 auto pDict = pDoc->New<CPDF_Dictionary>();
285 pDict->SetNewFor<CPDF_Name>("Type", "Font");
286 pDict->SetNewFor<CPDF_Name>("Subtype", "Type1");
287 pDict->SetNewFor<CPDF_Name>("BaseFont", fontname);
288 pDict->SetNewFor<CPDF_Name>("Encoding",
290 pFont = CPDF_Font::Create(nullptr, std::move(pDict), nullptr);
291 pFontGlobals->Set(pDoc, font_id.value(), pFont);
292 return pFont;
293}
294
295// static
297 RetainPtr<CPDF_Dictionary> pFontDict,
298 FormFactoryIface* pFactory) {
299 ByteString type = pFontDict->GetByteStringFor("Subtype");
300 RetainPtr<CPDF_Font> pFont;
301 if (type == "TrueType") {
302 ByteString tag = pFontDict->GetByteStringFor("BaseFont").First(4);
303 for (const char* chinese_font_name : kChineseFontNames) {
304 if (tag == chinese_font_name) {
305 RetainPtr<const CPDF_Dictionary> pFontDesc =
306 pFontDict->GetDictFor("FontDescriptor");
307 if (!pFontDesc || !pFontDesc->KeyExist("FontFile2"))
308 pFont = pdfium::MakeRetain<CPDF_CIDFont>(pDoc, std::move(pFontDict));
309 break;
310 }
311 }
312 if (!pFont)
313 pFont = pdfium::MakeRetain<CPDF_TrueTypeFont>(pDoc, std::move(pFontDict));
314 } else if (type == "Type3") {
315 pFont = pdfium::MakeRetain<CPDF_Type3Font>(pDoc, std::move(pFontDict),
316 pFactory);
317 } else if (type == "Type0") {
318 pFont = pdfium::MakeRetain<CPDF_CIDFont>(pDoc, std::move(pFontDict));
319 } else {
320 pFont = pdfium::MakeRetain<CPDF_Type1Font>(pDoc, std::move(pFontDict));
321 }
322 if (!pFont->Load())
323 return nullptr;
324
325 return pFont;
326}
327
328uint32_t CPDF_Font::GetNextChar(ByteStringView pString, size_t* pOffset) const {
329 if (pString.IsEmpty())
330 return 0;
331
332 size_t& offset = *pOffset;
333 return offset < pString.GetLength() ? pString[offset++] : pString.Back();
334}
335
337 if (!IsType1Font())
338 return false;
339 if (m_pFontFile)
340 return false;
342}
343
345 CFX_SubstFont* pFont = m_Font.GetSubstFont();
346 if (!pFont)
347 return std::nullopt;
348 return pFont->m_Charset;
349}
350
351// static
352const char* CPDF_Font::GetAdobeCharName(
353 FontEncoding base_encoding,
354 const std::vector<ByteString>& charnames,
355 uint32_t charcode) {
356 if (charcode >= 256)
357 return nullptr;
358
359 if (!charnames.empty() && !charnames[charcode].IsEmpty())
360 return charnames[charcode].c_str();
361
362 const char* name = nullptr;
363 if (base_encoding != FontEncoding::kBuiltin)
364 name = CharNameFromPredefinedCharSet(base_encoding, charcode);
365 if (!name)
366 return nullptr;
367
368 DCHECK(name[0]);
369 return name;
370}
371
372uint32_t CPDF_Font::FallbackFontFromCharcode(uint32_t charcode) {
373 if (m_FontFallbacks.empty()) {
374 m_FontFallbacks.push_back(std::make_unique<CFX_Font>());
375 FX_SAFE_INT32 safeWeight = m_StemV;
376 safeWeight *= 5;
377 m_FontFallbacks[0]->LoadSubst("Arial", IsTrueTypeFont(), m_Flags,
378 safeWeight.ValueOrDefault(FXFONT_FW_NORMAL),
379 m_ItalicAngle, FX_CodePage::kDefANSI,
380 IsVertWriting());
381 }
382 return 0;
383}
384
385int CPDF_Font::FallbackGlyphFromCharcode(int fallbackFont, uint32_t charcode) {
386 if (!fxcrt::IndexInBounds(m_FontFallbacks, fallbackFont))
387 return -1;
388
389 WideString str = UnicodeFromCharCode(charcode);
390 uint32_t unicode = !str.IsEmpty() ? str[0] : charcode;
391 int glyph = m_FontFallbacks[fallbackFont]->GetFace()->GetCharIndex(unicode);
392 if (glyph == 0)
393 return -1;
394
395 return glyph;
396}
397
399 if (position < 0 || static_cast<size_t>(position) >= m_FontFallbacks.size())
400 return nullptr;
401 return m_FontFallbacks[position].get();
402}
403
404// static
405bool CPDF_Font::UseTTCharmap(const RetainPtr<CFX_Face>& face,
406 int platform_id,
407 int encoding_id) {
408 for (size_t i = 0; i < face->GetCharMapCount(); i++) {
409 if (face->GetCharMapPlatformIdByIndex(i) == platform_id &&
410 face->GetCharMapEncodingIdByIndex(i) == encoding_id) {
411 face->SetCharMapByIndex(i);
412 return true;
413 }
414 }
415 return false;
416}
417
419 FX_SAFE_INT32 safeStemV(m_StemV);
420 if (m_StemV < 140)
421 safeStemV *= 5;
422 else
423 safeStemV = safeStemV * 4 + 140;
424 return safeStemV.ValueOrDefault(FXFONT_FW_NORMAL);
425}
fxcrt::ByteString ByteString
Definition bytestring.h:180
#define DCHECK
Definition check.h:33
FX_Charset m_Charset
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
Definition cpdf_array.h:29
bool KeyExist(const ByteString &key) const
int GetIntegerFor(const ByteString &key) const
RetainPtr< const CPDF_Stream > GetStreamFor(const ByteString &key) const
int GetIntegerFor(const ByteString &key, int default_int) const
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
void Set(CPDF_Document *pDoc, CFX_FontMapper::StandardFont index, RetainPtr< CPDF_Font > pFont)
static CPDF_FontGlobals * GetInstance()
virtual FX_RECT GetCharBBox(uint32_t charcode)=0
virtual bool IsTrueTypeFont() const
Definition cpdf_font.cpp:66
virtual const CPDF_CIDFont * AsCIDFont() const
int m_ItalicAngle
Definition cpdf_font.h:178
std::optional< FX_Charset > GetSubstFontCharset() const
virtual void WillBeDestroyed()
int FallbackGlyphFromCharcode(int fallbackFont, uint32_t charcode)
void LoadFontDescriptor(const CPDF_Dictionary *pFontDesc)
virtual void AppendChar(ByteString *buf, uint32_t charcode) const
virtual CPDF_CIDFont * AsCIDFont()
virtual bool IsType1Font() const
Definition cpdf_font.cpp:62
virtual bool IsVertWriting() const
CPDF_Font(CPDF_Document *pDocument, RetainPtr< CPDF_Dictionary > pFontDict)
Definition cpdf_font.cpp:50
~CPDF_Font() override
Definition cpdf_font.cpp:56
void LoadUnicodeMap() const
static RetainPtr< CPDF_Font > Create(CPDF_Document *pDoc, RetainPtr< CPDF_Dictionary > pFontDict, FormFactoryIface *pFactory)
virtual uint32_t CharCodeFromUnicode(wchar_t Unicode) const
virtual const CPDF_TrueTypeFont * AsTrueTypeFont() const
Definition cpdf_font.cpp:86
virtual const CPDF_Type1Font * AsType1Font() const
Definition cpdf_font.cpp:78
int m_Flags
Definition cpdf_font.h:174
virtual bool IsCIDFont() const
Definition cpdf_font.cpp:74
int m_StemV
Definition cpdf_font.h:175
virtual WideString UnicodeFromCharCode(uint32_t charcode) const
virtual const CPDF_Type3Font * AsType3Font() const
Definition cpdf_font.cpp:94
static RetainPtr< CPDF_Font > GetStockFont(CPDF_Document *pDoc, ByteStringView fontname)
static bool UseTTCharmap(const RetainPtr< CFX_Face > &face, int platform_id, int encoding_id)
bool m_bWillBeDestroyed
Definition cpdf_font.h:173
virtual size_t CountChar(ByteStringView pString) const
int GetStringWidth(ByteStringView pString)
virtual CPDF_Type1Font * AsType1Font()
Definition cpdf_font.cpp:82
virtual bool HasFontWidths() const
virtual bool IsType3Font() const
Definition cpdf_font.cpp:70
virtual CPDF_Type3Font * AsType3Font()
Definition cpdf_font.cpp:98
virtual CPDF_TrueTypeFont * AsTrueTypeFont()
Definition cpdf_font.cpp:90
FX_RECT m_FontBBox
Definition cpdf_font.h:179
int GetFontWeight() const
int m_Ascent
Definition cpdf_font.h:176
int m_Descent
Definition cpdf_font.h:177
virtual uint32_t GetNextChar(ByteStringView pString, size_t *pOffset) const
bool m_bToUnicodeLoaded
Definition cpdf_font.h:172
uint32_t FallbackFontFromCharcode(uint32_t charcode)
bool IsStandardFont() const
void CheckFontMetrics()
CFX_Font * GetFontFallback(int position)
bool IsBase14Font() const
ByteString & operator+=(char ch)
bool operator==(const char *ptr) const
const char * CharNameFromPredefinedCharSet(FontEncoding encoding, uint8_t charcode)
FontEncoding
FX_Charset
Definition fx_codepage.h:71
int NormalizeFontMetric(int64_t value, uint16_t upem)
Definition fx_font.cpp:150
#define FXFONT_USEEXTERNATTR
Definition fx_font.h:41
#define FXFONT_NONSYMBOLIC
Definition fx_font.h:34
#define FXFONT_FW_NORMAL
Definition fx_font.h:24
#define FXFONT_ITALIC
Definition fx_font.h:35
pdfium::CheckedNumeric< int32_t > FX_SAFE_INT32
fxcrt::ByteStringView ByteStringView
FX_RECT & operator=(const FX_RECT &that)=default
int32_t bottom
int32_t right
int32_t top
int32_t left
fxcrt::WideString WideString
Definition widestring.h:207