blob: b8c8865d44c83d0e3e4660d41b1694521babe73a [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Dan Sinclairedbb3192016-03-21 09:08:24 -04007#include "fpdfsdk/formfiller/cba_fontmap.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -08008
dan sinclair61b2fc72016-03-23 19:21:44 -04009#include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
Dan Sinclair455a4192016-03-16 09:48:56 -040010#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
Dan Sinclairaa403d32016-03-15 14:57:22 -040011#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
12#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
dan sinclair61b2fc72016-03-23 19:21:44 -040013#include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080014#include "fpdfsdk/include/fsdk_baseannot.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070015
Nico Weber9d8ec5a2015-08-04 13:00:21 -070016CBA_FontMap::CBA_FontMap(CPDFSDK_Annot* pAnnot,
dsinclairb9590102016-04-27 06:38:59 -070017 CFX_SystemHandler* pSystemHandler)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070018 : CPWL_FontMap(pSystemHandler),
thestig1cd352e2016-06-07 17:53:06 -070019 m_pDocument(nullptr),
20 m_pAnnotDict(nullptr),
21 m_pDefaultFont(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -070022 m_sAPType("N") {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070023 CPDF_Page* pPage = pAnnot->GetPDFPage();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025 m_pDocument = pPage->m_pDocument;
26 m_pAnnotDict = pAnnot->GetPDFAnnot()->GetAnnotDict();
Lei Zhangfcfa3b82015-12-24 21:07:28 -080027 Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070028}
29
Nico Weber9d8ec5a2015-08-04 13:00:21 -070030CBA_FontMap::~CBA_FontMap() {}
31
32void CBA_FontMap::Reset() {
33 Empty();
thestig1cd352e2016-06-07 17:53:06 -070034 m_pDefaultFont = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070035 m_sDefaultFontName = "";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070036}
37
Lei Zhangfcfa3b82015-12-24 21:07:28 -080038void CBA_FontMap::Initialize() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070039 int32_t nCharset = DEFAULT_CHARSET;
40
41 if (!m_pDefaultFont) {
42 m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName);
43 if (m_pDefaultFont) {
Lei Zhangc2fb35f2016-01-05 16:46:58 -080044 if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070045 nCharset = pSubstFont->m_Charset;
Lei Zhangc2fb35f2016-01-05 16:46:58 -080046 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047 if (m_sDefaultFontName == "Wingdings" ||
48 m_sDefaultFontName == "Wingdings2" ||
49 m_sDefaultFontName == "Wingdings3" ||
50 m_sDefaultFontName == "Webdings")
51 nCharset = SYMBOL_CHARSET;
52 else
53 nCharset = ANSI_CHARSET;
54 }
55 AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
56 AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
57 }
58 }
59
60 if (nCharset != ANSI_CHARSET)
Lei Zhangfcfa3b82015-12-24 21:07:28 -080061 CPWL_FontMap::Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070062}
63
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064void CBA_FontMap::SetDefaultFont(CPDF_Font* pFont,
65 const CFX_ByteString& sFontName) {
Lei Zhang5eca3052016-02-22 20:32:21 -080066 ASSERT(pFont);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067
68 if (m_pDefaultFont)
69 return;
70
71 m_pDefaultFont = pFont;
72 m_sDefaultFontName = sFontName;
73
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074 int32_t nCharset = DEFAULT_CHARSET;
75 if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
76 nCharset = pSubstFont->m_Charset;
77 AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070078}
79
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias,
81 int32_t nCharset) {
thestig907a5222016-06-21 14:38:27 -070082 if (m_pAnnotDict->GetStringBy("Subtype") != "Widget")
83 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070084
thestig907a5222016-06-21 14:38:27 -070085 CPDF_Document* pDocument = GetDocument();
86 CPDF_Dictionary* pRootDict = pDocument->GetRoot();
87 if (!pRootDict)
88 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089
thestig907a5222016-06-21 14:38:27 -070090 CPDF_Dictionary* pAcroFormDict = pRootDict->GetDictBy("AcroForm");
91 if (!pAcroFormDict)
92 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070093
thestig907a5222016-06-21 14:38:27 -070094 CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR");
95 if (!pDRDict)
96 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097
thestig907a5222016-06-21 14:38:27 -070098 return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070099}
100
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700101CPDF_Document* CBA_FontMap::GetDocument() {
102 return m_pDocument;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700103}
104
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700105CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict,
106 CFX_ByteString& sFontAlias,
107 int32_t nCharset) {
108 if (!pResDict)
thestig1cd352e2016-06-07 17:53:06 -0700109 return nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700110
Wei Li9b761132016-01-29 15:44:20 -0800111 CPDF_Dictionary* pFonts = pResDict->GetDictBy("Font");
Lei Zhang412e9082015-12-14 18:34:00 -0800112 if (!pFonts)
thestig1cd352e2016-06-07 17:53:06 -0700113 return nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700114
Lei Zhang5eca3052016-02-22 20:32:21 -0800115 CPDF_Document* pDocument = GetDocument();
thestig1cd352e2016-06-07 17:53:06 -0700116 CPDF_Font* pFind = nullptr;
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800117 for (const auto& it : *pFonts) {
118 const CFX_ByteString& csKey = it.first;
119 CPDF_Object* pObj = it.second;
Lei Zhang412e9082015-12-14 18:34:00 -0800120 if (!pObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 continue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700122
Dan Sinclairf1251c12015-10-20 16:24:45 -0400123 CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
124 if (!pElement)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700125 continue;
Wei Li9b761132016-01-29 15:44:20 -0800126 if (pElement->GetStringBy("Type") != "Font")
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 continue;
128
129 CPDF_Font* pFont = pDocument->LoadFont(pElement);
Lei Zhang412e9082015-12-14 18:34:00 -0800130 if (!pFont)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 continue;
132 const CFX_SubstFont* pSubst = pFont->GetSubstFont();
Lei Zhang412e9082015-12-14 18:34:00 -0800133 if (!pSubst)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 continue;
135 if (pSubst->m_Charset == nCharset) {
136 sFontAlias = csKey;
137 pFind = pFont;
138 }
139 }
140 return pFind;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700141}
142
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143void CBA_FontMap::AddedFont(CPDF_Font* pFont,
144 const CFX_ByteString& sFontAlias) {
145 AddFontToAnnotDict(pFont, sFontAlias);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700146}
147
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700148void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont,
149 const CFX_ByteString& sAlias) {
150 if (!pFont)
151 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700152
Wei Li9b761132016-01-29 15:44:20 -0800153 CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700154
Lei Zhang412e9082015-12-14 18:34:00 -0800155 if (!pAPDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700156 pAPDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 m_pAnnotDict->SetAt("AP", pAPDict);
158 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700159
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700160 // to avoid checkbox and radiobutton
tsepez7b1ccf92016-04-14 11:04:57 -0700161 CPDF_Object* pObject = pAPDict->GetObjectBy(m_sAPType);
Dan Sinclairf1251c12015-10-20 16:24:45 -0400162 if (ToDictionary(pObject))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700164
tsepez7b1ccf92016-04-14 11:04:57 -0700165 CPDF_Stream* pStream = pAPDict->GetStreamBy(m_sAPType);
Lei Zhang412e9082015-12-14 18:34:00 -0800166 if (!pStream) {
thestig1cd352e2016-06-07 17:53:06 -0700167 pStream = new CPDF_Stream(nullptr, 0, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 int32_t objnum = m_pDocument->AddIndirectObject(pStream);
tsepez71a452f2016-05-13 17:51:27 -0700169 pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700171
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 CPDF_Dictionary* pStreamDict = pStream->GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700173
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700174 if (!pStreamDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700175 pStreamDict = new CPDF_Dictionary;
thestig1cd352e2016-06-07 17:53:06 -0700176 pStream->InitStream(nullptr, 0, pStreamDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177 }
178
179 if (pStreamDict) {
Wei Li9b761132016-01-29 15:44:20 -0800180 CPDF_Dictionary* pStreamResList = pStreamDict->GetDictBy("Resources");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181 if (!pStreamResList) {
Tom Sepezae51c812015-08-05 12:34:06 -0700182 pStreamResList = new CPDF_Dictionary();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 pStreamDict->SetAt("Resources", pStreamResList);
184 }
185
186 if (pStreamResList) {
Wei Li9b761132016-01-29 15:44:20 -0800187 CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictBy("Font");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188 if (!pStreamResFontList) {
189 pStreamResFontList = new CPDF_Dictionary;
190 int32_t objnum = m_pDocument->AddIndirectObject(pStreamResFontList);
191 pStreamResList->SetAtReference("Font", m_pDocument, objnum);
192 }
tsepez7b1ccf92016-04-14 11:04:57 -0700193 if (!pStreamResFontList->KeyExist(sAlias))
194 pStreamResFontList->SetAtReference(sAlias, m_pDocument,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700195 pFont->GetFontDict());
196 }
197 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700198}
199
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString& sAlias) {
thestig1cd352e2016-06-07 17:53:06 -0700201 CPDF_Dictionary* pAcroFormDict = nullptr;
Tom Sepez007e6c02016-02-26 14:31:56 -0800202 const bool bWidget = (m_pAnnotDict->GetStringBy("Subtype") == "Widget");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700203 if (bWidget) {
204 if (CPDF_Dictionary* pRootDict = m_pDocument->GetRoot())
Wei Li9b761132016-01-29 15:44:20 -0800205 pAcroFormDict = pRootDict->GetDictBy("AcroForm");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206 }
207
208 CFX_ByteString sDA;
Wei Lid4e8f122016-03-21 11:20:44 -0700209 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pAnnotDict, "DA");
210 if (pObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211 sDA = pObj->GetString();
212
213 if (bWidget) {
214 if (sDA.IsEmpty()) {
215 pObj = FPDF_GetFieldAttr(pAcroFormDict, "DA");
216 sDA = pObj ? pObj->GetString() : CFX_ByteString();
217 }
218 }
219
thestig1cd352e2016-06-07 17:53:06 -0700220 CPDF_Dictionary* pFontDict = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221
222 if (!sDA.IsEmpty()) {
tsepez4c3debb2016-04-08 12:20:38 -0700223 CPDF_SimpleParser syntax(sDA.AsStringC());
Wei Li970c11e2016-02-16 14:26:22 -0800224 syntax.FindTagParamFromStart("Tf", 2);
tsepez71a452f2016-05-13 17:51:27 -0700225 CFX_ByteString sFontName(syntax.GetWord());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700226 sAlias = PDF_NameDecode(sFontName).Mid(1);
227
Wei Li9b761132016-01-29 15:44:20 -0800228 if (CPDF_Dictionary* pDRDict = m_pAnnotDict->GetDictBy("DR"))
229 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font"))
tsepez7b1ccf92016-04-14 11:04:57 -0700230 pFontDict = pDRFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231
232 if (!pFontDict)
Wei Li9b761132016-01-29 15:44:20 -0800233 if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP"))
234 if (CPDF_Dictionary* pNormalDict = pAPDict->GetDictBy("N"))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235 if (CPDF_Dictionary* pNormalResDict =
Wei Li9b761132016-01-29 15:44:20 -0800236 pNormalDict->GetDictBy("Resources"))
237 if (CPDF_Dictionary* pResFontDict =
238 pNormalResDict->GetDictBy("Font"))
tsepez7b1ccf92016-04-14 11:04:57 -0700239 pFontDict = pResFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240
241 if (bWidget) {
242 if (!pFontDict) {
243 if (pAcroFormDict) {
Wei Li9b761132016-01-29 15:44:20 -0800244 if (CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR"))
245 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font"))
tsepez7b1ccf92016-04-14 11:04:57 -0700246 pFontDict = pDRFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 }
248 }
249 }
250 }
251
252 return pFontDict ? m_pDocument->LoadFont(pFontDict) : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253}
254
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType) {
256 m_sAPType = sAPType;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700257
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258 Reset();
Lei Zhangfcfa3b82015-12-24 21:07:28 -0800259 Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700260}