Delete unused fpdfsdkdll.rc and resource.h.
[pdfium.git] / fpdfsdk / src / formfiller / FFL_CBA_Fontmap.cpp
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 "../../include/formfiller/FormFiller.h"
8 #include "../../include/formfiller/FFL_CBA_Fontmap.h"
9
10 CBA_FontMap::CBA_FontMap(CPDFSDK_Annot* pAnnot,
11                          IFX_SystemHandler* pSystemHandler)
12     : CPWL_FontMap(pSystemHandler),
13       m_pDocument(NULL),
14       m_pAnnotDict(NULL),
15       m_pDefaultFont(NULL),
16       m_sAPType("N") {
17   ASSERT(pAnnot != NULL);
18
19   CPDF_Page* pPage = pAnnot->GetPDFPage();
20
21   m_pDocument = pPage->m_pDocument;
22   m_pAnnotDict = pAnnot->GetPDFAnnot()->GetAnnotDict();
23 }
24
25 CBA_FontMap::CBA_FontMap(CPDF_Document* pDocument,
26                          CPDF_Dictionary* pAnnotDict,
27                          IFX_SystemHandler* pSystemHandler)
28     : CPWL_FontMap(pSystemHandler),
29       m_pDocument(pDocument),
30       m_pAnnotDict(pAnnotDict),
31       m_pDefaultFont(NULL),
32       m_sAPType("N") {}
33
34 CBA_FontMap::~CBA_FontMap() {}
35
36 void CBA_FontMap::Reset() {
37   Empty();
38   m_pDefaultFont = NULL;
39   m_sDefaultFontName = "";
40 }
41
42 void CBA_FontMap::Initial(const FX_CHAR* fontname) {
43   int32_t nCharset = DEFAULT_CHARSET;
44
45   if (!m_pDefaultFont) {
46     m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName);
47     if (m_pDefaultFont) {
48       if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
49         nCharset = pSubstFont->m_Charset;
50       else {
51         if (m_sDefaultFontName == "Wingdings" ||
52             m_sDefaultFontName == "Wingdings2" ||
53             m_sDefaultFontName == "Wingdings3" ||
54             m_sDefaultFontName == "Webdings")
55           nCharset = SYMBOL_CHARSET;
56         else
57           nCharset = ANSI_CHARSET;
58       }
59       AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
60       AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
61     }
62   }
63
64   if (nCharset != ANSI_CHARSET)
65     CPWL_FontMap::Initial(fontname);
66 }
67
68 void CBA_FontMap::SetDefaultFont(CPDF_Font* pFont,
69                                  const CFX_ByteString& sFontName) {
70   ASSERT(pFont != NULL);
71
72   if (m_pDefaultFont)
73     return;
74
75   m_pDefaultFont = pFont;
76   m_sDefaultFontName = sFontName;
77
78   //    if (m_sDefaultFontName.IsEmpty())
79   //            m_sDefaultFontName = pFont->GetFontTypeName();
80
81   int32_t nCharset = DEFAULT_CHARSET;
82   if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
83     nCharset = pSubstFont->m_Charset;
84   AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
85 }
86
87 CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias,
88                                             int32_t nCharset) {
89   ASSERT(m_pAnnotDict != NULL);
90
91   if (m_pAnnotDict->GetString("Subtype") == "Widget") {
92     CPDF_Document* pDocument = GetDocument();
93     ASSERT(pDocument != NULL);
94
95     CPDF_Dictionary* pRootDict = pDocument->GetRoot();
96     if (!pRootDict)
97       return NULL;
98
99     CPDF_Dictionary* pAcroFormDict = pRootDict->GetDict("AcroForm");
100     if (!pAcroFormDict)
101       return NULL;
102
103     CPDF_Dictionary* pDRDict = pAcroFormDict->GetDict("DR");
104     if (!pDRDict)
105       return NULL;
106
107     return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
108   }
109
110   return NULL;
111 }
112
113 CPDF_Document* CBA_FontMap::GetDocument() {
114   return m_pDocument;
115 }
116
117 CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict,
118                                                CFX_ByteString& sFontAlias,
119                                                int32_t nCharset) {
120   if (!pResDict)
121     return NULL;
122
123   CPDF_Document* pDocument = GetDocument();
124   ASSERT(pDocument != NULL);
125
126   CPDF_Dictionary* pFonts = pResDict->GetDict("Font");
127   if (pFonts == NULL)
128     return NULL;
129
130   CPDF_Font* pFind = NULL;
131
132   FX_POSITION pos = pFonts->GetStartPos();
133   while (pos) {
134     CPDF_Object* pObj = NULL;
135     CFX_ByteString csKey;
136     pObj = pFonts->GetNextElement(pos, csKey);
137     if (pObj == NULL)
138       continue;
139
140     CPDF_Dictionary* pElement = ToDictionary(pObj->GetDirect());
141     if (!pElement)
142       continue;
143     if (pElement->GetString("Type") != "Font")
144       continue;
145
146     CPDF_Font* pFont = pDocument->LoadFont(pElement);
147     if (pFont == NULL)
148       continue;
149     const CFX_SubstFont* pSubst = pFont->GetSubstFont();
150     if (pSubst == NULL)
151       continue;
152     if (pSubst->m_Charset == nCharset) {
153       sFontAlias = csKey;
154       pFind = pFont;
155     }
156   }
157   return pFind;
158 }
159
160 void CBA_FontMap::AddedFont(CPDF_Font* pFont,
161                             const CFX_ByteString& sFontAlias) {
162   AddFontToAnnotDict(pFont, sFontAlias);
163 }
164
165 void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont,
166                                      const CFX_ByteString& sAlias) {
167   if (!pFont)
168     return;
169
170   ASSERT(m_pAnnotDict != NULL);
171   ASSERT(m_pDocument != NULL);
172
173   CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDict("AP");
174
175   if (pAPDict == NULL) {
176     pAPDict = new CPDF_Dictionary;
177     m_pAnnotDict->SetAt("AP", pAPDict);
178   }
179
180   // to avoid checkbox and radiobutton
181   CPDF_Object* pObject = pAPDict->GetElement(m_sAPType);
182   if (ToDictionary(pObject))
183     return;
184
185   CPDF_Stream* pStream = pAPDict->GetStream(m_sAPType);
186   if (pStream == NULL) {
187     pStream = new CPDF_Stream(NULL, 0, NULL);
188     int32_t objnum = m_pDocument->AddIndirectObject(pStream);
189     pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum);
190   }
191
192   CPDF_Dictionary* pStreamDict = pStream->GetDict();
193
194   if (!pStreamDict) {
195     pStreamDict = new CPDF_Dictionary;
196     pStream->InitStream(NULL, 0, pStreamDict);
197   }
198
199   if (pStreamDict) {
200     CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
201     if (!pStreamResList) {
202       pStreamResList = new CPDF_Dictionary();
203       pStreamDict->SetAt("Resources", pStreamResList);
204     }
205
206     if (pStreamResList) {
207       CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDict("Font");
208       if (!pStreamResFontList) {
209         pStreamResFontList = new CPDF_Dictionary;
210         int32_t objnum = m_pDocument->AddIndirectObject(pStreamResFontList);
211         pStreamResList->SetAtReference("Font", m_pDocument, objnum);
212       }
213       if (!pStreamResFontList->KeyExist(sAlias))
214         pStreamResFontList->SetAtReference(sAlias, m_pDocument,
215                                            pFont->GetFontDict());
216     }
217   }
218 }
219
220 CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString& sAlias) {
221   ASSERT(m_pAnnotDict != NULL);
222   ASSERT(m_pDocument != NULL);
223
224   CPDF_Dictionary* pAcroFormDict = NULL;
225
226   FX_BOOL bWidget = (m_pAnnotDict->GetString("Subtype") == "Widget");
227
228   if (bWidget) {
229     if (CPDF_Dictionary* pRootDict = m_pDocument->GetRoot())
230       pAcroFormDict = pRootDict->GetDict("AcroForm");
231   }
232
233   CFX_ByteString sDA;
234   CPDF_Object* pObj;
235   if ((pObj = FPDF_GetFieldAttr(m_pAnnotDict, "DA")))
236     sDA = pObj->GetString();
237
238   if (bWidget) {
239     if (sDA.IsEmpty()) {
240       pObj = FPDF_GetFieldAttr(pAcroFormDict, "DA");
241       sDA = pObj ? pObj->GetString() : CFX_ByteString();
242     }
243   }
244
245   CPDF_Dictionary* pFontDict = NULL;
246
247   if (!sDA.IsEmpty()) {
248     CPDF_SimpleParser syntax(sDA);
249     syntax.FindTagParam("Tf", 2);
250     CFX_ByteString sFontName = syntax.GetWord();
251     sAlias = PDF_NameDecode(sFontName).Mid(1);
252
253     if (CPDF_Dictionary* pDRDict = m_pAnnotDict->GetDict("DR"))
254       if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDict("Font"))
255         pFontDict = pDRFontDict->GetDict(sAlias);
256
257     if (!pFontDict)
258       if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDict("AP"))
259         if (CPDF_Dictionary* pNormalDict = pAPDict->GetDict("N"))
260           if (CPDF_Dictionary* pNormalResDict =
261                   pNormalDict->GetDict("Resources"))
262             if (CPDF_Dictionary* pResFontDict = pNormalResDict->GetDict("Font"))
263               pFontDict = pResFontDict->GetDict(sAlias);
264
265     if (bWidget) {
266       if (!pFontDict) {
267         if (pAcroFormDict) {
268           if (CPDF_Dictionary* pDRDict = pAcroFormDict->GetDict("DR"))
269             if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDict("Font"))
270               pFontDict = pDRFontDict->GetDict(sAlias);
271         }
272       }
273     }
274   }
275
276   return pFontDict ? m_pDocument->LoadFont(pFontDict) : nullptr;
277 }
278
279 void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType) {
280   m_sAPType = sAPType;
281
282   Reset();
283   Initial();
284 }