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

« back to all changes in this revision

Viewing changes to src/xpdflib/page.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
 
// Page.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 <stddef.h>
16
 
#include "globalparams.h"
17
 
#include "object.h"
18
 
#include "array.h"
19
 
#include "dict.h"
20
 
#include "xref.h"
21
 
#include "link.h"
22
 
#include "outputdev.h"
23
 
#ifndef PDF_PARSER_ONLY
24
 
#include "gfx.h"
25
 
#include "annot.h"
26
 
#endif
27
 
#include "error.h"
28
 
#include "page.h"
29
 
 
30
 
//------------------------------------------------------------------------
31
 
// PageAttrs
32
 
//------------------------------------------------------------------------
33
 
 
34
 
PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) {
35
 
  Object obj1;
36
 
  double w, h;
37
 
 
38
 
  // get old/default values
39
 
  if (attrs) {
40
 
    mediaBox = attrs->mediaBox;
41
 
    cropBox = attrs->cropBox;
42
 
    haveCropBox = attrs->haveCropBox;
43
 
    rotate = attrs->rotate;
44
 
    attrs->resources.copy(&resources);
45
 
  } else {
46
 
    // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary
47
 
    // but some (non-compliant) PDF files don't specify a MediaBox
48
 
    mediaBox.x1 = 0;
49
 
    mediaBox.y1 = 0;
50
 
    mediaBox.x2 = 612;
51
 
    mediaBox.y2 = 792;
52
 
    cropBox.x1 = cropBox.y1 = cropBox.x2 = cropBox.y2 = 0;
53
 
    haveCropBox = gFalse;
54
 
    rotate = 0;
55
 
    resources.initNull();
56
 
  }
57
 
 
58
 
  // media box
59
 
  readBox(dict, "MediaBox", &mediaBox);
60
 
 
61
 
  // crop box
62
 
  cropBox = mediaBox;
63
 
  haveCropBox = readBox(dict, "CropBox", &cropBox);
64
 
 
65
 
  // if the MediaBox is excessively larger than the CropBox,
66
 
  // just use the CropBox
67
 
  limitToCropBox = gFalse;
68
 
  if (haveCropBox) {
69
 
    w = 0.25 * (cropBox.x2 - cropBox.x1);
70
 
    h = 0.25 * (cropBox.y2 - cropBox.y1);
71
 
    if ((cropBox.x1 - mediaBox.x1) + (mediaBox.x2 - cropBox.x2) > w ||
72
 
        (cropBox.y1 - mediaBox.y1) + (mediaBox.y2 - cropBox.y2) > h) {
73
 
      limitToCropBox = gTrue;
74
 
    }
75
 
  }
76
 
 
77
 
  // other boxes
78
 
  bleedBox = cropBox;
79
 
  readBox(dict, "BleedBox", &bleedBox);
80
 
  trimBox = cropBox;
81
 
  readBox(dict, "TrimBox", &trimBox);
82
 
  artBox = cropBox;
83
 
  readBox(dict, "ArtBox", &artBox);
84
 
 
85
 
  // rotate
86
 
  dict->lookup("Rotate", &obj1);
87
 
  if (obj1.isInt()) {
88
 
    rotate = obj1.getInt();
89
 
  }
90
 
  obj1.free();
91
 
  while (rotate < 0) {
92
 
    rotate += 360;
93
 
  }
94
 
  while (rotate >= 360) {
95
 
    rotate -= 360;
96
 
  }
97
 
 
98
 
  // misc attributes
99
 
  dict->lookup("LastModified", &lastModified);
100
 
  dict->lookup("BoxColorInfo", &boxColorInfo);
101
 
  dict->lookup("Group", &group);
102
 
  dict->lookup("Metadata", &metadata);
103
 
  dict->lookup("PieceInfo", &pieceInfo);
104
 
  dict->lookup("SeparationInfo", &separationInfo);
105
 
 
106
 
  // resource dictionary
107
 
  dict->lookup("Resources", &obj1);
108
 
  if (obj1.isDict()) {
109
 
    resources.free();
110
 
    obj1.copy(&resources);
111
 
  }
112
 
  obj1.free();
113
 
}
114
 
 
115
 
PageAttrs::~PageAttrs() {
116
 
  lastModified.free();
117
 
  boxColorInfo.free();
118
 
  group.free();
119
 
  metadata.free();
120
 
  pieceInfo.free();
121
 
  separationInfo.free();
122
 
  resources.free();
123
 
}
124
 
 
125
 
