~ubuntu-branches/ubuntu/precise/ipe/precise

« back to all changes in this revision

Viewing changes to src/xpdflib/pdfdoc.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve M. Robbins
  • Date: 2005-02-24 22:09:16 UTC
  • mfrom: (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050224220916-9vxiiqjz066r5489
Tags: 6.0pre23-2
debian/control: Ipe should depend on exact version of libipe.
Closes: #296771.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//========================================================================
2
 
//
3
 
// PDFDoc.cc
4
 
//
5
 
// Copyright 1996-2002 Glyph & Cog, LLC
6
 
//
7
 
//========================================================================
8
 
 
9
 
#include "aconf.h"
10
 
 
11
 
#ifdef USE_GCC_PRAGMAS
12
 
#pragma implementation
13
 
#endif
14
 
 
15
 
#include <stdio.h>
16
 
#include "ocfile.h"
17
 
#include <stdlib.h>
18
 
#include <stddef.h>
19
 
#include <string.h>
20
 
#include "gstring.h"
21
 
#include "config.h"
22
 
#include "globalparams.h"
23
 
#include "page.h"
24
 
#include "catalog.h"
25
 
#include "stream.h"
26
 
#include "xref.h"
27
 
#include "link.h"
28
 
#include "outputdev.h"
29
 
#include "error.h"
30
 
#include "errorcodes.h"
31
 
#include "lexer.h"
32
 
#include "parser.h"
33
 
#ifndef DISABLE_OUTLINE
34
 
#include "outline.h"
35
 
#endif
36
 
#include "pdfdoc.h"
37
 
 
38
 
//------------------------------------------------------------------------
39
 
 
40
 
#define headerSearchSize 1024   // read this many bytes at beginning of
41
 
                                //   file to look for '%PDF'
42
 
 
43
 
//------------------------------------------------------------------------
44
 
// PDFDoc
45
 
//------------------------------------------------------------------------
46
 
 
47
 
PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
48
 
               GString *userPassword) {
49
 
  Object obj;
50
 
  GString *fileName1, *fileName2;
51
 
 
52
 
  ok = gFalse;
53
 
  errCode = errNone;
54
 
 
55
 
  file = NULL;
56
 
  str = NULL;
57
 
  xref = NULL;
58
 
  catalog = NULL;
59
 
  links = NULL;
60
 
#ifndef DISABLE_OUTLINE
61
 
  outline = NULL;
62
 
#endif
63
 
 
64
 
  fileName = fileNameA;
65
 
  fileName1 = fileName;
66
 
 
67
 
 
68
 
  // try to open file
69
 
  fileName2 = NULL;
70
 
#ifdef VMS
71
 
  if (!(file = ocfopen(fileName1->getCString(), "rb", "ctx=stm"))) {
72
 
    error(-1, "Couldn't open file '%s'", fileName1->getCString());
73
 
    errCode = errOpenFile;
74
 
    return;
75
 
  }
76
 
#else
77
 
  if (!(file = ocfopen(fileName1->getCString(), "rb"))) {
78
 
    fileName2 = fileName->copy();
79
 
    fileName2->lowerCase();
80
 
    if (!(file = ocfopen(fileName2->getCString(), "rb"))) {
81
 
      fileName2->upperCase();
82
 
      if (!(file = ocfopen(fileName2->getCString(), "rb"))) {
83
 
        error(-1, "Couldn't open file '%s'", fileName->getCString());
84
 
        delete fileName2;
85
 
        errCode = errOpenFile;
86
 
        return;
87
 
      }
88
 
    }
89
 
    delete fileName2;
90
 
  }
91
 
#endif
92
 
 
93
 
  // create stream
94
 
  obj.initNull();
95
 
  str = new FileStream(file, 0, gFalse, 0, &obj);
96
 
 
97
 
  ok = setup(ownerPassword, userPassword);
98
 
}
99
 
 
100
 
PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword,
101
 
               GString *userPassword) {
102
 
  ok = gFalse;
103
 
  errCode = errNone;
104
 
  fileName = NULL;
105
 
  file = NULL;
106
 
  str = strA;
107
 
  xref = NULL;
108
 
  catalog = NULL;
109
 
  links = NULL;
110
 
#ifndef DISABLE_OUTLINE
111
 
  outline = NULL;
112
 
#endif
113
 
  ok = setup(ownerPassword, userPassword);
114
 
}
115
 
 
116
 
GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
117
 
  // check header
118
 
  checkHeader();
119
 
 
120
 
  // read xref table
121
 
  xref = new XRef(str, ownerPassword, userPassword);
122
 
  if (!xref->isOk()) {
123
 
    error(-1, "Couldn't read xref table");
124
 
    errCode = xref->getErrorCode();
125
 
    return gFalse;
126
 
  }
127
 
 
128
 
  // read catalog
129
 
  catalog = new Catalog(xref);
130
 
  if (!catalog->isOk()) {
131
 
    error(-1, "Couldn't read page catalog");
132
 
    errCode = errBadCatalog;
133
 
    return gFalse;
134
 
  }
135
 
 
136
 
#ifndef DISABLE_OUTLINE
137
 
  // read outline
138
 
  outline = new Outline(catalog->getOutline(), xref);
139
 
#endif
140
 
 
141
 
  // done
142
 
  return gTrue;
143
 
}
144
 
 
145
 
PDFDoc::~PDFDoc() {
146
 
#ifndef DISABLE_OUTLINE
147
 
  if (outline) {
148
 
    delete outline;
149
 
  }
150
 
#endif
151
 
  if (catalog) {
152
 
    delete catalog;
153
 
  }
154
 
  if (xref) {
155
 
    delete xref;
156
 
  }
157
 
  if (str) {
158
 
    delete str;
159
 
  }
160
 
  if (file) {
161
 
    fclose(file);
162
 
  }
163
 
  if (fileName) {
164
 
    delete fileName;
165
 
  }
166
 
  if (links) {
167
 
    delete links;
168
 
  }
169
 
}
170
 
 
171
 
