aboutsummaryrefslogtreecommitdiffstats
path: root/examples/pdf-create.cc
diff options
context:
space:
mode:
Diffstat (limited to 'examples/pdf-create.cc')
-rw-r--r--examples/pdf-create.cc121
1 files changed, 53 insertions, 68 deletions
diff --git a/examples/pdf-create.cc b/examples/pdf-create.cc
index e0fa93b1..136643d1 100644
--- a/examples/pdf-create.cc
+++ b/examples/pdf-create.cc
@@ -1,7 +1,6 @@
//
-// This is an example of creating a PDF file from scratch. It
-// illustrates use of several QPDF operations for creating objects and
-// streams. It also serves as an illustration of how to use
+// This is an example of creating a PDF file from scratch. It illustrates use of several QPDF
+// operations for creating objects and streams. It also serves as an illustration of how to use
// StreamDataProvider with different types of filters.
//
@@ -20,8 +19,8 @@
static char const* whoami = nullptr;
-// This is a simple StreamDataProvider that writes image data for an
-// orange square of the given width and height.
+// 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:
@@ -32,47 +31,43 @@ class ImageProvider: public QPDFObjectHandle::StreamDataProvider
size_t getHeight() const;
private:
- size_t width;
- size_t stripe_height;
+ size_t width{400};
+ size_t stripe_height{80};
std::string color_space;
std::string filter;
- size_t n_stripes;
+ size_t n_stripes{6};
std::vector<std::string> stripes;
- J_COLOR_SPACE j_color_space;
+ J_COLOR_SPACE j_color_space{JCS_UNKNOWN};
};
ImageProvider::ImageProvider(std::string const& color_space, std::string const& filter) :
- width(400),
- stripe_height(80),
color_space(color_space),
- filter(filter),
- n_stripes(6),
- j_color_space(JCS_UNKNOWN)
+ filter(filter)
{
if (color_space == "/DeviceCMYK") {
j_color_space = JCS_CMYK;
- stripes.push_back(std::string("\xff\x00\x00\x00", 4));
- stripes.push_back(std::string("\x00\xff\x00\x00", 4));
- stripes.push_back(std::string("\x00\x00\xff\x00", 4));
- stripes.push_back(std::string("\xff\x00\xff\x00", 4));
- stripes.push_back(std::string("\xff\xff\x00\x00", 4));
- stripes.push_back(std::string("\x00\x00\x00\xff", 4));
+ stripes.emplace_back("\xff\x00\x00\x00", 4);
+ stripes.emplace_back("\x00\xff\x00\x00", 4);
+ stripes.emplace_back("\x00\x00\xff\x00", 4);
+ stripes.emplace_back("\xff\x00\xff\x00", 4);
+ stripes.emplace_back("\xff\xff\x00\x00", 4);
+ stripes.emplace_back("\x00\x00\x00\xff", 4);
} else if (color_space == "/DeviceRGB") {
j_color_space = JCS_RGB;
- stripes.push_back(std::string("\xff\x00\x00", 3));
- stripes.push_back(std::string("\x00\xff\x00", 3));
- stripes.push_back(std::string("\x00\x00\xff", 3));
- stripes.push_back(std::string("\xff\x00\xff", 3));
- stripes.push_back(std::string("\xff\xff\x00", 3));
- stripes.push_back(std::string("\x00\x00\x00", 3));
+ stripes.emplace_back("\xff\x00\x00", 3);
+ stripes.emplace_back("\x00\xff\x00", 3);
+ stripes.emplace_back("\x00\x00\xff", 3);
+ stripes.emplace_back("\xff\x00\xff", 3);
+ stripes.emplace_back("\xff\xff\x00", 3);
+ stripes.emplace_back("\x00\x00\x00", 3);
} else if (color_space == "/DeviceGray") {
j_color_space = JCS_GRAYSCALE;
- stripes.push_back(std::string("\xee", 1));
- stripes.push_back(std::string("\xcc", 1));
- stripes.push_back(std::string("\x99", 1));
- stripes.push_back(std::string("\x66", 1));
- stripes.push_back(std::string("\x33", 1));
- stripes.push_back(std::string("\x00", 1));
+ stripes.emplace_back("\xee", 1);
+ stripes.emplace_back("\xcc", 1);
+ stripes.emplace_back("\x99", 1);
+ stripes.emplace_back("\x66", 1);
+ stripes.emplace_back("\x33", 1);
+ stripes.emplace_back("\x00", 1);
}
}
@@ -130,8 +125,7 @@ usage()
static QPDFObjectHandle
createPageContents(QPDF& pdf, std::string const& text)
{
- // Create a stream that displays our image and the given text in
- // our font.
+ // Create a stream that displays our image and the given text in our font.
std::string contents = "BT /F1 24 Tf 72 320 Td (" + text +
") Tj ET\n"
"q 244 0 0 144 184 100 cm /Im1 Do Q\n";
@@ -159,11 +153,9 @@ add_page(
{
QPDF& pdf(dh.getQPDF());
- // Create a stream to encode our image. QPDFWriter will fill in
- // the length and will respect our filters based on stream data
- // mode. Since we are not specifying, QPDFWriter will compress
- // with /FlateDecode if we don't provide any other form of
- // compression.
+ // Create a stream to encode our image. QPDFWriter will fill in the length and will respect our
+ // filters based on stream data mode. Since we are not specifying, QPDFWriter will compress with
+ // /FlateDecode if we don't provide any other form of compression.
auto* p = new ImageProvider(color_space, filter);
std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider(p);
size_t width = p->getWidth();
@@ -219,20 +211,17 @@ check(
std::vector<std::string> const& color_spaces,
std::vector<std::string> const& filters)
{
- // Each stream is compressed the way it is supposed to be. We will
- // add additional tests in qpdf.test to exercise QPDFWriter more
- // fully. In this case, we want to make sure that we actually have
- // RunLengthDecode and DCTDecode where we are supposed to and
- // FlateDecode where we provided no filters.
+ // Each stream is compressed the way it is supposed to be. We will add additional tests in
+ // qpdf.test to exercise QPDFWriter more fully. In this case, we want to make sure that we
+ // actually have RunLengthDecode and DCTDecode where we are supposed to and FlateDecode where we
+ // provided no filters.
- // Each image is correct. For non-lossy image compression, the
- // uncompressed image data should exactly match what ImageProvider
- // provided. For the DCTDecode data, allow for some fuzz to handle
- // jpeg compression as well as its variance on different systems.
+ // Each image is correct. For non-lossy image compression, the uncompressed image data should
+ // exactly match what ImageProvider provided. For the DCTDecode data, allow for some fuzz to
+ // handle jpeg compression as well as its variance on different systems.
- // These tests should use QPDFObjectHandle's stream data retrieval
- // methods, but don't try to fully exercise them here. That is
- // done elsewhere.
+ // These tests should use QPDFObjectHandle's stream data retrieval methods, but don't try to
+ // fully exercise them here. That is done elsewhere.
size_t n_color_spaces = color_spaces.size();
size_t n_filters = filters.size();
@@ -254,8 +243,8 @@ check(
// Check filter and color space.
std::string desired_color_space = color_spaces[(pageno - 1) / n_color_spaces];
std::string desired_filter = filters[(pageno - 1) % n_filters];
- // In the default mode, QPDFWriter will compress with
- // /FlateDecode if no filters are provided.
+ // In the default mode, QPDFWriter will compress with /FlateDecode if no filters are
+ // provided.
if (desired_filter == "null") {
desired_filter = "/FlateDecode";
}
@@ -288,11 +277,9 @@ check(
std::cout << "page " << pageno << ": image data length mismatch" << std::endl;
this_errors = errors = true;
} else {
- // Compare bytes. For JPEG, allow a certain number of
- // the bytes to be off desired by more than a given
- // tolerance. Any of the samples may be a little off
- // because of lossy compression, and around sharp
- // edges, things can be quite off. For non-lossy
+ // Compare bytes. For JPEG, allow a certain number of the bytes to be off desired by
+ // more than a given tolerance. Any of the samples may be a little off because of
+ // lossy compression, and around sharp edges, things can be quite off. For non-lossy
// compression, do not allow any tolerance.
unsigned char const* actual_bytes = actual_data->getBuffer();
unsigned char const* desired_bytes = desired_data->getBuffer();
@@ -332,8 +319,7 @@ create_pdf(char const* filename)
// 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.
+ // Add an indirect object to contain a font descriptor for the built-in Helvetica font.
QPDFObjectHandle font = pdf.makeIndirectObject(
// line-break
"<<"
@@ -345,13 +331,13 @@ create_pdf(char const* filename)
">>"_qpdf);
std::vector<std::string> color_spaces;
- color_spaces.push_back("/DeviceCMYK");
- color_spaces.push_back("/DeviceRGB");
- color_spaces.push_back("/DeviceGray");
+ color_spaces.emplace_back("/DeviceCMYK");
+ color_spaces.emplace_back("/DeviceRGB");
+ color_spaces.emplace_back("/DeviceGray");
std::vector<std::string> filters;
- filters.push_back("null");
- filters.push_back("/DCTDecode");
- filters.push_back("/RunLengthDecode");
+ filters.emplace_back("null");
+ filters.emplace_back("/DCTDecode");
+ filters.emplace_back("/RunLengthDecode");
QPDFPageDocumentHelper dh(pdf);
for (auto const& color_space: color_spaces) {
for (auto const& filter: filters) {
@@ -362,8 +348,7 @@ create_pdf(char const* filename)
QPDFWriter w(pdf, filename);
w.write();
- // For test suite, verify that everything is the way it is
- // supposed to be.
+ // For test suite, verify that everything is the way it is supposed to be.
check(filename, color_spaces, filters);
}