Commit b6bdc0f5950287c1c9e76115bdec230dcf99b964
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.
Showing
8 changed files
with
59 additions
and
40 deletions
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 | ... | ... |
TODO
| ... | ... | @@ -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
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& 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
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 | ... | ... |