blob: 0923c4d1ca49102d067c2851052abf059f0adbe3 [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"
Lei Zhangc2fb35f2016-01-05 16:46:58 -080012#include "fpdfsdk/include/fsdk_baseannot.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070013
Nico Weber9d8ec5a2015-08-04 13:00:21 -070014CBA_FontMap::CBA_FontMap(CPDFSDK_Annot* pAnnot,
15 IFX_SystemHandler* pSystemHandler)
16 : CPWL_FontMap(pSystemHandler),
17 m_pDocument(NULL),
18 m_pAnnotDict(NULL),
19 m_pDefaultFont(NULL),
20 m_sAPType("N") {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070021 CPDF_Page* pPage = pAnnot->GetPDFPage();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070022
Nico Weber9d8ec5a2015-08-04 13:00:21 -070023 m_pDocument = pPage->m_pDocument;
24 m_pAnnotDict = pAnnot->GetPDFAnnot()->GetAnnotDict();
Lei Zhangfcfa3b82015-12-24 21:07:28 -080025 Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026}
27
Nico Weber9d8ec5a2015-08-04 13:00:21 -070028CBA_FontMap::~CBA_FontMap() {}
29
30void CBA_FontMap::Reset() {
31 Empty();
32 m_pDefaultFont = NULL;
33 m_sDefaultFontName = "";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070034}
35
Lei Zhangfcfa3b82015-12-24 21:07:28 -080036void CBA_FontMap::Initialize() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070037 int32_t nCharset = DEFAULT_CHARSET;
38
39 if (!m_pDefaultFont) {
40 m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName);
41 if (m_pDefaultFont) {
Lei Zhangc2fb35f2016-01-05 16:46:58 -080042 if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 nCharset = pSubstFont->m_Charset;
Lei Zhangc2fb35f2016-01-05 16:46:58 -080044 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070045 if (m_sDefaultFontName == "Wingdings" ||
46 m_sDefaultFontName == "Wingdings2" ||
47 m_sDefaultFontName == "Wingdings3" ||
48 m_sDefaultFontName == "Webdings")
49 nCharset = SYMBOL_CHARSET;
50 else
51 nCharset = ANSI_CHARSET;
52 }
53 AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
54 AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
55 }
56 }
57
58 if (nCharset != ANSI_CHARSET)
Lei Zhangfcfa3b82015-12-24 21:07:28 -080059 CPWL_FontMap::Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070060}
61
Nico Weber9d8ec5a2015-08-04 13:00:21 -070062void CBA_FontMap::SetDefaultFont(CPDF_Font* pFont,
63 const CFX_ByteString& sFontName) {
Lei Zhang5eca3052016-02-22 20:32:21 -080064 ASSERT(pFont);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070065
66 if (m_pDefaultFont)
67 return;
68
69 m_pDefaultFont = pFont;
70 m_sDefaultFontName = sFontName;
71
Nico Weber9d8ec5a2015-08-04 13:00:21 -070072 int32_t nCharset = DEFAULT_CHARSET;
73 if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
74 nCharset = pSubstFont->m_Charset;
75 AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070076}
77
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias,
79 int32_t nCharset) {
Wei Li9b761132016-01-29 15:44:20 -080080 if (m_pAnnotDict->GetStringBy("Subtype") == "Widget") {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 CPDF_Document* pDocument = GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082 CPDF_Dictionary* pRootDict = pDocument->GetRoot();
83 if (!pRootDict)
84 return NULL;
85
Wei Li9b761132016-01-29 15:44:20 -080086 CPDF_Dictionary* pAcroFormDict = pRootDict->GetDictBy("AcroForm");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070087 if (!pAcroFormDict)
88 return NULL;
89
Wei Li9b761132016-01-29 15:44:20 -080090 CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091 if (!pDRDict)
92 return NULL;
93
94 return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
95 }
96
97 return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098}
99
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100CPDF_Document* CBA_FontMap::GetDocument() {
101 return m_pDocument;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700102}
103
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict,
105 CFX_ByteString& sFontAlias,
106 int32_t nCharset) {
107 if (!pResDict)
108 return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700109
Wei Li9b761132016-01-29 15:44:20 -0800110 CPDF_Dictionary* pFonts = pResDict->GetDictBy("Font");
Lei Zhang412e9082015-12-14 18:34:00 -0800111 if (!pFonts)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700112 return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700113
Lei Zhang5eca3052016-02-22 20:32:21 -0800114 CPDF_Document* pDocument = GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700115 CPDF_Font* pFind = NULL;
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800116 for (const auto& it : *pFonts) {
117 const CFX_ByteString& csKey = it.first;
118 CPDF_Object* pObj = it.second;
Lei Zhang412e9082015-12-14 18:34:00 -0800119 if (!pObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120 continue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700121
Dan Sinclairf1251c12015-10-20 16:24:45 -0400122 CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
123 if (!pElement)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124 continue;
Wei Li9b761132016-01-29 15:44:20 -0800125 if (pElement->GetStringBy("Type") != "Font")
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 continue;
127
128 CPDF_Font* pFont = pDocument->LoadFont(pElement);
Lei Zhang412e9082015-12-14 18:34:00 -0800129 if (!pFont)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130 continue;
131 const CFX_SubstFont* pSubst = pFont->GetSubstFont();
Lei Zhang412e9082015-12-14 18:34:00 -0800132 if (!pSubst)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133 continue;
134 if (pSubst->m_Charset == nCharset) {
135 sFontAlias = csKey;
136 pFind = pFont;
137 }
138 }
139 return pFind;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700140}
141
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700142void CBA_FontMap::AddedFont(CPDF_Font* pFont,
143 const CFX_ByteString& sFontAlias) {
144 AddFontToAnnotDict(pFont, sFontAlias);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700145}
146
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont,
148 const CFX_ByteString& sAlias) {
149 if (!pFont)
150 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700151
Wei Li9b761132016-01-29 15:44:20 -0800152 CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700153
Lei Zhang412e9082015-12-14 18:34:00 -0800154 if (!pAPDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700155 pAPDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156 m_pAnnotDict->SetAt("AP", pAPDict);
157 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700158
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 // to avoid checkbox and radiobutton
160 CPDF_Object* pObject = pAPDict->GetElement(m_sAPType);
Dan Sinclairf1251c12015-10-20 16:24:45 -0400161 if (ToDictionary(pObject))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700163
Wei Li9b761132016-01-29 15:44:20 -0800164 CPDF_Stream* pStream = pAPDict->GetStreamBy(m_sAPType);
Lei Zhang412e9082015-12-14 18:34:00 -0800165 if (!pStream) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 pStream = new CPDF_Stream(NULL, 0, NULL);
167 int32_t objnum = m_pDocument->AddIndirectObject(pStream);
168 pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum);
169 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700170
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 CPDF_Dictionary* pStreamDict = pStream->GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700172
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 if (!pStreamDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700174 pStreamDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 pStream->InitStream(NULL, 0, pStreamDict);
176 }
177
178 if (pStreamDict) {
Wei Li9b761132016-01-29 15:44:20 -0800179 CPDF_Dictionary* pStreamResList = pStreamDict->GetDictBy("Resources");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180 if (!pStreamResList) {
Tom Sepezae51c812015-08-05 12:34:06 -0700181 pStreamResList = new CPDF_Dictionary();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 pStreamDict->SetAt("Resources", pStreamResList);
183 }
184
185 if (pStreamResList) {
Wei Li9b761132016-01-29 15:44:20 -0800186 CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictBy("Font");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187 if (!pStreamResFontList) {
188 pStreamResFontList = new CPDF_Dictionary;
189 int32_t objnum = m_pDocument->AddIndirectObject(pStreamResFontList);
190 pStreamResList->SetAtReference("Font", m_pDocument, objnum);
191 }
192 if (!pStreamResFontList->KeyExist(sAlias))
193 pStreamResFontList->SetAtReference(sAlias, m_pDocument,
194 pFont->GetFontDict());
195 }
196 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700197}
198
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700199CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString& sAlias) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200 CPDF_Dictionary* pAcroFormDict = NULL;
Tom Sepez007e6c02016-02-26 14:31:56 -0800201 const bool bWidget = (m_pAnnotDict->GetStringBy("Subtype") == "Widget");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202 if (bWidget) {
203 if (CPDF_Dictionary* pRootDict = m_pDocument->GetRoot())
Wei Li9b761132016-01-29 15:44:20 -0800204 pAcroFormDict = pRootDict->GetDictBy("AcroForm");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205 }
206
207 CFX_ByteString sDA;
208 CPDF_Object* pObj;
209 if ((pObj = FPDF_GetFieldAttr(m_pAnnotDict, "DA")))
210 sDA = pObj->GetString();
211
212 if (bWidget) {
213 if (sDA.IsEmpty()) {
214 pObj = FPDF_GetFieldAttr(pAcroFormDict, "DA");
215 sDA = pObj ? pObj->GetString() : CFX_ByteString();
216 }
217 }
218
219 CPDF_Dictionary* pFontDict = NULL;
220
221 if (!sDA.IsEmpty()) {
222 CPDF_SimpleParser syntax(sDA);
Wei Li970c11e2016-02-16 14:26:22 -0800223 syntax.FindTagParamFromStart("Tf", 2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224 CFX_ByteString sFontName = syntax.GetWord();
225 sAlias = PDF_NameDecode(sFontName).Mid(1);
226
Wei Li9b761132016-01-29 15:44:20 -0800227 if (CPDF_Dictionary* pDRDict = m_pAnnotDict->GetDictBy("DR"))
228 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font"))
229 pFontDict = pDRFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230
231 if (!pFontDict)
Wei Li9b761132016-01-29 15:44:20 -0800232 if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP"))
233 if (CPDF_Dictionary* pNormalDict = pAPDict->GetDictBy("N"))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234 if (CPDF_Dictionary* pNormalResDict =
Wei Li9b761132016-01-29 15:44:20 -0800235 pNormalDict->GetDictBy("Resources"))
236 if (CPDF_Dictionary* pResFontDict =
237 pNormalResDict->GetDictBy("Font"))
238 pFontDict = pResFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700239
240 if (bWidget) {
241 if (!pFontDict) {
242 if (pAcroFormDict) {
Wei Li9b761132016-01-29 15:44:20 -0800243 if (CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR"))
244 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font"))
245 pFontDict = pDRFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 }
247 }
248 }
249 }
250
251 return pFontDict ? m_pDocument->LoadFont(pFontDict) : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700252}
253
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType) {
255 m_sAPType = sAPType;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257 Reset();
Lei Zhangfcfa3b82015-12-24 21:07:28 -0800258 Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700259}