aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2019-01-26 23:33:06 +0100
committerJay Berkenbilt <ejb@ql.org>2019-01-27 13:50:30 +0100
commit2d1db060422eabb82aaa1764926a3f9e881116e2 (patch)
treea3915a98112e2705ad4fe92ab9587534a47bc619 /examples
parent623f5b664ece02027b550bec085fc9c6486986ff (diff)
downloadqpdf-2d1db060422eabb82aaa1764926a3f9e881116e2.tar.zst
Example of form XObject, page overlay
Diffstat (limited to 'examples')
-rw-r--r--examples/build.mk3
-rw-r--r--examples/pdf-overlay-page.cc110
-rw-r--r--examples/qtest/overlay-page.test28
-rw-r--r--examples/qtest/overlay-page/in.pdfbin0 -> 1840 bytes
-rw-r--r--examples/qtest/overlay-page/out.pdfbin0 -> 3361 bytes
-rw-r--r--examples/qtest/overlay-page/stamp.pdfbin0 -> 799 bytes
6 files changed, 140 insertions, 1 deletions
diff --git a/examples/build.mk b/examples/build.mk
index 031601ff..8033d7d2 100644
--- a/examples/build.mk
+++ b/examples/build.mk
@@ -9,7 +9,8 @@ BINS_examples = \
pdf-split-pages \
pdf-filter-tokens \
pdf-count-strings \
- pdf-set-form-values
+ pdf-set-form-values \
+ pdf-overlay-page
CBINS_examples = pdf-linearize
TARGETS_examples = $(foreach B,$(BINS_examples) $(CBINS_examples),examples/$(OUTPUT_DIR)/$(call binname,$(B)))
diff --git a/examples/pdf-overlay-page.cc b/examples/pdf-overlay-page.cc
new file mode 100644
index 00000000..88722352
--- /dev/null
+++ b/examples/pdf-overlay-page.cc
@@ -0,0 +1,110 @@
+#include <iostream>
+#include <string.h>
+#include <stdlib.h>
+#include <qpdf/QPDF.hh>
+#include <qpdf/QPDFPageDocumentHelper.hh>
+#include <qpdf/QPDFPageObjectHelper.hh>
+#include <qpdf/QPDFWriter.hh>
+#include <qpdf/QUtil.hh>
+
+// This program demonstrates use of form XObjects to overlay a page
+// from one file onto all pages of another file. The qpdf program's
+// --overlay and --underlay options provide a more general version of
+// this capability.
+
+static char const* whoami = 0;
+
+void usage()
+{
+ std::cerr << "Usage: " << whoami << " infile pagefile outfile"
+ << std::endl
+ << "Stamp page 1 of pagefile on every page of infile,"
+ << " writing to outfile"
+ << std::endl;
+ exit(2);
+}
+
+static void stamp_page(char const* infile,
+ char const* stampfile,
+ char const* outfile)
+{
+ QPDF inpdf;
+ inpdf.processFile(infile);
+ QPDF stamppdf;
+ stamppdf.processFile(stampfile);
+
+ // Get first page from other file
+ QPDFPageObjectHelper stamp_page_1 =
+ QPDFPageDocumentHelper(stamppdf).getAllPages().at(0);
+ // Convert page to a form XObject
+ QPDFObjectHandle foreign_fo = stamp_page_1.getFormXObjectForPage();
+ // Copy form XObject to the input file
+ QPDFObjectHandle stamp_fo = inpdf.copyForeignObject(foreign_fo);
+
+ // For each page...
+ std::vector<QPDFPageObjectHelper> pages =
+ QPDFPageDocumentHelper(inpdf).getAllPages();
+ for (std::vector<QPDFPageObjectHelper>::iterator iter = pages.begin();
+ iter != pages.end(); ++iter)
+ {
+ QPDFPageObjectHelper& ph = *iter;
+
+ // Find a unique resource name for the new form XObject
+ QPDFObjectHandle resources = ph.getAttribute("/Resources", true);
+ int min_suffix = 1;
+ std::string name = resources.getUniqueResourceName("/Fx", min_suffix);
+
+ // Generate content to place the form XObject centered within
+ // destination page's trim box.
+ std::string content =
+ ph.placeFormXObject(
+ stamp_fo, name, ph.getTrimBox().getArrayAsRectangle());
+ if (! content.empty())
+ {
+ // Append the content to the page's content. Surround the
+ // original content with q...Q to the new content from the
+ // page's original content.
+ resources.mergeResources(
+ QPDFObjectHandle::parse("<< /XObject << >> >>"));
+ resources.getKey("/XObject").replaceKey(name, stamp_fo);
+ ph.addPageContents(
+ QPDFObjectHandle::newStream(&inpdf, "q\n"), true);
+ ph.addPageContents(
+ QPDFObjectHandle::newStream(&inpdf, "\nQ\n" + content), false);
+ }
+ }
+
+ QPDFWriter w(inpdf, outfile);
+ w.setStaticID(true); // for testing only
+ w.write();
+}
+
+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 != 4)
+ {
+ usage();
+ }
+ char const* infile = argv[1];
+ char const* stampfile = argv[2];
+ char const* outfile = argv[3];
+
+ try
+ {
+ stamp_page(infile, stampfile, outfile);
+ }
+ catch (std::exception &e)
+ {
+ std::cerr << whoami << ": " << e.what() << std::endl;
+ exit(2);
+ }
+ return 0;
+}
diff --git a/examples/qtest/overlay-page.test b/examples/qtest/overlay-page.test
new file mode 100644
index 00000000..68e695d3
--- /dev/null
+++ b/examples/qtest/overlay-page.test
@@ -0,0 +1,28 @@
+#!/usr/bin/env perl
+require 5.008;
+use warnings;
+use strict;
+
+chdir("overlay-page");
+
+require TestDriver;
+
+my $td = new TestDriver('overlay-page');
+
+cleanup();
+
+$td->runtest("overlay-page",
+ {$td->COMMAND => "pdf-overlay-page in.pdf stamp.pdf a.pdf"},
+ {$td->STRING => "", $td->EXIT_STATUS => 0});
+$td->runtest("compare files",
+ {$td->FILE => "a.pdf"},
+ {$td->FILE => "out.pdf"});
+
+cleanup();
+
+$td->report(2);
+
+sub cleanup
+{
+ unlink("a.pdf");
+}
diff --git a/examples/qtest/overlay-page/in.pdf b/examples/qtest/overlay-page/in.pdf
new file mode 100644
index 00000000..f94c739a
--- /dev/null
+++ b/examples/qtest/overlay-page/in.pdf
Binary files differ
diff --git a/examples/qtest/overlay-page/out.pdf b/examples/qtest/overlay-page/out.pdf
new file mode 100644
index 00000000..b589d2c4
--- /dev/null
+++ b/examples/qtest/overlay-page/out.pdf
Binary files differ
diff --git a/examples/qtest/overlay-page/stamp.pdf b/examples/qtest/overlay-page/stamp.pdf
new file mode 100644
index 00000000..a86f4344
--- /dev/null
+++ b/examples/qtest/overlay-page/stamp.pdf
Binary files differ