blob: 519c7d8cef5d9d2fbc702176eab1c8d912b41e4f [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 Sinclair455a4192016-03-16 09:48:56 -04009#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
Dan Sinclairaa403d32016-03-15 14:57:22 -040010#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
11#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
Dan Sinclair584b1e62016-03-21 09:15:45 -040012#include "core/include/fpdfapi/fpdf_resource.h"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080013#include "fpdfsdk/include/fsdk_baseannot.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070014
Nico Weber9d8ec5a2015-08-04 13:00:21 -070015CBA_FontMap::CBA_FontMap(CPDFSDK_Annot* pAnnot,
16 IFX_SystemHandler* pSystemHandler)
17 : CPWL_FontMap(pSystemHandler),
18 m_pDocument(NULL),
19 m_pAnnotDict(NULL),
20 m_pDefaultFont(NULL),
21 m_sAPType("N") {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070022 CPDF_Page* pPage = pAnnot->GetPDFPage();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070023
Nico Weber9d8ec5a2015-08-04 13:00:21 -070024 m_pDocument = pPage->m_pDocument;
25 m_pAnnotDict = pAnnot->GetPDFAnnot()->GetAnnotDict();
Lei Zhangfcfa3b82015-12-24 21:07:28 -080026 Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070027}
28
Nico Weber9d8ec5a2015-08-04 13:00:21 -070029CBA_FontMap::~CBA_FontMap() {}
30
31void CBA_FontMap::Reset() {
32 Empty();
33 m_pDefaultFont = NULL;
34 m_sDefaultFontName = "";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070035}
36
Lei Zhangfcfa3b82015-12-24 21:07:28 -080037void CBA_FontMap::Initialize() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070038 int32_t nCharset = DEFAULT_CHARSET;
39
40 if (!m_pDefaultFont) {
41 m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName);
42 if (m_pDefaultFont) {
Lei Zhangc2fb35f2016-01-05 16:46:58 -080043 if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070044 nCharset = pSubstFont->m_Charset;
Lei Zhangc2fb35f2016-01-05 16:46:58 -080045 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 if (m_sDefaultFontName == "Wingdings" ||
47 m_sDefaultFontName == "Wingdings2" ||
48 m_sDefaultFontName == "Wingdings3" ||
49 m_sDefaultFontName == "Webdings")
50 nCharset = SYMBOL_CHARSET;
51 else
52 nCharset = ANSI_CHARSET;
53 }
54 AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
55 AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
56 }
57 }
58
59 if (nCharset != ANSI_CHARSET)
Lei Zhangfcfa3b82015-12-24 21:07:28 -080060 CPWL_FontMap::Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070061}
62
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063void CBA_FontMap::SetDefaultFont(CPDF_Font* pFont,
64 const CFX_ByteString& sFontName) {
Lei Zhang5eca3052016-02-22 20:32:21 -080065 ASSERT(pFont);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066
67 if (m_pDefaultFont)
68 return;
69
70 m_pDefaultFont = pFont;
71 m_sDefaultFontName = sFontName;
72
Nico Weber9d8ec5a2015-08-04 13:00:21 -070073 int32_t nCharset = DEFAULT_CHARSET;
74 if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
75 nCharset = pSubstFont->m_Charset;
76 AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070077}
78
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias,
80 int32_t nCharset) {
Wei Li9b761132016-01-29 15:44:20 -080081 if (m_pAnnotDict->GetStringBy("Subtype") == "Widget") {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082 CPDF_Document* pDocument = GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083 CPDF_Dictionary* pRootDict = pDocument->GetRoot();
84 if (!pRootDict)
85 return NULL;
86
Wei Li9b761132016-01-29 15:44:20 -080087 CPDF_Dictionary* pAcroFormDict = pRootDict->GetDictBy("AcroForm");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070088 if (!pAcroFormDict)
89 return NULL;
90
Wei Li9b761132016-01-29 15:44:20 -080091 CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 if (!pDRDict)
93 return NULL;
94
95 return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
96 }
97
98 return NULL;
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)
109 return NULL;
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)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113 return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700114
Lei Zhang5eca3052016-02-22 20:32:21 -0800115 CPDF_Document* pDocument = GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 CPDF_Font* pFind = NULL;
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
161 CPDF_Object* pObject = pAPDict->GetElement(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
Wei Li9b761132016-01-29 15:44:20 -0800165 CPDF_Stream* pStream = pAPDict->GetStreamBy(m_sAPType);
Lei Zhang412e9082015-12-14 18:34:00 -0800166 if (!pStream) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167 pStream = new CPDF_Stream(NULL, 0, NULL);
168 int32_t objnum = m_pDocument->AddIndirectObject(pStream);
169 pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum);
170 }
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;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 pStream->InitStream(NULL, 0, pStreamDict);
177 }
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 }
193 if (!pStreamResFontList->KeyExist(sAlias))
194 pStreamResFontList->SetAtReference(sAlias, m_pDocument,
195 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) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201 CPDF_Dictionary* pAcroFormDict = NULL;
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;
209 CPDF_Object* pObj;
210 if ((pObj = FPDF_GetFieldAttr(m_pAnnotDict, "DA")))
211 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
220 CPDF_Dictionary* pFontDict = NULL;
221
222 if (!sDA.IsEmpty()) {
223 CPDF_SimpleParser syntax(sDA);
Wei Li970c11e2016-02-16 14:26:22 -0800224 syntax.FindTagParamFromStart("Tf", 2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225 CFX_ByteString sFontName = syntax.GetWord();
226 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"))
230 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"))
239 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"))
246 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}