1 //========================================================================
5 // Copyright 1996-2002 Glyph & Cog, LLC
7 //========================================================================
10 #pragma implementation
20 #include "OutputDev.h"
21 #ifndef PDF_PARSER_ONLY
28 //------------------------------------------------------------------------
30 //------------------------------------------------------------------------
32 PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
36 // get old/default values
38 mediaBox = attrs->mediaBox;
39 cropBox = attrs->cropBox;
40 haveCropBox = attrs->haveCropBox;
41 rotate = attrs->rotate;
42 attrs->resources.copy(&resources);
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
50 cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0;
57 readBox(dict, "MediaBox", &mediaBox);
61 haveCropBox = readBox(dict, "CropBox", &cropBox);
63 // if the MediaBox is excessively larger than the CropBox,
64 // just use the CropBox
65 limitToCropBox = gFalse;
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;
77 readBox(dict, "BleedBox", &bleedBox);
79 readBox(dict, "TrimBox", &trimBox);
81 readBox(dict, "ArtBox", &artBox);
84 dict->lookup("Rotate", &obj1);
86 rotate = obj1.getInt();
92 while (rotate >= 360) {
97 dict->lookup("LastModified", &lastModified);
98 dict->lookup("BoxColorInfo", &boxColorInfo);
99 dict->lookup("Group", &group);
100 dict->lookup("Metadata", &metadata);
101 dict->lookup("PieceInfo", &pieceInfo);
102 dict->lookup("SeparationInfo", &separationInfo);
104 // resource dictionary
105 dict->lookup("Resources", &obj1);
108 obj1.copy(&resources);
113 PageAttrs::~PageAttrs() {
119 separationInfo.free();
123 GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) {
128 dict->lookup(key, &obj1);
129 if (obj1.isArray() && obj1.arrayGetLength() == 4) {
131 obj1.arrayGet(0, &obj2);
133 tmp.x1 = obj2.getNum();
138 obj1.arrayGet(1, &obj2);
140 tmp.y1 = obj2.getNum();
145 obj1.arrayGet(2, &obj2);
147 tmp.x2 = obj2.getNum();
152 obj1.arrayGet(3, &obj2);
154 tmp.y2 = obj2.getNum();
169 //------------------------------------------------------------------------
171 //------------------------------------------------------------------------
173 Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA,
174 GBool printCommandsA) {
179 printCommands = printCommandsA;
185 pageDict->lookupNF("Annots", &annots);
186 if (!(annots.isRef() || annots.isArray() || annots.isNull())) {
187 error(-1, "Page annotations object (page %d) is wrong type (%s)",
188 num, annots.getTypeName());
194 pageDict->lookupNF("Contents", &contents);
195 if (!(contents.isRef() || contents.isArray() ||
196 contents.isNull())) {
197 error(-1, "Page contents object (page %d) is wrong type (%s)",
198 num, contents.getTypeName());
218 void Page::display(OutputDev *out, double dpi, int rotate,
219 Links *links, Catalog *catalog) {
220 #ifndef PDF_PARSER_ONLY
221 PDFRectangle *box, *cropBox;
229 cropBox = getCropBox();
232 printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
233 box->x1, box->y1, box->x2, box->y2);
235 printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
236 cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2);
238 printf("***** Rotate = %d\n", attrs->getRotate());
241 rotate += getRotate();
244 } else if (rotate < 0) {
247 gfx = new Gfx(xref, out, num, attrs->getResourceDict(),
248 dpi, box, isCropped(), cropBox, rotate, printCommands);
249 contents.fetch(xref, &obj);
257 for (i = 0; i < links->getNumLinks(); ++i) {
258 link = links->getLink(i);
259 out->drawLink(link, catalog);
264 // draw non-link annotations
265 //~ need to reset CTM ???
266 annotList = new Annots(xref, annots.fetch(xref, &obj));
268 if (annotList->getNumAnnots() > 0) {
270 printf("***** Annotations\n");
272 for (i = 0; i < annotList->getNumAnnots(); ++i) {
273 annotList->getAnnot(i)->draw(gfx);