Commit 0dadf17ab705fa2f96f0513278672978d73601ed

Authored by Jay Berkenbilt
1 parent 2e6e1204

Convert command-line and test suite to use page helper classes

This provides better test coverage and more useful code for people to
read and copy.
qpdf/pdf_from_scratch.cc
... ... @@ -4,6 +4,7 @@
4 4 #include <qpdf/QTC.hh>
5 5 #include <qpdf/QPDFWriter.hh>
6 6 #include <qpdf/QPDFObjectHandle.hh>
  7 +#include <qpdf/QPDFPageDocumentHelper.hh>
7 8 #include <iostream>
8 9 #include <stdio.h>
9 10 #include <string.h>
... ... @@ -67,7 +68,7 @@ void runtest(int n)
67 68 page.replaceKey("/Contents", contents);
68 69 page.replaceKey("/Resources", resources);
69 70  
70   - pdf.addPage(page, true);
  71 + QPDFPageDocumentHelper(pdf).addPage(page, true);
71 72  
72 73 QPDFWriter w(pdf, "a.pdf");
73 74 w.setStaticID(true);
... ...
qpdf/qpdf.cc
... ... @@ -12,6 +12,8 @@
12 12 #include <qpdf/PointerHolder.hh>
13 13  
14 14 #include <qpdf/QPDF.hh>
  15 +#include <qpdf/QPDFPageDocumentHelper.hh>
  16 +#include <qpdf/QPDFPageObjectHelper.hh>
15 17 #include <qpdf/QPDFExc.hh>
16 18  
17 19 #include <qpdf/QPDFWriter.hh>
... ... @@ -1810,17 +1812,19 @@ static void do_check(QPDF&amp; pdf, Options&amp; o, int&amp; exit_code)
1810 1812 w.write();
1811 1813  
1812 1814 // Parse all content streams
1813   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
  1815 + QPDFPageDocumentHelper dh(pdf);
  1816 + std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
