~ubuntu-branches/ubuntu/quantal/cups-filters/quantal-proposed

« back to all changes in this revision

Viewing changes to filter/pdftopdf.old/P2PPage.cxx

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2012-08-20 14:53:42 UTC
  • mfrom: (2.1.2 experimental)
  • Revision ID: package-import@ubuntu.com-20120820145342-bddzpwqv0klmt84d
Tags: 1.0.22-1
* New upstream release
   - pdftopdf filter replaced by new QPDF-based filter from Tobias
     Hoffmann's Google Summer of Code project. The former Poppler-based
     pdftopdf duplicated a lot of Poppler's code. The old filter is
     still in the package as pdftopdf.old with source code in
     filter/pdftopdf.old. It will be removed in a later release.
   - bannertopdf: Page duplication routine fixed.
   - bannertopdf: Fixed invalid output of a direct stream object.
   - Added most recent contributors to AUTHORS and COPYING files.
* debian/control: Added build dependency on libqpdf-dev.
* debian/copyright: Updated for the addition of the new pdftopdf filter.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
Copyright (c) 2006-2007, BBR Inc.  All rights reserved.
 
4
 
 
5
Permission is hereby granted, free of charge, to any person obtaining
 
6
a copy of this software and associated documentation files (the
 
7
"Software"), to deal in the Software without restriction, including
 
8
without limitation the rights to use, copy, modify, merge, publish,
 
9
distribute, sublicense, and/or sell copies of the Software, and to
 
10
permit persons to whom the Software is furnished to do so, subject to
 
11
the following conditions:
 
12
 
 
13
The above copyright notice and this permission notice shall be included
 
14
in all copies or substantial portions of the Software.
 
15
 
 
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
17
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
18
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
19
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 
20
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 
21
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
22
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
23
 
 
24
*/
 
25
/*
 
26
 P2PPage.cc
 
27
 pdftopdf page
 
28
*/
 
29
 
 
30
#include <config.h>
 
31
#include "goo/gmem.h"
 
32
#include "P2PPage.h"
 
33
#include "P2PPageTree.h"
 
34
#include "P2POutput.h"
 
35
#include "P2PGfx.h"
 
36
#include "P2PDoc.h"
 
37
#include "P2PFont.h"
 
38
 
 
39
#define NUP_MARGIN 3
 
40
#define NUP_PAGE_MARGIN 4
 
41
 
 
42
 
 
43
/* Constructor */
 
44
P2PPage::P2PPage(Page *orgPageA, XRef *xrefA)
 
45
{
 
46
  int rotateTag;
 
47
 
 
48
  numOrgPages = 1;
 
49
  orgPages = new OrgPage [1];
 
50
  orgPages[0].page = orgPageA;
 
51
  fontResource = 0;
 
52
 
 
53
  xref = xrefA;
 
54
  mediaBox = *orgPageA->getMediaBox();
 
55
  cropBox = *orgPageA->getCropBox();
 
56
  haveCropBox = orgPageA->isCropped();
 
57
  bleedBox = *orgPageA->getBleedBox();
 
58
  trimBox = *orgPageA->getTrimBox();
 
59
  artBox = *orgPageA->getArtBox();
 
60
 
 
61
  /* rotate tag */
 
62
  if ((rotateTag = orgPageA->getRotate()) != 0) {
 
63
    /* Note: rotate tag of PDF is clockwise and 
 
64
     *       orientation-requested attrobute of IPP is anti-clockwise
 
65
     */
 
66
    int orientation = 0;
 
67
    switch (rotateTag) {
 
68
    case 90:
 
69
    case -270:
 
70
        orientation = 3;
 
71
        break;
 
72
    case 180:
 
73
    case -180:
 
74
        orientation = 2;
 
75
        break;
 
76
    case 270:
 
77
    case -90:
 
78
        orientation = 1;
 
79
        break;
 
80
    case 0:
 
81
    default:
 
82
        break;
 
83
    }
 
84
    rotate(orientation);
 
85
  }
 
86
 
 
87
  /* when 0, use original resource dictionary of orgPages[0] */
 
88
  resources = 0;
 
89
}
 
