mirror of
https://github.com/qpdf/qpdf.git
synced 2024-11-16 17:45:09 +00:00
4f24617e1e
Where not possible, use "auto" to get the iterator type. Editorial note: I have avoid this change for a long time because of not wanting to make gratuitous changes to version history, which can obscure when certain changes were made, but with having recently touched every single file to apply automatic code formatting and with making several broad changes to the API, I decided it was time to take the plunge and get rid of the older (pre-C++11) verbose iterator syntax. The new code is just easier to read and understand, and in many cases, it will be more effecient as fewer temporary copies are being made. m-holger, if you're reading, you can see that I've finally come around. :-)
99 lines
3.3 KiB
C++
99 lines
3.3 KiB
C++
#include <qpdf/QPDF.hh>
|
|
#include <qpdf/QPDFPageDocumentHelper.hh>
|
|
#include <qpdf/QPDFPageObjectHelper.hh>
|
|
#include <qpdf/QPDFWriter.hh>
|
|
#include <qpdf/QUtil.hh>
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
// 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 (auto& ph: pages) {
|
|
// 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.
|
|
QPDFMatrix m;
|
|
std::string content = ph.placeFormXObject(
|
|
stamp_fo, name, ph.getTrimBox().getArrayAsRectangle(), m);
|
|
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("<< /XObject << >> >>"_qpdf);
|
|
resources.getKey("/XObject").replaceKey(name, stamp_fo);
|
|
ph.addPageContents(
|
|
QPDFObjectHandle::newStream(&inpdf, "q\n"), true);
|
|
ph.addPageContents(
|
|
QPDFObjectHandle::newStream(&inpdf, "\nQ\n" + content), false);
|
|
}
|
|
// Copy the annotations and form fields from the original page
|
|
// to the new page. For more efficiency when copying multiple
|
|
// pages, we can create a QPDFAcroFormDocumentHelper and pass
|
|
// it in. See comments in QPDFPageObjectHelper.hh for details.
|
|
ph.copyAnnotations(stamp_page_1, m);
|
|
}
|
|
|
|
QPDFWriter w(inpdf, outfile);
|
|
w.setStaticID(true); // for testing only
|
|
w.write();
|
|
}
|
|
|
|
int
|
|
main(int argc, char* argv[])
|
|
{
|
|
whoami = QUtil::getWhoami(argv[0]);
|
|
|
|
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;
|
|
}
|