Commit b6bdc0f5950287c1c9e76115bdec230dcf99b964

Authored by Jay Berkenbilt
1 parent a0768e41

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
  1 +2012-06-22 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Add empty QPDFObjectHandle factories for array and dictionary.
  4 + With PDF-from-scratch capability, it is useful to be able to
  5 + create empty arrays and dictionaries and add keys to them.
  6 + Updated pdf_from_scratch.cc to use these interfaces.
  7 +
1 8 2012-06-21 Jay Berkenbilt <ejb@ql.org>
2 9  
3 10 * Add QPDF::emptyPDF() to create an empty QPDF object suitable for
... ...
... ... @@ -37,7 +37,10 @@ Next
37 37 space to do the tests, probably enough space for two coipes of
38 38 the file. The test program should also have an interactive mode
39 39 so we can generate the large file and then look at it with a
40   - PDF viewer like Adobe Reader.
  40 + PDF viewer like Adobe Reader. The test suite should actually
  41 + read the file back in and look at all the page and stream
  42 + contents to make sure the file is really correct. We need to
  43 + test normal writing and linearization.
41 44  
42 45 * Consider adding an example that uses the page APIs, or update the
43 46 documentation to refer the user to the test suite.
... ...
include/qpdf/QPDFObjectHandle.hh
... ... @@ -106,9 +106,13 @@ class QPDFObjectHandle
106 106 QPDF_DLL
107 107 static QPDFObjectHandle newString(std::string const& str);
108 108 QPDF_DLL
  109 + static QPDFObjectHandle newArray();
  110 + QPDF_DLL
109 111 static QPDFObjectHandle newArray(
110 112 std::vector<QPDFObjectHandle> const& items);
111 113 QPDF_DLL
  114 + static QPDFObjectHandle newDictionary();
  115 + QPDF_DLL
