2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 10:58:58 +00:00

add double-page-size example

git-svn-id: svn+q:///qpdf/trunk@996 71b93d88-0707-0410-a8cf-f5a4172ac649
This commit is contained in:
Jay Berkenbilt 2010-08-05 21:51:19 +00:00
parent 2dbc1006fb
commit 9ba5b27ce4
7 changed files with 276 additions and 6 deletions

View File

@ -1,5 +1,9 @@
2010-08-05 Jay Berkenbilt <ejb@ql.org> 2010-08-05 Jay Berkenbilt <ejb@ql.org>
* Add QPDFObjectHandle::addPageContents, a convenience routine for
appending or prepending new streams to a page's content streams.
The "double-page-size" example illustrates its use.
* Add new methods to QPDFObjectHandle: replaceStreamData and * Add new methods to QPDFObjectHandle: replaceStreamData and
newStream. These methods allow users of the qpdf library to add newStream. These methods allow users of the qpdf library to add
new streams and to replace data of existing streams. Examples are new streams and to replace data of existing streams. Examples are

8
TODO
View File

@ -7,9 +7,9 @@ Next
in August, 2009. He seems to like to send encrypted mail (key in August, 2009. He seems to like to send encrypted mail (key
01FCC336). Tell him about newStream and replaceStreamData. 01FCC336). Tell him about newStream and replaceStreamData.
* Tell stronghorse@tom.com about QPDFObjectHandle::addPageContents. * Tell stronghorse@tom.com about QPDFObjectHandle::addPageContents
See message from stronghorse@tom.com ("Suggestion for qpdf") from and double-page-size example. See message from stronghorse@tom.com
2010-06-09 and my response. ("Suggestion for qpdf") from 2010-06-09 and my response.
2.2 2.2
=== ===
@ -18,8 +18,6 @@ Next
image. Use QPDF::getAllPages and QPDFObjectHandle::getPageImages image. Use QPDF::getAllPages and QPDFObjectHandle::getPageImages
along with new stream data and dictionary manipulation. along with new stream data and dictionary manipulation.
* Add example program for addPageContents using suggestion from
stronghorse@tom.com's message above.
General General
======= =======

View File

@ -1,4 +1,4 @@
BINS_examples = pdf-bookmarks pdf-mod-info pdf-npages BINS_examples = pdf-bookmarks pdf-mod-info pdf-npages double-page-size
CBINS_examples = pdf-linearize CBINS_examples = pdf-linearize
TARGETS_examples = $(foreach B,$(BINS_examples) $(CBINS_examples),examples/$(OUTPUT_DIR)/$(call binname,$(B))) TARGETS_examples = $(foreach B,$(BINS_examples) $(CBINS_examples),examples/$(OUTPUT_DIR)/$(call binname,$(B)))

View File

@ -0,0 +1,113 @@
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <qpdf/QPDF.hh>
#include <qpdf/QUtil.hh>
#include <qpdf/Buffer.hh>
#include <qpdf/QPDFWriter.hh>
static char const* whoami = 0;
void usage()
{
std::cerr << "Usage: " << whoami << " infile.pdf outfile.pdf [in-password]"
<< std::endl
<< "Double size of all pages in infile.pdf;"
<< " write output to outfile.pdf" << std::endl;
exit(2);
}
static void doubleBoxSize(QPDFObjectHandle& page, char const* box_name)
{
QPDFObjectHandle box = page.getKey(box_name);
if (box.isNull())
{
return;
}
if (! (box.isArray() && (box.getArrayNItems() == 4)))
{
throw std::runtime_error(std::string("box ") + box_name +
" is not an array of four elements");
}
std::vector<QPDFObjectHandle> doubled;
for (unsigned int i = 0; i < 4; ++i)
{
doubled.push_back(
QPDFObjectHandle::newReal(
QUtil::double_to_string(
box.getArrayItem(i).getNumericValue() * 2.0, 2)));
}
page.replaceKey(box_name, QPDFObjectHandle::newArray(doubled));
}
int main(int argc, char* argv[])
{
whoami = QUtil::getWhoami(argv[0]);
// For libtool's sake....
if (strncmp(whoami, "lt-", 3) == 0)
{
whoami += 3;
}
if (! ((argc == 3) || (argc == 4)))
{
usage();
}
char const* infilename = argv[1];
char const* outfilename = argv[2];
char const* password = (argc == 4) ? argv[3] : "";
// Text to prepend to each page's contents
char const* content = "2 0 0 2 0 0 cm\n";
// Copy text into a buffer without the null terminator
PointerHolder<Buffer> b = new Buffer(strlen(content));
unsigned char* bp = b.getPointer()->getBuffer();
memcpy(bp, (unsigned char*)content, strlen(content));
try
{
QPDF qpdf;
qpdf.processFile(infilename, password);
std::vector<QPDFObjectHandle> pages = qpdf.getAllPages();
for (std::vector<QPDFObjectHandle>::iterator iter = pages.begin();
iter != pages.end(); ++iter)
{
QPDFObjectHandle& page = *iter;
// Prepend the buffer to the page's contents
page.addPageContents(QPDFObjectHandle::newStream(&qpdf, b), true);
// Double the size of each of the content boxes
doubleBoxSize(page, "/MediaBox");
doubleBoxSize(page, "/CropBox");
doubleBoxSize(page, "/BleedBox");
doubleBoxSize(page, "/TrimBox");
doubleBoxSize(page, "/ArtBox");
}
// Write out a new file
QPDFWriter w(qpdf, outfilename);
if (QUtil::get_env("IN_TESTSUITE"))
{
// For the test suite, uncompress streams and use static
// IDs.
w.setStaticID(true);
w.setStreamDataMode(qpdf_s_uncompress);
}
w.write();
std::cout << whoami << ": new file written to " << outfilename
<< std::endl;
}
catch (std::exception &e)
{
std::cerr << whoami << " processing file " << infilename << ": "
<< e.what() << std::endl;
exit(2);
}
return 0;
}

