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
cfgas_pdffontmgr.cpp
Go to the documentation of this file.
1// Copyright 2017 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 "xfa/fgas/font/cfgas_pdffontmgr.h"
8
9#include <algorithm>
10#include <iterator>
11#include <utility>
12
13#include "core/fpdfapi/font/cpdf_font.h"
14#include "core/fpdfapi/page/cpdf_docpagedata.h"
15#include "core/fpdfapi/parser/cpdf_dictionary.h"
16#include "core/fpdfapi/parser/cpdf_document.h"
17#include "core/fpdfapi/parser/fpdf_parser_utility.h"
18#include "core/fxge/fx_font.h"
19#include "third_party/base/check.h"
20#include "xfa/fgas/font/cfgas_fontmgr.h"
21#include "xfa/fgas/font/cfgas_gefont.h"
22
23namespace {
24
25// The 5 names per entry are: PsName, Normal, Bold, Italic, BoldItalic.
26const char* const kXFAPDFFontName[][5] = {
27 {"Adobe PI Std", "AdobePIStd", "AdobePIStd", "AdobePIStd", "AdobePIStd"},
28 {"Myriad Pro Light", "MyriadPro-Light", "MyriadPro-Semibold",
29 "MyriadPro-LightIt", "MyriadPro-SemiboldIt"},
30};
31
32} // namespace
33
34CFGAS_PDFFontMgr::CFGAS_PDFFontMgr(const CPDF_Document* pDoc) : m_pDoc(pDoc) {
35 DCHECK(pDoc);
36}
37
38CFGAS_PDFFontMgr::~CFGAS_PDFFontMgr() = default;
39
40RetainPtr<CFGAS_GEFont> CFGAS_PDFFontMgr::FindFont(const ByteString& strPsName,
41 bool bBold,
42 bool bItalic,
43 bool bStrictMatch) {
44 RetainPtr<const CPDF_Dictionary> pFontSetDict =
45 m_pDoc->GetRoot()->GetDictFor("AcroForm")->GetDictFor("DR");
46 if (!pFontSetDict)
47 return nullptr;
48
49 pFontSetDict = pFontSetDict->GetDictFor("Font");
50 if (!pFontSetDict)
51 return nullptr;
52
53 ByteString name = strPsName;
54 name.Remove(' ');
55
56 auto* pData = CPDF_DocPageData::FromDocument(m_pDoc);
57 CPDF_DictionaryLocker locker(pFontSetDict);
58 for (const auto& it : locker) {
59 const ByteString& key = it.first;
60 const RetainPtr<CPDF_Object>& pObj = it.second;
61 if (!PsNameMatchDRFontName(name.AsStringView(), bBold, bItalic, key,
62 bStrictMatch)) {
63 continue;
64 }
65 RetainPtr<CPDF_Dictionary> pFontDict =
66 ToDictionary(pObj->GetMutableDirect());
67 if (!ValidateDictType(pFontDict.Get(), "Font"))
68 return nullptr;
69
70 RetainPtr<CPDF_Font> pPDFFont = pData->GetFont(pFontDict);
71 if (!pPDFFont || !pPDFFont->IsEmbedded())
72 return nullptr;
73
74 return CFGAS_GEFont::LoadFont(std::move(pPDFFont));
75 }
76 return nullptr;
77}
78
79RetainPtr<CFGAS_GEFont> CFGAS_PDFFontMgr::GetFont(
80 const WideString& wsFontFamily,
81 uint32_t dwFontStyles,
82 bool bStrictMatch) {
83 auto key = std::make_pair(wsFontFamily, dwFontStyles);
84 auto it = m_FontMap.find(key);
85 if (it != m_FontMap.end())
86 return it->second;
87
88 ByteString bsPsName = WideString(wsFontFamily).ToDefANSI();
89 bool bBold = FontStyleIsForceBold(dwFontStyles);
90 bool bItalic = FontStyleIsItalic(dwFontStyles);
91 ByteString strFontName = PsNameToFontName(bsPsName, bBold, bItalic);
92 RetainPtr<CFGAS_GEFont> pFont =
93 FindFont(strFontName, bBold, bItalic, bStrictMatch);
94 if (!pFont)
95 return nullptr;
96
97 m_FontMap[key] = pFont;
98 return pFont;
99}
100
101ByteString CFGAS_PDFFontMgr::PsNameToFontName(const ByteString& strPsName,
102 bool bBold,
103 bool bItalic) {
104 for (size_t i = 0; i < std::size(kXFAPDFFontName); ++i) {
105 if (strPsName == kXFAPDFFontName[i][0]) {
106 size_t index = 1;
107 if (bBold)
108 ++index;
109 if (bItalic)
110 index += 2;
111 return kXFAPDFFontName[i][index];
112 }
113 }
114 return strPsName;
115}
116
117bool CFGAS_PDFFontMgr::PsNameMatchDRFontName(ByteStringView bsPsName,
118 bool bBold,
119 bool bItalic,
120 const ByteString& bsDRFontName,
121 bool bStrictMatch) {
122 ByteString bsDRName = bsDRFontName;
123 bsDRName.Remove('-');
124 size_t iPsLen = bsPsName.GetLength();
125 auto nIndex = bsDRName.Find(bsPsName);
126 if (nIndex.has_value() && !bStrictMatch)
127 return true;
128
129 if (!nIndex.has_value() || nIndex.value() != 0)
130 return false;
131
132 size_t iDifferLength = bsDRName.GetLength() - iPsLen;
133 if (iDifferLength > 1 || (bBold || bItalic)) {
134 auto iBoldIndex = bsDRName.Find("Bold");
135 if (bBold != iBoldIndex.has_value())
136 return false;
137
138 if (iBoldIndex.has_value()) {
139 iDifferLength = std::min(iDifferLength - 4,
140 bsDRName.GetLength() - iBoldIndex.value() - 4);
141 }
142 bool bItalicFont = true;
143 if (bsDRName.Contains("Italic"))
144 iDifferLength -= 6;
145 else if (bsDRName.Contains("It"))
146 iDifferLength -= 2;
147 else if (bsDRName.Contains("Oblique"))
148 iDifferLength -= 7;
149 else
150 bItalicFont = false;
151
152 if (bItalic != bItalicFont)
153 return false;
154
155 if (iDifferLength > 1) {
156 ByteString bsDRTailer = bsDRName.Last(iDifferLength);
157 if (bsDRTailer == "MT" || bsDRTailer == "PSMT" ||
158 bsDRTailer == "Regular" || bsDRTailer == "Reg") {
159 return true;
160 }
161 if (iBoldIndex.has_value() || bItalicFont)
162 return false;
163
164 bool bMatch = false;
165 switch (bsPsName[iPsLen - 1]) {
166 case 'L':
167 if (bsDRName.Last(5) == "Light")
168 bMatch = true;
169
170 break;
171 case 'R':
172 if (bsDRName.Last(7) == "Regular" || bsDRName.Last(3) == "Reg")
173 bMatch = true;
174
175 break;
176 case 'M':
177 if (bsDRName.Last(5) == "Medium")
178 bMatch = true;
179 break;
180 default:
181 break;
182 }
183 return bMatch;
184 }
185 }
186 return true;
187}
RetainPtr< CFGAS_GEFont > GetFont(const WideString &wsFontFamily, uint32_t dwFontStyles, bool bStrictMatch)
CFGAS_PDFFontMgr(const CPDF_Document *pDoc)
bool operator==(const char *ptr) const
WideString(const WideString &other)
ByteString ToDefANSI() const
bool FontStyleIsItalic(uint32_t style)
Definition fx_font.h:62
bool FontStyleIsForceBold(uint32_t style)
Definition fx_font.h:59