1814 1817 DiscardContents discard_contents;
1815 1818 int pageno = 0;
1816   - for (std::vector<QPDFObjectHandle>::iterator iter =
  1819 + for (std::vector<QPDFPageObjectHelper>::iterator iter =
1817 1820 pages.begin();
1818 1821 iter != pages.end(); ++iter)
1819 1822 {
  1823 + QPDFPageObjectHelper& page(*iter);
1820 1824 ++pageno;
1821 1825 try
1822 1826 {
1823   - (*iter).parsePageContents(&discard_contents);
  1827 + page.parsePageContents(&discard_contents);
1824 1828 }
1825 1829 catch (QPDFExc& e)
1826 1830 {
... ... @@ -1897,17 +1901,18 @@ static void do_show_obj(QPDF&amp; pdf, Options&amp; o, int&amp; exit_code)
1897 1901  
1898 1902 static void do_show_pages(QPDF& pdf, Options& o)
1899 1903 {
  1904 + QPDFPageDocumentHelper dh(pdf);
1900 1905 if (o.show_page_images)
1901 1906 {
1902   - pdf.pushInheritedAttributesToPage();
  1907 + dh.pushInheritedAttributesToPage();
1903 1908 }
1904   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
  1909 + std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
1905 1910 int pageno = 0;
1906   - for (std::vector<QPDFObjectHandle>::iterator iter =
1907   - pages.begin();
  1911 + for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
1908 1912 iter != pages.end(); ++iter)
1909 1913 {
1910   - QPDFObjectHandle& page = *iter;
  1914 + QPDFPageObjectHelper& ph(*iter);
  1915 + QPDFObjectHandle page = ph.getObjectHandle();
1911 1916 ++pageno;
1912 1917  
1913 1918 std::cout << "page " << pageno << ": "
... ... @@ -1916,7 +1921,7 @@ static void do_show_pages(QPDF&amp; pdf, Options&amp; o)
1916 1921 if (o.show_page_images)
1917 1922 {
1918 1923 std::map<std::string, QPDFObjectHandle> images =
1919   - page.getPageImages();
  1924 + ph.getPageImages();
1920 1925 if (! images.empty())
1921 1926 {
1922 1927 std::cout << " images:" << std::endl;
... ... @@ -1942,7 +1947,7 @@ static void do_show_pages(QPDF&amp; pdf, Options&amp; o)
1942 1947  
1943 1948 std::cout << " content:" << std::endl;
1944 1949 std::vector<QPDFObjectHandle> content =
1945   - page.getPageContents();
  1950 + ph.getPageContents();
1946 1951 for (std::vector<QPDFObjectHandle>::iterator iter =
1947 1952 content.begin();
1948 1953 iter != content.end(); ++iter)
... ... @@ -2013,10 +2018,11 @@ static void do_inspection(QPDF&amp; pdf, Options&amp; o)
2013 2018  
2014 2019 static void handle_transformations(QPDF& pdf, Options& o)
2015 2020 {
  2021 + QPDFPageDocumentHelper dh(pdf);
2016 2022 if (o.coalesce_contents)
2017 2023 {
2018   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
2019   - for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
  2024 + std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
  2025 + for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
2020 2026 iter != pages.end(); ++iter)
2021 2027 {
2022 2028 (*iter).coalesceContentStreams();
... ... @@ -2077,12 +2083,13 @@ static void handle_page_specs(QPDF&amp; pdf, Options&amp; o,
2077 2083 // without changing their object numbers. This enables other
2078 2084 // things in the original file, such as outlines, to continue to
2079 2085 // work.
2080   - std::vector<QPDFObjectHandle> orig_pages = pdf.getAllPages();
2081   - for (std::vector<QPDFObjectHandle>::iterator iter =
  2086 + QPDFPageDocumentHelper dh(pdf);
  2087 + std::vector<QPDFPageObjectHelper> orig_pages = dh.getAllPages();
  2088 + for (std::vector<QPDFPageObjectHelper>::iterator iter =
2082 2089 orig_pages.begin();
2083 2090 iter != orig_pages.end(); ++iter)
2084 2091 {
2085   - pdf.removePage(*iter);
  2092 + dh.removePage(*iter);
2086 2093 }
2087 2094  
2088 2095 // Add all the pages from all the files in the order specified.
... ... @@ -2102,7 +2109,7 @@ static void handle_page_specs(QPDF&amp; pdf, Options&amp; o,
2102 2109 // Pages are specified from 1 but numbered from 0 in the
2103 2110 // vector
2104 2111 int pageno = *pageno_iter - 1;
2105   - pdf.addPage(page_data.orig_pages.at(pageno), false);
  2112 + dh.addPage(page_data.orig_pages.at(pageno), false);
2106 2113 if (page_data.qpdf == &pdf)
2107 2114 {
2108 2115 // This is a page from the original file. Keep track
... ... @@ -2119,15 +2126,17 @@ static void handle_page_specs(QPDF&amp; pdf, Options&amp; o,
2119 2126 {
2120 2127 if (selected_from_orig.count(pageno) == 0)
2121 2128 {
2122   - pdf.replaceObject(orig_pages.at(pageno).getObjGen(),
2123   - QPDFObjectHandle::newNull());
  2129 + pdf.replaceObject(
  2130 + orig_pages.at(pageno).getObjectHandle().getObjGen(),
  2131 + QPDFObjectHandle::newNull());
2124 2132 }
2125 2133 }
2126 2134 }
2127 2135  
2128 2136 static void handle_rotations(QPDF& pdf, Options& o)
2129 2137 {
2130   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
  2138 + QPDFPageDocumentHelper dh(pdf);
  2139 + std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
2131 2140 int npages = static_cast<int>(pages.size());
2132 2141 for (std::map<std::string, RotationSpec>::iterator iter =
2133 2142 o.rotations.begin();
... ...
qpdf/test_driver.cc
... ... @@ -3,6 +3,8 @@
3 3  
4 4 #include <qpdf/QPDF.hh>
5 5  
  6 +#include <qpdf/QPDFPageDocumentHelper.hh>
  7 +#include <qpdf/QPDFPageObjectHelper.hh>
6 8 #include <qpdf/QUtil.hh>
7 9 #include <qpdf/QTC.hh>
8 10 #include <qpdf/Pl_StdioFile.hh>
... ... @@ -455,12 +457,13 @@ void runtest(int n, char const* filename1, char const* arg2)
455 457 }
456 458 else if (n == 5)
457 459 {
458   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
  460 + QPDFPageDocumentHelper dh(pdf);
  461 + std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
459 462 int pageno = 0;
460   - for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
  463 + for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
461 464 iter != pages.end(); ++iter)
462 465 {
463   - QPDFObjectHandle& page = *iter;
  466 + QPDFPageObjectHelper& page(*iter);
464 467 ++pageno;
465 468  
466 469 std::cout << "page " << pageno << ":" << std::endl;
... ... @@ -633,11 +636,13 @@ void runtest(int n, char const* filename1, char const* arg2)
633 636 }
634 637 else if (n == 10)
635 638 {
636   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
637   - pages.at(0).addPageContents(
  639 + std::vector<QPDFPageObjectHelper> pages =
  640 + QPDFPageDocumentHelper(pdf).getAllPages();
  641 + QPDFPageObjectHelper& ph(pages.at(0));
  642 + ph.addPageContents(
638 643 QPDFObjectHandle::newStream(
639 644 &pdf, "BT /F1 12 Tf 72 620 Td (Baked) Tj ET\n"), true);
640   - pages.at(0).addPageContents(
  645 + ph.addPageContents(
641 646 QPDFObjectHandle::newStream(
642 647 &pdf, "BT /F1 18 Tf 72 520 Td (Mashed) Tj ET\n"), false);
643 648  
... ... @@ -887,6 +892,7 @@ void runtest(int n, char const* filename1, char const* arg2)
887 892 assert(pages.size() == 10);
888 893 QPDFObjectHandle page5 = pages.at(5);
889 894 pdf.removePage(page5);
  895 + assert(pages.size() == 9);
890 896 pdf.addPage(page5, false);
891 897 assert(pages.size() == 10);
892 898 assert(pages.back().getObjGen() == page5.getObjGen());
... ... @@ -899,10 +905,11 @@ void runtest(int n, char const* filename1, char const* arg2)
899 905 else if (n == 19)
900 906 {
901 907 // Remove a page and re-insert it in the same file.
902   - std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages();
  908 + QPDFPageDocumentHelper dh(pdf);
  909 + std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
903 910  
904 911 // Try to insert a page that's already there.
905   - pdf.addPage(pages.at(5), false);
  912 + dh.addPage(pages.at(5), false);
906 913 std::cout << "you can't see this" << std::endl;
907 914 }
908 915 else if (n == 20)
... ... @@ -932,16 +939,18 @@ void runtest(int n, char const* filename1, char const* arg2)
932 939 else if (n == 22)
933 940 {
934 941 // Try to remove a page we don't have
935   - std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages();
936   - QPDFObjectHandle page = pages.at(0);
937   - pdf.removePage(page);
938   - pdf.removePage(page);
  942 + QPDFPageDocumentHelper dh(pdf);
  943 + std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
  944 + QPDFPageObjectHelper& page = pages.at(0);
  945 + dh.removePage(page);
  946 + dh.removePage(page);
939 947 std::cout << "you can't see this" << std::endl;
940 948 }
941 949 else if (n == 23)
942 950 {
943   - std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages();
944   - pdf.removePage(pages.back());
  951 + QPDFPageDocumentHelper dh(pdf);
  952 + std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
  953 + dh.removePage(pages.back());
945 954 }
946 955 else if (n == 24)
947 956 {
... ... @@ -1053,7 +1062,7 @@ void runtest(int n, char const* filename1, char const* arg2)
1053 1062 newpdf.processFile(arg2);
1054 1063 QPDFObjectHandle qtest = pdf.getTrailer().getKey("/QTest");
1055 1064 QPDFObjectHandle O3 = qtest.getKey("/O3");
1056   - newpdf.addPage(O3, false);
  1065 + QPDFPageDocumentHelper(newpdf).addPage(O3, false);
1057 1066 newpdf.getTrailer().replaceKey(
1058 1067 "/QTest", newpdf.copyForeignObject(qtest));
1059 1068  
... ... @@ -1073,8 +1082,9 @@ void runtest(int n, char const* filename1, char const* arg2)
1073 1082 newpdf.processFile(arg2);
1074 1083 QPDFObjectHandle qtest = pdf.getTrailer().getKey("/QTest");
1075 1084 QPDFObjectHandle O3 = qtest.getKey("/O3");
1076   - newpdf.addPage(O3.getKey("/OtherPage"), false);
1077   - newpdf.addPage(O3, false);
  1085 + QPDFPageDocumentHelper dh(newpdf);
  1086 + dh.addPage(O3.getKey("/OtherPage"), false);
  1087 + dh.addPage(O3, false);
1078 1088 newpdf.getTrailer().replaceKey(
1079 1089 "/QTest", newpdf.copyForeignObject(qtest));
1080 1090  
... ... @@ -1320,11 +1330,12 @@ void runtest(int n, char const* filename1, char const* arg2)
1320 1330 else if (n == 37)
1321 1331 {
1322 1332 // Parse content streams of all pages
1323   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
1324   - for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
  1333 + std::vector<QPDFPageObjectHelper> pages =
  1334 + QPDFPageDocumentHelper(pdf).getAllPages();
  1335 + for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
1325 1336 iter != pages.end(); ++iter)
1326 1337 {
1327   - QPDFObjectHandle page = *iter;
  1338 + QPDFPageObjectHelper& page(*iter);
1328 1339 ParserCallbacks cb;
1329 1340 page.parsePageContents(&cb);
1330 1341 }
... ... @@ -1341,9 +1352,10 @@ void runtest(int n, char const* filename1, char const* arg2)
1341 1352 else if (n == 39)
1342 1353 {
1343 1354 // Display image filter and color set for each image on each page
1344   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
  1355 + std::vector<QPDFPageObjectHelper> pages =
  1356 + QPDFPageDocumentHelper(pdf).getAllPages();
1345 1357 int pageno = 0;
1346   - for (std::vector<QPDFObjectHandle>::iterator p_iter =
  1358 + for (std::vector<QPDFPageObjectHelper>::iterator p_iter =
1347 1359 pages.begin();
1348 1360 p_iter != pages.end(); ++p_iter)
1349 1361 {
... ... @@ -1378,8 +1390,9 @@ void runtest(int n, char const* filename1, char const* arg2)
1378 1390 {
1379 1391 // Apply a token filter. This test case is crafted to work
1380 1392 // with coalesce.pdf.
1381   - std::vector<QPDFObjectHandle> pages = pdf.getAllPages();
1382   - for (std::vector<QPDFObjectHandle>::iterator iter =
  1393 + std::vector<QPDFPageObjectHelper> pages =
  1394 + QPDFPageDocumentHelper(pdf).getAllPages();
  1395 + for (std::vector<QPDFPageObjectHelper>::iterator iter =
1383 1396 pages.begin();
1384 1397 iter != pages.end(); ++iter)
1385 1398 {
... ... @@ -1446,7 +1459,7 @@ void runtest(int n, char const* filename1, char const* arg2)
1446 1459 std::cerr << "One error\n";
1447 1460 array.getArrayItem(1).getKey("/K").getArrayItem(0).getStringValue();
1448 1461 // Stream dictionary
1449   - QPDFObjectHandle page = pdf.getAllPages()[0];
  1462 + QPDFObjectHandle page = pdf.getAllPages().at(0);
1450 1463 assert("/QPDFFakeName" ==
1451 1464 page.getKey("/Contents").getDict().getKey("/Potato").getName());
1452 1465 // Rectangles
... ...
qpdf/test_large_file.cc
... ... @@ -5,6 +5,7 @@
5 5 // I/O.
6 6  
7 7 #include <qpdf/QPDF.hh>
  8 +#include <qpdf/QPDFPageDocumentHelper.hh>
8 9 #include <qpdf/QPDFWriter.hh>
9 10 #include <qpdf/QPDFObjectHandle.hh>
10 11 #include <qpdf/QUtil.hh>
... ... @@ -208,6 +209,7 @@ static void create_pdf(char const* filename)
208 209 mediabox.appendItem(newInteger(612));
209 210 mediabox.appendItem(newInteger(792));
210 211  
  212 + QPDFPageDocumentHelper dh(pdf);
211 213 for (int pageno = 1; pageno <= npages; ++pageno)
212 214 {
213 215 QPDFObjectHandle image = QPDFObjectHandle::newStream(&pdf);
... ... @@ -241,7 +243,7 @@ static void create_pdf(char const* filename)
241 243 page.replaceKey("/Contents", contents);
242 244 page.replaceKey("/Resources", resources);
243 245  
244   - pdf.addPage(page, false);
  246 + dh.addPage(page, false);
245 247 }
246 248  
247 249 QPDFWriter w(pdf, filename);
... ...
qpdf/test_tokenizer.cc
1 1 #include <qpdf/QPDFTokenizer.hh>
  2 +#include <qpdf/QPDFPageDocumentHelper.hh>
  3 +#include <qpdf/QPDFPageObjectHelper.hh>
2 4 #include <qpdf/QUtil.hh>
3 5 #include <qpdf/FileInputSource.hh>
4 6 #include <qpdf/BufferInputSource.hh>
... ... @@ -206,9 +208,10 @@ static void process(char const* filename, bool include_ignorable,
206 208 // Tokenize content streams, skipping inline images
207 209 QPDF qpdf;
208 210 qpdf.processFile(filename);
209   - std::vector<QPDFObjectHandle> pages = qpdf.getAllPages();
  211 + std::vector<QPDFPageObjectHelper> pages =
  212 + QPDFPageDocumentHelper(qpdf).getAllPages();
210 213 int pageno = 0;
211   - for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
  214 + for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
212 215 iter != pages.end(); ++iter)
213 216 {
214 217 ++pageno;
... ...