#include #include #include #include #include #include #include static char const* whoami = 0; // This is a simple StreamDataProvider that writes image data for an // orange square of the given width and height. class ImageProvider: public QPDFObjectHandle::StreamDataProvider { public: ImageProvider(int width, int height); virtual ~ImageProvider(); virtual void provideStreamData(int objid, int generation, Pipeline* pipeline); private: int width; int height; }; ImageProvider::ImageProvider(int width, int height) : width(width), height(height) { } ImageProvider::~ImageProvider() { } void ImageProvider::provideStreamData(int objid, int generation, Pipeline* pipeline) { for (int i = 0; i < width * height; ++i) { pipeline->write(QUtil::unsigned_char_pointer("\xff\x7f\x00"), 3); } pipeline->finish(); } void usage() { std::cerr << "Usage: " << whoami << " filename" << std::endl << "Creates a simple PDF and writes it to filename" << std::endl; exit(2); } static QPDFObjectHandle createPageContents(QPDF& pdf, std::string const& text) { // Create a stream that displays our image and the given text in // our font. std::string contents = "BT /F1 24 Tf 72 720 Td (" + text + ") Tj ET\n" "q 144 0 0 144 234 324 cm /Im1 Do Q\n"; return QPDFObjectHandle::newStream(&pdf, contents); } QPDFObjectHandle newName(std::string const& name) { return QPDFObjectHandle::newName(name); } QPDFObjectHandle newInteger(int val) { return QPDFObjectHandle::newInteger(val); } static void create_pdf(char const* filename) { QPDF pdf; // Start with an empty PDF that has no pages or non-required objects. pdf.emptyPDF(); // Add an indirect object to contain a font descriptor for the // built-in Helvetica font. QPDFObjectHandle font = pdf.makeIndirectObject( QPDFObjectHandle::parse( "<<" " /Type /Font" " /Subtype /Type1" " /Name /F1" " /BaseFont /Helvetica" " /Encoding /WinAnsiEncoding" ">>")); // Create a stream to encode our image. We don't have to set the // length or filters. QPDFWriter will fill in the length and // compress the stream data using FlateDecode by default. QPDFObjectHandle image = QPDFObjectHandle::newStream(&pdf); image.replaceDict(QPDFObjectHandle::parse( "<<" " /Type /XObject" " /Subtype /Image" " /ColorSpace /DeviceRGB" " /BitsPerComponent 8" " /Width 100" " /Height 100" ">>")); // Provide the stream data. ImageProvider* p = new ImageProvider(100, 100); PointerHolder provider(p); image.replaceStreamData(provider, QPDFObjectHandle::newNull(), QPDFObjectHandle::newNull()); // Create direct objects as needed by the page dictionary. QPDFObjectHandle procset = QPDFObjectHandle::parse( "[/PDF /Text /ImageC]"); QPDFObjectHandle rfont = QPDFObjectHandle::newDictionary(); rfont.replaceKey("/F1", font); QPDFObjectHandle xobject = QPDFObjectHandle::newDictionary(); xobject.replaceKey("/Im1", image); QPDFObjectHandle resources = QPDFObjectHandle::newDictionary(); resources.replaceKey("/ProcSet", procset); resources.replaceKey("/Font", rfont); resources.replaceKey("/XObject", xobject); QPDFObjectHandle mediabox = QPDFObjectHandle::newArray(); mediabox.appendItem(newInteger(0)); mediabox.appendItem(newInteger(0)); mediabox.appendItem(newInteger(612)); mediabox.appendItem(newInteger(792)); // Create the page content stream QPDFObjectHandle contents = createPageContents( pdf, "Look at the pretty, orange square!"); // Create the page dictionary QPDFObjectHandle page = pdf.makeIndirectObject( QPDFObjectHandle::newDictionary()); page.replaceKey("/Type", newName("/Page")); page.replaceKey("/MediaBox", mediabox); page.replaceKey("/Contents", contents); page.replaceKey("/Resources", resources); // Add the page to the PDF file pdf.addPage(page, true); // Write the results. A real application would not call // setStaticID here, but this example does it for the sake of its // test suite. QPDFWriter w(pdf, filename); 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 != 2) { usage(); } char const* filename = argv[1]; try { create_pdf(filename); } catch (std::exception& e) { std::cerr << e.what() << std::endl; exit(2); } return 0; }