GBool PageAttrs::readBox(Dict *dict, char *key, PDFRectangle *box) {
126
 
  PDFRectangle tmp;
127
 
  Object obj1, obj2;
128
 
  GBool ok;
129
 
 
130
 
  dict->lookup(key, &obj1);
131
 
  if (obj1.isArray() && obj1.arrayGetLength() == 4) {
132
 
    ok = gTrue;
133
 
    obj1.arrayGet(0, &obj2);
134
 
    if (obj2.isNum()) {
135
 
      tmp.x1 = obj2.getNum();
136
 
    } else {
137
 
      ok = gFalse;
138
 
    }
139
 
    obj2.free();
140
 
    obj1.arrayGet(1, &obj2);
141
 
    if (obj2.isNum()) {
142
 
      tmp.y1 = obj2.getNum();
143
 
    } else {
144
 
      ok = gFalse;
145
 
    }
146
 
    obj2.free();
147
 
    obj1.arrayGet(2, &obj2);
148
 
    if (obj2.isNum()) {
149
 
      tmp.x2 = obj2.getNum();
150
 
    } else {
151
 
      ok = gFalse;
152
 
    }
153
 
    obj2.free();
154
 
    obj1.arrayGet(3, &obj2);
155
 
    if (obj2.isNum()) {
156
 
      tmp.y2 = obj2.getNum();
157
 
    } else {
158
 
      ok = gFalse;
159
 
    }
160
 
    obj2.free();
161
 
    if (ok) {
162
 
      *box = tmp;
163
 
    }
164
 
  } else {
165
 
    ok = gFalse;
166
 
  }
167
 
  obj1.free();
168
 
  return ok;
169
 
}
170
 
 
171
 
//------------------------------------------------------------------------
172
 
// Page
173
 
//------------------------------------------------------------------------
174
 
 
175
 
Page::Page(XRef *xrefA, int numA, Dict *pageDict, PageAttrs *attrsA) {
176
 
  ok = gTrue;
177
 
  xref = xrefA;
178
 
  num = numA;
179
 
 
180
 
  // get attributes
181
 
  attrs = attrsA;
182
 
 
183
 
  // annotations
184
 
  pageDict->lookupNF("Annots", &annots);
185
 
  if (!(annots.isRef() || annots.isArray() || annots.isNull())) {
186
 
    error(-1, "Page annotations object (page %d) is wrong type (%s)",
187
 
          num, annots.getTypeName());
188
 
    annots.free();
189
 
    goto err2;
190
 
  }
191
 
 
192
 
  // contents
193
 
  pageDict->lookupNF("Contents", &contents);
194
 
  if (!(contents.isRef() || contents.isArray() ||
195
 
        contents.isNull())) {
196
 
    error(-1, "Page contents object (page %d) is wrong type (%s)",
197
 
          num, contents.getTypeName());
198
 
    contents.free();
199
 
    goto err1;
200
 
  }
201
 
 
202
 
  return;
203
 
 
204
 
 err2:
205
 
  annots.initNull();
206
 
 err1:
207
 
  contents.initNull();
208
 
  ok = gFalse;
209
 
}
210
 
 
211
 
Page::~Page() {
212
 
  delete attrs;
213
 
  annots.free();
214
 
  contents.free();
215
 
}
216
 
 
217
 
void Page::display(OutputDev *out, double dpi, int rotate,
218
 
                   Links *links, Catalog *catalog,
219
 
                   GBool (*abortCheckCbk)(void *data),
220
 
                   void *abortCheckCbkData) {
221
 
  displaySlice(out, dpi, rotate, -1, -1, -1, -1, links, catalog,
222
 
               abortCheckCbk, abortCheckCbkData);
223
 
}
224
 
 
225
 
