1 : //========================================================================
2 : //
3 : // PDFDoc.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, 2006, 2008 Brad Hards <bradh@frogmouth.net>
17 : // Copyright (C) 2005, 2009 Albert Astals Cid <aacid@kde.org>
18 : // Copyright (C) 2008 Julien Rebetez <julienr@svn.gnome.org>
19 : // Copyright (C) 2008 Pino Toscano <pino@kde.org>
20 : // Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
21 : // Copyright (C) 2009 Eric Toombs <ewtoombs@uwaterloo.ca>
22 : // Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
23 : // Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
24 : // Copyright (C) 2010 Srinivas Adicherla <srinivas.adicherla@geodesic.com>
25 : // Copyright (C) 2011, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
26 : // Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
27 : // Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
28 : //
29 : // To see a description of the changes please see the Changelog file that
30 : // came with your tarball or type make ChangeLog if you are building from git
31 : //
32 : //========================================================================
33 :
34 : #ifndef PDFDOC_H
35 : #define PDFDOC_H
36 :
37 : #ifdef USE_GCC_PRAGMAS
38 : #pragma interface
39 : #endif
40 :
41 : #include "poppler-config.h"
42 : #include <stdio.h>
43 : #include "goo/GooMutex.h"
44 : #include "XRef.h"
45 : #include "Catalog.h"
46 : #include "Page.h"
47 : #include "Annot.h"
48 : #include "OptionalContent.h"
49 : #include "Stream.h"
50 :
51 : class GooString;
52 : class BaseStream;
53 : class OutputDev;
54 : class Links;
55 : class LinkAction;
56 : class LinkDest;
57 : class Outline;
58 : class Linearization;
59 : class SecurityHandler;
60 : class Hints;
61 :
62 : enum PDFWriteMode {
63 : writeStandard,
64 : writeForceRewrite,
65 : writeForceIncremental
66 : };
67 :
68 : //------------------------------------------------------------------------
69 : // PDFDoc
70 : //------------------------------------------------------------------------
71 :
72 : class PDFDoc {
73 : public:
74 :
75 : PDFDoc(GooString *fileNameA, GooString *ownerPassword = NULL,
76 : GooString *userPassword = NULL, void *guiDataA = NULL);
77 :
78 : #ifdef _WIN32
79 : PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword = NULL,
80 : GooString *userPassword = NULL, void *guiDataA = NULL);
81 : #endif
82 :
83 : PDFDoc(BaseStream *strA, GooString *ownerPassword = NULL,
84 : GooString *userPassword = NULL, void *guiDataA = NULL);
85 : ~PDFDoc();
86 :
87 : static PDFDoc *ErrorPDFDoc(int errorCode, GooString *fileNameA = NULL);
88 :
89 : // Was PDF document successfully opened?
90 149 : GBool isOk() { return ok; }
91 :
92 : // Get the error code (if isOk() returns false).
93 0 : int getErrorCode() { return errCode; }
94 :
95 : // Get the error code returned by fopen() (if getErrorCode() ==
96 : // errOpenFile).
97 : int getFopenErrno() { return fopenErrno; }
98 :
99 : // Get file name.
100 : GooString *getFileName() { return fileName; }
101 : #ifdef _WIN32
102 : wchar_t *getFileNameU() { return fileNameU; }
103 : #endif
104 :
105 : // Get the linearization table.
106 : Linearization *getLinearization();
107 :
108 : // Get the xref table.
109 157 : XRef *getXRef() { return xref; }
110 :
111 : // Get catalog.
112 197 : Catalog *getCatalog() { return catalog; }
113 :
114 : // Get optional content configuration
115 376 : OCGs *getOptContentConfig() { return catalog->getOptContentConfig(); }
116 :
117 : // Get base stream.
118 : BaseStream *getBaseStream() { return str; }
119 :
120 : // Get page parameters.
121 : double getPageMediaWidth(int page)
122 : { return getPage(page) ? getPage(page)->getMediaWidth() : 0.0 ; }
123 : double getPageMediaHeight(int page)
124 : { return getPage(page) ? getPage(page)->getMediaHeight() : 0.0 ; }
125 : double getPageCropWidth(int page)
126 : { return getPage(page) ? getPage(page)->getCropWidth() : 0.0 ; }
127 : double getPageCropHeight(int page)
128 : { return getPage(page) ? getPage(page)->getCropHeight() : 0.0 ; }
129 149 : int getPageRotate(int page)
130 149 : { return getPage(page) ? getPage(page)->getRotate() : 0 ; }
131 :
132 : // Get number of pages.
133 : int getNumPages();
134 :
135 : // Return the contents of the metadata stream, or NULL if there is
136 : // no metadata.
137 : GooString *readMetadata() { return catalog->readMetadata(); }
138 :
139 : // Return the structure tree root object.
140 : Object *getStructTreeRoot() { return catalog->getStructTreeRoot(); }
141 :
142 : // Get page.
143 : Page *getPage(int page);
144 :
145 : // Display a page.
146 : void displayPage(OutputDev *out, int page,
147 : double hDPI, double vDPI, int rotate,
148 : GBool useMediaBox, GBool crop, GBool printing,
149 : GBool (*abortCheckCbk)(void *data) = NULL,
150 : void *abortCheckCbkData = NULL,
151 : GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
152 : void *annotDisplayDecideCbkData = NULL, GBool copyXRef = gFalse);
153 :
154 : // Display a range of pages.
155 : void displayPages(OutputDev *out, int firstPage, int lastPage,
156 : double hDPI, double vDPI, int rotate,
157 : GBool useMediaBox, GBool crop, GBool printing,
158 : GBool (*abortCheckCbk)(void *data) = NULL,
159 : void *abortCheckCbkData = NULL,
160 : GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
161 : void *annotDisplayDecideCbkData = NULL);
162 :
163 : // Display part of a page.
164 : void displayPageSlice(OutputDev *out, int page,
165 : double hDPI, double vDPI, int rotate,
166 : GBool useMediaBox, GBool crop, GBool printing,
167 : int sliceX, int sliceY, int sliceW, int sliceH,
168 : GBool (*abortCheckCbk)(void *data) = NULL,
169 : void *abortCheckCbkData = NULL,
170 : GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL,
171 : void *annotDisplayDecideCbkData = NULL, GBool copyXRef = gFalse);
172 :
173 : // Find a page, given its object ID. Returns page number, or 0 if
174 : // not found.
175 : int findPage(int num, int gen) { return catalog->findPage(num, gen); }
176 :
177 : // Returns the links for the current page, transferring ownership to
178 : // the caller.
179 : Links *getLinks(int page);
180 :
181 : // Find a named destination. Returns the link destination, or
182 : // NULL if <name> is not a destination.
183 : LinkDest *findDest(GooString *name)
184 : { return catalog->findDest(name); }
185 :
186 : // Process the links for a page.
187 : void processLinks(OutputDev *out, int page);
188 :
189 :
190 : #ifndef DISABLE_OUTLINE
191 : // Return the outline object.
192 : Outline *getOutline();
193 : #endif
194 :
195 : // Is the file encrypted?
196 : GBool isEncrypted() { return xref->isEncrypted(); }
197 :
198 : // Check various permissions.
199 : GBool okToPrint(GBool ignoreOwnerPW = gFalse)
200 : { return xref->okToPrint(ignoreOwnerPW); }
201 : GBool okToPrintHighRes(GBool ignoreOwnerPW = gFalse)
202 : { return xref->okToPrintHighRes(ignoreOwnerPW); }
203 : GBool okToChange(GBool ignoreOwnerPW = gFalse)
204 : { return xref->okToChange(ignoreOwnerPW); }
205 : GBool okToCopy(GBool ignoreOwnerPW = gFalse)
206 : { return xref->okToCopy(ignoreOwnerPW); }
207 : GBool okToAddNotes(GBool ignoreOwnerPW = gFalse)
208 : { return xref->okToAddNotes(ignoreOwnerPW); }
209 : GBool okToFillForm(GBool ignoreOwnerPW = gFalse)
210 : { return xref->okToFillForm(ignoreOwnerPW); }
211 : GBool okToAccessibility(GBool ignoreOwnerPW = gFalse)
212 : { return xref->okToAccessibility(ignoreOwnerPW); }
213 : GBool okToAssemble(GBool ignoreOwnerPW = gFalse)
214 : { return xref->okToAssemble(ignoreOwnerPW); }
215 :
216 :
217 : // Is this document linearized?
218 : GBool isLinearized();
219 :
220 : // Return the document's Info dictionary (if any).
221 149 : Object *getDocInfo(Object *obj) { return xref->getDocInfo(obj); }
222 : Object *getDocInfoNF(Object *obj) { return xref->getDocInfoNF(obj); }
223 :
224 : // Return the PDF version specified by the file.
225 : int getPDFMajorVersion() { return pdfMajorVersion; }
226 : int getPDFMinorVersion() { return pdfMinorVersion; }
227 :
228 : //Return the PDF ID in the trailer dictionary (if any).
229 : GBool getID(GooString *permanent_id, GooString *update_id);
230 :
231 : // Save one page with another name.
232 : int savePageAs(GooString *name, int pageNo);
233 : // Save this file with another name.
234 : int saveAs(GooString *name, PDFWriteMode mode=writeStandard);
235 : // Save this file in the given output stream.
236 : int saveAs(OutStream *outStr, PDFWriteMode mode=writeStandard);
237 : // Save this file with another name without saving changes
238 : int saveWithoutChangesAs(GooString *name);
239 : // Save this file in the given output stream without saving changes
240 : int saveWithoutChangesAs(OutStream *outStr);
241 :
242 : // Return a pointer to the GUI (XPDFCore or WinPDFCore object).
243 : void *getGUIData() { return guiData; }
244 :
245 : // rewrite pageDict with MediaBox, CropBox and new page CTM
246 : void replacePageDict(int pageNo, int rotate, PDFRectangle *mediaBox, PDFRectangle *cropBox, Object *pageCTM);
247 : void markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset);
248 : // write all objects used by pageDict to outStr
249 : Guint writePageObjects(OutStream *outStr, XRef *xRef, Guint numOffset, GBool combine = gFalse);
250 : static void writeObject (Object *obj, OutStream* outStr, XRef *xref, Guint numOffset, Guchar *fileKey,
251 : CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen);
252 : static void writeHeader(OutStream *outStr, int major, int minor);
253 :
254 : // Ownership goes to the caller
255 : static Dict *createTrailerDict (int uxrefSize, GBool incrUpdate, Goffset startxRef,
256 : Ref *root, XRef *xRef, const char *fileName, Goffset fileSize);
257 : static void writeXRefTableTrailer (Dict *trailerDict, XRef *uxref, GBool writeAllEntries,
258 : Goffset uxrefOffset, OutStream* outStr, XRef *xRef);
259 : static void writeXRefStreamTrailer (Dict *trailerDict, XRef *uxref, Ref *uxrefStreamRef,
260 : Goffset uxrefOffset, OutStream* outStr, XRef *xRef);
261 :
262 : private:
263 : // insert referenced objects in XRef
264 : void markDictionnary (Dict* dict, XRef *xRef, XRef *countRef, Guint numOffset);
265 : void markObject (Object *obj, XRef *xRef, XRef *countRef, Guint numOffset);
266 : static void writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey,
267 : CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen);
268 :
269 : // Write object header to current file stream and return its offset
270 : static Goffset writeObjectHeader (Ref *ref, OutStream* outStr);
271 : static void writeObjectFooter (OutStream* outStr);
272 :
273 : void writeObject (Object *obj, OutStream* outStr, Guchar *fileKey, CryptAlgorithm encAlgorithm,
274 : int keyLength, int objNum, int objGen)
275 : { writeObject(obj, outStr, getXRef(), 0, fileKey, encAlgorithm, keyLength, objNum, objGen); }
276 : void writeDictionnary (Dict* dict, OutStream* outStr, Guchar *fileKey, CryptAlgorithm encAlgorithm,
277 : int keyLength, int objNum, int objGen)
278 : { writeDictionnary(dict, outStr, getXRef(), 0, fileKey, encAlgorithm, keyLength, objNum, objGen); }
279 : static void writeStream (Stream* str, OutStream* outStr);
280 : static void writeRawStream (Stream* str, OutStream* outStr);
281 : void writeXRefTableTrailer (Goffset uxrefOffset, XRef *uxref, GBool writeAllEntries,
282 : int uxrefSize, OutStream* outStr, GBool incrUpdate);
283 : static void writeString (GooString* s, OutStream* outStr, Guchar *fileKey,
284 : CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen);
285 : void saveIncrementalUpdate (OutStream* outStr);
286 : void saveCompleteRewrite (OutStream* outStr);
287 :
288 : Page *parsePage(int page);
289 :
290 : // Get hints.
291 : Hints *getHints();
292 :
293 : PDFDoc();
294 : void init();
295 : GBool setup(GooString *ownerPassword, GooString *userPassword);
296 : GBool checkFooter();
297 : void checkHeader();
298 : GBool checkEncryption(GooString *ownerPassword, GooString *userPassword);
299 : // Get the offset of the start xref table.
300 : Goffset getStartXRef();
301 : // Get the offset of the entries in the main XRef table of a
302 : // linearized document (0 for non linearized documents).
303 : Goffset getMainXRefEntriesOffset();
304 : long long strToLongLong(char *s);
305 :
306 : GooString *fileName;
307 : #ifdef _WIN32
308 : wchar_t *fileNameU;
309 : #endif
310 : FILE *file;
311 : BaseStream *str;
312 : void *guiData;
313 : int pdfMajorVersion;
314 : int pdfMinorVersion;
315 : Linearization *linearization;
316 : XRef *xref;
317 : SecurityHandler *secHdlr;
318 : Catalog *catalog;
319 : Hints *hints;
320 : #ifndef DISABLE_OUTLINE
321 : Outline *outline;
322 : #endif
323 : Page **pageCache;
324 :
325 : GBool ok;
326 : int errCode;
327 : //If there is an error opening the PDF file with fopen() in the constructor,
328 : //then the POSIX errno will be here.
329 : int fopenErrno;
330 :
331 : Goffset startXRefPos; // offset of last xref table
332 : #if MULTITHREADED
333 : GooMutex mutex;
334 : #endif
335 : };
336 :
337 : #endif
|