00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <aconf.h>
00010
00011 #ifdef USE_GCC_PRAGMAS
00012 #pragma implementation
00013 #endif
00014
00015 #include <stddef.h>
00016 #include "GlobalParams.h"
00017 #include "Object.h"
00018 #include "Array.h"
00019 #include "Dict.h"
00020 #include "XRef.h"
00021 #include "Link.h"
00022 #include "OutputDev.h"
00023 #ifndef PDF_PARSER_ONLY
00024 #include "Gfx.h"
00025 #include "Annot.h"
00026 #endif
00027 #include "Error.h"
00028 #include "Page.h"
00029
00030
00031
00032
00033
00034 PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
00035 Object obj1;
00036 double w, h;
00037
00038
00039 if (attrs) {
00040 mediaBox = attrs->mediaBox;
00041 cropBox = attrs->cropBox;
00042 haveCropBox = attrs->haveCropBox;
00043 rotate = attrs->rotate;
00044 attrs->resources.copy(&resources);
00045 } else {
00046
00047
00048 mediaBox.x1 = 0;
00049 mediaBox.y1 = 0;
00050 mediaBox.x2 = 612;
00051 mediaBox.y2 = 792;
00052 cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0;
00053 haveCropBox = gFalse;
00054 rotate = 0;
00055 resources.initNull();
00056 }
00057
00058
00059 readBox(dict, "MediaBox", &mediaBox);
00060
00061
00062 cropBox = mediaBox;
00063 haveCropBox = readBox(dict, "CropBox", &cropBox);
00064
00065
00066
00067 limitToCropBox = gFalse;
00068 if (haveCropBox) {
00069 w = 0.25 * (cropBox.x2 - cropBox.x1);
00070 h = 0.25 * (cropBox.y2 - cropBox.y1);
00071 if ((cropBox.x1 - mediaBox.x1) + (mediaBox.x2 - cropBox.x2) > w ||
00072 (cropBox.y1 - mediaBox.y1) + (mediaBox.y2 - cropBox.y2) > h) {
00073 limitToCropBox = gTrue;
00074 }
00075 }
00076
00077
00078 bleedBox = cropBox;
00079 readBox(dict, "BleedBox", &bleedBox);
00080 trimBox = cropBox;
00081 readBox(dict, "TrimBox", &trimBox);
00082 artBox = cropBox;
00083 readBox(dict, "ArtBox", &artBox);
00084
00085
00086 dict->lookup("Rotate", &obj1);
00087 if (obj1.isInt()) {
00088 rotate = obj1.getInt();
00089 }
00090 obj1.free();
00091 while (rotate < 0) {
00092 rotate += 360;
00093 }
00094 while (rotate >= 360) {
00095 rotate -= 360;
00096 }
00097
00098
00099 dict->lookup("LastModified", &lastModified);
00100 dict->lookup("BoxColorInfo", &boxColorInfo);
00101 dict->lookup("Group", &group);
00102 dict->lookup("Metadata", &metadata);
00103 dict->lookup("PieceInfo", &pieceInfo);
00104 dict->lookup("SeparationInfo", &separationInfo);
00105
00106
00107 dict->lookup("Resources", &obj1);
00108 if (obj1.isDict()) {
00109 resources.free();
00110 obj1.copy(&resources);
00111 }
00112 obj1.free();
00113 }
00114
00115 PageAttrs::~PageAttrs() {
00116 lastModified.free();
00117 boxColorInfo.free();
00118 group.free();
00119 metadata.free();
00120 pieceInfo.free();
00121 separationInfo.free();
00122 resources.free();
00123 }
00124
00125 GBool PageAttrs::readBox(Dict *dict, const char *key, PDFRectangle *box) {
00126 PDFRectangle tmp;
00127 Object obj1, obj2;
00128 GBool ok;
00129
00130 dict->lookup(key, &obj1);
00131 if (obj1.isArray() && obj1.arrayGetLength() == 4) {
00132 ok = gTrue;
00133 obj1.arrayGet(0, &obj2);
00134 if (obj2.isNum()) {
00135 tmp.x1 = obj2.getNum();
00136 } else {
00137 ok = gFalse;
00138 }
00139 obj2.free();
00140 obj1.arrayGet(1, &obj2);
00141 if (obj2.isNum()) {
00142 tmp.y1 = obj2.getNum();
00143 } else {
00144 ok = gFalse;
00145 }
00146 obj2.free();
00147 obj1.arrayGet(2, &obj2);
00148 if (obj2.isNum()) {
00149 tmp.x2 = obj2.getNum();
00150 } else {
00151 ok = gFalse;
00152 }
00153 obj2.free();
00154 obj1.arrayGet(3, &obj2);
00155 if (obj2.isNum()) {
00156 tmp.y2 = obj2.getNum();
00157 } else {
00158 ok = gFalse;
00159 }
00160 obj2.free();
00161 if (ok) {
00162 *box = tmp;
00163 }
00164 } else {
00165 ok = gFalse;
00166 }
00167 obj1.free();
00168 return ok;
00169 }
00170
00171
00172
00173
00174
00175 Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA) {
00176 ok = gTrue;
00177 xref = xrefA;
00178 num = numA;
00179
00180
00181 attrs = attrsA;
00182
00183
00184 pageDict->lookupNF("Annots", &annots);
00185 if (!(annots.isRef() || annots.isArray() || annots.isNull())) {
00186 error(-1, "Page annotations object (page %d) is wrong type (%s)",
00187 num, annots.getTypeName());
00188 annots.free();
00189 goto err2;
00190 }
00191
00192
00193 pageDict->lookupNF("Contents", &contents);
00194 if (!(contents.isRef() || contents.isArray() ||
00195 contents.isNull())) {
00196 error(-1, "Page contents object (page %d) is wrong type (%s)",
00197 num, contents.getTypeName());
00198 contents.free();
00199 goto err1;
00200 }
00201
00202 return;
00203
00204 err2:
00205 annots.initNull();
00206 err1:
00207 contents.initNull();
00208 ok = gFalse;
00209 }
00210
00211 Page::~Page() {
00212 delete attrs;
00213 annots.free();
00214 contents.free();
00215 }
00216
00217 void Page::display(OutputDev *out, double dpi, int rotate,
00218 Links *links, Catalog *catalog,
00219 GBool (*abortCheckCbk)(void *data),
00220 void *abortCheckCbkData) {
00221 displaySlice(out, dpi, rotate, -1, -1, -1, -1, links, catalog,
00222 abortCheckCbk, abortCheckCbkData);
00223 }
00224
00225 void Page::displaySlice(OutputDev *out, double dpi, int rotate,
00226 int sliceX, int sliceY, int sliceW, int sliceH,
00227 Links *links, Catalog *catalog,
00228 GBool (*abortCheckCbk)(void *data),
00229 void *abortCheckCbkData) {
00230 #ifndef PDF_PARSER_ONLY
00231 PDFRectangle *mediaBox, *cropBox;
00232 PDFRectangle box;
00233 Gfx *gfx;
00234 Object obj;
00235 Link *link;
00236 Annots *annotList;
00237 double k;
00238 int i;
00239
00240 rotate += getRotate();
00241 if (rotate >= 360) {
00242 rotate -= 360;
00243 } else if (rotate < 0) {
00244 rotate += 360;
00245 }
00246
00247 mediaBox = getBox();
00248 if (sliceW >= 0 && sliceH >= 0) {
00249 k = 72.0 / dpi;
00250 if (rotate == 90) {
00251 if (out->upsideDown()) {
00252 box.x1 = mediaBox->x1 + k * sliceY;
00253 box.x2 = mediaBox->x1 + k * (sliceY + sliceH);
00254 } else {
00255 box.x1 = mediaBox->x2 - k * (sliceY + sliceH);
00256 box.x2 = mediaBox->x2 - k * sliceY;
00257 }
00258 box.y1 = mediaBox->y1 + k * sliceX;
00259 box.y2 = mediaBox->y1 + k * (sliceX + sliceW);
00260 } else if (rotate == 180) {
00261 box.x1 = mediaBox->x2 - k * (sliceX + sliceW);
00262 box.x2 = mediaBox->x2 - k * sliceX;
00263 if (out->upsideDown()) {
00264 box.y1 = mediaBox->y1 + k * sliceY;
00265 box.y2 = mediaBox->y1 + k * (sliceY + sliceH);
00266 } else {
00267 box.y1 = mediaBox->y2 - k * (sliceY + sliceH);
00268 box.y2 = mediaBox->y2 - k * sliceY;
00269 }
00270 } else if (rotate == 270) {
00271 if (out->upsideDown()) {
00272 box.x1 = mediaBox->x2 - k * (sliceY + sliceH);
00273 box.x2 = mediaBox->x2 - k * sliceY;
00274 } else {
00275 box.x1 = mediaBox->x1 + k * sliceY;
00276 box.x2 = mediaBox->x1 + k * (sliceY + sliceH);
00277 }
00278 box.y1 = mediaBox->y2 - k * (sliceX + sliceW);
00279 box.y2 = mediaBox->y2 - k * sliceX;
00280 } else {
00281 box.x1 = mediaBox->x1 + k * sliceX;
00282 box.x2 = mediaBox->x1 + k * (sliceX + sliceW);
00283 if (out->upsideDown()) {
00284 box.y1 = mediaBox->y2 - k * (sliceY + sliceH);
00285 box.y2 = mediaBox->y2 - k * sliceY;
00286 } else {
00287 box.y1 = mediaBox->y1 + k * sliceY;
00288 box.y2 = mediaBox->y1 + k * (sliceY + sliceH);
00289 }
00290 }
00291 } else {
00292 box = *mediaBox;
00293 }
00294 cropBox = getCropBox();
00295
00296 if (globalParams->getPrintCommands()) {
00297 printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
00298 box.x1, box.y1, box.x2, box.y2);
00299 if (isCropped()) {
00300 printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
00301 cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2);
00302 }
00303 printf("***** Rotate = %d\n", attrs->getRotate());
00304 }
00305
00306 gfx = new Gfx(xref, out, num, attrs->getResourceDict(),
00307 dpi, &box, isCropped(), cropBox, rotate,
00308 abortCheckCbk, abortCheckCbkData);
00309 contents.fetch(xref, &obj);
00310 if (!obj.isNull()) {
00311 gfx->display(&obj);
00312 }
00313 obj.free();
00314
00315
00316 if (links) {
00317 for (i = 0; i < links->getNumLinks(); ++i) {
00318 link = links->getLink(i);
00319 out->drawLink(link, catalog);
00320 }
00321 out->dump();
00322 }
00323
00324
00325
00326 annotList = new Annots(xref, annots.fetch(xref, &obj));
00327 obj.free();
00328 if (annotList->getNumAnnots() > 0) {
00329 if (globalParams->getPrintCommands()) {
00330 printf("***** Annotations\n");
00331 }
00332 for (i = 0; i < annotList->getNumAnnots(); ++i) {
00333 annotList->getAnnot(i)->draw(gfx);
00334 }
00335 out->dump();
00336 }
00337 delete annotList;
00338
00339 delete gfx;
00340 #endif
00341 }