]> mj.ucw.cz Git - paperjam.git/blob - pdf-tools.h
TODO: a4r paper
[paperjam.git] / pdf-tools.h
1 /*
2  *      Auxiliary functions for processing PDF files
3  *
4  *      (c) 2018 Martin Mares <mj@ucw.cz>
5  */
6
7 #ifndef _PDF_TOOLS_H
8 #define _PDF_TOOLS_H
9
10 #include <cmath>
11 #include <string>
12
13 #include <qpdf/QPDF.hh>
14
15 /*** Basic macros and constants ***/
16
17 #define A4_WIDTH 595
18 #define A4_HEIGHT 842
19 static const double mm = 72/25.4;
20
21 /*** Transformation matrices ***/
22
23 struct pdf_matrix {
24         /*
25          *  A transformation matrix corresponds to the linear transform
26          *
27          *            (a b 0)
28          *  (x y 1) * (c d 0) = (ax+cy+e bx+dy+f 1)
29          *            (e f 1)
30          *
31          *  We represent the non-trivial coefficients of the matrix by
32          *  an array {a,b,c,d,e,f}.
33          */
34         double m[6];
35
36         pdf_matrix() {
37                 m[0] = 1;
38                 m[1] = 0;
39                 m[2] = 0;
40                 m[3] = 1;
41                 m[4] = m[5] = 0;
42         }
43
44         pdf_matrix(double a, double b, double c, double d, double e, double f)
45         {
46                 m[0] = a;
47                 m[1] = b;
48                 m[2] = c;
49                 m[3] = d;
50                 m[4] = e;
51                 m[5] = f;
52         }
53
54         void apply(double *px, double *py)
55         {
56                 double x=*px, y=*py;
57                 *px = m[0]*x + m[2]*y + m[4];
58                 *py = m[1]*x + m[3]*y + m[5];
59         }
60
61         // A*B is a matrix which transforms first by A and then by B
62         pdf_matrix operator *(pdf_matrix y)
63         {
64                 return pdf_matrix(
65                         m[0]*y.m[0] + m[1]*y.m[2],
66                         m[0]*y.m[1] + m[1]*y.m[3],
67                         m[2]*y.m[0] + m[3]*y.m[2],
68                         m[2]*y.m[1] + m[3]*y.m[3],
69                         m[4]*y.m[0] + m[5]*y.m[2] + y.m[4],
70                         m[4]*y.m[1] + m[5]*y.m[3] + y.m[5]
71                 );
72         }
73
74         void concat(pdf_matrix y)
75         {
76                 pdf_matrix t = *this * y;
77                 for (int i=0; i<6; i++)
78                         m[i] = t.m[i];
79         }
80
81         void shift(double dx, double dy)
82         {
83                 m[4] += dx;
84                 m[5] += dy;
85         }
86
87         void scale(double s)
88         {
89                 concat(pdf_matrix(s, 0, 0, s, 0, 0));
90         }
91
92         void scale(double sx, double sy)
93         {
94                 concat(pdf_matrix(sx, 0, 0, sy, 0, 0));
95         }
96
97         void rotate_rad(double angle)
98         {
99                 double c = std::cos(angle), s = std::sin(angle);
100                 concat(pdf_matrix(c, s, -s, c, 0, 0));
101         }
102
103         void rotate_deg(double angle)
104         {
105                 rotate_rad(angle/180. * M_PI);
106         }
107
108         std::string to_string();
109 };
110
111 /*** Bounding boxes ***/
112
113 struct BBox {
114         double x_min, x_max, y_min, y_max;
115         BBox() {
116                 x_min = y_min = x_max = y_max = 0;
117         }
118         BBox(double xmin, double ymin, double xmax, double ymax) {
119                 x_min = xmin, x_max = xmax;
120                 y_min = ymin, y_max = ymax;
121         }
122         BBox(double x, double y) {
123                 x_min = 0, x_max = x;
124                 y_min = 0, y_max = y;
125         }
126         BBox(QPDFObjectHandle box);
127         QPDFObjectHandle to_array();
128         string to_rect();
129         double width() { return x_max - x_min; }
130         double height() { return y_max - y_min; }
131         void transform(pdf_matrix &m);
132         BBox transformed(pdf_matrix &m);
133         void enlarge(double by);
134         BBox enlarged(double by);
135         void join(BBox &with);
136         void intersect(BBox &with);
137 private:
138         bool parse(QPDFObjectHandle h);
139 };
140
141 /*** Miscellaneous ***/
142
143 QPDFObjectHandle unicode_string(std::string s);
144 QPDFObjectHandle page_to_xobject(QPDF *out, QPDFObjectHandle page);
145 string pdf_coord(double x, uint digits=1);
146 pdf_matrix pdf_rotation_matrix(int deg, double width, double height);
147
148 #endif