90
 
 
91
/* Constructor for a empty page */
 
92
P2PPage::P2PPage(PDFRectangle *mediaBoxA, XRef *xrefA)
 
93
{
 
94
  numOrgPages = 1;
 
95
  orgPages = new OrgPage [1];
 
96
  orgPages[0].page = 0;
 
97
  fontResource = 0;
 
98
 
 
99
  xref = xrefA;
 
100
  if (mediaBoxA != 0) {
 
101
    mediaBox = *mediaBoxA;
 
102
  } else {
 
103
    mediaBox.x2 = mediaBox.y2 = 1;
 
104
  }
 
105
  haveCropBox = gFalse;
 
106
  bleedBox = mediaBox;
 
107
  trimBox = mediaBox;
 
108
  artBox = mediaBox;
 
109
 
 
110
  /* when 0, use original resource dictionary of orgPages[0] */
 
111
  resources = 0;
 
112
}
 
113
 
 
114
void P2PPage::nupCalcLayout(int n, unsigned int layout, PDFRectangle *box,
 
115
  PDFRectangle *rects)
 
116
{
 
117
  double aw = box->x2 - box->x1;
 
118
  double ah = box->y2 - box->y1;
 
119
  int nx, ny;
 
120
  int *nxp, *nyp;
 
121
  double advx, advy, sx, sy, x, y;
 
122
  double w,h;
 
123
  int i,ix,iy;
 
124
 
 
125
  if (aw > ah){
 
126
    /* landscape */
 
127
    nxp = &ny;
 
128
    nyp = &nx;
 
129
  } else {
 
130
    /* portlate */
 
131
    nxp = &nx;
 
132
    nyp = &ny;
 
133
  }
 
134
  /* should be h >= w here */
 
135
  switch (n) {
 
136
  case 2:
 
137
    *nxp = 1;
 
138
    *nyp = 2;
 
139
    break;
 
140
  case 4:
 
141
    *nxp = 2;
 
142
    *nyp = 2;
 
143
    break;
 
144
  case 6:
 
145
    *nxp = 2;
 
146
    *nyp = 3;
 
147
    break;
 
148
  case 8:
 
149
    *nxp = 2;
 
150
    *nyp = 4;
 
151
    break;
 
152
  case 9:
 
153
    *nxp = 3;
 
154
    *nyp = 3;
 
155
    break;
 
156
  default:
 
157
  case 16:
 
158
    *nxp = 4;
 
159
    *nyp = 4;
 
160
    break;
 
161
  }
 
162
  w = (box->x2 - box->x1)/nx;
 
163
  h = (box->y2 - box->y1)/ny;
 
164
  if ((layout & PDFTOPDF_LAYOUT_NEGATEX) != 0) {
 
165
    advx = -w;
 
166
    sx = box->x2 + advx;
 
167
  } else {
 
168
    advx = w;
 
169
    sx = box->x1;
 
170
  }
 
171
  if ((layout & PDFTOPDF_LAYOUT_NEGATEY) != 0) {
 
172
    advy = -h;
 
173
    sy = box->y2 + advy;
 
174
  } else {
 
175
    advy = h;
 
176
    sy = box->y1;
 
177
  }
 
178
  if ((layout & PDFTOPDF_LAYOUT_VERTICAL) != 0) {
 
179
    i = 0;
 
180
    for (x = sx, ix = 0;ix < nx;ix++) {
 
181
      for (y = sy, iy = 0;iy < ny;iy++) {
 
182
        rects[i].x1 = x+NUP_MARGIN;
 
183
        rects[i].x2 = x+w-NUP_MARGIN;
 
184
        rects[i].y1 = y+NUP_MARGIN;
 
185
        rects[i].y2 = y+h-NUP_MARGIN;
 
186
        i++;
 
187
        y += advy;
 
188
      }
 
189
      x += advx;
 
190
    }
 
191
  } else {
 
192
    i = 0;
 
193
    for (y = sy, iy = 0;iy < ny;iy++) {
 
194
      for (x = sx, ix = 0;ix < nx;ix++) {
 
195
        rects[i].x1 = x+NUP_MARGIN;
 
196
        rects[i].x2 = x+w-NUP_MARGIN;
 
197
        rects[i].y1 = y+NUP_MARGIN;
 
198
        rects[i].y2 = y+h-NUP_MARGIN;
 
199
        i++;
 
200
        x += advx;
 
201
      }
 
202
      y += advy;
 
203
    }
 
204
  }
 
205
}
 
