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