2 * Auxiliary functions for processing PDF files
4 * (c) 2018 Martin Mares <mj@ucw.cz>
13 #include <qpdf/QPDF.hh>
15 /*** Basic macros and constants ***/
17 #define UNUSED __attribute__((unused))
18 #define FORMAT_CHECK(x,y,z) __attribute__((format(x,y,z)))
19 #define NONRET __attribute__((noreturn))
23 static const double mm = 72/25.4;
27 void debug(const char *msg, ...) FORMAT_CHECK(printf, 1, 2);
28 void warn(const char *msg, ...) FORMAT_CHECK(printf, 1, 2);
29 void die(const char *msg, ...) FORMAT_CHECK(printf, 1, 2) NONRET;
30 void bad(const char *msg, ...) FORMAT_CHECK(printf, 1, 2) NONRET;
32 extern int debug_mode;
33 extern int debug_indent;
35 /*** Transformation matrices ***/
39 * A transformation matrix corresponds to the linear transform
42 * (x y 1) * (c d 0) = (ax+cy+e bx+dy+f 1)
45 * We represent the non-trivial coefficients of the matrix by
46 * an array {a,b,c,d,e,f}.
58 pdf_matrix(double a, double b, double c, double d, double e, double f)
68 // A*B is a matrix which transforms first by A and then by B
69 pdf_matrix operator *(pdf_matrix y)
72 m[0]*y.m[0] + m[1]*y.m[2],
73 m[0]*y.m[1] + m[1]*y.m[3],
74 m[2]*y.m[0] + m[3]*y.m[2],
75 m[2]*y.m[1] + m[3]*y.m[3],
76 m[4]*y.m[0] + m[5]*y.m[2] + y.m[4],
77 m[4]*y.m[1] + m[5]*y.m[3] + y.m[5]
81 void concat(pdf_matrix y)
83 pdf_matrix t = *this * y;
84 for (int i=0; i<6; i++)
88 void shift(double dx, double dy)
96 concat(pdf_matrix(s, 0, 0, s, 0, 0));
99 void scale(double sx, double sy)
101 concat(pdf_matrix(sx, 0, 0, sy, 0, 0));
104 void rotate_rad(double angle)
106 double c = std::cos(angle), s = std::sin(angle);
107 concat(pdf_matrix(c, s, -s, c, 0, 0));
110 void rotate_deg(double angle)
112 rotate_rad(angle/180. * M_PI);
115 std::string to_string();
118 /*** Bounding boxes ***/
121 double x_min, x_max, y_min, y_max;
123 x_min = y_min = x_max = y_max = 0;
125 BBox(double xmin, double ymin, double xmax, double ymax) {
126 x_min = xmin, x_max = xmax;
127 y_min = ymin, y_max = ymax;
129 BBox(double x, double y) {
130 x_min = 0, x_max = x;
131 y_min = 0, y_max = y;
133 BBox(QPDFObjectHandle box) {
135 warn("Invalid bounding box, falling back to A4");
136 x_min = 0, x_max = A4_WIDTH;
137 y_min = 0, y_max = A4_HEIGHT;
140 QPDFObjectHandle to_array();
141 double width() { return x_max - x_min; }
142 double height() { return y_max - y_min; }
144 bool parse(QPDFObjectHandle h);
147 /*** Miscellaneous ***/
149 QPDFObjectHandle unicode_string(std::string s);
150 QPDFObjectHandle page_to_xobject(QPDF *out, QPDFObjectHandle page);