206
 
 
207
/* Construct nup page */
 
208
P2PPage::P2PPage(int n, P2PPage **pages, int len, PDFRectangle *box,
 
209
      unsigned int borderFlagA,
 
210
      unsigned int layout, XRef *xrefA, int xpos, int ypos)
 
211
{
 
212
  int i;
 
213
  PDFRectangle rects[16];
 
214
 
 
215
  xref = xrefA;
 
216
  numOrgPages = len;
 
217
  orgPages = new OrgPage [len];
 
218
  mediaBox = *box;
 
219
  cropBox = mediaBox;
 
220
  haveCropBox = gFalse;
 
221
  bleedBox = cropBox;
 
222
  trimBox = cropBox;
 
223
  artBox = cropBox;
 
224
  fontResource = 0;
 
225
 
 
226
  if (n == 8 || n == 6 || n == 2) {
 
227
    /* Rotating is reqiured, layout change is needed.
 
228
       rotating is done in fit method, only change layout here */
 
229
    unsigned int t;
 
230
 
 
231
    t = layout ^ (PDFTOPDF_LAYOUT_NEGATEX | PDFTOPDF_LAYOUT_VERTICAL);
 
232
    /* swap x and y */
 
233
    layout = ((t << 1) & 2) | ((t >> 1) & 1) | (t & 4);
 
234
  }
 
235
  nupCalcLayout(n,layout,&mediaBox,rects);
 
236
  resources = new P2PResources(xref);
 
237
  for (i = 0;i < len;i++) {
 
238
    PDFRectangle rBox;
 
239
 
 
240
    orgPages[i] = pages[i]->orgPages[0]; /* copy */
 
241
    orgPages[i].frame = rects[i];
 
242
    orgPages[i].borderFlag = borderFlagA;
 
243
    /* fixup rect to fit inner rectangle */
 
244
    rects[i].x1 += NUP_PAGE_MARGIN;
 
245
    rects[i].y1 += NUP_PAGE_MARGIN;
 
246
    rects[i].x2 -= NUP_PAGE_MARGIN;
 
247
    rects[i].y2 -= NUP_PAGE_MARGIN;
 
248
 
 
249
    /* do fitting page contents */
 
250
    orgPages[i].fit(&rects[i],&(pages[i]->mediaBox),1.0,&rBox);
 
251
    orgPages[i].position(&rects[i],&rBox,xpos,ypos);
 
252
 
 
253
    /* merge resources */
 
254
    if (pages[i]->resources != 0) {
 
255
      orgPages[i].mappingTable 
 
256
        = resources->merge(pages[i]->resources);
 
257
    } else if (orgPages[i].page != 0) {
 
258
      orgPages[i].mappingTable 
 
259
        = resources->merge(orgPages[i].page->getResourceDict());
 
260
    }
 
261
  }
 
262
}
 
263
 
 
264
P2PPage::~P2PPage()
 
265
{
 
266
  if (fontResource != 0) {
 
267
    delete fontResource;
 
268
    fontResource = 0;
 
269
  }
 
270
  if (resources != 0) {
 
271
    delete resources;
 
272
    resources = 0;
 
273
  }
 
274
  if (orgPages != 0) {
 
275
    delete[] orgPages;
 
276
  }
 
277
}
 
278
 
 
279
void P2PPage::outputPDFRectangle(PDFRectangle *rect, P2POutputStream *str)
 
280
{
 
281
  str->printf("[ %f %f %f %f ]",rect->x1,rect->y1,rect->x2,rect->y2);
 
282
}
 
283
 
 
284
void P2PPage::outputPDFRectangleForPath(PDFRectangle *rect, P2POutputStream *str)
 
