CFDF_Document* CPDF_InterForm::ExportToFDF( const CFX_WideStringC& pdf_path, const std::vector<CPDF_FormField*>& fields, bool bIncludeOrExclude, bool bSimpleFileSpec) const { CFDF_Document* pDoc = CFDF_Document::CreateNewDoc(); if (!pDoc) return nullptr; CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDictBy("FDF"); if (!pdf_path.IsEmpty()) { if (bSimpleFileSpec) { CFX_WideString wsFilePath = CPDF_FileSpec::EncodeFileName(pdf_path); pMainDict->SetAtString("F", CFX_ByteString::FromUnicode(wsFilePath)); pMainDict->SetAtString("UF", PDF_EncodeText(wsFilePath)); } else { CPDF_FileSpec filespec; filespec.SetFileName(pdf_path); pMainDict->SetAt("F", filespec.GetObj()); } } CPDF_Array* pFields = new CPDF_Array; pMainDict->SetAt("Fields", pFields); int nCount = m_pFieldTree->m_Root.CountFields(); for (int i = 0; i < nCount; i++) { CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); if (!pField || pField->GetType() == CPDF_FormField::PushButton) continue; uint32_t dwFlags = pField->GetFieldFlags(); if (dwFlags & 0x04) continue; if (bIncludeOrExclude == pdfium::ContainsValue(fields, pField)) { if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetStringBy("V").IsEmpty()) continue; CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict()); CPDF_Dictionary* pFieldDict = new CPDF_Dictionary; pFieldDict->SetAt("T", new CPDF_String(fullname)); if (pField->GetType() == CPDF_FormField::CheckBox || pField->GetType() == CPDF_FormField::RadioButton) { CFX_WideString csExport = pField->GetCheckValue(FALSE); CFX_ByteString csBExport = PDF_EncodeText(csExport); CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt"); if (pOpt) pFieldDict->SetAtString("V", csBExport); else pFieldDict->SetAtName("V", csBExport); } else { CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V"); if (pV) pFieldDict->SetAt("V", pV->CloneDirectObject()); } pFields->Add(pFieldDict); } } return pDoc; }
CPDF_FormField* CPDF_InterForm::GetFieldByDict( CPDF_Dictionary* pFieldDict) const { if (!pFieldDict) return nullptr; CFX_WideString csWName = FPDF_GetFullName(pFieldDict); return m_pFieldTree->GetField(csWName); }
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()); }
std::unique_ptr<CFDF_Document> CPDF_InterForm::ExportToFDF( const CFX_WideStringC& pdf_path, const std::vector<CPDF_FormField*>& fields, bool bIncludeOrExclude, bool bSimpleFileSpec) const { std::unique_ptr<CFDF_Document> pDoc = CFDF_Document::CreateNewDoc(); if (!pDoc) return nullptr; CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDictFor("FDF"); if (!pdf_path.IsEmpty()) { if (bSimpleFileSpec) { CFX_WideString wsFilePath = CPDF_FileSpec::EncodeFileName(pdf_path); pMainDict->SetNewFor<CPDF_String>( "F", CFX_ByteString::FromUnicode(wsFilePath), false); pMainDict->SetNewFor<CPDF_String>("UF", PDF_EncodeText(wsFilePath), false); } else { CPDF_FileSpec filespec(pDoc->GetByteStringPool()); filespec.SetFileName(pdf_path); pMainDict->SetFor("F", pdfium::WrapUnique(filespec.GetObj())); } } CPDF_Array* pFields = pMainDict->SetNewFor<CPDF_Array>("Fields"); size_t nCount = m_pFieldTree->m_Root.CountFields(); for (size_t i = 0; i < nCount; ++i) { CPDF_FormField* pField = m_pFieldTree->m_Root.GetFieldAtIndex(i); if (!pField || pField->GetType() == CPDF_FormField::PushButton) continue; uint32_t dwFlags = pField->GetFieldFlags(); if (dwFlags & 0x04) continue; if (bIncludeOrExclude == pdfium::ContainsValue(fields, pField)) { if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetStringFor("V").IsEmpty()) continue; CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict()); auto pFieldDict = pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); pFieldDict->SetNewFor<CPDF_String>("T", fullname); if (pField->GetType() == CPDF_FormField::CheckBox || pField->GetType() == CPDF_FormField::RadioButton) { CFX_WideString csExport = pField->GetCheckValue(false); CFX_ByteString csBExport = PDF_EncodeText(csExport); CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt"); if (pOpt) pFieldDict->SetNewFor<CPDF_String>("V", csBExport, false); else pFieldDict->SetNewFor<CPDF_Name>("V", csBExport); } else { CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V"); if (pV) pFieldDict->SetFor("V", pV->CloneDirectObject()); } pFields->Add(std::move(pFieldDict)); } } return pDoc; }
CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { if (!pFieldDict->KeyExist("FT")) { // Key "FT" is required for terminal fields, it is also inheritable. CPDF_Dictionary* pParentDict = pFieldDict->GetDictFor("Parent"); if (!pParentDict || !pParentDict->KeyExist("FT")) return nullptr; } CPDF_Dictionary* pDict = pFieldDict; CFX_WideString csWName = FPDF_GetFullName(pFieldDict); if (csWName.IsEmpty()) return nullptr; CPDF_FormField* pField = nullptr; pField = m_pFieldTree->GetField(csWName); if (!pField) { CPDF_Dictionary* pParent = pFieldDict; if (!pFieldDict->KeyExist("T") && pFieldDict->GetStringFor("Subtype") == "Widget") { pParent = pFieldDict->GetDictFor("Parent"); if (!pParent) pParent = pFieldDict; } if (pParent && pParent != pFieldDict && !pParent->KeyExist("FT")) { if (pFieldDict->KeyExist("FT")) { CPDF_Object* pFTValue = pFieldDict->GetDirectObjectFor("FT"); if (pFTValue) pParent->SetFor("FT", pFTValue->Clone()); } if (pFieldDict->KeyExist("Ff")) { CPDF_Object* pFfValue = pFieldDict->GetDirectObjectFor("Ff"); if (pFfValue) pParent->SetFor("Ff", pFfValue->Clone()); } } pField = new CPDF_FormField(this, pParent); CPDF_Object* pTObj = pDict->GetObjectFor("T"); if (ToReference(pTObj)) { std::unique_ptr<CPDF_Object> pClone = pTObj->CloneDirectObject(); if (pClone) pDict->SetFor("T", std::move(pClone)); else pDict->SetNewFor<CPDF_Name>("T", ""); } m_pFieldTree->SetField(csWName, pField); } CPDF_Array* pKids = pFieldDict->GetArrayFor("Kids"); if (pKids) { for (size_t i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pKid = pKids->GetDictAt(i); if (!pKid) continue; if (pKid->GetStringFor("Subtype") != "Widget") continue; AddControl(pField, pKid); } } else { if (pFieldDict->GetStringFor("Subtype") == "Widget") AddControl(pField, pFieldDict); } return pField; }
CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) { if (!pFieldDict->KeyExist("T")) return nullptr; CPDF_Dictionary* pDict = pFieldDict; CFX_WideString csWName = FPDF_GetFullName(pFieldDict); if (csWName.IsEmpty()) return nullptr; CPDF_FormField* pField = nullptr; pField = m_pFieldTree->GetField(csWName); if (!pField) { CPDF_Dictionary* pParent = pFieldDict; if (!pFieldDict->KeyExist("T") && pFieldDict->GetStringBy("Subtype") == "Widget") { pParent = pFieldDict->GetDictBy("Parent"); if (!pParent) pParent = pFieldDict; } if (pParent && pParent != pFieldDict && !pParent->KeyExist("FT")) { if (pFieldDict->KeyExist("FT")) { CPDF_Object* pFTValue = pFieldDict->GetDirectObjectBy("FT"); if (pFTValue) pParent->SetAt("FT", pFTValue->Clone()); } if (pFieldDict->KeyExist("Ff")) { CPDF_Object* pFfValue = pFieldDict->GetDirectObjectBy("Ff"); if (pFfValue) pParent->SetAt("Ff", pFfValue->Clone()); } } pField = new CPDF_FormField(this, pParent); CPDF_Object* pTObj = pDict->GetObjectBy("T"); if (ToReference(pTObj)) { CPDF_Object* pClone = pTObj->CloneDirectObject(); if (pClone) pDict->SetAt("T", pClone); else pDict->SetAtName("T", ""); } m_pFieldTree->SetField(csWName, pField); } CPDF_Array* pKids = pFieldDict->GetArrayBy("Kids"); if (!pKids) { if (pFieldDict->GetStringBy("Subtype") == "Widget") AddControl(pField, pFieldDict); } else { for (size_t i = 0; i < pKids->GetCount(); i++) { CPDF_Dictionary* pKid = pKids->GetDictAt(i); if (!pKid) continue; if (pKid->GetStringBy("Subtype") != "Widget") continue; AddControl(pField, pKid); } } return pField; }
CFX_WideString CPDF_FormField::GetFullName() const { return FPDF_GetFullName(m_pDict); }