Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Page.cc

Go to the documentation of this file.
00001 //========================================================================
00002 //
00003 // Page.cc
00004 //
00005 // Copyright 1996-2002 Glyph & Cog, LLC
00006 //
00007 //========================================================================
00008 
00009 #ifdef __GNUC__
00010 #pragma implementation
00011 #endif
00012 
00013 #include <aconf.h>
00014 #include <stddef.h>
00015 #include "Object.h"
00016 #include "Array.h"
00017 #include "Dict.h"
00018 #include "XRef.h"
00019 #include "Link.h"
00020 #include "OutputDev.h"
00021 #ifndef PDF_PARSER_ONLY
00022 #include "Gfx.h"
00023 #include "Annot.h"
00024 #endif
00025 #include "Error.h"
00026 #include "Page.h"
00027 
00028 //------------------------------------------------------------------------
00029 // PageAttrs
00030 //------------------------------------------------------------------------
00031 
00032 PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
00033   Object obj1;
00034   fouble w, h;
00035 
00036   // get old/default values
00037   if (attrs) {
00038     mediaBox = attrs->mediaBox;
00039     cropBox = attrs->cropBox;
00040     haveCropBox = attrs->haveCropBox;
00041     rotate = attrs->rotate;
00042     attrs->resources.copy(&resources);
00043   } else {
00044     // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary
00045     // but some (non-compliant) PDF files don't specify a MediaBox
00046     mediaBox.x1 = 0;
00047     mediaBox.y1 = 0;
00048     mediaBox.x2 = 612;
00049     mediaBox.y2 = 792;
00050     cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0;
00051     haveCropBox = gFalse;
00052     rotate = 0;
00053     resources.initNull();
00054   }
00055 
00056   // media box
00057   readBox(dict, "MediaBox", &mediaBox);
00058 
00059   // crop box
00060   cropBox = mediaBox;
00061   haveCropBox = readBox(dict, "CropBox", &cropBox);
00062 
00063   // if the MediaBox is excessively larger than the CropBox,
00064   // just use the CropBox
00065   limitToCropBox = gFalse;
00066   if (haveCropBox) {
00067     w = 0.25 * (cropBox.x2 - cropBox.x1);
00068     h = 0.25 * (cropBox.y2 - cropBox.y1);
00069     if ((cropBox.x1 - mediaBox.x1) + (mediaBox.x2 - cropBox.x2) > w ||
00070         (cropBox.y1 - mediaBox.y1) + (mediaBox.y2 - cropBox.y2) > h) {
00071       limitToCropBox = gTrue;
00072     }
00073   }
00074 
00075   // other boxes
00076   bleedBox = cropBox;
00077   readBox(dict, "BleedBox", &bleedBox);
00078   trimBox = cropBox;
00079   readBox(dict, "TrimBox", &trimBox);
00080   artBox = cropBox;
00081   readBox(dict, "ArtBox", &artBox);
00082 
00083   // rotate
00084   dict->lookup("Rotate", &obj1);
00085   if (obj1.isInt()) {
00086     rotate = obj1.getInt();
00087   }
00088   obj1.free();
00089   while (rotate < 0) {
00090     rotate += 360;
00091   }
00092   while (rotate >= 360) {
00093     rotate -= 360;
00094   }
00095 
00096   // misc attributes
00097   dict->lookup("LastModified", &lastModified);
00098   dict->lookup("BoxColorInfo", &boxColorInfo);
00099   dict->lookup("Group", &group);
00100   dict->lookup("Metadata", &metadata);
00101   dict->lookup("PieceInfo", &pieceInfo);
00102   dict->lookup("SeparationInfo", &separationInfo);
00103 
00104   // resource dictionary
00105   dict->lookup("Resources", &obj1);
00106   if (obj1.isDict()) {
00107     resources.free();
00108     obj1.copy(&resources);
00109   }
00110   obj1.free();
00111 }
00112 
00113 PageAttrs::~PageAttrs() {
00114   lastModified.free();
00115   boxColorInfo.free();
00116   group.free();
00117   metadata.free();
00118   pieceInfo.free();
00119   separationInfo.free();
00120   resources.free();
00121 }
00122 
00123 GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) {
00124   PDFRectangle tmp;
00125   Object obj1, obj2;
00126   GBool ok;
00127 
00128   dict->lookup(key, &obj1);
00129   if (obj1.isArray() && obj1.arrayGetLength() == 4) {
00130     ok = gTrue;
00131     obj1.arrayGet(0, &obj2);
00132     if (obj2.isNum()) {
00133       tmp.x1 = obj2.getNum();
00134     } else {
00135       ok = gFalse;
00136     }
00137     obj2.free();
00138     obj1.arrayGet(1, &obj2);
00139     if (obj2.isNum()) {
00140       tmp.y1 = obj2.getNum();
00141     } else {
00142       ok = gFalse;
00143     }
00144     obj2.free();
00145     obj1.arrayGet(2, &obj2);
00146     if (obj2.isNum()) {
00147       tmp.x2 = obj2.getNum();
00148     } else {
00149       ok = gFalse;
00150     }
00151     obj2.free();
00152     obj1.arrayGet(3, &obj2);
00153     if (obj2.isNum()) {
00154       tmp.y2 = obj2.getNum();
00155     } else {
00156       ok = gFalse;
00157     }
00158     obj2.free();
00159     if (ok) {
00160       *box = tmp;
00161     }
00162   } else {
00163     ok = gFalse;
00164   }
00165   obj1.free();
00166   return ok;
00167 }
00168 
00169 //------------------------------------------------------------------------
00170 // Page
00171 //------------------------------------------------------------------------
00172 
00173 Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA,
00174            GBool printCommandsA) {
00175 
00176   ok = gTrue;
00177   xref = xrefA;
00178   num = numA;
00179   printCommands = printCommandsA;
00180 
00181   // get attributes
00182   attrs = attrsA;
00183 
00184   // annotations
00185   pageDict->lookupNF("Annots", &annots);
00186   if (!(annots.isRef() || annots.isArray() || annots.isNull())) {
00187     error(-1, "Page annotations object (page %d) is wrong type (%s)",
00188           num, annots.getTypeName());
00189     annots.free();
00190     goto err2;
00191   }
00192 
00193   // contents
00194   pageDict->lookupNF("Contents", &contents);
00195   if (!(contents.isRef() || contents.isArray() ||
00196         contents.isNull())) {
00197     error(-1, "Page contents object (page %d) is wrong type (%s)",
00198           num, contents.getTypeName());
00199     contents.free();
00200     goto err1;
00201   }
00202 
00203   return;
00204 
00205  err2:
00206   annots.initNull();
00207  err1:
00208   contents.initNull();
00209   ok = gFalse;
00210 }
00211 
00212 Page::~Page() {
00213   delete attrs;
00214   annots.free();
00215   contents.free();
00216 }
00217 
00218 void Page::display(OutputDev *out, fouble dpi, int rotate,
00219                    Links *links, Catalog *catalog) {
00220 #ifndef PDF_PARSER_ONLY
00221   PDFRectangle *box, *cropBox;
00222   Gfx *gfx;
00223   Object obj;
00224   Link *link;
00225   int i;
00226   Annots *annotList;
00227 
00228   box = getBox();
00229   cropBox = getCropBox();
00230 
00231   if (printCommands) {
00232     printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
00233            static_cast<double>(box->x1), static_cast<double>(box->y1), static_cast<double>(box->x2), static_cast<double>(box->y2));
00234     if (isCropped()) {
00235       printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
00236              static_cast<double>(cropBox->x1), static_cast<double>(cropBox->y1), static_cast<double>(cropBox->x2), static_cast<double>(cropBox->y2));
00237     }
00238     printf("***** Rotate = %d\n", attrs->getRotate());
00239   }
00240 
00241   rotate += getRotate();
00242   if (rotate >= 360) {
00243     rotate -= 360;
00244   } else if (rotate < 0) {
00245     rotate += 360;
00246   }
00247   gfx = new Gfx(xref, out, num, attrs->getResourceDict(),
00248                 dpi, box, isCropped(), cropBox, rotate, printCommands);
00249   contents.fetch(xref, &obj);
00250   if (!obj.isNull()) {
00251     gfx->display(&obj);
00252   }
00253   obj.free();
00254 
00255   // draw links
00256   if (links) {
00257     for (i = 0; i < links->getNumLinks(); ++i) {
00258       link = links->getLink(i);
00259       out->drawLink(link, catalog);
00260     }
00261     out->dump();
00262   }
00263 
00264   // draw non-link annotations
00265   //~ need to reset CTM ???
00266   annotList = new Annots(xref, annots.fetch(xref, &obj));
00267   obj.free();
00268   if (annotList->getNumAnnots() > 0) {
00269     if (printCommands) {
00270       printf("***** Annotations\n");
00271     }
00272     for (i = 0; i < annotList->getNumAnnots(); ++i) {
00273       annotList->getAnnot(i)->draw(gfx);
00274     }
00275     out->dump();
00276   }
00277   delete annotList;
00278 
00279   delete gfx;
00280 #endif
00281 }

Generated on Sat Nov 5 16:18:16 2005 for OPIE by  doxygen 1.4.2