| 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 |