Diffstat (limited to 'noncore/unsupported/qpdf/xpdf/Page.cc') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/unsupported/qpdf/xpdf/Page.cc | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/noncore/unsupported/qpdf/xpdf/Page.cc b/noncore/unsupported/qpdf/xpdf/Page.cc new file mode 100644 index 0000000..17c4481 --- a/dev/null +++ b/noncore/unsupported/qpdf/xpdf/Page.cc | |||
@@ -0,0 +1,267 @@ | |||
1 | //======================================================================== | ||
2 | // | ||
3 | // Page.cc | ||
4 | // | ||
5 | // Copyright 1996 Derek B. Noonburg | ||
6 | // | ||
7 | //======================================================================== | ||
8 | |||
9 | #ifdef __GNUC__ | ||
10 | #pragma implementation | ||
11 | #endif | ||
12 | |||
13 | #include <aconf.h> | ||
14 | #include <stddef.h> | ||
15 | #include "Object.h" | ||
16 | #include "Array.h" | ||
17 | #include "Dict.h" | ||
18 | #include "XRef.h" | ||
19 | #include "Link.h" | ||
20 | #include "OutputDev.h" | ||
21 | #ifndef PDF_PARSER_ONLY | ||
22 | #include "Gfx.h" | ||
23 | #include "FormWidget.h" | ||
24 | #endif | ||
25 | #include "Error.h" | ||
26 | #include "Page.h" | ||
27 | |||
28 | //------------------------------------------------------------------------ | ||
29 | // PageAttrs | ||
30 | //------------------------------------------------------------------------ | ||
31 | |||
32 | PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) { | ||
33 | Object obj1; | ||
34 | fouble w, h; | ||
35 | |||
36 | // get old/default values | ||
37 | if (attrs) { | ||
38 | mediaBox = attrs->mediaBox; | ||
39 | cropBox = attrs->cropBox; | ||
40 | haveCropBox = attrs->haveCropBox; | ||
41 | rotate = attrs->rotate; | ||
42 | attrs->resources.copy(&resources); | ||
43 | } else { | ||
44 | // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary | ||
45 | // but some (non-compliant) PDF files don't specify a MediaBox | ||
46 | mediaBox.x1 = 0; | ||
47 | mediaBox.y1 = 0; | ||
48 | mediaBox.x2 = 612; | ||
49 | mediaBox.y2 = 792; | ||
50 | cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0; | ||
51 | haveCropBox = gFalse; | ||
52 | rotate = 0; | ||
53 | resources.initNull(); | ||
54 | } | ||
55 | |||
56 | // media box | ||
57 | readBox(dict, "MediaBox", &mediaBox); | ||
58 | |||
59 | // crop box | ||
60 | cropBox = mediaBox; | ||
61 | haveCropBox = readBox(dict, "CropBox", &cropBox); | ||
62 | |||
63 | // if the MediaBox is excessively larger than the CropBox, | ||
64 | // just use the CropBox | ||
65 | limitToCropBox = gFalse; | ||
66 | if (haveCropBox) { | ||
67 | w = 0.25 * (cropBox.x2 - cropBox.x1); | ||
68 | h = 0.25 * (cropBox.y2 - cropBox.y1); | ||
69 | if ((cropBox.x1 - mediaBox.x1) + (mediaBox.x2 - cropBox.x2) > w || | ||
70 | (cropBox.y1 - mediaBox.y1) + (mediaBox.y2 - cropBox.y2) > h) { | ||
71 | limitToCropBox = gTrue; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | // other boxes | ||
76 | bleedBox = cropBox; | ||
77 | readBox(dict, "BleedBox", &bleedBox); | ||
78 | trimBox = cropBox; | ||
79 | readBox(dict, "TrimBox", &trimBox); | ||
80 | artBox = cropBox; | ||
81 | readBox(dict, "ArtBox", &artBox); | ||
82 | |||
83 | // rotate | ||
84 | dict->lookup("Rotate", &obj1); | ||
85 | if (obj1.isInt()) { | ||
86 | rotate = obj1.getInt(); | ||
87 | } | ||
88 | obj1.free(); | ||
89 | while (rotate < 0) { | ||
90 | rotate += 360; | ||
91 | } | ||
92 | while (rotate >= 360) { | ||
93 | rotate -= 360; | ||
94 | } | ||
95 | |||
96 | // resource dictionary | ||
97 | dict->lookup("Resources", &obj1); | ||
98 | if (obj1.isDict()) { | ||
99 | resources.free(); | ||
100 | obj1.copy(&resources); | ||
101 | } | ||
102 | obj1.free(); | ||
103 | } | ||
104 | |||
105 | PageAttrs::~PageAttrs() { | ||
106 | resources.free(); | ||
107 | } | ||
108 | |||
109 | GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) { | ||
110 | PDFRectangle tmp; | ||
111 | Object obj1, obj2; | ||
112 | GBool ok; | ||
113 | |||
114 | dict->lookup(key, &obj1); | ||
115 | if (obj1.isArray() && obj1.arrayGetLength() == 4) { | ||
116 | ok = gTrue; | ||
117 | obj1.arrayGet(0, &obj2); | ||
118 | if (obj2.isNum()) { | ||
119 | tmp.x1 = obj2.getNum(); | ||
120 | } else { | ||
121 | ok = gFalse; | ||
122 | } | ||
123 | obj2.free(); | ||
124 | obj1.arrayGet(1, &obj2); | ||
125 | if (obj2.isNum()) { | ||
126 | tmp.y1 = obj2.getNum(); | ||
127 | } else { | ||
128 | ok = gFalse; | ||
129 | } | ||
130 | obj2.free(); | ||
131 | obj1.arrayGet(2, &obj2); | ||
132 | if (obj2.isNum()) { | ||
133 | tmp.x2 = obj2.getNum(); | ||
134 | } else { | ||
135 | ok = gFalse; | ||
136 | } | ||
137 | obj2.free(); | ||
138 | obj1.arrayGet(3, &obj2); | ||
139 | if (obj2.isNum()) { | ||
140 | tmp.y2 = obj2.getNum(); | ||
141 | } else { | ||
142 | ok = gFalse; | ||
143 | } | ||
144 | obj2.free(); | ||
145 | if (ok) { | ||
146 | *box = tmp; | ||
147 | } | ||
148 | } else { | ||
149 | ok = gFalse; | ||
150 | } | ||
151 | obj1.free(); | ||
152 | return ok; | ||
153 | } | ||
154 | |||
155 | //------------------------------------------------------------------------ | ||
156 | // Page | ||
157 | //------------------------------------------------------------------------ | ||
158 | |||
159 | Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA, | ||
160 | GBool printCommandsA) { | ||
161 | |||
162 | ok = gTrue; | ||
163 | xref = xrefA; | ||
164 | num = numA; | ||
165 | printCommands = printCommandsA; | ||
166 | |||
167 | // get attributes | ||
168 | attrs = attrsA; | ||
169 | |||
170 | // annotations | ||
171 | pageDict->lookupNF("Annots", &annots); | ||
172 | if (!(annots.isRef() || annots.isArray() || annots.isNull())) { | ||
173 | error(-1, "Page annotations object (page %d) is wrong type (%s)", | ||
174 | num, annots.getTypeName()); | ||
175 | annots.free(); | ||
176 | goto err2; | ||
177 | } | ||
178 | |||
179 | // contents | ||
180 | pageDict->lookupNF("Contents", &contents); | ||
181 | if (!(contents.isRef() || contents.isArray() || | ||
182 | contents.isNull())) { | ||
183 | error(-1, "Page contents object (page %d) is wrong type (%s)", | ||
184 | num, contents.getTypeName()); | ||
185 | contents.free(); | ||
186 | goto err1; | ||
187 | } | ||
188 | |||
189 | return; | ||
190 | |||
191 | err2: | ||
192 | annots.initNull(); | ||
193 | err1: | ||
194 | contents.initNull(); | ||
195 | ok = gFalse; | ||
196 | } | ||
197 | |||
198 | Page::~Page() { | ||
199 | delete attrs; | ||
200 | annots.free(); | ||
201 | contents.free(); | ||
202 | } | ||
203 | |||
204 | void Page::display(OutputDev *out, fouble dpi, int rotate, | ||
205 | Links *links, Catalog *catalog) { | ||
206 | #ifndef PDF_PARSER_ONLY | ||
207 | PDFRectangle *box, *cropBox; | ||
208 | Gfx *gfx; | ||
209 | Object obj; | ||
210 | Link *link; | ||
211 | int i; | ||
212 | FormWidgets *formWidgets; | ||
213 | |||
214 | box = getBox(); | ||
215 | cropBox = getCropBox(); | ||
216 | |||
217 | if (printCommands) { | ||
218 | printf("***** MediaBox = ll:%g,%g ur:%g,%g\n", | ||
219 | box->x1, box->y1, box->x2, box->y2); | ||
220 | if (isCropped()) { | ||
221 | printf("***** CropBox = ll:%g,%g ur:%g,%g\n", | ||
222 | cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2); | ||
223 | } | ||
224 | printf("***** Rotate = %d\n", attrs->getRotate()); | ||
225 | } | ||
226 | |||
227 | rotate += getRotate(); | ||
228 | if (rotate >= 360) { | ||
229 | rotate -= 360; | ||
230 | } else if (rotate < 0) { | ||
231 | rotate += 360; | ||
232 | } | ||
233 | gfx = new Gfx(xref, out, num, attrs->getResourceDict(), | ||
234 | dpi, box, isCropped(), cropBox, rotate, printCommands); | ||
235 | contents.fetch(xref, &obj); | ||
236 | if (!obj.isNull()) { | ||
237 | gfx->display(&obj); | ||
238 | } | ||
239 | obj.free(); | ||
240 | |||
241 | // draw links | ||
242 | if (links) { | ||
243 | for (i = 0; i < links->getNumLinks(); ++i) { | ||
244 | link = links->getLink(i); | ||
245 | out->drawLink(link, catalog); | ||
246 | } | ||
247 | out->dump(); | ||
248 | } | ||
249 | |||
250 | // draw AcroForm widgets | ||
251 | //~ need to reset CTM ??? | ||
252 | formWidgets = new FormWidgets(xref, annots.fetch(xref, &obj)); | ||
253 | obj.free(); | ||
254 | if (printCommands && formWidgets->getNumWidgets() > 0) { | ||
255 | printf("***** AcroForm widgets\n"); | ||
256 | } | ||
257 | for (i = 0; i < formWidgets->getNumWidgets(); ++i) { | ||
258 | formWidgets->getWidget(i)->draw(gfx); | ||
259 | } | ||
260 | if (formWidgets->getNumWidgets() > 0) { | ||
261 | out->dump(); | ||
262 | } | ||
263 | delete formWidgets; | ||
264 | |||
265 | delete gfx; | ||
266 | #endif | ||
267 | } | ||