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;
34 /*** Transformation matrices ***/
38 * A transformation matrix corresponds to the linear transform
41 * (x y 1) * (c d 0) = (ax+cy+e bx+dy+f 1)
44 * We represent the non-trivial coefficients of the matrix by
45 * an array {a,b,c,d,e,f}.
57 pdf_matrix(double a, double b, double c, double d, double e, double f)
67 // A*B is a matrix which transforms first by A and then by B
68 pdf_matrix operator *(pdf_matrix y)
71 m[0]*y.m[0] + m[1]*y.m[2],
72 m[0]*y.m[1] + m[1]*y.m[3],
73 m[2]*y.m[0] + m[3]*y.m[2],
74 m[2]*y.m[1] + m[3]*y.m[3],
75 m[4]*y.m[0] + m[5]*y.m[2] + y.m[4],
76 m[4]*y.m[1] + m[5]*y.m[3] + y.m[5]
80 void concat(pdf_matrix y)
82 pdf_matrix t = *this * y;
83 for (int i=0; i<6; i++)
87 void shift(double dx, double dy)
95 concat(pdf_matrix(s, 0, 0, s, 0, 0));
98 void scale(double sx, double sy)
100 concat(pdf_matrix(sx, 0, 0, sy, 0, 0));
103 void rotate_rad(double angle)
105 double c = std::cos(angle), s = std::sin(angle);
106 concat(pdf_matrix(c, s, -s, c, 0, 0));
109 void rotate_deg(double angle)
111 rotate_rad(angle/180. * M_PI);
114 std::string to_string();
117 /*** Bounding boxes ***/
120 double x_min, x_max, y_min, y_max;
122 x_min = y_min = x_max = y_max = 0;
124 BBox(double xmin, double ymin, double xmax, double ymax) {
125 x_min = xmin, x_max = xmax;
126 y_min = ymin, y_max = ymax;
128 BBox(double x, double y) {
129 x_min = 0, x_max = x;
130 y_min = 0, y_max = y;
132 BBox(QPDFObjectHandle box) {
134 warn("Invalid bounding box, falling back to A4");
135 x_min = 0, x_max = A4_WIDTH;
136 y_min = 0, y_max = A4_HEIGHT;
139 QPDFObjectHandle to_array();
140 double width() { return x_max - x_min; }
141 double height() { return y_max - y_min; }
143 bool parse(QPDFObjectHandle h);
146 /*** Miscellaneous ***/
148 QPDFObjectHandle unicode_string(std::string s);
149 QPDFObjectHandle page_to_xobject(QPDF *out, QPDFObjectHandle page);