void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action) { ASSERT(action); if ((CPDF_Action&)action != CPDF_Action(m_pAnnot->GetAnnotDict()->GetDictBy("A"))) { CPDF_Document* pDoc = m_pPageView->GetPDFDocument(); CPDF_Dictionary* pDict = action.GetDict(); if (pDict && pDict->GetObjNum() == 0) { pDoc->AddIndirectObject(pDict); } m_pAnnot->GetAnnotDict()->SetAtReference("A", pDoc, pDict->GetObjNum()); } }
CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { if (iPage < 0 || iPage >= m_PageList.GetSize()) return nullptr; if (m_bLinearized && (iPage == m_iFirstPageNo)) { if (CPDF_Dictionary* pDict = ToDictionary(GetOrParseIndirectObject(m_dwFirstPageObjNum))) { return pDict; } } int objnum = m_PageList.GetAt(iPage); if (objnum) { if (CPDF_Dictionary* pDict = ToDictionary(GetOrParseIndirectObject(objnum))) return pDict; } CPDF_Dictionary* pPages = GetPagesDict(); if (!pPages) return nullptr; CPDF_Dictionary* pPage = FindPDFPage(pPages, iPage, iPage, 0); if (!pPage) return nullptr; m_PageList.SetAt(iPage, pPage->GetObjNum()); return pPage; }
void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) { if (nLevel > nMaxRecursion) return; if (!pFieldDict) return; uint32_t dwParentObjNum = pFieldDict->GetObjNum(); CPDF_Array* pKids = pFieldDict->GetArrayFor("Kids"); if (!pKids) { AddTerminalField(pFieldDict); return; } CPDF_Dictionary* pFirstKid = pKids->GetDictAt(0); if (!pFirstKid) return; if (pFirstKid->KeyExist("T") || pFirstKid->KeyExist("Kids")) { for (size_t i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pChildDict = pKids->GetDictAt(i); if (pChildDict) { if (pChildDict->GetObjNum() != dwParentObjNum) LoadField(pChildDict, nLevel + 1); } } } else { AddTerminalField(pFieldDict); } }
static int InsertNewPage(CPDF_Document* pDoc, int iPage, CPDF_Dictionary* pPageDict, CFX_DWordArray &pageList) { CPDF_Dictionary* pRoot = pDoc->GetRoot(); if (!pRoot) { return -1; } CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); if (!pPages) { return -1; } int nPages = pDoc->GetPageCount(); if (iPage < 0 || iPage > nPages) { return -1; } if (iPage == nPages) { CPDF_Array* pPagesList = pPages->GetArray(FX_BSTRC("Kids")); if (!pPagesList) { pPagesList = FX_NEW CPDF_Array; pPages->SetAt(FX_BSTRC("Kids"), pPagesList); } pPagesList->Add(pPageDict, pDoc); pPages->SetAtInteger(FX_BSTRC("Count"), nPages + 1); pPageDict->SetAtReference(FX_BSTRC("Parent"), pDoc, pPages->GetObjNum()); } else { CFX_PtrArray stack; stack.Add(pPages); if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, stack) < 0) { return -1; } } pageList.InsertAt(iPage, pPageDict->GetObjNum()); return iPage; }
void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) { if (nLevel > nMaxRecursion) { return; } if (pFieldDict == NULL) { return; } FX_DWORD dwParentObjNum = pFieldDict->GetObjNum(); CPDF_Array* pKids = pFieldDict->GetArray("Kids"); if (!pKids) { AddTerminalField(pFieldDict); return; } CPDF_Dictionary* pFirstKid = pKids->GetDict(0); if (pFirstKid == NULL) { return; } if (pFirstKid->KeyExist("T") || pFirstKid->KeyExist("Kids")) { for (FX_DWORD i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pChildDict = pKids->GetDict(i); if (pChildDict) { if (pChildDict->GetObjNum() != dwParentObjNum) { LoadField(pChildDict, nLevel + 1); } } } } else { AddTerminalField(pFieldDict); } }
CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { if (iPage < 0 || iPage >= m_PageList.GetSize()) return nullptr; if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) { if (CPDF_Dictionary* pDict = ToDictionary(GetIndirectObject(m_dwFirstPageObjNum, nullptr))) return pDict; } int objnum = m_PageList.GetAt(iPage); if (objnum) { if (CPDF_Dictionary* pDict = ToDictionary(GetIndirectObject(objnum, nullptr))) { return pDict; } } CPDF_Dictionary* pRoot = GetRoot(); if (!pRoot) return nullptr; CPDF_Dictionary* pPages = pRoot->GetDict("Pages"); if (!pPages) return nullptr; CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0); if (!pPage) return nullptr; m_PageList.SetAt(iPage, pPage->GetObjNum()); return pPage; }
CPDF_Dictionary* CPDF_Document::FindPDFPage(CPDF_Dictionary* pPages, int iPage, int nPagesToGo, int level) { CPDF_Array* pKidList = pPages->GetArrayFor("Kids"); if (!pKidList) return nPagesToGo == 0 ? pPages : nullptr; if (level >= FX_MAX_PAGE_LEVEL) return nullptr; for (size_t i = 0; i < pKidList->GetCount(); i++) { CPDF_Dictionary* pKid = pKidList->GetDictAt(i); if (!pKid) { nPagesToGo--; continue; } if (pKid == pPages) continue; if (!pKid->KeyExist("Kids")) { if (nPagesToGo == 0) return pKid; m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); nPagesToGo--; } else { int nPages = pKid->GetIntegerFor("Count"); if (nPagesToGo < nPages) return FindPDFPage(pKid, iPage, nPagesToGo, level + 1); nPagesToGo -= nPages; } } return nullptr; }
std::vector<DictObjInfo> CreateDictObjs(int num) { std::vector<DictObjInfo> info; for (int i = 0; i < num; ++i) { // Objects created will be released by the document. CPDF_Dictionary* obj = m_pIndirectObjs->NewIndirect<CPDF_Dictionary>(); info.push_back({obj->GetObjNum(), obj}); } return info; }
int CPDFSDK_PageView::GetPageIndex() { if (m_page) { CPDF_Dictionary* pDic = m_page->m_pFormDict; CPDF_Document* pDoc = m_pSDKDoc->GetDocument(); if (pDoc && pDic) { return pDoc->GetPageIndex(pDic->GetObjNum()); } } return -1; }
CPDF_AnnotList::CPDF_AnnotList(CPDF_Page* pPage) : m_pDocument(pPage->m_pDocument) { if (!pPage->m_pFormDict) return; CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayBy("Annots"); if (!pAnnots) return; CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); CPDF_Dictionary* pAcroForm = pRoot->GetDictBy("AcroForm"); FX_BOOL bRegenerateAP = pAcroForm && pAcroForm->GetBooleanBy("NeedAppearances"); for (size_t i = 0; i < pAnnots->GetCount(); ++i) { CPDF_Dictionary* pDict = ToDictionary(pAnnots->GetDirectObjectAt(i)); if (!pDict) continue; uint32_t dwObjNum = pDict->GetObjNum(); if (dwObjNum == 0) { dwObjNum = m_pDocument->AddIndirectObject(pDict); CPDF_Reference* pAction = new CPDF_Reference(m_pDocument, dwObjNum); pAnnots->InsertAt(i, pAction); pAnnots->RemoveAt(i + 1); pDict = pAnnots->GetDictAt(i); } // Skip creating Popup annotation in the PDF document since PDFium provides // its own Popup annotations. if (pDict->GetStringBy("Subtype") == "Popup") continue; m_AnnotList.push_back( std::unique_ptr<CPDF_Annot>(new CPDF_Annot(pDict, m_pDocument, false))); if (bRegenerateAP && pDict->GetStringBy("Subtype") == "Widget" && CPDF_InterForm::IsUpdateAPEnabled()) { FPDF_GenerateAP(m_pDocument, pDict); } } size_t nAnnotListSize = m_AnnotList.size(); for (size_t i = 0; i < nAnnotListSize; ++i) { std::unique_ptr<CPDF_Annot> pPopupAnnot( CreatePopupAnnot(m_AnnotList[i].get(), m_pDocument)); if (pPopupAnnot) m_AnnotList.push_back(std::move(pPopupAnnot)); } }
CPDF_AnnotList::CPDF_AnnotList(CPDF_Page* pPage) { ASSERT(pPage != NULL); m_pPageDict = pPage->m_pFormDict; if (m_pPageDict == NULL) { return; } m_pDocument = pPage->m_pDocument; CPDF_Array* pAnnots = m_pPageDict->GetArray("Annots"); if (pAnnots == NULL) { return; } CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm"); FX_BOOL bRegenerateAP = pAcroForm && pAcroForm->GetBoolean("NeedAppearances"); for (FX_DWORD i = 0; i < pAnnots->GetCount(); i ++) { CPDF_Dictionary* pDict = (CPDF_Dictionary*)pAnnots->GetElementValue(i); if (pDict == NULL || pDict->GetType() != PDFOBJ_DICTIONARY) { continue; } FX_DWORD dwObjNum = pDict->GetObjNum(); if (dwObjNum == 0) { dwObjNum = m_pDocument->AddIndirectObject(pDict); CPDF_Reference* pAction = CPDF_Reference::Create(m_pDocument, dwObjNum); if (pAction == NULL) { break; } pAnnots->InsertAt(i, pAction); pAnnots->RemoveAt(i + 1); pDict = pAnnots->GetDict(i); } CPDF_Annot* pAnnot = FX_NEW CPDF_Annot(pDict); if (pAnnot == NULL) { break; } pAnnot->m_pList = this; m_AnnotList.Add(pAnnot); if (bRegenerateAP && pDict->GetConstString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget")) if (CPDF_InterForm::UpdatingAPEnabled()) { FPDF_GenerateAP(m_pDocument, pDict); } } }
TEST(cpdf_formfield, FPDF_GetFullName) { CFX_WideString name = FPDF_GetFullName(nullptr); EXPECT_TRUE(name.IsEmpty()); CPDF_IndirectObjectHolder obj_holder; CPDF_Dictionary* root = new CPDF_Dictionary(); obj_holder.AddIndirectObject(root); root->SetNameFor("T", "foo"); name = FPDF_GetFullName(root); EXPECT_STREQ("foo", name.UTF8Encode().c_str()); CPDF_Dictionary* dict1 = new CPDF_Dictionary(); root->SetReferenceFor("Parent", &obj_holder, obj_holder.AddIndirectObject(dict1)); dict1->SetNameFor("T", "bar"); name = FPDF_GetFullName(root); EXPECT_STREQ("bar.foo", name.UTF8Encode().c_str()); CPDF_Dictionary* dict2 = new CPDF_Dictionary(); dict1->SetFor("Parent", dict2); name = FPDF_GetFullName(root); EXPECT_STREQ("bar.foo", name.UTF8Encode().c_str()); CPDF_Dictionary* dict3 = new CPDF_Dictionary(); dict2->SetReferenceFor("Parent", &obj_holder, obj_holder.AddIndirectObject(dict3)); dict3->SetNameFor("T", "qux"); name = FPDF_GetFullName(root); EXPECT_STREQ("qux.bar.foo", name.UTF8Encode().c_str()); dict3->SetReferenceFor("Parent", &obj_holder, root->GetObjNum()); name = FPDF_GetFullName(root); EXPECT_STREQ("qux.bar.foo", name.UTF8Encode().c_str()); name = FPDF_GetFullName(dict1); EXPECT_STREQ("foo.qux.bar", name.UTF8Encode().c_str()); name = FPDF_GetFullName(dict2); EXPECT_STREQ("bar.foo.qux", name.UTF8Encode().c_str()); name = FPDF_GetFullName(dict3); EXPECT_STREQ("bar.foo.qux", name.UTF8Encode().c_str()); }
CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, int iPage, int nPagesToGo, int level) { CPDF_Array* pKidList = pPages->GetArray("Kids"); if (!pKidList) { if (nPagesToGo == 0) { return pPages; } return NULL; } if (level >= FX_MAX_PAGE_LEVEL) { return NULL; } int nKids = pKidList->GetCount(); for (int i = 0; i < nKids; i++) { CPDF_Dictionary* pKid = pKidList->GetDict(i); if (!pKid) { nPagesToGo--; continue; } if (pKid == pPages) { continue; } if (!pKid->KeyExist("Kids")) { if (nPagesToGo == 0) { return pKid; } m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); nPagesToGo--; } else { int nPages = pKid->GetInteger("Count"); if (nPagesToGo < nPages) { return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1); } nPagesToGo -= nPages; } } return NULL; }
FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, CFX_WordArray* nPageNum, CPDF_Document* pDestPDFDoc, int nIndex) { int curpage = nIndex; nonstd::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); for (int i = 0; i < nPageNum->GetSize(); ++i) { CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(nPageNum->GetAt(i) - 1); if (!pSrcPageDict || !pCurPageDict) return FALSE; // Clone the page dictionary/////////// FX_POSITION SrcPos = pSrcPageDict->GetStartPos(); while (SrcPos) { CFX_ByteString cbSrcKeyStr; CPDF_Object* pObj = pSrcPageDict->GetNextElement(SrcPos, cbSrcKeyStr); if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { if (pCurPageDict->KeyExist(cbSrcKeyStr)) pCurPageDict->RemoveAt(cbSrcKeyStr); pCurPageDict->SetAt(cbSrcKeyStr, pObj->Clone()); } } // inheritable item/////////////////////// CPDF_Object* pInheritable = nullptr; // 1 MediaBox //required if (!pCurPageDict->KeyExist("MediaBox")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); if (!pInheritable) { // Search the "CropBox" from source page dictionary, // if not exists,we take the letter size. pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); if (pInheritable) { pCurPageDict->SetAt("MediaBox", pInheritable->Clone()); } else { // Make the default size to be letter size (8.5'x11') CPDF_Array* pArray = new CPDF_Array; pArray->AddNumber(0); pArray->AddNumber(0); pArray->AddNumber(612); pArray->AddNumber(792); pCurPageDict->SetAt("MediaBox", pArray); } } else { pCurPageDict->SetAt("MediaBox", pInheritable->Clone()); } } // 2 Resources //required if (!pCurPageDict->KeyExist("Resources")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources"); if (!pInheritable) return FALSE; pCurPageDict->SetAt("Resources", pInheritable->Clone()); } // 3 CropBox //Optional if (!pCurPageDict->KeyExist("CropBox")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); if (pInheritable) pCurPageDict->SetAt("CropBox", pInheritable->Clone()); } // 4 Rotate //Optional if (!pCurPageDict->KeyExist("Rotate")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); if (pInheritable) pCurPageDict->SetAt("Rotate", pInheritable->Clone()); } ///////////////////////////////////////////// // Update the reference FX_DWORD dwOldPageObj = pSrcPageDict->GetObjNum(); FX_DWORD dwNewPageObj = pCurPageDict->GetObjNum(); (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); ++curpage; } return TRUE; }
FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, std::vector<uint16_t>* pPageNums, CPDF_Document* pDestPDFDoc, int nIndex) { int curpage = nIndex; std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); int nSize = pdfium::CollectionSize<int>(*pPageNums); for (int i = 0; i < nSize; ++i) { CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(pPageNums->at(i) - 1); if (!pSrcPageDict || !pCurPageDict) return FALSE; // Clone the page dictionary for (const auto& it : *pSrcPageDict) { const CFX_ByteString& cbSrcKeyStr = it.first; CPDF_Object* pObj = it.second; if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { if (pCurPageDict->KeyExist(cbSrcKeyStr)) pCurPageDict->RemoveFor(cbSrcKeyStr); pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone()); } } // inheritable item CPDF_Object* pInheritable = nullptr; // 1 MediaBox //required if (!pCurPageDict->KeyExist("MediaBox")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); if (!pInheritable) { // Search the "CropBox" from source page dictionary, // if not exists,we take the letter size. pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); if (pInheritable) { pCurPageDict->SetFor("MediaBox", pInheritable->Clone()); } else { // Make the default size to be letter size (8.5'x11') CPDF_Array* pArray = new CPDF_Array; pArray->AddNumber(0); pArray->AddNumber(0); pArray->AddNumber(612); pArray->AddNumber(792); pCurPageDict->SetFor("MediaBox", pArray); } } else { pCurPageDict->SetFor("MediaBox", pInheritable->Clone()); } } // 2 Resources //required if (!pCurPageDict->KeyExist("Resources")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources"); if (!pInheritable) return FALSE; pCurPageDict->SetFor("Resources", pInheritable->Clone()); } // 3 CropBox //Optional if (!pCurPageDict->KeyExist("CropBox")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); if (pInheritable) pCurPageDict->SetFor("CropBox", pInheritable->Clone()); } // 4 Rotate //Optional if (!pCurPageDict->KeyExist("Rotate")) { pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); if (pInheritable) pCurPageDict->SetFor("Rotate", pInheritable->Clone()); } // Update the reference uint32_t dwOldPageObj = pSrcPageDict->GetObjNum(); uint32_t dwNewPageObj = pCurPageDict->GetObjNum(); (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); ++curpage; } return TRUE; }