285
{
 
286
  double x,y,w,h;
 
287
 
 
288
  if (rect->x1 > rect->x2) {
 
289
    x = rect->x2;
 
290
    w = rect->x1 - rect->x2;
 
291
  } else {
 
292
    x = rect->x1;
 
293
    w = rect->x2 - rect->x1;
 
294
  }
 
295
  if (rect->y1 > rect->y2) {
 
296
    y = rect->y2;
 
297
    h = rect->y1 - rect->y2;
 
298
  } else {
 
299
    y = rect->y1;
 
300
    h = rect->y2 - rect->y1;
 
301
  }
 
302
  str->printf("%f %f %f %f",x,y,w,h);
 
303
}
 
304
 
 
305
void P2PPage::transPDFRectangle(PDFRectangle *rect, P2PMatrix *matA)
 
306
{
 
307
  matA->apply(rect->x1, rect->y1, &(rect->x1), &(rect->y1));
 
308
  matA->apply(rect->x2, rect->y2, &(rect->x2), &(rect->y2));
 
309
}
 
310
 
 
311
void P2PPage::outputSelf(P2POutputStream *str, P2PPageTree *tree,
 
312
  P2PObject *copiedObj)
 
313
{
 
314
  if (copiedObj == 0) {
 
315
    outputBegin(str);
 
316
  } else {
 
317
    copiedObj->outputBegin(str);
 
318
  }
 
319
  str->puts("<< /Type /Page /Parent ");
 
320
  tree->outputRef(str);
 
321
  str->puts("\n/MediaBox ");
 
322
  outputPDFRectangle(&mediaBox,str);
 
323
  if (haveCropBox && !eqPDFRectangle(&mediaBox,&cropBox)) {
 
324
    str->puts("\n/CropBox ");
 
325
    outputPDFRectangle(&cropBox,str);
 
326
  }
 
327
  if (!eqPDFRectangle(&cropBox,&bleedBox)) {
 
328
    str->puts("\n/BleedBox ");
 
329
    outputPDFRectangle(&bleedBox,str);
 
330
  }
 
331
  if (eqPDFRectangle(&trimBox,&artBox)) {
 
332
    str->puts("\n/TrimBox ");
 
333
    outputPDFRectangle(&trimBox,str);
 
334
  } else {
 
335
    str->puts("\n/ArtBox ");
 
336
    outputPDFRectangle(&artBox,str);
 
337
  }
 
338
 
 
339
  if (numOrgPages > 1 || orgPages[0].page != 0) {
 
340
    /* not empty page */
 
341
    P2PXRef::put(&contents);
 
342
    str->puts("\n/Contents ");
 
343
    contents.outputRef(str);
 
344
 
 
345
    str->puts("\n/Resources ");
 
346
    if (resources != 0) {
 
347
      resources->output(str);
 
348
    } else {
 
349
      Dict *dict = orgPages[0].page->getResourceDict();
 
350
 
 
351
      if (dict != 0) {
 
352
        if (fontResource != 0 && fontResource->getNDicts() > 0) {
 
353
          /* replace font resource */
 
354
          const char *p = "Font";
 
355
          P2PObject *objp = fontResource;
 
356
 
 
357
          P2POutput::outputDict(dict,&p,&objp,1,str,xref);
 
358
        } else {
 
359
          P2POutput::outputDict(dict,str,xref);
 
360
        }
 
361
      } else {
 
362
        str->puts("<< >>");
 
363
      }
 
364
    }
 
365
  } else {
 
366
    /* empty page */
 
367
    str->puts("\n/Resources << >>");
 
368
  }
 
369
  str->puts(" >>\n");
 
370
  if (copiedObj == 0) {
 
371
    outputEnd(str);
 
372
  } else {
 
373
    copiedObj->outputEnd(str);
 
374
  }
 
375
}
 
376
 
 
377
void P2PPage::outputContents(P2POutputStream *str)
 
