]>
git.ipfire.org Git - thirdparty/cups.git/blob - pdftops/Page.cxx
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
31 //------------------------------------------------------------------------
33 //------------------------------------------------------------------------
35 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
)) {
71 readBox(dict
, "BleedBox", &bleedBox
);
73 readBox(dict
, "TrimBox", &trimBox
);
75 readBox(dict
, "ArtBox", &artBox
);
78 dict
->lookup("Rotate", &obj1
);
80 rotate
= obj1
.getInt();
86 while (rotate
>= 360) {
91 dict
->lookup("LastModified", &lastModified
);
92 dict
->lookup("BoxColorInfo", &boxColorInfo
);
93 dict
->lookup("Group", &group
);
94 dict
->lookup("Metadata", &metadata
);
95 dict
->lookup("PieceInfo", &pieceInfo
);
96 dict
->lookup("SeparationInfo", &separationInfo
);
98 // resource dictionary
99 dict
->lookup("Resources", &obj1
);
102 obj1
.copy(&resources
);
107 PageAttrs::~PageAttrs() {
113 separationInfo
.free();
117 GBool
PageAttrs::readBox(Dict
*dict
, char *key
, PDFRectangle
*box
) {
123 dict
->lookup(key
, &obj1
);
124 if (obj1
.isArray() && obj1
.arrayGetLength() == 4) {
126 obj1
.arrayGet(0, &obj2
);
128 tmp
.x1
= obj2
.getNum();
133 obj1
.arrayGet(1, &obj2
);
135 tmp
.y1
= obj2
.getNum();
140 obj1
.arrayGet(2, &obj2
);
142 tmp
.x2
= obj2
.getNum();
147 obj1
.arrayGet(3, &obj2
);
149 tmp
.y2
= obj2
.getNum();
155 if (tmp
.x1
> tmp
.x2
) {
156 t
= tmp
.x1
; tmp
.x1
= tmp
.x2
; tmp
.x2
= t
;
158 if (tmp
.y1
> tmp
.y2
) {
159 t
= tmp
.y1
; tmp
.y1
= tmp
.y2
; tmp
.y2
= t
;
170 //------------------------------------------------------------------------
172 //------------------------------------------------------------------------
174 Page::Page(XRef
*xrefA
, int numA
, Dict
*pageDict
, PageAttrs
*attrsA
) {
183 pageDict
->lookupNF("Annots", &annots
);
184 if (!(annots
.isRef() || annots
.isArray() || annots
.isNull())) {
185 error(-1, "Page annotations object (page %d) is wrong type (%s)",
186 num
, annots
.getTypeName());
192 pageDict
->lookupNF("Contents", &contents
);
193 if (!(contents
.isRef() || contents
.isArray() ||
194 contents
.isNull())) {
195 error(-1, "Page contents object (page %d) is wrong type (%s)",
196 num
, contents
.getTypeName());
216 void Page::display(OutputDev
*out
, double hDPI
, double vDPI
,
217 int rotate
, GBool useMediaBox
, GBool crop
,
218 Links
*links
, Catalog
*catalog
,
219 GBool (*abortCheckCbk
)(void *data
),
220 void *abortCheckCbkData
) {
221 displaySlice(out
, hDPI
, vDPI
, rotate
, useMediaBox
, crop
,
222 -1, -1, -1, -1, links
, catalog
,
223 abortCheckCbk
, abortCheckCbkData
);
226 void Page::displaySlice(OutputDev
*out
, double hDPI
, double vDPI
,
227 int rotate
, GBool useMediaBox
, GBool crop
,
228 int sliceX
, int sliceY
, int sliceW
, int sliceH
,
229 Links
*links
, Catalog
*catalog
,
230 GBool (*abortCheckCbk
)(void *data
),
231 void *abortCheckCbkData
) {
232 #ifndef PDF_PARSER_ONLY
233 PDFRectangle
*mediaBox
, *cropBox
, *baseBox
;
242 rotate
+= getRotate();
245 } else if (rotate
< 0) {
249 mediaBox
= getMediaBox();
250 cropBox
= getCropBox();
251 if (sliceW
>= 0 && sliceH
>= 0) {
252 baseBox
= useMediaBox
? mediaBox
: cropBox
;
256 if (out
->upsideDown()) {
257 box
.x1
= baseBox
->x1
+ ky
* sliceY
;
258 box
.x2
= baseBox
->x1
+ ky
* (sliceY
+ sliceH
);
260 box
.x1
= baseBox
->x2
- ky
* (sliceY
+ sliceH
);
261 box
.x2
= baseBox
->x2
- ky
* sliceY
;
263 box
.y1
= baseBox
->y1
+ kx
* sliceX
;
264 box
.y2
= baseBox
->y1
+ kx
* (sliceX
+ sliceW
);
265 } else if (rotate
== 180) {
266 box
.x1
= baseBox
->x2
- kx
* (sliceX
+ sliceW
);
267 box
.x2
= baseBox
->x2
- kx
* sliceX
;
268 if (out
->upsideDown()) {
269 box
.y1
= baseBox
->y1
+ ky
* sliceY
;
270 box
.y2
= baseBox
->y1
+ ky
* (sliceY
+ sliceH
);
272 box
.y1
= baseBox
->y2
- ky
* (sliceY
+ sliceH
);
273 box
.y2
= baseBox
->y2
- ky
* sliceY
;
275 } else if (rotate
== 270) {
276 if (out
->upsideDown()) {
277 box
.x1
= baseBox
->x2
- ky
* (sliceY
+ sliceH
);
278 box
.x2
= baseBox
->x2
- ky
* sliceY
;
280 box
.x1
= baseBox
->x1
+ ky
* sliceY
;
281 box
.x2
= baseBox
->x1
+ ky
* (sliceY
+ sliceH
);
283 box
.y1
= baseBox
->y2
- kx
* (sliceX
+ sliceW
);
284 box
.y2
= baseBox
->y2
- kx
* sliceX
;
286 box
.x1
= baseBox
->x1
+ kx
* sliceX
;
287 box
.x2
= baseBox
->x1
+ kx
* (sliceX
+ sliceW
);
288 if (out
->upsideDown()) {
289 box
.y1
= baseBox
->y2
- ky
* (sliceY
+ sliceH
);
290 box
.y2
= baseBox
->y2
- ky
* sliceY
;
292 box
.y1
= baseBox
->y1
+ ky
* sliceY
;
293 box
.y2
= baseBox
->y1
+ ky
* (sliceY
+ sliceH
);
296 } else if (useMediaBox
) {
303 if (globalParams
->getPrintCommands()) {
304 printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
305 mediaBox
->x1
, mediaBox
->y1
, mediaBox
->x2
, mediaBox
->y2
);
306 printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
307 cropBox
->x1
, cropBox
->y1
, cropBox
->x2
, cropBox
->y2
);
308 printf("***** Rotate = %d\n", attrs
->getRotate());
311 gfx
= new Gfx(xref
, out
, num
, attrs
->getResourceDict(),
312 hDPI
, vDPI
, &box
, crop
? cropBox
: (PDFRectangle
*)NULL
,
313 rotate
, abortCheckCbk
, abortCheckCbkData
);
314 contents
.fetch(xref
, &obj
);
325 for (i
= 0; i
< links
->getNumLinks(); ++i
) {
326 link
= links
->getLink(i
);
327 out
->drawLink(link
, catalog
);
333 // draw non-link annotations
334 annotList
= new Annots(xref
, catalog
, annots
.fetch(xref
, &obj
));
336 if (annotList
->getNumAnnots() > 0) {
337 if (globalParams
->getPrintCommands()) {
338 printf("***** Annotations\n");
340 for (i
= 0; i
< annotList
->getNumAnnots(); ++i
) {
341 annotList
->getAnnot(i
)->draw(gfx
);
351 void Page::getDefaultCTM(double *ctm
, double hDPI
, double vDPI
,
352 int rotate
, GBool upsideDown
) {
356 rotate
+= getRotate();
359 } else if (rotate
< 0) {
362 state
= new GfxState(hDPI
, vDPI
, getMediaBox(), rotate
, upsideDown
);
363 for (i
= 0; i
< 6; ++i
) {
364 ctm
[i
] = state
->getCTM()[i
];