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 void apply(double *px, double *py)
71 *px = m[0]*x + m[2]*y + m[4];
72 *py = m[1]*x + m[3]*y + m[5];
75 // A*B is a matrix which transforms first by A and then by B
76 pdf_matrix operator *(pdf_matrix y)
79 m[0]*y.m[0] + m[1]*y.m[2],
80 m[0]*y.m[1] + m[1]*y.m[3],
81 m[2]*y.m[0] + m[3]*y.m[2],
82 m[2]*y.m[1] + m[3]*y.m[3],
83 m[4]*y.m[0] + m[5]*y.m[2] + y.m[4],
84 m[4]*y.m[1] + m[5]*y.m[3] + y.m[5]
88 void concat(pdf_matrix y)
90 pdf_matrix t = *this * y;
91 for (int i=0; i<6; i++)
95 void shift(double dx, double dy)
103 concat(pdf_matrix(s, 0, 0, s, 0, 0));
106 void scale(double sx, double sy)
108 concat(pdf_matrix(sx, 0, 0, sy, 0, 0));
111 void rotate_rad(double angle)
113 double c = std::cos(angle), s = std::sin(angle);
114 concat(pdf_matrix(c, s, -s, c, 0, 0));
117 void rotate_deg(double angle)
119 rotate_rad(angle/180. * M_PI);
122 std::string to_string();
125 /*** Bounding boxes ***/
128 double x_min, x_max, y_min, y_max;
130 x_min = y_min = x_max = y_max = 0;
132 BBox(double xmin, double ymin, double xmax, double ymax) {
133 x_min = xmin, x_max = xmax;
134 y_min = ymin, y_max = ymax;
136 BBox(double x, double y) {
137 x_min = 0, x_max = x;
138 y_min = 0, y_max = y;
140 BBox(QPDFObjectHandle box) {
142 warn("Invalid bounding box, falling back to A4");
143 x_min = 0, x_max = A4_WIDTH;
144 y_min = 0, y_max = A4_HEIGHT;
147 QPDFObjectHandle to_array();
149 double width() { return x_max - x_min; }
150 double height() { return y_max - y_min; }
151 void transform(pdf_matrix &m);
153 bool parse(QPDFObjectHandle h);
156 /*** Miscellaneous ***/
158 QPDFObjectHandle unicode_string(std::string s);
159 QPDFObjectHandle page_to_xobject(QPDF *out, QPDFObjectHandle page);