378
{
 
379
  int i;
 
380
  int start;
 
381
  int len;
 
382
  Object lenobj;
 
383
 
 
384
  /* if empty, do nothing */
 
385
  if (orgPages[0].page == 0) return;
 
386
 
 
387
  P2PGfx output(xref,str,fontResource,resources);
 
388
  P2PObj *pobj = new P2PObj();
 
389
 
 
390
  contents.outputBegin(str);
 
391
  str->puts("<< /Length ");
 
392
  P2PXRef::put(pobj);
 
393
  pobj->outputRef(str);
 
394
  if (P2PDoc::options.contentsCompress && str->canDeflate()) {
 
395
    str->puts(" /Filter /FlateDecode ");
 
396
  }
 
397
  str->puts(" >>\n");
 
398
  str->puts("stream\n");
 
399
  start = str->getPosition();
 
400
  if (P2PDoc::options.contentsCompress) str->startDeflate();
 
401
  for (i = 0;i < numOrgPages;i++) {
 
402
    Object contentsObj;
 
403
    GBool save;
 
404
 
 
405
    save = orgPages[i].clipFrame || orgPages[i].trans;
 
406
    if (save) {
 
407
      str->puts("q ");
 
408
    }
 
409
    if (orgPages[i].page->getContents(&contentsObj) != 0
 
410
        && !contentsObj.isNull()) {
 
411
      if (orgPages[i].clipFrame) {
 
412
        outputPDFRectangleForPath(&orgPages[i].frame,str);
 
413
        str->puts(" re W n ");
 
414
      }
 
415
      if (orgPages[i].borderFlag != 0) {
 
416
        PDFRectangle inner = *(orgPages[i].page->getMediaBox());
 
417
        PDFRectangle ident(0,0,1,1);
 
418
        double xs,ys;
 
419
 
 
420
        transPDFRectangle(&ident,&(orgPages[i].mat));
 
421
        xs = ident.x2-ident.x1 > 0 ? 1: -1;
 
422
        ys = ident.y2-ident.y1 > 0 ? 1: -1;
 
423
 
 
424
        str->puts("q ");
 
425
        if ((orgPages[i].borderFlag & PDFTOPDF_BORDERHAIRLINE) != 0) {
 
426
          str->puts("0 w ");
 
427
        }
 
428
        if ((orgPages[i].borderFlag & PDFTOPDF_BORDERDOUBLE) != 0) {
 
429
          PDFRectangle outer = *(orgPages[i].page->getMediaBox());
 
430
 
 
431
          transPDFRectangle(&outer,&(orgPages[i].mat));
 
432
          outer.x1 -= 3*xs;
 
433
          outer.y1 -= 3*ys;
 
434
          outer.x2 += 3*xs;
 
435
          outer.y2 += 3*ys;
 
436
          outputPDFRectangleForPath(&outer,str);
 
437
          str->puts(" re S ");
 
438
        }
 
439
 
 
440
        transPDFRectangle(&inner,&(orgPages[i].mat));
 
441
        inner.x1 -= 1*xs;
 
442
        inner.y1 -= 1*ys;
 
443
        inner.x2 += 1*xs;
 
444
        inner.y2 += 1*ys;
 
445
        outputPDFRectangleForPath(&inner,str);
 
446
        str->puts(" re S Q ");
 
447
      }
 
448
 
 
449
      if (orgPages[i].trans) {
 
450
        orgPages[i].mat.output(str);
 
451
        str->puts(" cm ");
 
452
      }
 
453
 
 
454
      output.outputContents(&contentsObj,orgPages[i].mappingTable,
 
455
        orgPages[i].page->getResourceDict(),&(orgPages[i].mat));
 
456
      contentsObj.free();
 
457
    }
 
458
    if (save) {
 
459
      str->puts(" Q\n");
 
460
    }
 
461
  }
 
462
  if (P2PDoc::options.contentsCompress) str->endDeflate();
 
463
  len = str->getPosition()-start;
 
464
  str->puts("\nendstream\n");
 
465
  contents.outputEnd(str);
 
466
  /* set length object value */
 
467
  lenobj.initInt(len);
 
468
  pobj->setObj(&lenobj);
 
469
  lenobj.free();
 
470
  pobj->output(str,xref);
 
471
}
 
472
 
 
473
void P2PPage::output(P2POutputStream *str, P2PPageTree *tree, P2PObject *copiedObj)
 
