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