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.
This commit is contained in:
Jay Berkenbilt 2012-06-22 09:46:33 -04:00
parent a0768e4190
commit b6bdc0f595
8 changed files with 56 additions and 37 deletions

View File

@ -1,3 +1,10 @@
2012-06-22 Jay Berkenbilt <ejb@ql.org>
* 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 <ejb@ql.org>
* Add QPDF::emptyPDF() to create an empty QPDF object suitable for

5
TODO
View File

@ -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.

View File

@ -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<QPDFObjectHandle> const& items);
QPDF_DLL
static QPDFObjectHandle newDictionary();
QPDF_DLL
static QPDFObjectHandle newDictionary(
std::map<std::string, QPDFObjectHandle> const& items);

View File

@ -14,7 +14,6 @@
#include <list>
#include <stdexcept>
#include <stdio.h>
#include <sys/stat.h>
namespace QUtil
{

View File

@ -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

View File

@ -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
QPDFObjectHandle::newArray(std::vector<QPDFObjectHandle> const& items)
{
return QPDFObjectHandle(new QPDF_Array(items));
}
QPDFObjectHandle
QPDFObjectHandle::newDictionary()
{
return newDictionary(std::map<std::string, QPDFObjectHandle>());
}
QPDFObjectHandle
QPDFObjectHandle::newDictionary(
std::map<std::string, QPDFObjectHandle> const& items)

View File

@ -1,5 +1,8 @@
#include <qpdf/QUtil.hh>
// Include qpdf-config.h first so off_t is gauaranteed to have the right size.
#include <qpdf/qpdf-config.h>
#include <qpdf/QUtil.hh>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>

View File

@ -40,49 +40,40 @@ void runtest(int n)
{
// Create a minimal PDF from scratch.
std::map<std::string, QPDFObjectHandle> keys;
std::vector<QPDFObjectHandle> 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);