474
{
 
475
  if (fontResource != 0) {
 
476
    delete fontResource;
 
477
    fontResource = 0;
 
478
  }
 
479
  if (resources == 0 && orgPages[0].page != 0/* not empty page */) {
 
480
    /* make P2PResource for pattern handling */
 
481
    /* when number-upped, page must have P2PResource already. 
 
482
       so, we handling one page case */
 
483
    resources = new P2PResources(xref);
 
484
    orgPages[0].mappingTable 
 
485
        = resources->merge(orgPages[0].page->getResourceDict());
 
486
  }
 
487
  if (copiedObj == 0) {
 
488
    if (P2PDoc::options.fontEmbedding && orgPages[0].page != 0) {
 
489
      /* only not empty page */
 
490
      fontResource = new P2PFontResource();
 
491
      if (resources != 0) {
 
492
        fontResource->setup(resources,xref);
 
493
      } else {
 
494
        fontResource->setup(orgPages[0].page->getResourceDict(),xref);
 
495
      }
 
496
    }
 
497
  }
 
498
  if (resources != 0) {
 
499
    /* setup pattern dict for translation */
 
500
    resources->setupPattern();
 
501
 
 
502
    resources->setP2PFontResource(fontResource);
 
503
  }
 
504
 
 
505
  outputContents(str);
 
506
  outputSelf(str,tree,copiedObj);
 
507
}
 
508
 
 
509
void P2PPage::fit(PDFRectangle *box, double zoom)
 
510
{
 
511
  PDFRectangle rBox;
 
512
  /* only first orginal page is fitted */
 
513
  orgPages[0].fit(box,&mediaBox,zoom,&rBox);
 
514
 
 
515
  mediaBox = rBox;
 
516
  cropBox = mediaBox;
 
517
  haveCropBox = gFalse;
 
518
  bleedBox = cropBox;
 
519
  trimBox = cropBox;
 
520
  artBox = cropBox;
 
521
 
 
522
}
 
523
 
 
524
void P2PPage::mirror()
 
525
{
 
526
  P2PMatrix mat(-1,0,0,1,mediaBox.x2-mediaBox.x1,0);
 
527
 
 
528
  /* only first orginale page is mirrored */
 
529
  orgPages[0].mat.trans(&mat);
 
530
  orgPages[0].trans = gTrue;
 
531
}
 
532
 
 
533
void P2PPage::rotate(int orientation)
 
534
{
 
535
  PDFRectangle rBox;
 
536
 
 
537
  /* only first orginal page */
 
538
  orgPages[0].rotate(&mediaBox,orientation,&rBox);
 
539
 
 
540
  mediaBox = rBox;
 
541
  cropBox = mediaBox;
 
542
  haveCropBox = gFalse;
 
543
  bleedBox = cropBox;
 
544
  trimBox = cropBox;
 
545
  artBox = cropBox;
 
546
}
 
547
 
 
548
void P2PPage::position(PDFRectangle *box, int xpos, int ypos)
 
549
{
 
550
  /* only first orginal page */
 
551
  orgPages[0].position(box,&mediaBox,xpos,ypos);
 
552
 
 
553
  mediaBox = *box;
 
554
  cropBox = mediaBox;
 
555
  haveCropBox = gFalse;
 
556
  bleedBox = cropBox;
 
557
  trimBox = cropBox;
 
558
  artBox = cropBox;
 
559
}
 
560
 
 
561
void P2PPage::scale(double zoom)
 
562
{
 
563
  PDFRectangle rBox;
 
564
 
 
565
  /* only first orginal page */
 
566
  orgPages[0].scale(&mediaBox,zoom,&rBox);
 
567
 
 
568
  mediaBox = rBox;
 
569
  cropBox = mediaBox;
 
570
  haveCropBox = gFalse;
 
571
  bleedBox = cropBox;
 
572
  trimBox = cropBox;
 
573
  artBox = cropBox;
 
574
}
 
575
 
 
576
void P2PPage::autoRotate(PDFRectangle *box)
 