View File

@ -0,0 +1,31 @@
#!/usr/bin/env perl
require 5.008;
BEGIN { $^W = 1; }
use strict;
chdir("double-page-size") or die "chdir testdir failed: $!\n";
require TestDriver;
my $td = new TestDriver('double-page-size');
cleanup();
$td->runtest("double page size",
{$td->COMMAND => "double-page-size in.pdf a.pdf"},
{$td->STRING => "double-page-size: new file written to a.pdf\n",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
$td->runtest("check output",
{$td->FILE => "a.pdf"},
{$td->FILE => "out.pdf"});
cleanup();
$td->report(2);
sub cleanup
{
unlink 'a.pdf';
}

View File

@ -0,0 +1,55 @@
%PDF-1.3
%¿÷¢þ
1 0 obj
<< /Pages 2 0 R /Type /Catalog >>
endobj
2 0 obj
<< /Count 2 /Kids [ 3 0 R 4 0 R ] /Type /Pages >>
endobj
3 0 obj
<< /Contents 5 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 6 0 R >> /ProcSet 7 0 R >> /Type /Page >>
endobj
4 0 obj
<< /Contents 8 0 R /MediaBox [ 0 0 612 792 ] /Parent 2 0 R /Resources << /Font << /F1 6 0 R >> /ProcSet 7 0 R >> /Type /Page >>
endobj
5 0 obj
<< /Length 44 >>
stream
BT
/F1 24 Tf
72 720 Td
(Potato) Tj
ET
endstream
endobj
6 0 obj
<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
endobj
7 0 obj
[ /PDF /Text ]
endobj
8 0 obj
<< /Length 43 >>
stream
BT
/F1 24 Tf
72 720 Td
(Salad) Tj
ET
endstream
endobj
xref
0 9
0000000000 65535 f
0000000015 00000 n
0000000064 00000 n
0000000129 00000 n
0000000272 00000 n
0000000415 00000 n
0000000508 00000 n
0000000615 00000 n
0000000645 00000 n
trailer << /Root 1 0 R /Size 9 /ID [<071a6499182be9cfc990b11d0c4e5bc0><90dbb2f2f000af76d1107187b0e00349>] >>
startxref
737
%%EOF

View File

@ -0,0 +1,69 @@
%PDF-1.3
%¿÷¢þ
1 0 obj
<< /Pages 2 0 R /Type /Catalog >>
endobj
2 0 obj
<< /Count 2 /Kids [ 3 0 R 4 0 R ] /Type /Pages >>
endobj
3 0 obj
<< /Contents [ 5 0 R 6 0 R ] /MediaBox [ 0.00 0.00 1224.00 1584.00 ] /Parent 2 0 R /Resources << /Font << /F1 7 0 R >> /ProcSet 8 0 R >> /Type /Page >>
endobj
4 0 obj
<< /Contents [ 9 0 R 10 0 R ] /MediaBox [ 0.00 0.00 1224.00 1584.00 ] /Parent 2 0 R /Resources << /Font << /F1 7 0 R >> /ProcSet 8 0 R >> /Type /Page >>
endobj
5 0 obj
<< /Length 15 >>
stream
2 0 0 2 0 0 cm
endstream
endobj
6 0 obj
<< /Length 44 >>
stream
BT
/F1 24 Tf
72 720 Td
(Potato) Tj
ET
endstream
endobj
7 0 obj
<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
endobj
8 0 obj
[ /PDF /Text ]
endobj
9 0 obj
<< /Length 15 >>
stream
2 0 0 2 0 0 cm
endstream
endobj
10 0 obj
<< /Length 43 >>
stream
BT
/F1 24 Tf
72 720 Td
(Salad) Tj
ET
endstream
endobj
xref
0 11
0000000000 65535 f
0000000015 00000 n
0000000064 00000 n
0000000129 00000 n
0000000296 00000 n
0000000464 00000 n
0000000528 00000 n
0000000621 00000 n
0000000728 00000 n
0000000758 00000 n
0000000822 00000 n
trailer << /Root 1 0 R /Size 11 /ID [<071a6499182be9cfc990b11d0c4e5bc0><31415926535897932384626433832795>] >>
startxref
915
%%EOF