void Page::displaySlice(OutputDev *out, double dpi, int rotate,
226
 
                        int sliceX, int sliceY, int sliceW, int sliceH,
227
 
                        Links *links, Catalog *catalog,
228
 
                        GBool (*abortCheckCbk)(void *data),
229
 
                        void *abortCheckCbkData) {
230
 
#ifndef PDF_PARSER_ONLY
231
 
  PDFRectangle *mediaBox, *cropBox;
232
 
  PDFRectangle box;
233
 
  Gfx *gfx;
234
 
  Object obj;
235
 
  Link *link;
236
 
  Annots *annotList;
237
 
  double k;
238
 
  int i;
239
 
 
240
 
  rotate += getRotate();
241
 
  if (rotate >= 360) {
242
 
    rotate -= 360;
243
 
  } else if (rotate < 0) {
244
 
    rotate += 360;
245
 
  }
246
 
 
247
 
  mediaBox = getBox();
248
 
  if (sliceW >= 0 && sliceH >= 0) {
249
 
    k = 72.0 / dpi;
250
 
    if (rotate == 90) {
251
 
      if (out->upsideDown()) {
252
 
        box.x1 = mediaBox->x1 + k * sliceY;
253
 
        box.x2 = mediaBox->x1 + k * (sliceY + sliceH);
254
 
      } else {
255
 
        box.x1 = mediaBox->x2 - k * (sliceY + sliceH);
256
 
        box.x2 = mediaBox->x2 - k * sliceY;
257
 
      }
258
 
      box.y1 = mediaBox->y1 + k * sliceX;
259
 
      box.y2 = mediaBox->y1 + k * (sliceX + sliceW);
260
 
    } else if (rotate == 180) {
261
 
      box.x1 = mediaBox->x2 - k * (sliceX + sliceW);
262
 
      box.x2 = mediaBox->x2 - k * sliceX;
263
 
      if (out->upsideDown()) {
264
 
        box.y1 = mediaBox->y1 + k * sliceY;
265
 
        box.y2 = mediaBox->y1 + k * (sliceY + sliceH);
266
 
      } else {
267
 
        box.y1 = mediaBox->y2 - k * (sliceY + sliceH);
268
 
        box.y2 = mediaBox->y2 - k * sliceY;
269
 
      }
270
 
    } else if (rotate == 270) {
271
 
      if (out->upsideDown()) {
272
 
        box.x1 = mediaBox->x2 - k * (sliceY + sliceH);
273
 
        box.x2 = mediaBox->x2 - k * sliceY;
274
 
      } else {
275
 
        box.x1 = mediaBox->x1 + k * sliceY;
276
 
        box.x2 = mediaBox->x1 + k * (sliceY + sliceH);
277
 
      }
278
 
      box.y1 = mediaBox->y2 - k * (sliceX + sliceW);
279
 
      box.y2 = mediaBox->y2 - k * sliceX;
280
 
    } else {
281
 
      box.x1 = mediaBox->x1 + k * sliceX;
282
 
      box.x2 = mediaBox->x1 + k * (sliceX + sliceW);
283
 
      if (out->upsideDown()) {
284
 
        box.y1 = mediaBox->y2 - k * (sliceY + sliceH);
285
 
        box.y2 = mediaBox->y2 - k * sliceY;
286
 
      } else {
287
 
        box.y1 = mediaBox->y1 + k * sliceY;
288
 
        box.y2 = mediaBox->y1 + k * (sliceY + sliceH);
289
 
      }
290
 
    }
291
 
  } else {
292
 
    box = *mediaBox;
293
 
  }
294
 
  cropBox = getCropBox();
295
 
 
296
 
  if (globalParams->getPrintCommands()) {
297
 
    printf("***** MediaBox = ll:%g,%g ur:%g,%g\n",
298
 
           box.x1, box.y1, box.x2, box.y2);
299
 
    if (isCropped()) {
300
 
      printf("***** CropBox = ll:%g,%g ur:%g,%g\n",
301
 
             cropBox->x1, cropBox->y1, cropBox->x2, cropBox->y2);
302
 
    }
303
 
    printf("***** Rotate = %d\n", attrs->getRotate());
304
 
  }
305
 
 
306
 
  gfx = new Gfx(xref, out, num, attrs->getResourceDict(),
307
 
                dpi, &box, isCropped(), cropBox, rotate,
308
 
                abortCheckCbk, abortCheckCbkData);
309
 
  contents.fetch(xref, &obj);
310
 
  if (!obj.isNull()) {
311
 
    gfx->display(&obj);
312
 
  }
313
 
  obj.free();
314
 
 
315
 
  // draw links
316
 
  if (links) {
317
 
    for (i = 0; i < links->getNumLinks(); ++i) {
318
 
      link = links->getLink(i);
319
 
      out->drawLink(link, catalog);
320
 
    }
321
 
    out->dump();
322
 
  }
323
 
 
324
 
  // draw non-link annotations
325
 
  //~ need to reset CTM ???
326
 
  annotList = new Annots(xref, annots.fetch(xref, &obj));
327
 
  obj.free();
328
 
  if (annotList->getNumAnnots() > 0) {
329
 
    if (globalParams->getPrintCommands()) {
330
 
      printf("***** Annotations\n");
331
 
    }
332
 
    for (i = 0; i < annotList->getNumAnnots(); ++i) {
333
 
      annotList->getAnnot(i)->draw(gfx);
334
 
    }
335
 
    out->dump();
336
 
  }
337
 
  delete annotList;
338
 
 
339
 
  delete gfx;
340
 
#endif
341
 
}