7#include "core/fpdfdoc/cpdf_bafontmap.h"
12#include "constants/annotation_common.h"
13#include "core/fpdfapi/font/cpdf_font.h"
14#include "core/fpdfapi/font/cpdf_fontencoding.h"
15#include "core/fpdfapi/page/cpdf_docpagedata.h"
16#include "core/fpdfapi/page/cpdf_page.h"
17#include "core/fpdfapi/parser/cpdf_dictionary.h"
18#include "core/fpdfapi/parser/cpdf_document.h"
19#include "core/fpdfapi/parser/cpdf_parser.h"
20#include "core/fpdfapi/parser/cpdf_reference.h"
21#include "core/fpdfapi/parser/cpdf_stream.h"
22#include "core/fpdfapi/parser/fpdf_parser_utility.h"
23#include "core/fpdfdoc/cpdf_defaultappearance.h"
24#include "core/fpdfdoc/cpdf_formfield.h"
25#include "core/fpdfdoc/ipvt_fontmap.h"
26#include "core/fxcrt/fx_codepage.h"
27#include "core/fxcrt/stl_util.h"
28#include "core/fxge/cfx_fontmapper.h"
29#include "core/fxge/cfx_fontmgr.h"
30#include "core/fxge/cfx_gemodule.h"
34bool FindNativeTrueTypeFont(ByteStringView sFontFaceName) {
43 ByteString sFontFaceName,
49 pFXFont->LoadSubst(sFontFaceName,
true, 0, 0, 0,
53 return pDocPageData->AddFont(
std::move(pFXFont), nCharset);
56ByteString EncodeFontAlias(ByteString sFontName,
FX_Charset nCharset) {
57 sFontName.Remove(
' ');
64CPDF_BAFontMap::Data::Data() =
default;
66CPDF_BAFontMap::Data::~Data() =
default;
70 const ByteString& sAPType)
75 m_pDefaultFont = GetAnnotDefaultFont(&m_sDefaultFontName);
77 auto maybe_charset = m_pDefaultFont->GetSubstFontCharset();
78 if (maybe_charset.has_value()) {
79 nCharset = maybe_charset.value();
80 }
else if (m_sDefaultFontName ==
"Wingdings" ||
81 m_sDefaultFontName ==
"Wingdings2" ||
82 m_sDefaultFontName ==
"Wingdings3" ||
83 m_sDefaultFontName ==
"Webdings") {
88 AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
89 AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
99 if (fxcrt::IndexInBounds(m_Data, nFontIndex))
100 return m_Data[nFontIndex]->pFont;
105 if (fxcrt::IndexInBounds(m_Data, nFontIndex))
106 return m_Data[nFontIndex]->sFontName;
112 int32_t nFontIndex) {
113 if (nFontIndex > 0) {
114 if (KnowWord(nFontIndex, word))
117 if (!m_Data.empty()) {
118 const Data* pData = m_Data.front().get();
121 nCharset == pData->nCharset) {
122 if (KnowWord(0, word))
128 int32_t nNewFontIndex =
129 GetFontIndex(GetCachedNativeFontName(nCharset), nCharset,
true);
130 if (nNewFontIndex >= 0) {
131 if (KnowWord(nNewFontIndex, word))
132 return nNewFontIndex;
136 if (nNewFontIndex >= 0) {
137 if (KnowWord(nNewFontIndex, word))
138 return nNewFontIndex;
144 if (!fxcrt::IndexInBounds(m_Data, nFontIndex))
147 Data* pData = m_Data[nFontIndex].get();
151 if (pData->pFont->IsUnicodeCompatible())
152 return pData->pFont->CharCodeFromUnicode(word);
154 return word < 0xFF ? word : -1;
176 if (m_pAnnotDict->GetNameFor(pdfium::annotation::kSubtype) !=
"Widget")
179 const CPDF_Dictionary* pRootDict = m_pDocument->GetRoot();
183 RetainPtr<
const CPDF_Dictionary> pAcroFormDict =
184 pRootDict->GetDictFor(
"AcroForm");
188 RetainPtr<
const CPDF_Dictionary> pDRDict = pAcroFormDict->GetDictFor(
"DR");
192 return FindResFontSameCharset(pDRDict.Get(), sFontAlias, nCharset);
196 const CPDF_Dictionary* pResDict,
197 ByteString* sFontAlias,
202 RetainPtr<
const CPDF_Dictionary> pFonts = pResDict->GetDictFor(
"Font");
208 for (
const auto& it : locker) {
209 const ByteString& csKey = it.first;
210 RetainPtr<CPDF_Dictionary> pElement =
211 ToDictionary(it.second->GetMutableDirect());
212 if (!ValidateDictType(pElement.Get(),
"Font"))
215 auto* pData = CPDF_DocPageData::FromDocument(m_pDocument);
216 RetainPtr<CPDF_Font> pFont = pData->GetFont(std::move(pElement));
220 auto maybe_charset = pFont->GetSubstFontCharset();
221 if (maybe_charset.has_value() && maybe_charset.value() == nCharset) {
223 pFind = std::move(pFont);
230 RetainPtr<CPDF_Dictionary> pAcroFormDict;
232 (m_pAnnotDict->GetNameFor(pdfium::annotation::kSubtype) ==
"Widget");
234 RetainPtr<CPDF_Dictionary> pRootDict = m_pDocument->GetMutableRoot();
236 pAcroFormDict = pRootDict->GetMutableDictFor(
"AcroForm");
241 CPDF_FormField::GetFieldAttrForDict(m_pAnnotDict.Get(),
"DA");
243 sDA = pObj->GetString();
248 sDA = pObj ? pObj->GetString() : ByteString
();
256 absl::optional<ByteString> font = appearance.GetFont(&font_size);
257 *sAlias = font.value_or(ByteString());
260 if (RetainPtr<CPDF_Dictionary> pAPDict =
261 m_pAnnotDict->GetMutableDictFor(pdfium::annotation::kAP)) {
262 if (RetainPtr<CPDF_Dictionary> pNormalDict =
263 pAPDict->GetMutableDictFor(
"N")) {
264 if (RetainPtr<CPDF_Dictionary> pNormalResDict =
265 pNormalDict->GetMutableDictFor(
"Resources")) {
266 if (RetainPtr<CPDF_Dictionary> pResFontDict =
267 pNormalResDict->GetMutableDictFor(
"Font")) {
268 pFontDict = pResFontDict->GetMutableDictFor(*sAlias);
273 if (bWidget && !pFontDict && pAcroFormDict) {
274 if (RetainPtr<CPDF_Dictionary> pDRDict =
275 pAcroFormDict->GetMutableDictFor(
"DR")) {
276 if (RetainPtr<CPDF_Dictionary> pDRFontDict =
277 pDRDict->GetMutableDictFor(
"Font")) {
278 pFontDict = pDRFontDict->GetMutableDictFor(*sAlias);
285 return CPDF_DocPageData::FromDocument(m_pDocument)->GetFont(pFontDict);
289 const ByteString& sAlias) {
294 m_pAnnotDict->GetOrCreateDictFor(pdfium::annotation::kAP);
297 if (ToDictionary(pAPDict->GetObjectFor(m_sAPType)))
300 RetainPtr<CPDF_Stream> pStream = pAPDict->GetMutableStreamFor(m_sAPType);
302 pStream = m_pDocument->NewIndirect<CPDF_Stream>();
303 pAPDict->SetNewFor<CPDF_Reference>(m_sAPType, m_pDocument,
304 pStream->GetObjNum());
307 RetainPtr<CPDF_Dictionary> pStreamDict = pStream->GetMutableDict();
309 pStreamDict = m_pDocument->New<CPDF_Dictionary>();
310 pStream->InitStreamWithEmptyData(pStreamDict);
313 RetainPtr<CPDF_Dictionary> pStreamResList =
314 pStreamDict->GetOrCreateDictFor(
"Resources");
315 RetainPtr<CPDF_Dictionary> pStreamResFontList =
316 pStreamResList->GetMutableDictFor(
"Font");
317 if (!pStreamResFontList) {
318 pStreamResFontList = m_pDocument->NewIndirect<CPDF_Dictionary>();
319 pStreamResList->SetNewFor<CPDF_Reference>(
"Font", m_pDocument,
320 pStreamResFontList->GetObjNum());
322 if (!pStreamResFontList->KeyExist(sAlias)) {
323 RetainPtr<
const CPDF_Dictionary> pFontDict = pFont->GetFontDict();
325 pFontDict->IsInline() ? pFontDict->Clone()
326 : pFontDict->MakeReference(m_pDocument);
327 pStreamResFontList->SetFor(sAlias,
std::move(pObject));
331bool CPDF_BAFontMap::KnowWord(int32_t nFontIndex, uint16_t word) {
332 return fxcrt::IndexInBounds(m_Data, nFontIndex) &&
333 CharCodeFromUnicode(nFontIndex, word) >= 0;
336int32_t CPDF_BAFontMap::GetFontIndex(
const ByteString& sFontName,
339 int32_t nFontIndex = FindFont(EncodeFontAlias(sFontName, nCharset), nCharset);
345 bFind ? FindFontSameCharset(&sAlias, nCharset) :
nullptr;
347 pFont = AddFontToDocument(sFontName, nCharset);
348 sAlias
= EncodeFontAlias(sFontName, nCharset);
350 AddFontToAnnotDict(pFont, sAlias);
351 return AddFontData(pFont, sAlias, nCharset);
355 const ByteString& sFontAlias,
357 auto pNewData =
std::make_unique<Data>();
358 pNewData->pFont = pFont;
359 pNewData->sFontName = sFontAlias;
360 pNewData->nCharset = nCharset;
361 m_Data.push_back(std::move(pNewData));
362 return fxcrt::CollectionSize<int32_t>(m_Data) - 1;
365int32_t CPDF_BAFontMap::FindFont(
const ByteString& sFontName,
368 for (
const auto& pData : m_Data) {
369 if ((nCharset == FX_Charset::kDefault || nCharset == pData->nCharset) &&
370 (sFontName.IsEmpty() || pData->sFontName == sFontName)) {
378ByteString CPDF_BAFontMap::GetNativeFontName(
FX_Charset nCharset) {
383 if (!FindNativeTrueTypeFont(sFontName.AsStringView()))
389ByteString CPDF_BAFontMap::GetCachedNativeFontName(
FX_Charset nCharset) {
390 for (
const auto& pData : m_NativeFont) {
391 if (pData && pData->nCharset == nCharset)
392 return pData->sFontName;
395 ByteString sNew = GetNativeFontName(nCharset);
399 auto pNewData =
std::make_unique<Native>();
400 pNewData->nCharset = nCharset;
401 pNewData->sFontName = sNew;
402 m_NativeFont.push_back(std::move(pNewData));
409 return AddStandardFont(sFontName);
411 return AddSystemFont(sFontName, nCharset);
415 auto* pPageData = CPDF_DocPageData::FromDocument(m_pDocument);
416 if (sFontName
== "ZapfDingbats")
417 return pPageData->AddStandardFont(sFontName,
nullptr);
420 return pPageData->AddStandardFont(sFontName, &fe);
426 sFontName
= GetNativeFontName(nCharset);
431 return AddNativeTrueTypeFontToPDF(m_pDocument, sFontName, nCharset);
bool HasLocalizedFont(ByteStringView name) const
bool HasInstalledFont(ByteStringView name) const
void LoadInstalledFonts()
static bool IsStandardFontName(const ByteString &name)
CFX_FontMapper * GetBuiltinMapper() const
static ByteString GetDefaultFontNameByCharset(FX_Charset nCharset)
static const char kDefaultAnsiFontName[]
static const char kUniversalDefaultFontName[]
static FX_Charset GetCharSetFromUnicode(uint16_t word)
static CFX_GEModule * Get()
CFX_FontMgr * GetFontMgr() const
int32_t CharCodeFromUnicode(int32_t nFontIndex, uint16_t word) override
FX_Charset CharSetFromUnicode(uint16_t word, FX_Charset nOldCharset) override
RetainPtr< CPDF_Font > GetPDFFont(int32_t nFontIndex) override
~CPDF_BAFontMap() override
static FX_Charset GetNativeCharset()
CPDF_BAFontMap(CPDF_Document *pDocument, RetainPtr< CPDF_Dictionary > pAnnotDict, const ByteString &sAPType)
int32_t GetWordFontIndex(uint16_t word, FX_Charset nCharset, int32_t nFontIndex) override
ByteString GetPDFFontAlias(int32_t nFontIndex) override
CPDF_DefaultAppearance(const ByteString &csDA)
static CPDF_DocPageData * FromDocument(const CPDF_Document *pDoc)
CPDF_FontEncoding(FontEncoding predefined_encoding)
static ByteString Format(const char *pFormat,...)
ByteString & operator+=(const ByteString &str)
bool operator==(const char *ptr) const
ByteString & operator=(ByteString &&that) noexcept
FX_CodePage FX_GetCodePageFromCharset(FX_Charset charset)
FX_Charset FX_GetCharsetFromCodePage(FX_CodePage codepage)