Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // dennis.jenkins.75 .at. gmail.com
- // http://www.mail-archive.com/[email protected]/msg00963.html
- // https://podofo.svn.sourceforge.net/svnroot/podofo/podofo/trunk/test/FormTest/FormTest.cpp
- // http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf
- #include <iostream>
- #include <podofo/podofo.h>
- #define CP() do { std::cerr << "CheckPoint, line " << __LINE__ << "\n"; } while (0)
- using namespace PoDoFo;
- static bool verbose = false;
- static const char *GetFieldTypeName (EPdfField eType)
- {
- switch (eType)
- {
- case ePdfField_PushButton: return "pushbutton";
- case ePdfField_CheckBox: return "checkbox";
- case ePdfField_RadioButton: return "radiobutton";
- case ePdfField_TextField: return "textfield";
- case ePdfField_ComboBox: return "combobox";
- case ePdfField_ListBox: return "listbox";
- case ePdfField_Signature: return "signature";
- case ePdfField_Unknown: return "unknown";
- default: return "??";
- }
- return NULL;
- }
- static void DumpPdfForm (const char *filename)
- {
- PdfMemDocument doc (filename);
- PdfPage *pPage = NULL;
- for (int iPage = 0; iPage < doc.GetPageCount(); ++iPage)
- {
- pPage = doc.GetPage (iPage);
- std::cout << filename << ": page: " << iPage + 1 << " fields: " << pPage->GetNumFields() << "\n";
- for (int iField = 0; iField < pPage->GetNumFields(); ++iField)
- {
- PdfField field = pPage->GetField (iField);
- if (verbose)
- {
- std::cout <<
- " field: " << iField + 1 <<
- ", name: " << field.GetFieldName().GetString() <<
- ", type: " << GetFieldTypeName (field.GetType()) <<
- "\n";
- }
- }
- }
- }
- void ListAnnotations (const char *filename, int nPage)
- {
- PdfMemDocument doc (filename);
- PdfPage *pPage = doc.GetPage (nPage);
- printf ("index GetType() HasKey('FT')\n");
- int nAnnots = pPage->GetNumAnnots();
- for (int i = 0; i < nAnnots; i++) {
- const PdfAnnotation* pAnnot = const_cast<PdfPage*>(pPage)->GetAnnotation (i);
- bool b = pAnnot->GetObject()->GetDictionary().HasKey (PdfName ("FT"));
- printf ("%5d %2d %1d\n", i, pAnnot->GetType(), b);
- }
- }
- // See section 12.7.3.3 (page 434) of ISO-32000-1:2008.
- // Need to construct an appearance stream for each form field,
- // or configure document to generated one dynamically.
- // See section 12.7.4.3 (page 444) of ISO-32000-1:2008.
- // Shows a correct "Appearance Stream" for a text field.
- // We can always directly hack the dictionary:
- // PdfAnnotation::GetObject()->GetDictionary()
- static void HackPdfFormDocument (PdfDocument &doc)
- {
- // http://www.mail-archive.com/[email protected]/msg01155.html
- // Stolen from PdfAcroForm::Init()
- // doc.GetAcroForm()->Init (PdfAcroForm::ePdfAcroFormDefaultAppearance_BlackText12pt);
- PdfObject *pObj = doc.GetAcroForm()->GetObject();
- pObj->GetDictionary().AddKey (PdfName ("NeedAppearances"), PdfVariant (true));
- if (!pObj->GetDictionary().HasKey("DA"))
- {
- PdfFont *pFont = doc.CreateFont ("Arial");
- PdfObject *pResource = NULL;
- PdfObject *pFontDict = NULL;
- // Create "DR" key.
- if (!pObj->GetDictionary().HasKey (PdfName ("DR")))
- {
- pObj->GetDictionary().AddKey (PdfName ("DR"), PdfDictionary());
- }
- pResource = pObj->GetDictionary().GetKey( PdfName("DR") );
- if (!pResource->GetDictionary().HasKey( PdfName ("Font")))
- {
- pResource->GetDictionary().AddKey (PdfName ("Font"), PdfDictionary());
- }
- pFontDict = pResource->GetDictionary().GetKey( PdfName("Font") );
- pFontDict->GetDictionary().AddKey( pFont->GetIdentifier(), pFont->GetObject()->Reference() );
- // Create "DA" key.
- std::ostringstream oss;
- PdfLocaleImbue (oss);
- oss << "0 0 0 rg /" << pFont->GetIdentifier().GetName() << " 12 Tf";
- pObj->GetDictionary().AddKey( PdfName("DA"), PdfString( oss.str() ) );
- }
- }
- static void HackPdfForm (const char *in_fn, const char *out_fn)
- {
- PdfMemDocument doc (in_fn);
- PdfPage *pPage = NULL;
- // PdfFont *pFont = doc.CreateFont ("Arial");
- HackPdfFormDocument (doc);
- for (int iPage = 0; iPage < doc.GetPageCount(); ++iPage)
- {
- pPage = doc.GetPage (iPage);
- if (verbose)
- {
- std::cout << " page: " << iPage + 1 << " fields: " << pPage->GetNumFields() << "\n";
- }
- for (int iField = 0; iField < pPage->GetNumFields(); ++iField)
- {
- PdfField field = pPage->GetField (iField);
- if (verbose)
- {
- std::cout <<
- " field: " << iField + 1 <<
- ", name: " << field.GetFieldName().GetString() <<
- ", type: " << GetFieldTypeName (field.GetType()) <<
- "\n";
- }
- if (field.GetType() == ePdfField_TextField)
- {
- char tmp[32];
- snprintf (tmp, sizeof(tmp), "%d", iField);
- auto *tf = reinterpret_cast<PdfTextField*>(&field);
- tf->SetText (tmp);
- tf->SetBackgroundColor (1.0, 0.0, 0.0);
- } else if (field.GetType() == ePdfField_CheckBox) {
- auto *cb = reinterpret_cast<PdfCheckBox*>(&field);
- cb->SetChecked (true);
- // cb->SetAppearanceChecked ();
- }
- }
- }
- doc.Write (out_fn);
- }
- int main (int argc, char *argv[])
- {
- try
- {
- PdfError::EnableDebug (false);
- if (argc == 2)
- {
- DumpPdfForm (argv[1]);
- // ListAnnotations (argv[1], 0);
- }
- else if (argc == 3)
- {
- HackPdfForm (argv[1], argv[2]);
- }
- else
- {
- std::cerr << "Usage:\n";
- std::cerr << " " << argv[0] << " src.pdf\n";
- std::cerr << " " << argv[0] << " src.pdf dest.pdf\n";
- return -1;
- }
- }
- catch (const PdfError &err)
- {
- err.PrintErrorMsg();
- return err.GetError();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment