1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
16 #include "GlobalParams.h"
22 #include "OutputDev.h"
23 #ifndef PDF_PARSER_ONLY
30 //------------------------------------------------------------------------
32 //------------------------------------------------------------------------
34 PageAttrs::PageAttrs(PageAttrs
*attrs
, Dict
*dict
) {
38 // get old/default values
40 mediaBox
= attrs
->mediaBox
;
41 cropBox
= attrs
->cropBox
;
42 haveCropBox
= attrs
->haveCropBox
;
43 rotate
= attrs
->rotate
;
44 attrs
->resources
.copy(&resources
);
46 // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary
47 // but some (non-compliant) PDF files don't specify a MediaBox
52 cropBox
.x1
= cropBox
.y1
= cropBox
.x2
= cropBox
.y2
= 0;
59 readBox(dict
, "MediaBox", &mediaBox
);
62 if (readBox(dict
, "CropBox", &cropBox
)) {
69 // if the MediaBox is excessively larger than the CropBox,
70 // just use the CropBox
71 limitToCropBox
= gFalse
;
73 w
= 0.25 * (cropBox
.x2
- cropBox
.x1
);
74 h
= 0.25 * (cropBox
.y2
- cropBox
.y1
);
75 if ((cropBox
.x1
- mediaBox
.x1
) + (mediaBox
.x2
- cropBox
.x2
) > w
||
76 (cropBox
.y1
- mediaBox
.y1
) + (mediaBox
.y2
- cropBox
.y2
) > h
) {
77 limitToCropBox
= gTrue
;
83 readBox(dict
, "BleedBox", &bleedBox
);
85 readBox(dict
, "TrimBox", &trimBox
);
87 readBox(dict
, "ArtBox", &artBox
);
90 dict
->lookup("Rotate", &obj1
);
92 rotate
= obj1
.getInt();
98 while (rotate
>= 360) {
103 dict
->lookup("LastModified", &lastModified
);
104 dict
->lookup("BoxColorInfo", &boxColorInfo
);
105 dict
->lookup("Group", &group
);
106 dict
->lookup("Metadata", &metadata
);
107 dict
->lookup("PieceInfo", &pieceInfo
);
108 dict
->lookup("SeparationInfo", &separationInfo
);
110 // resource dictionary
111 dict
->lookup("Resources", &obj1
);
114 obj1
.copy(&resources
);
119 PageAttrs::~PageAttrs() {
125 separationInfo
.free();
129 GBool
PageAttrs::readBox(Dict
*dict
, char *key
, PDFRectangle
*box
) {
134 dict
->lookup(key
, &obj1
);
135 if (obj1
.isArray() && obj1
.arrayGetLength() == 4) {
137 obj1
.arrayGet(0, &obj2
);
139 tmp
.x1
= obj2
.getNum();
144 obj1
.arrayGet(1, &obj2
);
146 tmp
.y1
= obj2
.getNum();
151 obj1
.arrayGet(2, &obj2
);
153 tmp
.x2
= obj2
.getNum();
158 obj1
.arrayGet(3, &obj2
);
160 tmp
.y2
= obj2
.getNum();
175 //------------------------------------------------------------------------
177 //------------------------------------------------------------------------
179 Page::Page(XRef
*xrefA
, int numA
, Dict
*pageDict
, PageAttrs
*attrsA
) {
188 pageDict
->lookupNF("Annots", &annots
);
189 if (!(annots
.isRef() || annots
.isArray() || annots
.isNull())) {
190 error(-1, "Page annotations object (page %d) is wrong type (%s)",
191 num
, annots
.getTypeName());
197 pageDict
->lookupNF("Contents", &contents
);
198 if (!(contents
.isRef() || contents
.isArray() ||
199 contents
.isNull())) {
200 error(-1, "Page contents object (page %d) is wrong type (%s)",
201 num
, contents
.getTypeName());
221 void Page::display(OutputDev
*out
, double hDPI
, double vDPI
,
222 int rotate
, GBool crop
,
223 Links
*links
, Catalog
*catalog
,
224 GBool (*abortCheckCbk
)(void *data
),
225 void *abortCheckCbkData
) {
226 displaySlice(out
, hDPI
, vDPI
, rotate
, crop
, -1, -1, -1, -1, links
, catalog
,
227 abortCheckCbk
, abortCheckCbkData
);
230 void Page::displaySlice(OutputDev
*out
, double hDPI
, double vDPI
,
231 int rotate
, GBool crop
,
232 int sliceX
, int sliceY
, int sliceW
, int sliceH
,
233 Links
*links
, Catalog
*catalog
,
234 GBool (*abortCheckCbk
)(void *data
),
235 void *abortCheckCbkData
) {
236 #ifndef PDF_PARSER_ONLY
237 PDFRectangle
*mediaBox
, *cropBox
;
246 rotate
+= getRotate();
249 } else if (rotate
< 0) {
254 if (sliceW
>= 0 && sliceH
>= 0) {
258 if (out
->upsideDown()) {
259 box
.x1
= mediaBox
->x1
+ ky
* sliceY
;
260 box
.x2
= mediaBox
->x1
+ ky
* (sliceY
+ sliceH
);
262 box
.x1
= mediaBox
->x2
- ky
* (sliceY
+ sliceH
);
263 box
.x2
= mediaBox
->x2
- ky
* sliceY
;
265 box
.y1
= mediaBox
->y1
+ kx
* sliceX
;
266 box
.y2
= mediaBox
->y1
+ kx
* (sliceX
+ sliceW
);
267 } else if (rotate
== 180) {
268 box
.x1
= mediaBox
->x2
- kx
* (sliceX
+ sliceW
);
269 box
.x2
= mediaBox
->x2
- kx
* sliceX
;
270 if (out
->upsideDown()) {
271 box
.y1
= mediaBox
->y1
+ ky
* sliceY
;
272 box
.y2
= mediaBox
->y1
+ ky
* (sliceY
+ sliceH
);
274 box
.y1
= mediaBox
->y2
- ky
* (sliceY
+ sliceH
);
275 box
.y2
= mediaBox
->y2
- ky
* sliceY
;
277 } else if (rotate
== 270) {
278 if (out
->upsideDown()) {
279 box
.x1
= mediaBox
->x2
- ky
* (sliceY
+ sliceH
);
280 box
.x2
= mediaBox
->x2
- ky
* sliceY
;
282 box
.x1
= mediaBox
->x1
+ ky
* sliceY
;
283 box
.x2
= mediaBox
->x1
+ ky
* (sliceY
+ sliceH
);
285 box
.y1
= mediaBox
->y2
- kx
* (sliceX
+ sliceW
);
286 box
.y2
= mediaBox
->y2
- kx
* sliceX
;
288 box
.x1
= mediaBox
->x1
+ kx
* sliceX
;
289 box
.x2
= mediaBox
->x1
+ kx
* (sliceX
+ sliceW
);
290 if (out
->upsideDown()) {
291 box
.y1
= mediaBox
->y2
- ky
* (sliceY
+ sliceH
);
292 box
.y2
= mediaBox
->y2
- ky
* sliceY
;
294 box
.y1
= mediaBox
->y1
+ ky
* sliceY
;
295 box
.y2
= mediaBox
->y1
+ ky
* (sliceY
+ sliceH
);
301 cropBox
= getCropBox();
303 if (globalParams
->getPrintCommands()) {
304 printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
305 box
.x1
, box
.y1
, box
.x2
, box
.y2
);
307 printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
308 cropBox
->x1
, cropBox
->y1
, cropBox
->x2
, cropBox
->y2
);
310 printf("***** Rotate = %d\n", attrs
->getRotate());
313 gfx
= new Gfx(xref
, out
, num
, attrs
->getResourceDict(),
314 hDPI
, vDPI
, &box
, crop
&& isCropped(), cropBox
, rotate
,
315 abortCheckCbk
, abortCheckCbkData
);
316 contents
.fetch(xref
, &obj
);
327 for (i
= 0; i
< links
->getNumLinks(); ++i
) {
328 link
= links
->getLink(i
);
329 out
->drawLink(link
, catalog
);
335 // draw non-link annotations
336 annotList
= new Annots(xref
, annots
.fetch(xref
, &obj
));
338 if (annotList
->getNumAnnots() > 0) {
339 if (globalParams
->getPrintCommands()) {
340 printf("***** Annotations\n");
342 for (i
= 0; i
< annotList
->getNumAnnots(); ++i
) {
343 annotList
->getAnnot(i
)->draw(gfx
);