From b6bdc0f5950287c1c9e76115bdec230dcf99b964 Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Fri, 22 Jun 2012 09:46:33 -0400 Subject: [PATCH] Add factory methods for creating empty arrays and dictionaries. Also updated pdf_from_scratch test driver to use the new factories, and made some cosmetic improvements and documentation updates for the emptyPDF() method. --- ChangeLog | 7 ++++ TODO | 5 ++- include/qpdf/QPDFObjectHandle.hh | 4 +++ include/qpdf/QUtil.hh | 1 - libqpdf/QPDF.cc | 2 +- libqpdf/QPDFObjectHandle.cc | 12 +++++++ libqpdf/QUtil.cc | 5 ++- qpdf/pdf_from_scratch.cc | 57 ++++++++++++++------------------ 8 files changed, 56 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5be2c8ea..a8fa227f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2012-06-22 Jay Berkenbilt + + * Add empty QPDFObjectHandle factories for array and dictionary. + With PDF-from-scratch capability, it is useful to be able to + create empty arrays and dictionaries and add keys to them. + Updated pdf_from_scratch.cc to use these interfaces. + 2012-06-21 Jay Berkenbilt * Add QPDF::emptyPDF() to create an empty QPDF object suitable for diff --git a/TODO b/TODO index 7f997b52..738a2346 100644 --- a/TODO +++ b/TODO @@ -37,7 +37,10 @@ Next space to do the tests, probably enough space for two coipes of the file. The test program should also have an interactive mode so we can generate the large file and then look at it with a - PDF viewer like Adobe Reader. + PDF viewer like Adobe Reader. The test suite should actually + read the file back in and look at all the page and stream + contents to make sure the file is really correct. We need to + test normal writing and linearization. * Consider adding an example that uses the page APIs, or update the documentation to refer the user to the test suite. diff --git a/include/qpdf/QPDFObjectHandle.hh b/include/qpdf/QPDFObjectHandle.hh index 4a056185..8fd19764 100644 --- a/include/qpdf/QPDFObjectHandle.hh +++ b/include/qpdf/QPDFObjectHandle.hh @@ -106,9 +106,13 @@ class QPDFObjectHandle QPDF_DLL static QPDFObjectHandle newString(std::string const& str); QPDF_DLL + static QPDFObjectHandle newArray(); + QPDF_DLL static QPDFObjectHandle newArray( std::vector const& items); QPDF_DLL + static QPDFObjectHandle newDictionary(); + QPDF_DLL static QPDFObjectHandle newDictionary( std::map const& items); diff --git a/include/qpdf/QUtil.hh b/include/qpdf/QUtil.hh index 4d5981de..8d2c09cf 100644 --- a/include/qpdf/QUtil.hh +++ b/include/qpdf/QUtil.hh @@ -14,7 +14,6 @@ #include #include #include -#include namespace QUtil { diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index b0a8741c..5f1ab48c 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -370,7 +370,7 @@ QPDF::processMemoryFile(char const* description, void QPDF::emptyPDF() { - processMemoryFile("empty file", EMPTY_PDF, strlen(EMPTY_PDF)); + processMemoryFile("empty PDF", EMPTY_PDF, strlen(EMPTY_PDF)); } void diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index 1c2481f8..d0d911f7 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -615,12 +615,24 @@ QPDFObjectHandle::newString(std::string const& str) return QPDFObjectHandle(new QPDF_String(str)); } +QPDFObjectHandle +QPDFObjectHandle::newArray() +{ + return newArray(std::vector()); +} + QPDFObjectHandle QPDFObjectHandle::newArray(std::vector const& items) { return QPDFObjectHandle(new QPDF_Array(items)); } +QPDFObjectHandle +QPDFObjectHandle::newDictionary() +{ + return newDictionary(std::map()); +} + QPDFObjectHandle QPDFObjectHandle::newDictionary( std::map const& items) diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc index 3c3bf011..bdb73f54 100644 --- a/libqpdf/QUtil.cc +++ b/libqpdf/QUtil.cc @@ -1,5 +1,8 @@ -#include +// Include qpdf-config.h first so off_t is gauaranteed to have the right size. #include + +#include + #include #include #include diff --git a/qpdf/pdf_from_scratch.cc b/qpdf/pdf_from_scratch.cc index 22d1999e..2d7d8a3d 100644 --- a/qpdf/pdf_from_scratch.cc +++ b/qpdf/pdf_from_scratch.cc @@ -40,49 +40,40 @@ void runtest(int n) { // Create a minimal PDF from scratch. - std::map keys; - std::vector items; - - keys.clear(); - keys["/Type"] = newName("/Font"); - keys["/Subtype"] = newName("/Type1"); - keys["/Name"] = newName("/F1"); - keys["/BaseFont"] = newName("/Helvetica"); - keys["/Encoding"] = newName("/WinAnsiEncoding"); QPDFObjectHandle font = pdf.makeIndirectObject( - QPDFObjectHandle::newDictionary(keys)); + QPDFObjectHandle::newDictionary()); + font.replaceKey("/Type", newName("/Font")); + font.replaceKey("/Subtype", newName("/Type1")); + font.replaceKey("/Name", newName("/F1")); + font.replaceKey("/BaseFont", newName("/Helvetica")); + font.replaceKey("/Encoding", newName("/WinAnsiEncoding")); - items.clear(); - items.push_back(newName("/PDF")); - items.push_back(newName("/Text")); QPDFObjectHandle procset = pdf.makeIndirectObject( - QPDFObjectHandle::newArray(items)); + QPDFObjectHandle::newArray()); + procset.appendItem(newName("/PDF")); + procset.appendItem(newName("/Text")); QPDFObjectHandle contents = createPageContents(pdf, "First Page"); - items.clear(); - items.push_back(QPDFObjectHandle::newInteger(0)); - items.push_back(QPDFObjectHandle::newInteger(0)); - items.push_back(QPDFObjectHandle::newInteger(612)); - items.push_back(QPDFObjectHandle::newInteger(792)); - QPDFObjectHandle mediabox = QPDFObjectHandle::newArray(items); + QPDFObjectHandle mediabox = QPDFObjectHandle::newArray(); + mediabox.appendItem(QPDFObjectHandle::newInteger(0)); + mediabox.appendItem(QPDFObjectHandle::newInteger(0)); + mediabox.appendItem(QPDFObjectHandle::newInteger(612)); + mediabox.appendItem(QPDFObjectHandle::newInteger(792)); - keys.clear(); - keys["/F1"] = font; - QPDFObjectHandle rfont = QPDFObjectHandle::newDictionary(keys); + QPDFObjectHandle rfont = QPDFObjectHandle::newDictionary(); + rfont.replaceKey("/F1", font); - keys.clear(); - keys["/ProcSet"] = procset; - keys["/Font"] = rfont; - QPDFObjectHandle resources = QPDFObjectHandle::newDictionary(keys); + QPDFObjectHandle resources = QPDFObjectHandle::newDictionary(); + resources.replaceKey("/ProcSet", procset); + resources.replaceKey("/Font", rfont); - keys.clear(); - keys["/Type"] = newName("/Page"); - keys["/MediaBox"] = mediabox; - keys["/Contents"] = contents; - keys["/Resources"] = resources; QPDFObjectHandle page = pdf.makeIndirectObject( - QPDFObjectHandle::newDictionary(keys)); + QPDFObjectHandle::newDictionary()); + page.replaceKey("/Type", newName("/Page")); + page.replaceKey("/MediaBox", mediabox); + page.replaceKey("/Contents", contents); + page.replaceKey("/Resources", resources); pdf.addPage(page, true);