blob: 97590d20dd9614b78ccf0aab9e793ab0eaecc254 [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"
dsinclaircac704d2016-07-28 12:59:09 -070014#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
15#include "core/fpdfdoc/include/cpdf_formfield.h"
jaepark27362762016-08-11 13:10:39 -070016#include "fpdfsdk/include/cpdfsdk_annot.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070017
Nico Weber9d8ec5a2015-08-04 13:00:21 -070018CBA_FontMap::CBA_FontMap(CPDFSDK_Annot* pAnnot,
dsinclairb9590102016-04-27 06:38:59 -070019 CFX_SystemHandler* pSystemHandler)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070020 : CPWL_FontMap(pSystemHandler),
thestig1cd352e2016-06-07 17:53:06 -070021 m_pDocument(nullptr),
22 m_pAnnotDict(nullptr),
23 m_pDefaultFont(nullptr),
Nico Weber9d8ec5a2015-08-04 13:00:21 -070024 m_sAPType("N") {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025 CPDF_Page* pPage = pAnnot->GetPDFPage();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027 m_pDocument = pPage->m_pDocument;
28 m_pAnnotDict = pAnnot->GetPDFAnnot()->GetAnnotDict();
Lei Zhangfcfa3b82015-12-24 21:07:28 -080029 Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070030}
31
Nico Weber9d8ec5a2015-08-04 13:00:21 -070032CBA_FontMap::~CBA_FontMap() {}
33
34void CBA_FontMap::Reset() {
35 Empty();
thestig1cd352e2016-06-07 17:53:06 -070036 m_pDefaultFont = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070037 m_sDefaultFontName = "";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070038}
39
Lei Zhangfcfa3b82015-12-24 21:07:28 -080040void CBA_FontMap::Initialize() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070041 int32_t nCharset = DEFAULT_CHARSET;
42
43 if (!m_pDefaultFont) {
44 m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName);
45 if (m_pDefaultFont) {
Lei Zhangc2fb35f2016-01-05 16:46:58 -080046 if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047 nCharset = pSubstFont->m_Charset;
Lei Zhangc2fb35f2016-01-05 16:46:58 -080048 } else {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070049 if (m_sDefaultFontName == "Wingdings" ||
50 m_sDefaultFontName == "Wingdings2" ||
51 m_sDefaultFontName == "Wingdings3" ||
52 m_sDefaultFontName == "Webdings")
53 nCharset = SYMBOL_CHARSET;
54 else
55 nCharset = ANSI_CHARSET;
56 }
57 AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
58 AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
59 }
60 }
61
62 if (nCharset != ANSI_CHARSET)
Lei Zhangfcfa3b82015-12-24 21:07:28 -080063 CPWL_FontMap::Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064}
65
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066void CBA_FontMap::SetDefaultFont(CPDF_Font* pFont,
67 const CFX_ByteString& sFontName) {
Lei Zhang5eca3052016-02-22 20:32:21 -080068 ASSERT(pFont);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070069
70 if (m_pDefaultFont)
71 return;
72
73 m_pDefaultFont = pFont;
74 m_sDefaultFontName = sFontName;
75
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076 int32_t nCharset = DEFAULT_CHARSET;
77 if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
78 nCharset = pSubstFont->m_Charset;
79 AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070080}
81
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias,
83 int32_t nCharset) {
thestig907a5222016-06-21 14:38:27 -070084 if (m_pAnnotDict->GetStringBy("Subtype") != "Widget")
85 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086
thestig907a5222016-06-21 14:38:27 -070087 CPDF_Document* pDocument = GetDocument();
88 CPDF_Dictionary* pRootDict = pDocument->GetRoot();
89 if (!pRootDict)
90 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091
thestig907a5222016-06-21 14:38:27 -070092 CPDF_Dictionary* pAcroFormDict = pRootDict->GetDictBy("AcroForm");
93 if (!pAcroFormDict)
94 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095
thestig907a5222016-06-21 14:38:27 -070096 CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR");
97 if (!pDRDict)
98 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070099
thestig907a5222016-06-21 14:38:27 -0700100 return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700101}
102
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700103CPDF_Document* CBA_FontMap::GetDocument() {
104 return m_pDocument;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700105}
106
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict,
108 CFX_ByteString& sFontAlias,
109 int32_t nCharset) {
110 if (!pResDict)
thestig1cd352e2016-06-07 17:53:06 -0700111 return nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700112
Wei Li9b761132016-01-29 15:44:20 -0800113 CPDF_Dictionary* pFonts = pResDict->GetDictBy("Font");
Lei Zhang412e9082015-12-14 18:34:00 -0800114 if (!pFonts)
thestig1cd352e2016-06-07 17:53:06 -0700115 return nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700116
Lei Zhang5eca3052016-02-22 20:32:21 -0800117 CPDF_Document* pDocument = GetDocument();
thestig1cd352e2016-06-07 17:53:06 -0700118 CPDF_Font* pFind = nullptr;
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800119 for (const auto& it : *pFonts) {
120 const CFX_ByteString& csKey = it.first;
121 CPDF_Object* pObj = it.second;
Lei Zhang412e9082015-12-14 18:34:00 -0800122 if (!pObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 continue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700124
Dan Sinclairf1251c12015-10-20 16:24:45 -0400125 CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
126 if (!pElement)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 continue;
Wei Li9b761132016-01-29 15:44:20 -0800128 if (pElement->GetStringBy("Type") != "Font")
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129 continue;
130
131 CPDF_Font* pFont = pDocument->LoadFont(pElement);
Lei Zhang412e9082015-12-14 18:34:00 -0800132 if (!pFont)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133 continue;
134 const CFX_SubstFont* pSubst = pFont->GetSubstFont();
Lei Zhang412e9082015-12-14 18:34:00 -0800135 if (!pSubst)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136 continue;
137 if (pSubst->m_Charset == nCharset) {
138 sFontAlias = csKey;
139 pFind = pFont;
140 }
141 }
142 return pFind;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700143}
144
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700145void CBA_FontMap::AddedFont(CPDF_Font* pFont,
146 const CFX_ByteString& sFontAlias) {
147 AddFontToAnnotDict(pFont, sFontAlias);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700148}
149
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700150void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont,
151 const CFX_ByteString& sAlias) {
152 if (!pFont)
153 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700154
Wei Li9b761132016-01-29 15:44:20 -0800155 CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700156
Lei Zhang412e9082015-12-14 18:34:00 -0800157 if (!pAPDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700158 pAPDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 m_pAnnotDict->SetAt("AP", pAPDict);
160 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700161
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162 // to avoid checkbox and radiobutton
tsepez7b1ccf92016-04-14 11:04:57 -0700163 CPDF_Object* pObject = pAPDict->GetObjectBy(m_sAPType);
Dan Sinclairf1251c12015-10-20 16:24:45 -0400164 if (ToDictionary(pObject))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700166
tsepez7b1ccf92016-04-14 11:04:57 -0700167 CPDF_Stream* pStream = pAPDict->GetStreamBy(m_sAPType);
Lei Zhang412e9082015-12-14 18:34:00 -0800168 if (!pStream) {
thestig1cd352e2016-06-07 17:53:06 -0700169 pStream = new CPDF_Stream(nullptr, 0, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700170 int32_t objnum = m_pDocument->AddIndirectObject(pStream);
tsepez71a452f2016-05-13 17:51:27 -0700171 pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700173
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700174 CPDF_Dictionary* pStreamDict = pStream->GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700175
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 if (!pStreamDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700177 pStreamDict = new CPDF_Dictionary;
thestig1cd352e2016-06-07 17:53:06 -0700178 pStream->InitStream(nullptr, 0, pStreamDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700179 }
180
181 if (pStreamDict) {
Wei Li9b761132016-01-29 15:44:20 -0800182 CPDF_Dictionary* pStreamResList = pStreamDict->GetDictBy("Resources");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 if (!pStreamResList) {
Tom Sepezae51c812015-08-05 12:34:06 -0700184 pStreamResList = new CPDF_Dictionary();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 pStreamDict->SetAt("Resources", pStreamResList);
186 }
187
188 if (pStreamResList) {
Wei Li9b761132016-01-29 15:44:20 -0800189 CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictBy("Font");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190 if (!pStreamResFontList) {
191 pStreamResFontList = new CPDF_Dictionary;
192 int32_t objnum = m_pDocument->AddIndirectObject(pStreamResFontList);
193 pStreamResList->SetAtReference("Font", m_pDocument, objnum);
194 }
tsepez7b1ccf92016-04-14 11:04:57 -0700195 if (!pStreamResFontList->KeyExist(sAlias))
196 pStreamResFontList->SetAtReference(sAlias, m_pDocument,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197 pFont->GetFontDict());
198 }
199 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700200}
201
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString& sAlias) {
thestig1cd352e2016-06-07 17:53:06 -0700203 CPDF_Dictionary* pAcroFormDict = nullptr;
Tom Sepez007e6c02016-02-26 14:31:56 -0800204 const bool bWidget = (m_pAnnotDict->GetStringBy("Subtype") == "Widget");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205 if (bWidget) {
206 if (CPDF_Dictionary* pRootDict = m_pDocument->GetRoot())
Wei Li9b761132016-01-29 15:44:20 -0800207 pAcroFormDict = pRootDict->GetDictBy("AcroForm");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208 }
209
210 CFX_ByteString sDA;
Wei Lid4e8f122016-03-21 11:20:44 -0700211 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pAnnotDict, "DA");
212 if (pObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 sDA = pObj->GetString();
214
215 if (bWidget) {
216 if (sDA.IsEmpty()) {
217 pObj = FPDF_GetFieldAttr(pAcroFormDict, "DA");
218 sDA = pObj ? pObj->GetString() : CFX_ByteString();
219 }
220 }
221
thestig1cd352e2016-06-07 17:53:06 -0700222 CPDF_Dictionary* pFontDict = nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223
224 if (!sDA.IsEmpty()) {
tsepez4c3debb2016-04-08 12:20:38 -0700225 CPDF_SimpleParser syntax(sDA.AsStringC());
Wei Li970c11e2016-02-16 14:26:22 -0800226 syntax.FindTagParamFromStart("Tf", 2);
tsepez71a452f2016-05-13 17:51:27 -0700227 CFX_ByteString sFontName(syntax.GetWord());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228 sAlias = PDF_NameDecode(sFontName).Mid(1);
229
Wei Li9b761132016-01-29 15:44:20 -0800230 if (CPDF_Dictionary* pDRDict = m_pAnnotDict->GetDictBy("DR"))
231 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font"))
tsepez7b1ccf92016-04-14 11:04:57 -0700232 pFontDict = pDRFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233
234 if (!pFontDict)
Wei Li9b761132016-01-29 15:44:20 -0800235 if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP"))
236 if (CPDF_Dictionary* pNormalDict = pAPDict->GetDictBy("N"))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237 if (CPDF_Dictionary* pNormalResDict =
Wei Li9b761132016-01-29 15:44:20 -0800238 pNormalDict->GetDictBy("Resources"))
239 if (CPDF_Dictionary* pResFontDict =
240 pNormalResDict->GetDictBy("Font"))
tsepez7b1ccf92016-04-14 11:04:57 -0700241 pFontDict = pResFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242
243 if (bWidget) {
244 if (!pFontDict) {
245 if (pAcroFormDict) {
Wei Li9b761132016-01-29 15:44:20 -0800246 if (CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR"))
247 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font"))
tsepez7b1ccf92016-04-14 11:04:57 -0700248 pFontDict = pDRFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249 }
250 }
251 }
252 }
253
254 return pFontDict ? m_pDocument->LoadFont(pFontDict) : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700255}
256
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType) {
258 m_sAPType = sAPType;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700259
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 Reset();
Lei Zhangfcfa3b82015-12-24 21:07:28 -0800261 Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700262}