OLD | NEW |
| (Empty) |
1 // 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. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "fpdfsdk/include/formfiller/FFL_CBA_Fontmap.h" | |
8 | |
9 #include "core/include/fpdfapi/cpdf_document.h" | |
10 #include "core/include/fpdfapi/cpdf_simple_parser.h" | |
11 #include "core/include/fpdfapi/fpdf_page.h" | |
12 #include "fpdfsdk/include/fsdk_baseannot.h" | |
13 | |
14 CBA_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") { | |
21 CPDF_Page* pPage = pAnnot->GetPDFPage(); | |
22 | |
23 m_pDocument = pPage->m_pDocument; | |
24 m_pAnnotDict = pAnnot->GetPDFAnnot()->GetAnnotDict(); | |
25 Initialize(); | |
26 } | |
27 | |
28 CBA_FontMap::~CBA_FontMap() {} | |
29 | |
30 void CBA_FontMap::Reset() { | |
31 Empty(); | |
32 m_pDefaultFont = NULL; | |
33 m_sDefaultFontName = ""; | |
34 } | |
35 | |
36 void CBA_FontMap::Initialize() { | |
37 int32_t nCharset = DEFAULT_CHARSET; | |
38 | |
39 if (!m_pDefaultFont) { | |
40 m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName); | |
41 if (m_pDefaultFont) { | |
42 if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont()) { | |
43 nCharset = pSubstFont->m_Charset; | |
44 } else { | |
45 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) | |
59 CPWL_FontMap::Initialize(); | |
60 } | |
61 | |
62 void CBA_FontMap::SetDefaultFont(CPDF_Font* pFont, | |
63 const CFX_ByteString& sFontName) { | |
64 ASSERT(pFont); | |
65 | |
66 if (m_pDefaultFont) | |
67 return; | |
68 | |
69 m_pDefaultFont = pFont; | |
70 m_sDefaultFontName = sFontName; | |
71 | |
72 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); | |
76 } | |
77 | |
78 CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias, | |
79 int32_t nCharset) { | |
80 if (m_pAnnotDict->GetStringBy("Subtype") == "Widget") { | |
81 CPDF_Document* pDocument = GetDocument(); | |
82 CPDF_Dictionary* pRootDict = pDocument->GetRoot(); | |
83 if (!pRootDict) | |
84 return NULL; | |
85 | |
86 CPDF_Dictionary* pAcroFormDict = pRootDict->GetDictBy("AcroForm"); | |
87 if (!pAcroFormDict) | |
88 return NULL; | |
89 | |
90 CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR"); | |
91 if (!pDRDict) | |
92 return NULL; | |
93 | |
94 return FindResFontSameCharset(pDRDict, sFontAlias, nCharset); | |
95 } | |
96 | |
97 return NULL; | |
98 } | |
99 | |
100 CPDF_Document* CBA_FontMap::GetDocument() { | |
101 return m_pDocument; | |
102 } | |
103 | |
104 CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict, | |
105 CFX_ByteString& sFontAlias, | |
106 int32_t nCharset) { | |
107 if (!pResDict) | |
108 return NULL; | |
109 | |
110 CPDF_Dictionary* pFonts = pResDict->GetDictBy("Font"); | |
111 if (!pFonts) | |
112 return NULL; | |
113 | |
114 CPDF_Document* pDocument = GetDocument(); | |
115 CPDF_Font* pFind = NULL; | |
116 for (const auto& it : *pFonts) { | |
117 const CFX_ByteString& csKey = it.first; | |
118 CPDF_Object* pObj = it.second; | |
119 if (!pObj) | |
120 continue; | |
121 | |
122 CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect()); | |
123 if (!pElement) | |
124 continue; | |
125 if (pElement->GetStringBy("Type") != "Font") | |
126 continue; | |
127 | |
128 CPDF_Font* pFont = pDocument->LoadFont(pElement); | |
129 if (!pFont) | |
130 continue; | |
131 const CFX_SubstFont* pSubst = pFont->GetSubstFont(); | |
132 if (!pSubst) | |
133 continue; | |
134 if (pSubst->m_Charset == nCharset) { | |
135 sFontAlias = csKey; | |
136 pFind = pFont; | |
137 } | |
138 } | |
139 return pFind; | |
140 } | |
141 | |
142 void CBA_FontMap::AddedFont(CPDF_Font* pFont, | |
143 const CFX_ByteString& sFontAlias) { | |
144 AddFontToAnnotDict(pFont, sFontAlias); | |
145 } | |
146 | |
147 void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont, | |
148 const CFX_ByteString& sAlias) { | |
149 if (!pFont) | |
150 return; | |
151 | |
152 CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP"); | |
153 | |
154 if (!pAPDict) { | |
155 pAPDict = new CPDF_Dictionary; | |
156 m_pAnnotDict->SetAt("AP", pAPDict); | |
157 } | |
158 | |
159 // to avoid checkbox and radiobutton | |
160 CPDF_Object* pObject = pAPDict->GetElement(m_sAPType); | |
161 if (ToDictionary(pObject)) | |
162 return; | |
163 | |
164 CPDF_Stream* pStream = pAPDict->GetStreamBy(m_sAPType); | |
165 if (!pStream) { | |
166 pStream = new CPDF_Stream(NULL, 0, NULL); | |
167 int32_t objnum = m_pDocument->AddIndirectObject(pStream); | |
168 pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum); | |
169 } | |
170 | |
171 CPDF_Dictionary* pStreamDict = pStream->GetDict(); | |
172 | |
173 if (!pStreamDict) { | |
174 pStreamDict = new CPDF_Dictionary; | |
175 pStream->InitStream(NULL, 0, pStreamDict); | |
176 } | |
177 | |
178 if (pStreamDict) { | |
179 CPDF_Dictionary* pStreamResList = pStreamDict->GetDictBy("Resources"); | |
180 if (!pStreamResList) { | |
181 pStreamResList = new CPDF_Dictionary(); | |
182 pStreamDict->SetAt("Resources", pStreamResList); | |
183 } | |
184 | |
185 if (pStreamResList) { | |
186 CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictBy("Font"); | |
187 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 } | |
197 } | |
198 | |
199 CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString& sAlias) { | |
200 CPDF_Dictionary* pAcroFormDict = NULL; | |
201 const bool bWidget = (m_pAnnotDict->GetStringBy("Subtype") == "Widget"); | |
202 if (bWidget) { | |
203 if (CPDF_Dictionary* pRootDict = m_pDocument->GetRoot()) | |
204 pAcroFormDict = pRootDict->GetDictBy("AcroForm"); | |
205 } | |
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); | |
223 syntax.FindTagParamFromStart("Tf", 2); | |
224 CFX_ByteString sFontName = syntax.GetWord(); | |
225 sAlias = PDF_NameDecode(sFontName).Mid(1); | |
226 | |
227 if (CPDF_Dictionary* pDRDict = m_pAnnotDict->GetDictBy("DR")) | |
228 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font")) | |
229 pFontDict = pDRFontDict->GetDictBy(sAlias); | |
230 | |
231 if (!pFontDict) | |
232 if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDictBy("AP")) | |
233 if (CPDF_Dictionary* pNormalDict = pAPDict->GetDictBy("N")) | |
234 if (CPDF_Dictionary* pNormalResDict = | |
235 pNormalDict->GetDictBy("Resources")) | |
236 if (CPDF_Dictionary* pResFontDict = | |
237 pNormalResDict->GetDictBy("Font")) | |
238 pFontDict = pResFontDict->GetDictBy(sAlias); | |
239 | |
240 if (bWidget) { | |
241 if (!pFontDict) { | |
242 if (pAcroFormDict) { | |
243 if (CPDF_Dictionary* pDRDict = pAcroFormDict->GetDictBy("DR")) | |
244 if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDictBy("Font")) | |
245 pFontDict = pDRFontDict->GetDictBy(sAlias); | |
246 } | |
247 } | |
248 } | |
249 } | |
250 | |
251 return pFontDict ? m_pDocument->LoadFont(pFontDict) : nullptr; | |
252 } | |
253 | |
254 void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType) { | |
255 m_sAPType = sAPType; | |
256 | |
257 Reset(); | |
258 Initialize(); | |
259 } | |
OLD | NEW |