1 //========================================================================
2 //
3 // Page.h
4 //
5 // Copyright 1996-2003 Glyph & Cog, LLC
6 //
7 //========================================================================
8 
9 //========================================================================
10 //
11 // Modified under the Poppler project - http://poppler.freedesktop.org
12 //
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
15 //
16 // Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
17 // Copyright (C) 2005 Jeff Muizelaar <jeff@infidigm.net>
18 // Copyright (C) 2006 Pino Toscano <pino@kde.org>
19 // Copyright (C) 2006, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
20 // Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
21 // Copyright (C) 2008 Iñigo Martínez <inigomartinez@gmail.com>
22 // Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
23 // Copyright (C) 2012 Albert Astals Cid <aacid@kde.org>
24 // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
25 // Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
26 //
27 // To see a description of the changes please see the Changelog file that
28 // came with your tarball or type make ChangeLog if you are building from git
29 //
30 //========================================================================
31 
32 #ifndef PAGE_H
33 #define PAGE_H
34 
35 #ifdef USE_GCC_PRAGMAS
36 #pragma interface
37 #endif
38 
39 #include "poppler-config.h"
40 #include "Object.h"
41 #include "goo/GooMutex.h"
42 
43 class Dict;
44 class PDFDoc;
45 class XRef;
46 class OutputDev;
47 class Links;
48 class LinkAction;
49 class Annots;
50 class Annot;
51 class Gfx;
52 class FormPageWidgets;
53 class Form;
54 
55 //------------------------------------------------------------------------
56 
57 class PDFRectangle {
58 public:
59   double x1, y1, x2, y2;
60 
PDFRectangle()61   PDFRectangle() { x1 = y1 = x2 = y2 = 0; }
PDFRectangle(double x1A,double y1A,double x2A,double y2A)62   PDFRectangle(double x1A, double y1A, double x2A, double y2A)
63     { x1 = x1A; y1 = y1A; x2 = x2A; y2 = y2A; }
isValid()64   GBool isValid() { return x1 != 0 || y1 != 0 || x2 != 0 || y2 != 0; }
contains(double x,double y)65   GBool contains(double x, double y) { return x1 <= x && x <= x2 && y1 <= y && y <= y2; }
66   void clipTo(PDFRectangle *rect);
67 
68   bool operator==(const PDFRectangle &rect) const { return x1 == rect.x1 && y1 == rect.y1 && x2 == rect.x2 && y2 == rect.y2; }
69 };
70 
71 //------------------------------------------------------------------------
72 // PageAttrs
73 //------------------------------------------------------------------------
74 
75 class PageAttrs {
76 public:
77 
78   // Construct a new PageAttrs object by merging a dictionary
79   // (of type Pages or Page) into another PageAttrs object.  If
80   // <attrs> is NULL, uses defaults.
81   PageAttrs(PageAttrs *attrs, Dict *dict);
82 
83   // Destructor.
84   ~PageAttrs();
85 
86   // Accessors.
getMediaBox()87   PDFRectangle *getMediaBox() { return &mediaBox; }
getCropBox()88   PDFRectangle *getCropBox() { return &cropBox; }
isCropped()89   GBool isCropped() { return haveCropBox; }
getBleedBox()90   PDFRectangle *getBleedBox() { return &bleedBox; }
getTrimBox()91   PDFRectangle *getTrimBox() { return &trimBox; }
getArtBox()92   PDFRectangle *getArtBox() { return &artBox; }
getRotate()93   int getRotate() { return rotate; }
getLastModified()94   GooString *getLastModified()
95     { return lastModified.isString()
96 	? lastModified.getString() : (GooString *)NULL; }
getBoxColorInfo()97   Dict *getBoxColorInfo()
98     { return boxColorInfo.isDict() ? boxColorInfo.getDict() : (Dict *)NULL; }
getGroup()99   Dict *getGroup()
100     { return group.isDict() ? group.getDict() : (Dict *)NULL; }
getMetadata()101   Stream *getMetadata()
102     { return metadata.isStream() ? metadata.getStream() : (Stream *)NULL; }
getPieceInfo()103   Dict *getPieceInfo()
104     { return pieceInfo.isDict() ? pieceInfo.getDict() : (Dict *)NULL; }
getSeparationInfo()105   Dict *getSeparationInfo()
106     { return separationInfo.isDict()
107 	? separationInfo.getDict() : (Dict *)NULL; }
getResourceDict()108   Dict *getResourceDict()
109     { return resources.isDict() ? resources.getDict() : (Dict *)NULL; }
replaceResource(Object obj1)110   void replaceResource(Object obj1)
111   {  resources.free(); obj1.copy(&resources); }
112 
113   // Clip all other boxes to the MediaBox.
114   void clipBoxes();
115 
116 private:
117 
118   GBool readBox(Dict *dict, const char *key, PDFRectangle *box);
119 
120   PDFRectangle mediaBox;
121   PDFRectangle cropBox;
122   GBool haveCropBox;
123   PDFRectangle bleedBox;
124   PDFRectangle trimBox;
125   PDFRectangle artBox;
126   int rotate;
127   Object lastModified;
128   Object boxColorInfo;
129   Object group;
130   Object metadata;
131   Object pieceInfo;
132   Object separationInfo;
133   Object resources;
134 };
135 
136 //------------------------------------------------------------------------
137 // Page
138 //------------------------------------------------------------------------
139 
140 class Page {
141 public:
142 
143   // Constructor.
144   Page(PDFDoc *docA, int numA, Dict *pageDict, Ref pageRefA, PageAttrs *attrsA, Form *form);
145 
146   // Destructor.
147   ~Page();
148 
149   // Is page valid?
isOk()150   GBool isOk() { return ok; }
151 
152   // Get page parameters.
getNum()153   int getNum() { return num; }
getMediaBox()154   PDFRectangle *getMediaBox() { return attrs->getMediaBox(); }
getCropBox()155   PDFRectangle *getCropBox() { return attrs->getCropBox(); }
isCropped()156   GBool isCropped() { return attrs->isCropped(); }
getMediaWidth()157   double getMediaWidth()
158     { return attrs->getMediaBox()->x2 - attrs->getMediaBox()->x1; }
getMediaHeight()159   double getMediaHeight()
160     { return attrs->getMediaBox()->y2 - attrs->getMediaBox()->y1; }
getCropWidth()161   double getCropWidth()
162     { return attrs->getCropBox()->x2 - attrs->getCropBox()->x1; }
getCropHeight()163   double getCropHeight()
164     { return attrs->getCropBox()->y2 - attrs->getCropBox()->y1; }
getBleedBox()165   PDFRectangle *getBleedBox() { return attrs->getBleedBox(); }
getTrimBox()166   PDFRectangle *getTrimBox() { return attrs->getTrimBox(); }
getArtBox()167   PDFRectangle *getArtBox() { return attrs->getArtBox(); }
getRotate()168   int getRotate() { return attrs->getRotate(); }
getLastModified()169   GooString *getLastModified() { return attrs->getLastModified(); }
getBoxColorInfo()170   Dict *getBoxColorInfo() { return attrs->getBoxColorInfo(); }
getGroup()171   Dict *getGroup() { return attrs->getGroup(); }
getMetadata()172   Stream *getMetadata() { return attrs->getMetadata(); }
getPieceInfo()173   Dict *getPieceInfo() { return attrs->getPieceInfo(); }
getSeparationInfo()174   Dict *getSeparationInfo() { return attrs->getSeparationInfo(); }
getDoc()175   PDFDoc *getDoc() { return doc; }
getRef()176   Ref getRef() { return pageRef; }
177 
178   // Get resource dictionary.
179   Dict *getResourceDict();
180   Dict *getResourceDictCopy(XRef *xrefA);
181 
182   // Get annotations array.
183   Object *getAnnots(Object *obj, XRef *xrefA = NULL) { return annotsObj.fetch((xrefA == NULL) ? xref : xrefA, obj); }
184   // Add a new annotation to the page
185   void addAnnot(Annot *annot);
186   // Remove an existing annotation from the page
187   void removeAnnot(Annot *annot);
188 
189   // Return a list of links.
190   Links *getLinks();
191 
192   // Return a list of annots. It will be valid until the page is destroyed
193   Annots *getAnnots(XRef *xrefA = NULL);
194 
195   // Get contents.
getContents(Object * obj)196   Object *getContents(Object *obj) { return contents.fetch(xref, obj); }
197 
198   // Get thumb.
getThumb(Object * obj)199   Object *getThumb(Object *obj) { return thumb.fetch(xref, obj); }
200   GBool loadThumb(unsigned char **data, int *width, int *height, int *rowstride);
201 
202   // Get transition.
getTrans(Object * obj)203   Object *getTrans(Object *obj) { return trans.fetch(xref, obj); }
204 
205   // Get form.
206   FormPageWidgets *getFormWidgets();
207 
208   // Get duration, the maximum length of time, in seconds,
209   // that the page is displayed before the presentation automatically
210   // advances to the next page
getDuration()211   double getDuration() { return duration; }
212 
213   // Get actions
getActions(Object * obj)214   Object *getActions(Object *obj) { return actions.fetch(xref, obj); }
215 
216   enum PageAdditionalActionsType {
217     actionOpenPage,     ///< Performed when opening the page
218     actionClosePage,    ///< Performed when closing the page
219   };
220 
221   LinkAction *getAdditionalAction(PageAdditionalActionsType type);
222 
223   Gfx *createGfx(OutputDev *out, double hDPI, double vDPI,
224 		 int rotate, GBool useMediaBox, GBool crop,
225 		 int sliceX, int sliceY, int sliceW, int sliceH,
226 		 GBool printing,
227 		 GBool (*abortCheckCbk)(void *data),
228 		 void *abortCheckCbkData, XRef *xrefA = NULL);
229 
230   // Display a page.
231   void display(OutputDev *out, double hDPI, double vDPI,
232 	       int rotate, GBool useMediaBox, GBool crop,
233 	       GBool printing,
234 	       GBool (*abortCheckCbk)(void *data) = NULL,
235 	       void *abortCheckCbkData = NULL,
236                GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
237                void *annotDisplayDecideCbkData = NULL,
238                GBool copyXRef = gFalse);
239 
240   // Display part of a page.
241   void displaySlice(OutputDev *out, double hDPI, double vDPI,
242 		    int rotate, GBool useMediaBox, GBool crop,
243 		    int sliceX, int sliceY, int sliceW, int sliceH,
244 		    GBool printing,
245 		    GBool (*abortCheckCbk)(void *data) = NULL,
246 		    void *abortCheckCbkData = NULL,
247                     GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
248                     void *annotDisplayDecideCbkData = NULL,
249                     GBool copyXRef = gFalse);
250 
251   void display(Gfx *gfx);
252 
253   void makeBox(double hDPI, double vDPI, int rotate,
254 	       GBool useMediaBox, GBool upsideDown,
255 	       double sliceX, double sliceY, double sliceW, double sliceH,
256 	       PDFRectangle *box, GBool *crop);
257 
258   void processLinks(OutputDev *out);
259 
260   // Get the page's default CTM.
261   void getDefaultCTM(double *ctm, double hDPI, double vDPI,
262 		     int rotate, GBool useMediaBox, GBool upsideDown);
263 
264 private:
265   // replace xref
266   void replaceXRef(XRef *xrefA);
267 
268   PDFDoc *doc;
269   XRef *xref;			// the xref table for this PDF file
270   Object pageObj;               // page dictionary
271   Ref pageRef;                  // page reference
272   int num;			// page number
273   PageAttrs *attrs;		// page attributes
274   Annots *annots;               // annotations
275   Object annotsObj;		// annotations array
276   Object contents;		// page contents
277   Object thumb;			// page thumbnail
278   Object trans;			// page transition
279   Object actions;		// page additional actions
280   double duration;              // page duration
281   GBool ok;			// true if page is valid
282 #if MULTITHREADED
283   GooMutex mutex;
284 #endif
285 };
286 
287 #endif
288