// Check for a PDF header on this stream.  Skip past some garbage
172
 
// if necessary.
173
 
void PDFDoc::checkHeader() {
174
 
  char hdrBuf[headerSearchSize+1];
175
 
  char *p;
176
 
  int i;
177
 
 
178
 
  pdfVersion = 0;
179
 
  for (i = 0; i < headerSearchSize; ++i) {
180
 
    hdrBuf[i] = str->getChar();
181
 
  }
182
 
  hdrBuf[headerSearchSize] = '\0';
183
 
  for (i = 0; i < headerSearchSize - 5; ++i) {
184
 
    if (!strncmp(&hdrBuf[i], "%PDF-", 5)) {
185
 
      break;
186
 
    }
187
 
  }
188
 
  if (i >= headerSearchSize - 5) {
189
 
    error(-1, "May not be a PDF file (continuing anyway)");
190
 
    return;
191
 
  }
192
 
  str->moveStart(i);
193
 
  p = strtok(&hdrBuf[i+5], " \t\n\r");
194
 
  pdfVersion = atof(p);
195
 
  if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') ||
196
 
      pdfVersion > supportedPDFVersionNum + 0.0001) {
197
 
    error(-1, "PDF version %s -- xpdf supports version %s"
198
 
          " (continuing anyway)", p, supportedPDFVersionStr);
199
 
  }
200
 
}
201
 
 
202
 
void PDFDoc::displayPage(OutputDev *out, int page, double zoom,
203
 
                         int rotate, GBool doLinks,
204
 
                         GBool (*abortCheckCbk)(void *data),
205
 
                         void *abortCheckCbkData) {
206
 
  Page *p;
207
 
 
208
 
  if (globalParams->getPrintCommands()) {
209
 
    printf("***** page %d *****\n", page);
210
 
  }
211
 
  p = catalog->getPage(page);
212
 
  if (doLinks) {
213
 
    if (links) {
214
 
      delete links;
215
 
    }
216
 
    getLinks(p);
217
 
    p->display(out, zoom, rotate, links, catalog,
218
 
               abortCheckCbk, abortCheckCbkData);
219
 
  } else {
220
 
    p->display(out, zoom, rotate, NULL, catalog,
221
 
               abortCheckCbk, abortCheckCbkData);
222
 
  }
223
 
}
224
 
 
225
 
void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
226
 
                          int zoom, int rotate, GBool doLinks,
227
 
                          GBool (*abortCheckCbk)(void *data),
228
 
                          void *abortCheckCbkData) {
229
 
  int page;
230
 
 
231
 
  for (page = firstPage; page <= lastPage; ++page) {
232
 
    displayPage(out, page, zoom, rotate, doLinks,
233
 
                abortCheckCbk, abortCheckCbkData);
234
 
  }
235
 
}
236
 
 
237
 
void PDFDoc::displayPageSlice(OutputDev *out, int page, double zoom,
238
 
                              int rotate, int sliceX, int sliceY,
239
 
                              int sliceW, int sliceH,
240
 
                              GBool (*abortCheckCbk)(void *data),
241
 
                              void *abortCheckCbkData) {
242
 
  Page *p;
243
 
 
244
 
  p = catalog->getPage(page);
245
 
  p->displaySlice(out, zoom, rotate, sliceX, sliceY, sliceW, sliceH,
246
 
                  NULL, catalog, abortCheckCbk, abortCheckCbkData);
247
 
}
248
 
 
249
 
GBool PDFDoc::isLinearized() {
250
 
  Parser *parser;
251
 
  Object obj1, obj2, obj3, obj4, obj5;
252
 
  GBool lin;
253
 
 
254
 
  lin = gFalse;
255
 
  obj1.initNull();
256
 
  parser = new Parser(xref,
257
 
             new Lexer(xref,
258
 
               str->makeSubStream(str->getStart(), gFalse, 0, &obj1)));
259
 
  parser->getObj(&obj1);
260
 
  parser->getObj(&obj2);
261
 
  parser->getObj(&obj3);
262
 
  parser->getObj(&obj4);
263
 
  if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") &&
264
 
      obj4.isDict()) {
265
 
    obj4.dictLookup("Linearized", &obj5);
266
 
    if (obj5.isNum() && obj5.getNum() > 0) {
267
 
      lin = gTrue;
268
 
    }
269
 
    obj5.free();
270
 
  }
271
 
  obj4.free();
272
 
  obj3.free();
273
 
  obj2.free();
274
 
  obj1.free();
275
 
  delete parser;
276
 
  return lin;
277
 
}
278
 
 
279
 
GBool PDFDoc::saveAs(GString *name) {
280
 
  OCFILE *f;
281
 
  int c;
282
 
 
283
 
  if (!(f = ocfopen(name->getCString(), "wb"))) {
284
 
    error(-1, "Couldn't open file '%s'", name->getCString());
285
 
    return gFalse;
286
 
  }
287
 
  str->reset();
288
 
  while ((c = str->getChar()) != EOF) {
289
 
    fputc(c, f);
290
 
  }
291
 
  str->close();
292
 
  fclose(f);
293
 
  return gTrue;
294
 
}
295
 
 
296
 
void PDFDoc::getLinks(Page *page) {
297
 
  Object obj;
298
 
 
299
 
  links = new Links(page->getAnnots(&obj), catalog->getBaseURI());
300
 
  obj.free();
301
 
}