577
{
 
578
  double mediaWidth = box->x2 - box->x1;
 
579
  if (mediaWidth < 0) mediaWidth = -mediaWidth;
 
580
  double mediaHeight = box->y2 - box->y1;
 
581
  if (mediaHeight < 0) mediaHeight = -mediaHeight;
 
582
  /* only proccess when the page has one original page. */
 
583
  double pageWidth = mediaBox.x2 - mediaBox.x1;
 
584
  if (pageWidth < 0) pageWidth = -pageWidth;
 
585
  double pageHeight = mediaBox.y2 - mediaBox.y1;
 
586
  if (pageHeight < 0) pageHeight = -pageHeight;
 
587
 
 
588
  if ((mediaWidth >= pageWidth && mediaHeight >= pageHeight)
 
589
    || (mediaWidth < pageHeight || mediaHeight < pageWidth)) {
 
590
       /* the page is inside the media or rotated page is not inside */
 
591
      return;
 
592
  }
 
593
  rotate(1);
 
594
  position(box,0,0);
 
595
}
 
596
 
 
597
P2PPage::OrgPage::OrgPage()
 
598
{
 
599
  page = 0;
 
600
  mappingTable = 0;
 
601
  trans = gFalse;
 
602
  borderFlag = 0;
 
603
  clipFrame = gFalse;
 
604
}
 
605
 
 
606
P2PPage::OrgPage::~OrgPage()
 
607
{
 
608
  if (mappingTable != 0) {
 
609
    delete mappingTable;
 
610
  }
 
611
}
 
612
 
 
613
void P2PPage::OrgPage::position(PDFRectangle *box, PDFRectangle *oldBox,
 
614
  int xpos, int ypos)
 
615
{
 
616
  double mx,my;
 
617
 
 
618
  mx = box->x1 - oldBox->x1;
 
619
  my = box->y1 - oldBox->y1;
 
620
  switch (xpos) {
 
621
  default:
 
622
  case 0:
 
623
    /* center */
 
624
    mx += (box->x2-box->x1 - (oldBox->x2-oldBox->x1))/2;
 
625
    break;
 
626
  case -1:
 
627
    /* left */
 
628
    break;
 
629
  case 1:
 
630
    /* right */
 
631
    mx += (box->x2-box->x1 - (oldBox->x2-oldBox->x1));
 
632
    break;
 
633
  }
 
634
  switch (ypos) {
 
635
  default:
 
636
  case 0:
 
637
    /* center */
 
638
    my += (box->y2-box->y1 - (oldBox->y2-oldBox->y1))/2;
 
639
    break;
 
640
  case -1:
 
641
    /* bottom */
 
642
    break;
 
643
  case 1:
 
644
    /* top */
 
645
    my += (box->y2-box->y1 - (oldBox->y2-oldBox->y1));
 
646
    break;
 
647
  }
 
648
  mat.move(mx,my);
 
649
  trans = gTrue;
 
650
}
 
651
 
 
652
void P2PPage::OrgPage::fit(PDFRectangle *box, PDFRectangle *oldBox,
 
653
  double zoom, PDFRectangle *rBox)
 
