1 #include "qpdf_pdftopdf.h"
2 #include <assert.h>
3 #include <stdexcept>
4 #include <qpdf/QUtil.hh>
5
getBoxAsRect(QPDFObjectHandle box)6 PageRect getBoxAsRect(QPDFObjectHandle box) // {{{
7 {
8 PageRect ret;
9
10 ret.left=box.getArrayItem(0).getNumericValue();
11 ret.bottom=box.getArrayItem(1).getNumericValue();
12 ret.right=box.getArrayItem(2).getNumericValue();
13 ret.top=box.getArrayItem(3).getNumericValue();
14
15 ret.width=ret.right-ret.left;
16 ret.height=ret.top-ret.bottom;
17
18 return ret;
19 }
20 // }}}
21
getRotate(QPDFObjectHandle page)22 Rotation getRotate(QPDFObjectHandle page) // {{{
23 {
24 if (!page.hasKey("/Rotate")) {
25 return ROT_0;
26 }
27 double rot=page.getKey("/Rotate").getNumericValue();
28 rot=fmod(rot,360.0);
29 if (rot<0) {
30 rot+=360.0;
31 }
32 if (rot==90.0) { // CW
33 return ROT_270; // CCW
34 } else if (rot==180.0) {
35 return ROT_180;
36 } else if (rot==270.0) {
37 return ROT_90;
38 } else if (rot!=0.0) {
39 throw std::runtime_error("Unexpected /Rotation value: "+QUtil::double_to_string(rot));
40 }
41 return ROT_0;
42 }
43 // }}}
44
getUserUnit(QPDFObjectHandle page)45 double getUserUnit(QPDFObjectHandle page) // {{{
46 {
47 if (!page.hasKey("/UserUnit")) {
48 return 1.0;
49 }
50 return page.getKey("/UserUnit").getNumericValue();
51 }
52 // }}}
53
makeRotate(Rotation rot)54 QPDFObjectHandle makeRotate(Rotation rot) // {{{
55 {
56 switch (rot) {
57 case ROT_0:
58 return QPDFObjectHandle::newNull();
59 case ROT_90: // CCW
60 return QPDFObjectHandle::newInteger(270); // CW
61 case ROT_180:
62 return QPDFObjectHandle::newInteger(180);
63 case ROT_270:
64 return QPDFObjectHandle::newInteger(90);
65 default:
66 throw std::invalid_argument("Bad rotation");
67 }
68 }
69 // }}}
70
71 #include "qpdf_tools.h"
72
getRectAsBox(const PageRect & rect)73 QPDFObjectHandle getRectAsBox(const PageRect &rect) // {{{
74 {
75 return makeBox(rect.left,rect.bottom,rect.right,rect.top);
76 }
77 // }}}
78
79 #include <qpdf/QUtil.hh>
80
Matrix()81 Matrix::Matrix() // {{{
82 : ctm{1,0,0,1,0,0}
83 {
84 }
85 // }}}
86
Matrix(QPDFObjectHandle ar)87 Matrix::Matrix(QPDFObjectHandle ar) // {{{
88 {
89 if (ar.getArrayNItems()!=6) {
90 throw std::runtime_error("Not a ctm matrix");
91 }
92 for (int iA=0;iA<6;iA++) {
93 ctm[iA]=ar.getArrayItem(iA).getNumericValue();
94 }
95 }
96 // }}}
97
rotate(Rotation rot)98 Matrix &Matrix::rotate(Rotation rot) // {{{
99 {
100 switch (rot) {
101 case ROT_0:
102 break;
103 case ROT_90:
104 std::swap(ctm[0],ctm[2]);
105 std::swap(ctm[1],ctm[3]);
106 ctm[2]=-ctm[2];
107 ctm[3]=-ctm[3];
108 break;
109 case ROT_180:
110 ctm[0]=-ctm[0];
111 ctm[3]=-ctm[3];
112 break;
113 case ROT_270:
114 std::swap(ctm[0],ctm[2]);
115 std::swap(ctm[1],ctm[3]);
116 ctm[0]=-ctm[0];
117 ctm[1]=-ctm[1];
118 break;
119 default:
120 assert(0);
121 }
122 return *this;
123 }
124 // }}}
125
126 // TODO: test
rotate_move(Rotation rot,double width,double height)127 Matrix &Matrix::rotate_move(Rotation rot,double width,double height) // {{{
128 {
129 rotate(rot);
130 switch (rot) {
131 case ROT_0:
132 break;
133 case ROT_90:
134 translate(width,0);
135 break;
136 case ROT_180:
137 translate(width,height);
138 break;
139 case ROT_270:
140 translate(0,height);
141 break;
142 }
143 return *this;
144 }
145 // }}}
146
rotate(double rad)147 Matrix &Matrix::rotate(double rad) // {{{
148 {
149 Matrix tmp;
150
151 tmp.ctm[0]=cos(rad);
152 tmp.ctm[1]=sin(rad);
153 tmp.ctm[2]=-sin(rad);
154 tmp.ctm[3]=cos(rad);
155
156 return (*this*=tmp);
157 }
158 // }}}
159
translate(double tx,double ty)160 Matrix &Matrix::translate(double tx,double ty) // {{{
161 {
162 ctm[4]+=ctm[0]*tx+ctm[2]*ty;
163 ctm[5]+=ctm[1]*tx+ctm[3]*ty;
164 return *this;
165 }
166 // }}}
167
scale(double sx,double sy)168 Matrix &Matrix::scale(double sx,double sy) // {{{
169 {
170 ctm[0]*=sx;
171 ctm[1]*=sx;
172 ctm[2]*=sy;
173 ctm[3]*=sy;
174 return *this;
175 }
176 // }}}
177
operator *=(const Matrix & rhs)178 Matrix &Matrix::operator*=(const Matrix &rhs) // {{{
179 {
180 double tmp[6];
181 std::copy(ctm,ctm+6,tmp);
182
183 ctm[0] = tmp[0]*rhs.ctm[0] + tmp[2]*rhs.ctm[1];
184 ctm[1] = tmp[1]*rhs.ctm[0] + tmp[3]*rhs.ctm[1];
185
186 ctm[2] = tmp[0]*rhs.ctm[2] + tmp[2]*rhs.ctm[3];
187 ctm[3] = tmp[1]*rhs.ctm[2] + tmp[3]*rhs.ctm[3];
188
189 ctm[4] = tmp[0]*rhs.ctm[4] + tmp[2]*rhs.ctm[5] + tmp[4];
190 ctm[5] = tmp[1]*rhs.ctm[4] + tmp[3]*rhs.ctm[5] + tmp[5];
191
192 return *this;
193 }
194 // }}}
195
get() const196 QPDFObjectHandle Matrix::get() const // {{{
197 {
198 QPDFObjectHandle ret=QPDFObjectHandle::newArray();
199 ret.appendItem(QPDFObjectHandle::newReal(ctm[0]));
200 ret.appendItem(QPDFObjectHandle::newReal(ctm[1]));
201 ret.appendItem(QPDFObjectHandle::newReal(ctm[2]));
202 ret.appendItem(QPDFObjectHandle::newReal(ctm[3]));
203 ret.appendItem(QPDFObjectHandle::newReal(ctm[4]));
204 ret.appendItem(QPDFObjectHandle::newReal(ctm[5]));
205 return ret;
206 }
207 // }}}
208
get_string() const209 std::string Matrix::get_string() const // {{{
210 {
211 std::string ret;
212 ret.append(QUtil::double_to_string(ctm[0]));
213 ret.append(" ");
214 ret.append(QUtil::double_to_string(ctm[1]));
215 ret.append(" ");
216 ret.append(QUtil::double_to_string(ctm[2]));
217 ret.append(" ");
218 ret.append(QUtil::double_to_string(ctm[3]));
219 ret.append(" ");
220 ret.append(QUtil::double_to_string(ctm[4]));
221 ret.append(" ");
222 ret.append(QUtil::double_to_string(ctm[5]));
223 return ret;
224 }
225 // }}}
226