blob: 4c74d5a242a4b9c4ae6abfd0a0f56bab5b631e66 [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),
19 m_pDocument(NULL),
20 m_pAnnotDict(NULL),
21 m_pDefaultFont(NULL),
22 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();
34 m_pDefaultFont = NULL;
35 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) {
Wei Li9b761132016-01-29 15:44:20 -080082 if (m_pAnnotDict->GetStringBy("Subtype") == "Widget") {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083 CPDF_Document* pDocument = GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -070084 CPDF_Dictionary* pRootDict = pDocument->GetRoot();
85 if (!pRootDict)
86 return NULL;
87
Wei Li9b761132016-01-29 15:44:20 -080088 CPDF_Dictionary* pAcroFormDict = pRootDict->GetDictBy("AcroForm");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089 if (!pAcroFormDict)
90 return NULL;
91
Wei Li9b761132016-01-29 15:44:20 -080092 CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070093 if (!pDRDict)
94 return NULL;
95
96 return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
97 }
98
99 return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700100}
101
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700102CPDF_Document* CBA_FontMap::GetDocument() {
103 return m_pDocument;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700104}
105
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700106CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict,
107 CFX_ByteString& sFontAlias,
108 int32_t nCharset) {
109 if (!pResDict)
110 return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700111
Wei Li9b761132016-01-29 15:44:20 -0800112 CPDF_Dictionary* pFonts = pResDict->GetDictBy("Font");
Lei Zhang412e9082015-12-14 18:34:00 -0800113 if (!pFonts)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114 return NULL;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700115
Lei Zhang5eca3052016-02-22 20:32:21 -0800116 CPDF_Document* pDocument = GetDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700117 CPDF_Font* pFind = NULL;
Oliver Chang3f1c71f2016-01-11 08:45:31 -0800118 for (const auto& it : *pFonts) {
119 const CFX_ByteString& csKey = it.first;
120 CPDF_Object* pObj = it.second;
Lei Zhang412e9082015-12-14 18:34:00 -0800121 if (!pObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122 continue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700123
Dan Sinclairf1251c12015-10-20 16:24:45 -0400124 CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
125 if (!pElement)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 continue;
Wei Li9b761132016-01-29 15:44:20 -0800127 if (pElement->GetStringBy("Type") != "Font")
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128 continue;
129
130 CPDF_Font* pFont = pDocument->LoadFont(pElement);
Lei Zhang412e9082015-12-14 18:34:00 -0800131 if (!pFont)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 continue;
133 const CFX_SubstFont* pSubst = pFont->GetSubstFont();
Lei Zhang412e9082015-12-14 18:34:00 -0800134 if (!pSubst)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 continue;
136 if (pSubst->m_Charset == nCharset) {
137 sFontAlias = csKey;
138 pFind = pFont;
139 }
140 }
141 return pFind;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700142}
143
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144void CBA_FontMap::AddedFont(CPDF_Font* pFont,
145 const CFX_ByteString& sFontAlias) {
146 AddFontToAnnotDict(pFont, sFontAlias);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700147}
148
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700149void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont,
150 const CFX_ByteString& sAlias) {
151 if (!pFont)
152 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700153
Wei Li9b761132016-01-29 15:44:20 -0800154 CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP");
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700155
Lei Zhang412e9082015-12-14 18:34:00 -0800156 if (!pAPDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700157 pAPDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158 m_pAnnotDict->SetAt("AP", pAPDict);
159 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700160
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 // to avoid checkbox and radiobutton
tsepez7b1ccf92016-04-14 11:04:57 -0700162 CPDF_Object* pObject = pAPDict->GetObjectBy(m_sAPType);
Dan Sinclairf1251c12015-10-20 16:24:45 -0400163 if (ToDictionary(pObject))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700165
tsepez7b1ccf92016-04-14 11:04:57 -0700166 CPDF_Stream* pStream = pAPDict->GetStreamBy(m_sAPType);
Lei Zhang412e9082015-12-14 18:34:00 -0800167 if (!pStream) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 pStream = new CPDF_Stream(NULL, 0, NULL);
169 int32_t objnum = m_pDocument->AddIndirectObject(pStream);
tsepez71a452f2016-05-13 17:51:27 -0700170 pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700172
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 CPDF_Dictionary* pStreamDict = pStream->GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 if (!pStreamDict) {
Tom Sepezae51c812015-08-05 12:34:06 -0700176 pStreamDict = new CPDF_Dictionary;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177 pStream->InitStream(NULL, 0, pStreamDict);
178 }
179
180 if (pStreamDict) {
Wei Li9b761132016-01-29 15:44:20 -0800181 CPDF_Dictionary* pStreamResList = pStreamDict->GetDictBy("Resources");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 if (!pStreamResList) {
Tom Sepezae51c812015-08-05 12:34:06 -0700183 pStreamResList = new CPDF_Dictionary();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184 pStreamDict->SetAt("Resources", pStreamResList);
185 }
186
187 if (pStreamResList) {
Wei Li9b761132016-01-29 15:44:20 -0800188 CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictBy("Font");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700189 if (!pStreamResFontList) {
190 pStreamResFontList = new CPDF_Dictionary;
191 int32_t objnum = m_pDocument->AddIndirectObject(pStreamResFontList);
192 pStreamResList->SetAtReference("Font", m_pDocument, objnum);
193 }
tsepez7b1ccf92016-04-14 11:04:57 -0700194 if (!pStreamResFontList->KeyExist(sAlias))
195 pStreamResFontList->SetAtReference(sAlias, m_pDocument,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196 pFont->GetFontDict());
197 }
198 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700199}
200
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString& sAlias) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202 CPDF_Dictionary* pAcroFormDict = NULL;
Tom Sepez007e6c02016-02-26 14:31:56 -0800203 const bool bWidget = (m_pAnnotDict->GetStringBy("Subtype") == "Widget");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204 if (bWidget) {
205 if (CPDF_Dictionary* pRootDict = m_pDocument->GetRoot())
Wei Li9b761132016-01-29 15:44:20 -0800206 pAcroFormDict = pRootDict->GetDictBy("AcroForm");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207 }
208
209 CFX_ByteString sDA;
Wei Lid4e8f122016-03-21 11:20:44 -0700210 CPDF_Object* pObj = FPDF_GetFieldAttr(m_pAnnotDict, "DA");
211 if (pObj)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212 sDA = pObj->GetString();
213
214 if (bWidget) {
215 if (sDA.IsEmpty()) {
216 pObj = FPDF_GetFieldAttr(pAcroFormDict, "DA");
217 sDA = pObj ? pObj->GetString() : CFX_ByteString();
218 }
219 }
220
221 CPDF_Dictionary* pFontDict = NULL;
222
223 if (!sDA.IsEmpty()) {
tsepez4c3debb2016-04-08 12:20:38 -0700224 CPDF_SimpleParser syntax(sDA.AsStringC());
Wei Li970c11e2016-02-16 14:26:22 -0800225 syntax.FindTagParamFromStart("Tf", 2);
tsepez71a452f2016-05-13 17:51:27 -0700226 CFX_ByteString sFontName(syntax.GetWord());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700227 sAlias = PDF_NameDecode(sFontName).Mid(1);
228
Wei Li9b761132016-01-29 15:44:20 -0800229 if (CPDF_Dictionary* pDRDict = m_pAnnotDict->GetDictBy("DR"))
230 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font"))
tsepez7b1ccf92016-04-14 11:04:57 -0700231 pFontDict = pDRFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232
233 if (!pFontDict)
Wei Li9b761132016-01-29 15:44:20 -0800234 if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP"))
235 if (CPDF_Dictionary* pNormalDict = pAPDict->GetDictBy("N"))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700236 if (CPDF_Dictionary* pNormalResDict =
Wei Li9b761132016-01-29 15:44:20 -0800237 pNormalDict->GetDictBy("Resources"))
238 if (CPDF_Dictionary* pResFontDict =
239 pNormalResDict->GetDictBy("Font"))
tsepez7b1ccf92016-04-14 11:04:57 -0700240 pFontDict = pResFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241
242 if (bWidget) {
243 if (!pFontDict) {
244 if (pAcroFormDict) {
Wei Li9b761132016-01-29 15:44:20 -0800245 if (CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR"))
246 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font"))
tsepez7b1ccf92016-04-14 11:04:57 -0700247 pFontDict = pDRFontDict->GetDictBy(sAlias);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700248 }
249 }
250 }
251 }
252
253 return pFontDict ? m_pDocument->LoadFont(pFontDict) : nullptr;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700254}
255
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType) {
257 m_sAPType = sAPType;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700258
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700259 Reset();
Lei Zhangfcfa3b82015-12-24 21:07:28 -0800260 Initialize();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700261}