]> www.fi.muni.cz Git - evince.git/blob - pdf/xpdf/Page.cc
embryonic PDF viewer as a Bonobo container...
[evince.git] / pdf / xpdf / Page.cc
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"
18 #include "OutputDev.h"
19 #ifndef PDF_PARSER_ONLY
20 #include "Gfx.h"
21 #endif
22 #include "Error.h"
23
24 #include "Params.h"
25 #include "Page.h"
26
27 //------------------------------------------------------------------------
28 // PageAttrs
29 //------------------------------------------------------------------------
30
31 PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
32   Object obj1, obj2;
33   double w, h;
34
35   // get old/default values
36   if (attrs) {
37     x1 = attrs->x1;
38     y1 = attrs->y1;
39     x2 = attrs->x2;
40     y2 = attrs->y2;
41     cropX1 = attrs->cropX1;
42     cropY1 = attrs->cropY1;
43     cropX2 = attrs->cropX2;
44     cropY2 = attrs->cropY2;
45     rotate = attrs->rotate;
46     attrs->resources.copy(&resources);
47   } else {
48     // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary
49     // but some (non-compliant) PDF files don't specify a MediaBox
50     x1 = 0;
51     y1 = 0;
52     x2 = 612;
53     y2 = 792;
54     cropX1 = cropY1 = cropX2 = cropY2 = 0;
55     rotate = 0;
56     resources.initNull();
57   }
58
59   // media box
60   dict->lookup("MediaBox", &obj1);
61   if (obj1.isArray() && obj1.arrayGetLength() == 4) {
62     obj1.arrayGet(0, &obj2);
63     if (obj2.isNum())
64       x1 = obj2.getNum();
65     obj2.free();
66     obj1.arrayGet(1, &obj2);
67     if (obj2.isNum())
68       y1 = obj2.getNum();
69     obj2.free();
70     obj1.arrayGet(2, &obj2);
71     if (obj2.isNum())
72       x2 = obj2.getNum();
73     obj2.free();
74     obj1.arrayGet(3, &obj2);
75     if (obj2.isNum())
76       y2 = obj2.getNum();
77     obj2.free();
78   }
79   obj1.free();
80
81   // crop box
82   dict->lookup("CropBox", &obj1);
83   if (obj1.isArray() && obj1.arrayGetLength() == 4) {
84     obj1.arrayGet(0, &obj2);
85     if (obj2.isNum())
86       cropX1 = obj2.getNum();
87     obj2.free();
88     obj1.arrayGet(1, &obj2);
89     if (obj2.isNum())
90       cropY1 = obj2.getNum();
91     obj2.free();
92     obj1.arrayGet(2, &obj2);
93     if (obj2.isNum())
94       cropX2 = obj2.getNum();
95     obj2.free();
96     obj1.arrayGet(3, &obj2);
97     if (obj2.isNum())
98       cropY2 = obj2.getNum();
99     obj2.free();
100   }
101   obj1.free();
102
103   // if the MediaBox is excessively larger than the CropBox,
104   // just use the CropBox
105   limitToCropBox = gFalse;
106   w = 0.25 * (cropX2 - cropX1);
107   h = 0.25 * (cropY2 - cropY1);
108   if (cropX2 > cropX1 &&
109       (cropX1 - x1 > w || x2 - cropX2 > w ||
110        cropY1 - y1 > h || y2 - cropY2 > h)) {
111     limitToCropBox = gTrue;
112   }
113
114   // rotate
115   dict->lookup("Rotate", &obj1);
116   if (obj1.isInt())
117     rotate = obj1.getInt();
118   obj1.free();
119   while (rotate < 0)
120     rotate += 360;
121   while (rotate >= 360)
122     rotate -= 360;
123
124   // resource dictionary
125   dict->lookup("Resources", &obj1);
126   if (obj1.isDict()) {
127     resources.free();
128     obj1.copy(&resources);
129   }
130   obj1.free();
131 }
132
133 PageAttrs::~PageAttrs() {
134   resources.free();
135 }
136
137 //------------------------------------------------------------------------
138 // Page
139 //------------------------------------------------------------------------
140
141 Page::Page(int num1, Dict *pageDict, PageAttrs *attrs1) {
142
143   ok = gTrue;
144   num = num1;
145
146   // get attributes
147   attrs = attrs1;
148
149   // annotations
150   pageDict->lookupNF("Annots", &annots);
151   if (!(annots.isRef() || annots.isArray() || annots.isNull())) {
152     error(-1, "Page annotations object (page %d) is wrong type (%s)",
153           num, annots.getTypeName());
154     annots.free();
155     goto err2;
156   }
157
158   // contents
159   pageDict->lookupNF("Contents", &contents);
160   if (!(contents.isRef() || contents.isArray() ||
161         contents.isNull())) {
162     error(-1, "Page contents object (page %d) is wrong type (%s)",
163           num, contents.getTypeName());
164     contents.free();
165     goto err1;
166   }
167
168   return;
169
170  err2:
171   annots.initNull();
172  err1:
173   contents.initNull();
174   ok = gFalse;
175 }
176
177 Page::~Page() {
178   delete attrs;
179   annots.free();
180   contents.free();
181 }
182
183 void Page::display(OutputDev *out, int dpi, int rotate) {
184 #ifndef PDF_PARSER_ONLY
185   Gfx *gfx;
186   Object obj;
187
188   if (printCommands) {
189     printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
190            getX1(), getY1(), getX2(), getY2());
191     if (isCropped()) {
192       printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
193              getCropX1(), getCropY1(), getCropX2(), getCropY2());
194     }
195     printf("***** Rotate = %d\n", attrs->getRotate());
196   }
197   rotate += getRotate();
198   if (rotate >= 360)
199     rotate -= 360;
200   else if (rotate < 0)
201     rotate += 360;
202   gfx = new Gfx(out, num, attrs->getResourceDict(),
203                 dpi, getX1(), getY1(), getX2(), getY2(), isCropped(),
204                 getCropX1(), getCropY1(), getCropX2(), getCropY2(), rotate);
205   contents.fetch(&obj);
206   if (!obj.isNull())
207     gfx->display(&obj);
208   obj.free();
209   delete gfx;
210 #endif
211 }