2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-06-21 03:12:20 +00:00

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.
This commit is contained in:
Jay Berkenbilt 2018-06-18 16:38:15 -04:00
parent 2e6e1204a5
commit 0dadf17ab7
5 changed files with 76 additions and 48 deletions

View File

@ -4,6 +4,7 @@
#include <qpdf/QTC.hh> #include <qpdf/QTC.hh>
#include <qpdf/QPDFWriter.hh> #include <qpdf/QPDFWriter.hh>
#include <qpdf/QPDFObjectHandle.hh> #include <qpdf/QPDFObjectHandle.hh>
#include <qpdf/QPDFPageDocumentHelper.hh>
#include <iostream> #include <iostream>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -67,7 +68,7 @@ void runtest(int n)
page.replaceKey("/Contents", contents); page.replaceKey("/Contents", contents);
page.replaceKey("/Resources", resources); page.replaceKey("/Resources", resources);
pdf.addPage(page, true); QPDFPageDocumentHelper(pdf).addPage(page, true);
QPDFWriter w(pdf, "a.pdf"); QPDFWriter w(pdf, "a.pdf");
w.setStaticID(true); w.setStaticID(true);

View File

@ -12,6 +12,8 @@
#include <qpdf/PointerHolder.hh> #include <qpdf/PointerHolder.hh>
#include <qpdf/QPDF.hh> #include <qpdf/QPDF.hh>
#include <qpdf/QPDFPageDocumentHelper.hh>
#include <qpdf/QPDFPageObjectHelper.hh>
#include <qpdf/QPDFExc.hh> #include <qpdf/QPDFExc.hh>
#include <qpdf/QPDFWriter.hh> #include <qpdf/QPDFWriter.hh>
@ -1810,17 +1812,19 @@ static void do_check(QPDF& pdf, Options& o, int& exit_code)
w.write(); w.write();
// Parse all content streams // Parse all content streams
std::vector<QPDFObjectHandle> pages = pdf.getAllPages(); QPDFPageDocumentHelper dh(pdf);
std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
DiscardContents discard_contents; DiscardContents discard_contents;
int pageno = 0; int pageno = 0;
for (std::vector<QPDFObjectHandle>::iterator iter = for (std::vector<QPDFPageObjectHelper>::iterator iter =
pages.begin(); pages.begin();
iter != pages.end(); ++iter) iter != pages.end(); ++iter)
{ {
QPDFPageObjectHelper& page(*iter);
++pageno; ++pageno;
try try
{ {
(*iter).parsePageContents(&discard_contents); page.parsePageContents(&discard_contents);
} }
catch (QPDFExc& e) catch (QPDFExc& e)
{ {
@ -1897,17 +1901,18 @@ static void do_show_obj(QPDF& pdf, Options& o, int& exit_code)
static void do_show_pages(QPDF& pdf, Options& o) static void do_show_pages(QPDF& pdf, Options& o)
{ {
QPDFPageDocumentHelper dh(pdf);
if (o.show_page_images) if (o.show_page_images)
{ {
pdf.pushInheritedAttributesToPage(); dh.pushInheritedAttributesToPage();
} }
std::vector<QPDFObjectHandle> pages = pdf.getAllPages(); std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
int pageno = 0; int pageno = 0;
for (std::vector<QPDFObjectHandle>::iterator iter = for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
pages.begin();
iter != pages.end(); ++iter) iter != pages.end(); ++iter)
{ {
QPDFObjectHandle& page = *iter; QPDFPageObjectHelper& ph(*iter);
QPDFObjectHandle page = ph.getObjectHandle();
++pageno; ++pageno;
std::cout << "page " << pageno << ": " std::cout << "page " << pageno << ": "
@ -1916,7 +1921,7 @@ static void do_show_pages(QPDF& pdf, Options& o)
if (o.show_page_images) if (o.show_page_images)
{ {
std::map<std::string, QPDFObjectHandle> images = std::map<std::string, QPDFObjectHandle> images =
page.getPageImages(); ph.getPageImages();
if (! images.empty()) if (! images.empty())
{ {
std::cout << " images:" << std::endl; std::cout << " images:" << std::endl;
@ -1942,7 +1947,7 @@ static void do_show_pages(QPDF& pdf, Options& o)
std::cout << " content:" << std::endl; std::cout << " content:" << std::endl;
std::vector<QPDFObjectHandle> content = std::vector<QPDFObjectHandle> content =
page.getPageContents(); ph.getPageContents();
for (std::vector<QPDFObjectHandle>::iterator iter = for (std::vector<QPDFObjectHandle>::iterator iter =
content.begin(); content.begin();
iter != content.end(); ++iter) iter != content.end(); ++iter)
@ -2013,10 +2018,11 @@ static void do_inspection(QPDF& pdf, Options& o)
static void handle_transformations(QPDF& pdf, Options& o) static void handle_transformations(QPDF& pdf, Options& o)
{ {
QPDFPageDocumentHelper dh(pdf);
if (o.coalesce_contents) if (o.coalesce_contents)
{ {
std::vector<QPDFObjectHandle> pages = pdf.getAllPages(); std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin(); for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
iter != pages.end(); ++iter) iter != pages.end(); ++iter)
{ {
(*iter).coalesceContentStreams(); (*iter).coalesceContentStreams();
@ -2077,12 +2083,13 @@ static void handle_page_specs(QPDF& pdf, Options& o,
// without changing their object numbers. This enables other // without changing their object numbers. This enables other
// things in the original file, such as outlines, to continue to // things in the original file, such as outlines, to continue to
// work. // work.
std::vector<QPDFObjectHandle> orig_pages = pdf.getAllPages(); QPDFPageDocumentHelper dh(pdf);
for (std::vector<QPDFObjectHandle>::iterator iter = std::vector<QPDFPageObjectHelper> orig_pages = dh.getAllPages();
for (std::vector<QPDFPageObjectHelper>::iterator iter =
orig_pages.begin(); orig_pages.begin();
iter != orig_pages.end(); ++iter) iter != orig_pages.end(); ++iter)
{ {
pdf.removePage(*iter); dh.removePage(*iter);
} }
// Add all the pages from all the files in the order specified. // 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,
// Pages are specified from 1 but numbered from 0 in the // Pages are specified from 1 but numbered from 0 in the
// vector // vector
int pageno = *pageno_iter - 1; int pageno = *pageno_iter - 1;
pdf.addPage(page_data.orig_pages.at(pageno), false); dh.addPage(page_data.orig_pages.at(pageno), false);
if (page_data.qpdf == &pdf) if (page_data.qpdf == &pdf)
{ {
// This is a page from the original file. Keep track // This is a page from the original file. Keep track
@ -2119,7 +2126,8 @@ static void handle_page_specs(QPDF& pdf, Options& o,
{ {
if (selected_from_orig.count(pageno) == 0) if (selected_from_orig.count(pageno) == 0)
{ {
pdf.replaceObject(orig_pages.at(pageno).getObjGen(), pdf.replaceObject(
orig_pages.at(pageno).getObjectHandle().getObjGen(),
QPDFObjectHandle::newNull()); QPDFObjectHandle::newNull());
} }
} }
@ -2127,7 +2135,8 @@ static void handle_page_specs(QPDF& pdf, Options& o,
static void handle_rotations(QPDF& pdf, Options& o) static void handle_rotations(QPDF& pdf, Options& o)
{ {
std::vector<QPDFObjectHandle> pages = pdf.getAllPages(); QPDFPageDocumentHelper dh(pdf);
std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
int npages = static_cast<int>(pages.size()); int npages = static_cast<int>(pages.size());
for (std::map<std::string, RotationSpec>::iterator iter = for (std::map<std::string, RotationSpec>::iterator iter =
o.rotations.begin(); o.rotations.begin();

View File

@ -3,6 +3,8 @@
#include <qpdf/QPDF.hh> #include <qpdf/QPDF.hh>
#include <qpdf/QPDFPageDocumentHelper.hh>
#include <qpdf/QPDFPageObjectHelper.hh>
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
#include <qpdf/QTC.hh> #include <qpdf/QTC.hh>
#include <qpdf/Pl_StdioFile.hh> #include <qpdf/Pl_StdioFile.hh>
@ -455,12 +457,13 @@ void runtest(int n, char const* filename1, char const* arg2)
} }
else if (n == 5) else if (n == 5)
{ {
std::vector<QPDFObjectHandle> pages = pdf.getAllPages(); QPDFPageDocumentHelper dh(pdf);
std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
int pageno = 0; int pageno = 0;
for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin(); for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
iter != pages.end(); ++iter) iter != pages.end(); ++iter)
{ {
QPDFObjectHandle& page = *iter; QPDFPageObjectHelper& page(*iter);
++pageno; ++pageno;
std::cout << "page " << pageno << ":" << std::endl; std::cout << "page " << pageno << ":" << std::endl;
@ -633,11 +636,13 @@ void runtest(int n, char const* filename1, char const* arg2)
} }
else if (n == 10) else if (n == 10)
{ {
std::vector<QPDFObjectHandle> pages = pdf.getAllPages(); std::vector<QPDFPageObjectHelper> pages =
pages.at(0).addPageContents( QPDFPageDocumentHelper(pdf).getAllPages();
QPDFPageObjectHelper& ph(pages.at(0));
ph.addPageContents(
QPDFObjectHandle::newStream( QPDFObjectHandle::newStream(
&pdf, "BT /F1 12 Tf 72 620 Td (Baked) Tj ET\n"), true); &pdf, "BT /F1 12 Tf 72 620 Td (Baked) Tj ET\n"), true);
pages.at(0).addPageContents( ph.addPageContents(
QPDFObjectHandle::newStream( QPDFObjectHandle::newStream(
&pdf, "BT /F1 18 Tf 72 520 Td (Mashed) Tj ET\n"), false); &pdf, "BT /F1 18 Tf 72 520 Td (Mashed) Tj ET\n"), false);
@ -887,6 +892,7 @@ void runtest(int n, char const* filename1, char const* arg2)
assert(pages.size() == 10); assert(pages.size() == 10);
QPDFObjectHandle page5 = pages.at(5); QPDFObjectHandle page5 = pages.at(5);
pdf.removePage(page5); pdf.removePage(page5);
assert(pages.size() == 9);
pdf.addPage(page5, false); pdf.addPage(page5, false);
assert(pages.size() == 10); assert(pages.size() == 10);
assert(pages.back().getObjGen() == page5.getObjGen()); assert(pages.back().getObjGen() == page5.getObjGen());
@ -899,10 +905,11 @@ void runtest(int n, char const* filename1, char const* arg2)
else if (n == 19) else if (n == 19)
{ {
// Remove a page and re-insert it in the same file. // Remove a page and re-insert it in the same file.
std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages(); QPDFPageDocumentHelper dh(pdf);
std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
// Try to insert a page that's already there. // Try to insert a page that's already there.
pdf.addPage(pages.at(5), false); dh.addPage(pages.at(5), false);
std::cout << "you can't see this" << std::endl; std::cout << "you can't see this" << std::endl;
} }
else if (n == 20) else if (n == 20)
@ -932,16 +939,18 @@ void runtest(int n, char const* filename1, char const* arg2)
else if (n == 22) else if (n == 22)
{ {
// Try to remove a page we don't have // Try to remove a page we don't have
std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages(); QPDFPageDocumentHelper dh(pdf);
QPDFObjectHandle page = pages.at(0); std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
pdf.removePage(page); QPDFPageObjectHelper& page = pages.at(0);
pdf.removePage(page); dh.removePage(page);
dh.removePage(page);
std::cout << "you can't see this" << std::endl; std::cout << "you can't see this" << std::endl;
} }
else if (n == 23) else if (n == 23)
{ {
std::vector<QPDFObjectHandle> const& pages = pdf.getAllPages(); QPDFPageDocumentHelper dh(pdf);
pdf.removePage(pages.back()); std::vector<QPDFPageObjectHelper> pages = dh.getAllPages();
dh.removePage(pages.back());
} }
else if (n == 24) else if (n == 24)
{ {
@ -1053,7 +1062,7 @@ void runtest(int n, char const* filename1, char const* arg2)
newpdf.processFile(arg2); newpdf.processFile(arg2);
QPDFObjectHandle qtest = pdf.getTrailer().getKey("/QTest"); QPDFObjectHandle qtest = pdf.getTrailer().getKey("/QTest");
QPDFObjectHandle O3 = qtest.getKey("/O3"); QPDFObjectHandle O3 = qtest.getKey("/O3");
newpdf.addPage(O3, false); QPDFPageDocumentHelper(newpdf).addPage(O3, false);
newpdf.getTrailer().replaceKey( newpdf.getTrailer().replaceKey(
"/QTest", newpdf.copyForeignObject(qtest)); "/QTest", newpdf.copyForeignObject(qtest));
@ -1073,8 +1082,9 @@ void runtest(int n, char const* filename1, char const* arg2)
newpdf.processFile(arg2); newpdf.processFile(arg2);
QPDFObjectHandle qtest = pdf.getTrailer().getKey("/QTest"); QPDFObjectHandle qtest = pdf.getTrailer().getKey("/QTest");
QPDFObjectHandle O3 = qtest.getKey("/O3"); QPDFObjectHandle O3 = qtest.getKey("/O3");
newpdf.addPage(O3.getKey("/OtherPage"), false); QPDFPageDocumentHelper dh(newpdf);
newpdf.addPage(O3, false); dh.addPage(O3.getKey("/OtherPage"), false);
dh.addPage(O3, false);
newpdf.getTrailer().replaceKey( newpdf.getTrailer().replaceKey(
"/QTest", newpdf.copyForeignObject(qtest)); "/QTest", newpdf.copyForeignObject(qtest));
@ -1320,11 +1330,12 @@ void runtest(int n, char const* filename1, char const* arg2)
else if (n == 37) else if (n == 37)
{ {
// Parse content streams of all pages // Parse content streams of all pages
std::vector<QPDFObjectHandle> pages = pdf.getAllPages(); std::vector<QPDFPageObjectHelper> pages =
for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin(); QPDFPageDocumentHelper(pdf).getAllPages();
for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
iter != pages.end(); ++iter) iter != pages.end(); ++iter)
{ {
QPDFObjectHandle page = *iter; QPDFPageObjectHelper& page(*iter);
ParserCallbacks cb; ParserCallbacks cb;
page.parsePageContents(&cb); page.parsePageContents(&cb);
} }
@ -1341,9 +1352,10 @@ void runtest(int n, char const* filename1, char const* arg2)
else if (n == 39) else if (n == 39)
{ {
// Display image filter and color set for each image on each page // Display image filter and color set for each image on each page
std::vector<QPDFObjectHandle> pages = pdf.getAllPages(); std::vector<QPDFPageObjectHelper> pages =
QPDFPageDocumentHelper(pdf).getAllPages();
int pageno = 0; int pageno = 0;
for (std::vector<QPDFObjectHandle>::iterator p_iter = for (std::vector<QPDFPageObjectHelper>::iterator p_iter =
pages.begin(); pages.begin();
p_iter != pages.end(); ++p_iter) p_iter != pages.end(); ++p_iter)
{ {
@ -1378,8 +1390,9 @@ void runtest(int n, char const* filename1, char const* arg2)
{ {
// Apply a token filter. This test case is crafted to work // Apply a token filter. This test case is crafted to work
// with coalesce.pdf. // with coalesce.pdf.
std::vector<QPDFObjectHandle> pages = pdf.getAllPages(); std::vector<QPDFPageObjectHelper> pages =
for (std::vector<QPDFObjectHandle>::iterator iter = QPDFPageDocumentHelper(pdf).getAllPages();
for (std::vector<QPDFPageObjectHelper>::iterator iter =
pages.begin(); pages.begin();
iter != pages.end(); ++iter) iter != pages.end(); ++iter)
{ {
@ -1446,7 +1459,7 @@ void runtest(int n, char const* filename1, char const* arg2)
std::cerr << "One error\n"; std::cerr << "One error\n";
array.getArrayItem(1).getKey("/K").getArrayItem(0).getStringValue(); array.getArrayItem(1).getKey("/K").getArrayItem(0).getStringValue();
// Stream dictionary // Stream dictionary
QPDFObjectHandle page = pdf.getAllPages()[0]; QPDFObjectHandle page = pdf.getAllPages().at(0);
assert("/QPDFFakeName" == assert("/QPDFFakeName" ==
page.getKey("/Contents").getDict().getKey("/Potato").getName()); page.getKey("/Contents").getDict().getKey("/Potato").getName());
// Rectangles // Rectangles

View File

@ -5,6 +5,7 @@
// I/O. // I/O.
#include <qpdf/QPDF.hh> #include <qpdf/QPDF.hh>
#include <qpdf/QPDFPageDocumentHelper.hh>
#include <qpdf/QPDFWriter.hh> #include <qpdf/QPDFWriter.hh>
#include <qpdf/QPDFObjectHandle.hh> #include <qpdf/QPDFObjectHandle.hh>
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
@ -208,6 +209,7 @@ static void create_pdf(char const* filename)
mediabox.appendItem(newInteger(612)); mediabox.appendItem(newInteger(612));
mediabox.appendItem(newInteger(792)); mediabox.appendItem(newInteger(792));
QPDFPageDocumentHelper dh(pdf);
for (int pageno = 1; pageno <= npages; ++pageno) for (int pageno = 1; pageno <= npages; ++pageno)
{ {
QPDFObjectHandle image = QPDFObjectHandle::newStream(&pdf); QPDFObjectHandle image = QPDFObjectHandle::newStream(&pdf);
@ -241,7 +243,7 @@ static void create_pdf(char const* filename)
page.replaceKey("/Contents", contents); page.replaceKey("/Contents", contents);
page.replaceKey("/Resources", resources); page.replaceKey("/Resources", resources);
pdf.addPage(page, false); dh.addPage(page, false);
} }
QPDFWriter w(pdf, filename); QPDFWriter w(pdf, filename);

View File

@ -1,4 +1,6 @@
#include <qpdf/QPDFTokenizer.hh> #include <qpdf/QPDFTokenizer.hh>
#include <qpdf/QPDFPageDocumentHelper.hh>
#include <qpdf/QPDFPageObjectHelper.hh>
#include <qpdf/QUtil.hh> #include <qpdf/QUtil.hh>
#include <qpdf/FileInputSource.hh> #include <qpdf/FileInputSource.hh>
#include <qpdf/BufferInputSource.hh> #include <qpdf/BufferInputSource.hh>
@ -206,9 +208,10 @@ static void process(char const* filename, bool include_ignorable,
// Tokenize content streams, skipping inline images // Tokenize content streams, skipping inline images
QPDF qpdf; QPDF qpdf;
qpdf.processFile(filename); qpdf.processFile(filename);
std::vector<QPDFObjectHandle> pages = qpdf.getAllPages(); std::vector<QPDFPageObjectHelper> pages =
QPDFPageDocumentHelper(qpdf).getAllPages();
int pageno = 0; int pageno = 0;
for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin(); for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
iter != pages.end(); ++iter) iter != pages.end(); ++iter)
{ {
++pageno; ++pageno;