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

« back to all changes in this revision

Viewing changes to filter/pdftopdf/P2PPageTree.cxx

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2012-07-28 11:54:32 UTC
  • mfrom: (1.1.17) (22 sid)
  • mto: This revision was merged to the branch mainline in revision 28.
  • Revision ID: package-import@ubuntu.com-20120728115432-p5fgn9hv6du22cqa
* New upstream release
   - pdftops: Added another workaround for Kyocera printers: Some
     models get very slow on images which request interpolation,
     so now we remove the image interpolation requests by additional
     PostScript code only inserted for Kyocera printers (LP: #1026974).
   - Made the Poppler-based filters pdftopdf and pdftoopvp build with
     both Poppler 0.18.x and 0.20.x (Upstream bug #1055).
   - Fixes according to Coverity scan results (Upstream bug #1054).
   - Switched build system to autotools. This especially fixes several
     build problems in Gentoo. Also build-tested with CUPS 1.6.0b1.
   - Fixes for compatibility with clang/gcc-4.7.
   - textonly: Filter did not work as a pipe with copies=1 (Upstream bug
     #1032).
   - texttopdf: Avoid trimming the results of FcFontSort(), as this may
     miss some reasonable candidates under certain circumstances. BTW,
     fix passing a non-pointer as a pointer to "result" (Closes: #670055).
   - Corrected documentation. The option for the maximum image rendering
     resolution in pdftops is "pdftops-max-image-resolution", not
     "pdftops-max-image-resolution-default".
* debian/patches/fcfontsort-no-trim.patch: Removed, fixed upstream.
* debian/rules: Updated options for ./configure and make for the new autotools
  build system.
* debian/watch: Switched to bz2 upstream packages.
* debian/rules, debian/copyright, debian/cups-filters.docs: Updated for
  renamed documentation files.
* debian/control, debian/libfontembed1.install,
  debian/libfontembed-dev.install: Added new binary packages for libfontembed.
* debian/copyright: Updated for recent file additions, and rearrangement of
  directories.
* debian/control: Added missing build dependency on libpoppler-cpp-dev.
* debian/copyright: Corrections (Closes: #682752).

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
 P2PPageTree.cc
 
27
 pdftopdf page tree
 
28
*/
 
29
 
 
30
#include <config.h>
 
31
#include "goo/gmem.h"
 
32
#include "P2PPageTree.h"
 
33
#include <ctype.h>
 
34
#include <stdlib.h>
 
35
 
 
36
GBool P2PPageTree::checkPageRange(int no, const char *pageSet,
 
37
  const char *pageRanges)
 
38
{
 
39
  const char *range;
 
40
  int lower, upper;
 
41
 
 
42
  if (pageSet != 0) {
 
43
    if (!strcasecmp(pageSet,"even") && (no % 2) == 1) {
 
44
      return gFalse;
 
45
    } else if (!strcasecmp(pageSet, "odd") && (no % 2) == 0) {
 
46
      return gFalse;
 
47
    }
 
48
  }
 
49
 
 
50
  if (pageRanges == 0) {
 
51
    return gTrue;
 
52
  }
 
53
 
 
54
  for (range = pageRanges; *range != '\0';) {
 
55
    if (*range == '-') {
 
56
      lower = 1;
 
57
      range ++;
 
58
      upper = strtol(range, (char **)&range, 10);
 
59
    } else {
 
60
      lower = strtol(range, (char **)&range, 10);
 
61
      if (*range == '-') {
 
62
        range ++;
 
63
        if (!isdigit(*range)) {
 
64
          upper = 65535;
 
65
        } else {
 
66
          upper = strtol(range, (char **)&range, 10);
 
67
        }
 
68
      } else {
 
69
        upper = lower;
 
70
      }
 
71
    }
 
72
    if (no >= lower && no <= upper) {
 
73
      return gTrue;
 
74
    }
 
75
 
 
76
    if (*range == ',') {
 
77
      range++;
 
78
    } else {
 
79
      break;
 
80
    }
 
81
  }
 
82
  return gFalse;
 
83
}
 
84
 
 
85
/* Constructor  */
 
86
P2PPageTree::P2PPageTree(Catalog *orgCatalogA, XRef *xrefA)
 
87
{
 
88
  int i;
 
89
 
 
90
  xref = xrefA;
 
91
  numPages = orgCatalogA->getNumPages();
 
92
  pages = new P2PPage *[numPages];
 
93
  for (i = 0;i < numPages;i++) {
 
94
    pages[i] = new P2PPage(orgCatalogA->getPage(i+1),xref);
 
95
  }
 
96
}
 
97
 
 
98
void P2PPageTree::cleanPages(P2PPage **pagesA, int size)
 
99
{
 
100
  int i;
 
101
 
 
102
  for (i = 0;i < size;i++) {
 
103
    if (pagesA[i] != 0) {
 
104
      delete pagesA[i];
 
105
    }
 
106
  }
 
107
  delete[] pagesA;
 
108
}
 
109
 
 
110
P2PPageTree::~P2PPageTree()
 
111
{
 
112
  cleanPages(pages,numPages);
 
113
}
 
114
 
 
115
void P2PPageTree::outputSelf(P2POutputStream *str, P2PObject **pageObjects,
 
116
  int len)
 
117
{
 
118
  int i;
 
119
 
 
120
  outputBegin(str);
 
121
  str->puts("<< /Type /Pages "
 
122
            "/Kids [ ");
 
123
  for (i = 0;i < len;i++) {
 
124
    P2PXRef::put(pageObjects[i]);
 
125
    pageObjects[i]->outputRef(str);
 
126
    str->putchar('\n');
 
127
  }
 
128
  str->printf(" ] /Count %d >>\n",len);
 
129
  outputEnd(str);
 
130
}
 
131
 
 
132
void P2PPageTree::output(P2POutputStream *str, int copies, GBool collate)
 
133
{
 
134
  int i,j,k;
 
135
  int n = numPages;
 
136
  int len;
 
137
  P2PObject **pageObjects;
 
138
  P2PPage **outPages;
 
139
 
 
140
  if (P2PDoc::options.even && (numPages % 2) != 0) {
 
141
    /* make number of pages even.
 
142
      append empty page to the last */
 
143
    /* only increment allocate size here */
 
144
    n++;
 
145
  }
 
146
  outPages = new P2PPage *[n];
 
147
  for (i = 0;i < numPages;i++) {
 
148
    outPages[i] = pages[i];
 
149
  }
 
150
  if (P2PDoc::options.even && (numPages % 2) != 0) {
 
151
    /* make number of pages even.
 
152
      append a empty page to the last. */
 
153
    /* assumed n >= 2 */
 
154
    /* empty page's mediaSize is same as a preceding page's media Size */
 
155
    outPages[n-1] = new P2PPage(outPages[n-2]->getMediaBox(),xref);
 
156
  }
 
157
  if (P2PDoc::options.reverse) {
 
158
    /* reverse output pages */
 
159
    for (i = 0;i < (n+1)/2;i++) {
 
160
      P2PPage *t;
 
161
 
 
162
      t = outPages[i];
 
163
      outPages[i] = outPages[n-i-1];
 
164
      outPages[n-i-1] = t;
 
165
    }
 
166
  }
 
167
 
 
168
  len = n*copies;
 
169
  pageObjects = new P2PObject * [len];
 
170
 
 
171
  if (collate) {
 
172
    for (i = 0;i < n;i++) {
 
173
      pageObjects[i] = static_cast<P2PObject *>(outPages[i]);
 
174
    }
 
175
    for (i = n;i < len;i++) {
 
176
      pageObjects[i] = new P2PObject();
 
177
    }
 
178
    outputSelf(str,pageObjects,len);
 
179
    for (i = 0;i < n;i++) {
 
180
      outPages[i]->output(str,this);
 
181
      if (P2PDoc::options.pdfPrinter)
 
182
        fprintf(stderr, "PAGE: %d %d\n", i+1, 1);
 
183
    }
 
184
    for (i = 1;i < copies;i++) {
 
185
      k = i*n;
 
186
      for (j = 0;j < n;j++) {
 
187
        outPages[j]->output(str,this,pageObjects[k+j]);
 
188
        if (P2PDoc::options.pdfPrinter)
 
189
          fprintf(stderr, "PAGE: %d %d\n", j+1, 1);
 
190
      }
 
191
    }
 
192
  } else {
 
193
    for (i = 0;i < n;i++) {
 
194
      k = i*copies;
 
195
      pageObjects[k] = static_cast<P2PObject *>(outPages[i]);
 
196
      for (j = 1;j < copies;j++) {
 
197
        pageObjects[k+j] = new P2PObject();
 
198
      }
 
199
    }
 
200
    outputSelf(str,pageObjects,len);
 
201
    for (i = 0;i < n;i++) {
 
202
      k = i*copies;
 
203
      outPages[i]->output(str,this);
 
204
      if (P2PDoc::options.pdfPrinter)
 
205
        fprintf(stderr, "PAGE: %d %d\n", i+1, 1);
 
206
      for (j = 1;j < copies;j++) {
 
207
        outPages[i]->output(str,this,pageObjects[k+j]);
 
208
        if (P2PDoc::options.pdfPrinter)
 
209
          fprintf(stderr, "PAGE: %d %d\n", i+1, 1);
 
210
      }
 
211
    }
 
212
  }
 
213
  delete[] pageObjects;
 
214
  delete[] outPages;
 
215
}
 
216
 
 
217
int P2PPageTree::nup(int n, PDFRectangle *box,
 
218
      unsigned int borderFlag, unsigned int layout,
 
219
      int xpos, int ypos)
 
220
{
 
221
  P2PPage **newPages;
 
222
  int size;
 
223
  int i,j;
 
224
 
 
225
  size = (numPages+(n-1))/n;
 
226
  newPages = new P2PPage *[size];
 
227
  for (i = 0,j = 0;i < numPages;j++, i += n) {
 
228
    int len = numPages - i;
 
229
    int k;
 
230
 
 
231
    if (len > n) {
 
232
      len = n;
 
233
    }
 
234
    /* check original pages */
 
235
    for (k = 0;k < len;k++) {
 
236
      if (pages[i+k]->getNumOrgPages() != 1) {
 
237
        /* nup twice error */
 
238
        return -1;
 
239
      }
 
240
    }
 
241
    newPages[j] = new P2PPage(n,pages+i,len,box,borderFlag,layout,
 
242
      xref,xpos,ypos);
 
243
  }
 
244
  cleanPages(pages,numPages);
 
245
  pages = newPages;
 
246
  numPages = size;
 
247
  return 0;
 
248
}
 
249
 
 
250
void P2PPageTree::select(const char *pageSet, const char *pageRanges)
 
251
{
 
252
  P2PPage **newPages;
 
253
  int i,j;
 
254
 
 
255
  newPages = new P2PPage *[numPages];
 
256
  for (i = 0,j = 0;i < numPages;i++) {
 
257
    if (checkPageRange(i+1, pageSet, pageRanges)) {
 
258
      newPages[j ++] = pages[i];
 
259
    } else {
 
260
      delete pages[i];
 
261
    }
 
262
  }
 
263
  delete pages;
 
264
  pages = newPages;
 
265
  numPages = j;
 
266
}
 
267
 
 
268
void P2PPageTree::fit(PDFRectangle *box, double zoom)
 
269
{
 
270
  int i;
 
271
 
 
272
  for (i = 0;i < numPages;i++) {
 
273
    pages[i]->fit(box,zoom);
 
274
  }
 
275
}
 
276
 
 
277
void P2PPageTree::mirror()
 
278
{
 
279
  int i;
 
280
 
 
281
  for (i = 0;i < numPages;i++) {
 
282
    pages[i]->mirror();
 
283
  }
 
284
}
 
285
 
 
286
void P2PPageTree::rotate(int orientation)
 
287
{
 
288
  int i;
 
289
 
 
290
  for (i = 0;i < numPages;i++) {
 
291
    pages[i]->rotate(orientation);
 
292
  }
 
293
}
 
294
 
 
295
void P2PPageTree::position(PDFRectangle *box, int xpos, int ypos)
 
296
{
 
297
  int i;
 
298
 
 
299
  for (i = 0;i < numPages;i++) {
 
300
    pages[i]->position(box,xpos,ypos);
 
301
  }
 
302
}
 
303
 
 
304
void P2PPageTree::scale(double zoom)
 
305
{
 
306
  int i;
 
307
 
 
308
  for (i = 0;i < numPages;i++) {
 
309
    pages[i]->scale(zoom);
 
310
  }
 
311
}
 
312
 
 
313
void P2PPageTree::autoRotate(PDFRectangle *box)
 
314
{
 
315
  int i;
 
316
 
 
317
  for (i = 0;i < numPages;i++) {
 
318
    pages[i]->autoRotate(box);
 
319
  }
 
320
}
 
321
 
 
322
void P2PPageTree::setMediaBox(PDFRectangle *mediaBoxA)
 
323
{
 
324
  int i;
 
325
 
 
326
  for (i = 0;i < numPages;i++) {
 
327
    pages[i]->setMediaBox(mediaBoxA);
 
328
  }
 
329
}