Commit 0dadf17ab705fa2f96f0513278672978d73601ed
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.
Showing
5 changed files
with
76 additions
and
48 deletions
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& pdf, Options& o, int& 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& pdf, Options& o, int& 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& pdf, Options& 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& pdf, Options& 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& pdf, Options& 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& pdf, Options& 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& pdf, Options& 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& pdf, Options& 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; | ... | ... |