654
{
 
655
  double w,h,ow,oh;
 
656
  GBool landscape, oLandscape;
 
657
  double scalex;
 
658
  double scaley;
 
659
 
 
660
  w = box->x2-box->x1;
 
661
  if (w < 0) w = -w;
 
662
  h = box->y2-box->y1;
 
663
  if (h < 0) h = -h;
 
664
  ow = oldBox->x2-oldBox->x1;
 
665
  if (ow < 0) ow = -ow;
 
666
  oh = oldBox->y2-oldBox->y1;
 
667
  if (oh < 0) oh = -oh;
 
668
  landscape = (w > h);
 
669
  oLandscape = (ow > oh);
 
670
  if (landscape != oLandscape) {
 
671
    /* rotate */
 
672
    mat.move(-oldBox->x1,-oldBox->y1);
 
673
    mat.rotate(-90);
 
674
    mat.move(0,ow);
 
675
    if (rBox != 0) {
 
676
      rBox->x1 = rBox->y1 = 0;
 
677
      rBox->x2 = oh;
 
678
      rBox->y2 = ow;
 
679
    }
 
680
 
 
681
    scalex = w/oh*zoom;
 
682
    scaley = h/ow*zoom;
 
683
    if (scalex > scaley) {
 
684
      mat.scale(scaley);
 
685
 
 
686
      if (rBox != 0) {
 
687
        rBox->x2 *= scaley;
 
688
        rBox->y2 *= scaley;
 
689
      }
 
690
    } else {
 
691
      mat.scale(scalex);
 
692
 
 
693
      if (rBox != 0) {
 
694
        rBox->x2 *= scalex;
 
695
        rBox->y2 *= scalex;
 
696
      }
 
697
    }
 
698
    mat.move(box->x1,box->y1);
 
699
    if (rBox != 0) {
 
700
      rBox->x1 += box->x1;
 
701
      rBox->x2 += box->x1;
 
702
      rBox->y1 += box->y1;
 
703
      rBox->y2 += box->y1;
 
704
    }
 
705
  } else {
 
706
    double mx, my;
 
707
 
 
708
    scalex = w/ow*zoom;
 
709
    scaley = h/oh*zoom;
 
710
    if (scalex > scaley) {
 
711
      mat.scale(scaley);
 
712
      if (rBox != 0) {
 
713
        rBox->x1 = oldBox->x1*scaley;
 
714
        rBox->y1 = oldBox->y1*scaley;
 
715
        rBox->x2 = oldBox->x2*scaley;
 
716
        rBox->y2 = oldBox->y2*scaley;
 
717
      }
 
718
    } else {
 
719
      mat.scale(scalex);
 
720
      if (rBox != 0) {
 
721
        rBox->x1 = oldBox->x1*scalex;
 
722
        rBox->y1 = oldBox->y1*scalex;
 
723
        rBox->x2 = oldBox->x2*scalex;
 
724
        rBox->y2 = oldBox->y2*scalex;
 
725
      }
 
726
    }
 
727
    mx = -rBox->x1+box->x1;
 
728
    my = -rBox->y1+box->y1;
 
729
    mat.move(mx,my);
 
730
    if (rBox != 0) {
 
731
      rBox->x1 += mx;
 
732
      rBox->x2 += mx;
 
733
      rBox->y1 += my;
 
734
      rBox->y2 += my;
 
735
    }
 
736
  }
 
737
  trans = gTrue;
 
738
}
 
739
 
 
740
void P2PPage::OrgPage::rotate(PDFRectangle *box,
 
741
  int orientation, PDFRectangle *rBox)
 
742
{
 
743
  PDFRectangle nbox;
 
744
  double t;
 
745
 
 
746
  /* move to origin point */
 
747
  mat.move(-box->x1, -box->y1);
 
748
  rBox->x1 = rBox->y1 = 0;
 
749
  rBox->x2 = box->x2-box->x1;
 
750
  rBox->y2 = box->y2-box->y1;
 
751
 
 
752
  switch (orientation) {
 
753
  case 0:
 
754
    /* 0 degree */
 
755
    break;
 
756
  case 1:
 
757
    /* 90 degree */
 
758
    mat.rotate(90);
 
759
    mat.move(rBox->y2,0);
 
760
    t = rBox->y2;
 
761
    rBox->y2 = rBox->x2;
 
762
    rBox->x2 = t;
 
763
    break;
 
764
  case 2:
 
765
    /* 180 degree */
 
766
    mat.rotate(180);
 
767
    mat.move(rBox->x2,rBox->y2);
 
768
    break;
 
769
  case 3:
 
770
    /* -90 degree */
 
771
    mat.rotate(270);
 
772
    mat.move(0,rBox->x2);
 
773
    t = rBox->y2;
 
774
    rBox->y2 = rBox->x2;
 
775
    rBox->x2 = t;
 
776
    break;
 
777
  }
 
778
  trans = gTrue;
 
779
  return;
 
780
}
 
781
 
 
782
void P2PPage::OrgPage::scale(PDFRectangle *box, double zoom, PDFRectangle *rBox)
 
783
{
 
784
  mat.scale(zoom,zoom);
 
785
  rBox->x1 = box->x1*zoom;
 
786
  rBox->y1 = box->y1*zoom;
 
787
  rBox->x2 = box->x2*zoom;
 
788
  rBox->y2 = box->y2*zoom;
 
789
}