112 116 static QPDFObjectHandle newDictionary(
113 117 std::map<std::string, QPDFObjectHandle> const& items);
114 118  
... ...
include/qpdf/QUtil.hh
... ... @@ -14,7 +14,6 @@
14 14 #include <list>
15 15 #include <stdexcept>
16 16 #include <stdio.h>
17   -#include <sys/stat.h>
18 17  
19 18 namespace QUtil
20 19 {
... ...
libqpdf/QPDF.cc
... ... @@ -370,7 +370,7 @@ QPDF::processMemoryFile(char const* description,
370 370 void
371 371 QPDF::emptyPDF()
372 372 {
373   - processMemoryFile("empty file", EMPTY_PDF, strlen(EMPTY_PDF));
  373 + processMemoryFile("empty PDF", EMPTY_PDF, strlen(EMPTY_PDF));
374 374 }
375 375  
376 376 void
... ...
libqpdf/QPDFObjectHandle.cc
... ... @@ -616,12 +616,24 @@ QPDFObjectHandle::newString(std::string const&amp; str)
616 616 }
617 617  
618 618 QPDFObjectHandle
  619 +QPDFObjectHandle::newArray()
  620 +{
  621 + return newArray(std::vector<QPDFObjectHandle>());
  622 +}
  623 +
  624 +QPDFObjectHandle
619 625 QPDFObjectHandle::newArray(std::vector<QPDFObjectHandle> const& items)
620 626 {
621 627 return QPDFObjectHandle(new QPDF_Array(items));
622 628 }
623 629  
624 630 QPDFObjectHandle
  631 +QPDFObjectHandle::newDictionary()
  632 +{
  633 + return newDictionary(std::map<std::string, QPDFObjectHandle>());
  634 +}
  635 +
  636 +QPDFObjectHandle
625 637 QPDFObjectHandle::newDictionary(
626 638 std::map<std::string, QPDFObjectHandle> const& items)
627 639 {
... ...
libqpdf/QUtil.cc
1   -#include <qpdf/QUtil.hh>
  1 +// Include qpdf-config.h first so off_t is gauaranteed to have the right size.
2 2 #include <qpdf/qpdf-config.h>
  3 +
  4 +#include <qpdf/QUtil.hh>
  5 +
3 6 #include <stdio.h>
4 7 #include <errno.h>
5 8 #include <ctype.h>
... ...
qpdf/pdf_from_scratch.cc
... ... @@ -40,49 +40,40 @@ void runtest(int n)
40 40 {
41 41 // Create a minimal PDF from scratch.
42 42  
43   - std::map<std::string, QPDFObjectHandle> keys;
44   - std::vector<QPDFObjectHandle> items;
45   -
46   - keys.clear();
47   - keys["/Type"] = newName("/Font");
48   - keys["/Subtype"] = newName("/Type1");
49   - keys["/Name"] = newName("/F1");
50   - keys["/BaseFont"] = newName("/Helvetica");
51   - keys["/Encoding"] = newName("/WinAnsiEncoding");
52 43 QPDFObjectHandle font = pdf.makeIndirectObject(
53   - QPDFObjectHandle::newDictionary(keys));
  44 + QPDFObjectHandle::newDictionary());
  45 + font.replaceKey("/Type", newName("/Font"));
  46 + font.replaceKey("/Subtype", newName("/Type1"));
  47 + font.replaceKey("/Name", newName("/F1"));
  48 + font.replaceKey("/BaseFont", newName("/Helvetica"));
  49 + font.replaceKey("/Encoding", newName("/WinAnsiEncoding"));
54 50  
55   - items.clear();
56   - items.push_back(newName("/PDF"));
57   - items.push_back(newName("/Text"));
58 51 QPDFObjectHandle procset = pdf.makeIndirectObject(
59   - QPDFObjectHandle::newArray(items));
  52 + QPDFObjectHandle::newArray());
  53 + procset.appendItem(newName("/PDF"));
  54 + procset.appendItem(newName("/Text"));
60 55  
61 56 QPDFObjectHandle contents = createPageContents(pdf, "First Page");
62 57  
63   - items.clear();
64   - items.push_back(QPDFObjectHandle::newInteger(0));
65   - items.push_back(QPDFObjectHandle::newInteger(0));
66   - items.push_back(QPDFObjectHandle::newInteger(612));
67   - items.push_back(QPDFObjectHandle::newInteger(792));
68   - QPDFObjectHandle mediabox = QPDFObjectHandle::newArray(items);
69   -
70   - keys.clear();
71   - keys["/F1"] = font;
72   - QPDFObjectHandle rfont = QPDFObjectHandle::newDictionary(keys);
73   -
74   - keys.clear();
75   - keys["/ProcSet"] = procset;
76   - keys["/Font"] = rfont;
77   - QPDFObjectHandle resources = QPDFObjectHandle::newDictionary(keys);
78   -
79   - keys.clear();
80   - keys["/Type"] = newName("/Page");
81   - keys["/MediaBox"] = mediabox;
82   - keys["/Contents"] = contents;
83   - keys["/Resources"] = resources;
  58 + QPDFObjectHandle mediabox = QPDFObjectHandle::newArray();
  59 + mediabox.appendItem(QPDFObjectHandle::newInteger(0));
  60 + mediabox.appendItem(QPDFObjectHandle::newInteger(0));
  61 + mediabox.appendItem(QPDFObjectHandle::newInteger(612));
  62 + mediabox.appendItem(QPDFObjectHandle::newInteger(792));
  63 +
  64 + QPDFObjectHandle rfont = QPDFObjectHandle::newDictionary();
  65 + rfont.replaceKey("/F1", font);
  66 +
  67 + QPDFObjectHandle resources = QPDFObjectHandle::newDictionary();
  68 + resources.replaceKey("/ProcSet", procset);
  69 + resources.replaceKey("/Font", rfont);
  70 +
84 71 QPDFObjectHandle page = pdf.makeIndirectObject(
85   - QPDFObjectHandle::newDictionary(keys));
  72 + QPDFObjectHandle::newDictionary());
  73 + page.replaceKey("/Type", newName("/Page"));
  74 + page.replaceKey("/MediaBox", mediabox);
  75 + page.replaceKey("/Contents", contents);
  76 + page.replaceKey("/Resources", resources);
86 77  
87 78 pdf.addPage(page, true);
88 79  
... ...