~ubuntu-branches/ubuntu/jaunty/cups/jaunty

« back to all changes in this revision

Viewing changes to debian/local/filters/pdf-filters/pdftopdf/pdftopdf.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt, Till Kamppeter, Martin Pitt
  • Date: 2009-02-15 18:39:03 UTC
  • mfrom: (6.1.30 jaunty)
  • Revision ID: james.westby@ubuntu.com-20090215183903-i0nhvqyqj4vyn52a
Tags: 1.3.9-13
[ Till Kamppeter ]
* debian/local/filters/pdf-filters/filter/imagetopdf.c: Added support for
  the new "fit-to-page" option (new, more intuitive name for "fitplot").
* debian/filters/pstopdf: Only apply paper size if the "fitplot" or the
  "fit-to-page" option is set.
* debian/local/filters/cpdftocps: Only the last digit of the number of
  copies was used (LP: #309314).
* debian/local/filters/pdf-filters/pdftopdf/pdftopdf.cxx: Do not preceed the
  PDF output with a newline (LP: #303691). Only impose the page size from
  the PPD file to all pages if the "fitplot" or the "fit-to-page" option is 
  set. This prevented from automatic paper tray switching to the correct paper
  sizes when a multiple-page-size document is printed (partial fix for
  LP: #310575).
* debian/patches/pdftops-cups-1.4.dpatch: Updated from CUPS 1.4 SVN. Contains
  fixes for multiple-page-size document printing (partial fix for
  LP: #310575).
* debian/patches/pdftops-dont_fail_on_cancel.dpatch: Removed, should be
  fixed in the new upstream version of pdftops.

[ Martin Pitt ]
* debian/patches/pdftops-cups-1.4.dpatch: Add definition of
  HAVE_PDFTOPS and CUPS_PDFTOPS, so that the filter actually gets
  again built with pdftops support. (Fixes Till's change from above).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2006-2007, BBR Inc.  All rights reserved.
 
3
 
 
4
Permission is hereby granted, free of charge, to any person obtaining
 
5
a copy of this software and associated documentation files (the
 
6
"Software"), to deal in the Software without restriction, including
 
7
without limitation the rights to use, copy, modify, merge, publish,
 
8
distribute, sublicense, and/or sell copies of the Software, and to
 
9
permit persons to whom the Software is furnished to do so, subject to
 
10
the following conditions:
 
11
 
 
12
The above copyright notice and this permission notice shall be included
 
13
in all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
16
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
18
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 
19
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 
20
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
21
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
22
 
 
23
*/
 
24
/*
 
25
 pdftopdf.cc
 
26
 pdf to pdf filter
 
27
*/
 
28
 
 
29
#include <config.h>
 
30
#include <stdio.h>
 
31
#include <stdlib.h>
 
32
#include "goo/GooString.h"
 
33
#include "goo/gmem.h"
 
34
#include "Object.h"
 
35
#include "Stream.h"
 
36
#include "PDFDoc.h"
 
37
#include "P2PDoc.h"
 
38
#include "P2POutputStream.h"
 
39
#include <cups/cups.h>
 
40
#include <stdarg.h>
 
41
#include "Error.h"
 
42
#include "GlobalParams.h"
 
43
#include "PDFFTrueTypeFont.h"
 
44
 
 
45
namespace {
 
46
  int exitCode = 0;
 
47
  GBool fitplot = gFalse;
 
48
  GBool mirror = gFalse;
 
49
  int numberUp = 1;
 
50
  unsigned int numberUpLayout = PDFTOPDF_LAYOUT_LRTB;
 
51
  unsigned int pageBorder = PDFTOPDF_BORDERNONE;
 
52
  double pageLeft = 18.0;
 
53
  double pageRight = 594.0;
 
54
  double pageBottom = 36.0;
 
55
  double pageTop = 756.0;
 
56
  double pageWidth = 612.0;
 
57
  double pageLength = 792.0;
 
58
  GBool emitJCL = gTrue;
 
59
  ppd_file_t *ppd = 0;
 
60
  int xposition = 0;
 
61
  int yposition = 0;
 
62
  GBool position = gFalse;
 
63
  int orientation = 0;
 
64
  double scaling = 1.0;
 
65
  double naturalScaling = 1.0;
 
66
  int deviceCopies = 1;
 
67
  GBool deviceCollate = gFalse;
 
68
  GBool deviceReverse = gFalse;
 
69
  GBool autoRotate = gTrue;
 
70
  GBool forcePageSize = gFalse;
 
71
};
 
72
 
 
73
void CDECL myErrorFun(int pos, char *msg, va_list args)
 
74
{
 
75
  if (pos >= 0) {
 
76
    fprintf(stderr, "ERROR (%d): ", pos);
 
77
  } else {
 
78
    fprintf(stderr, "ERROR: ");
 
79
  }
 
80
  vfprintf(stderr, msg, args);
 
81
  fprintf(stderr, "\n");
 
82
  fflush(stderr);
 
83
}
 
84
 
 
85
GBool checkFeature(const char *feature, int num_options, cups_option_t *options)
 
86
{
 
87
  const char *val;
 
88
  ppd_attr_t *attr;
 
89
 
 
90
  return ((val = cupsGetOption(feature,num_options,options)) != 0 &&
 
91
             (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
 
92
               !strcasecmp(val, "yes"))) ||
 
93
         ((attr = ppdFindAttr(ppd,feature,0)) != 0 &&
 
94
             (!strcasecmp(attr->value, "true")
 
95
               || !strcasecmp(attr->value, "on") ||
 
96
               !strcasecmp(attr->value, "yes")));
 
97
}
 
98
 
 
99
void emitJCLOptions(FILE *fp, int copies)
 
100
{
 
101
  int section;
 
102
  ppd_choice_t **choices;
 
103
  int i;
 
104
  char buf[1024];
 
105
  ppd_attr_t *attr;
 
106
  int pdftoopvp = 0;
 
107
  int datawritten = 0;
 
108
 
 
109
  if (ppd == 0) return;
 
110
  if ((attr = ppdFindAttr(ppd,"pdftopdfJCLBegin",NULL)) != NULL) {
 
111
    int n = strlen(attr->value);
 
112
    pdftoopvp = 1;
 
113
    for (i = 0;i < n;i++) {
 
114
        if (attr->value[i] == '\r' || attr->value[i] == '\n') {
 
115
            /* skip new line */
 
116
            continue;
 
117
        }
 
118
        fputc(attr->value[i],fp);
 
119
        datawritten = 1;
 
120
    }
 
121
  }
 
122
         
 
123
  snprintf(buf,sizeof(buf),"%d",copies);
 
124
  if (ppdFindOption(ppd,"Copies") != NULL) {
 
125
    ppdMarkOption(ppd,"Copies",buf);
 
126
  } else {
 
127
    if ((attr = ppdFindAttr(ppd,"pdftopdfJCLCopies",buf)) != NULL) {
 
128
      fputs(attr->value,fp);
 
129
      datawritten = 1;
 
130
    } else if (pdftoopvp) {
 
131
      fprintf(fp,"Copies=%d;",copies);
 
132
      datawritten = 1;
 
133
    }
 
134
  }
 
135
  for (section = (int)PPD_ORDER_ANY;
 
136
      section <= (int)PPD_ORDER_PROLOG;section++) {
 
137
    int n;
 
138
 
 
139
    n = ppdCollect(ppd,(ppd_section_t)section,&choices);
 
140
    for (i = 0;i < n;i++) {
 
141
      snprintf(buf,sizeof(buf),"pdftopdfJCL%s",
 
142
        ((ppd_option_t *)(choices[i]->option))->keyword);
 
143
      if ((attr = ppdFindAttr(ppd,buf,choices[i]->choice)) != NULL) {
 
144
        fputs(attr->value,fp);
 
145
        datawritten = 1;
 
146
      } else if (pdftoopvp) {
 
147
        fprintf(fp,"%s=%s;",
 
148
          ((ppd_option_t *)(choices[i]->option))->keyword,
 
149
          choices[i]->choice);
 
150
        datawritten = 1;
 
151
      }
 
152
    }
 
153
  }
 
154
  if (datawritten) fputc('\n',fp);
 
155
}
 
156
 
 
157
void parseOpts(int argc, char **argv)
 
158
{
 
159
  int num_options;
 
160
  cups_option_t *options;
 
161
  const char *val;
 
162
  ppd_attr_t *attr;
 
163
  ppd_choice_t *choice;
 
164
  ppd_size_t *pagesize;
 
165
  int intval;
 
166
 
 
167
  if (argc < 6 || argc > 7) {
 
168
    error(-1,const_cast<char *>("%s job-id user title copies options [file]"),
 
169
      argv[0]);
 
170
    exit(1);
 
171
  }
 
172
  P2PDoc::options.jobId = atoi(argv[1]);
 
173
  P2PDoc::options.user = argv[2];
 
174
  P2PDoc::options.title = argv[3];
 
175
  P2PDoc::options.copies = atoi(argv[4]);
 
176
 
 
177
  ppd = ppdOpenFile(getenv("PPD"));
 
178
  ppdMarkDefaults(ppd);
 
179
  options = NULL;
 
180
  num_options = cupsParseOptions(argv[5],0,&options);
 
181
  cupsMarkOptions(ppd,num_options,options);
 
182
  if (P2PDoc::options.copies == 1
 
183
     && (choice = ppdFindMarkedChoice(ppd,"Copies")) != NULL) {
 
184
    P2PDoc::options.copies = atoi(choice->choice);
 
185
  }
 
186
  if (P2PDoc::options.copies == 0) P2PDoc::options.copies = 1;
 
187
  if ((val = cupsGetOption("fitplot", num_options, options)) == NULL)
 
188
    val = cupsGetOption("fit-to-page", num_options, options);
 
189
  if (val && strcasecmp(val, "no") && strcasecmp(val, "off") &&
 
190
      strcasecmp(val, "false"))
 
191
    fitplot = gTrue;
 
192
  if ((pagesize = ppdPageSize(ppd,0)) != 0) {
 
193
    pageWidth = pagesize->width;
 
194
    pageLength = pagesize->length;
 
195
    pageTop = pagesize->top;
 
196
    pageBottom = pagesize->bottom;
 
197
    pageLeft = pagesize->left;
 
198
    pageRight = pagesize->right;
 
199
    forcePageSize = fitplot;
 
200
  }
 
201
  if ((val = cupsGetOption("landscape",num_options,options)) != 0) {
 
202
    if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 &&
 
203
        strcasecmp(val, "false") != 0) {
 
204
      if (ppd && ppd->landscape > 0) {
 
205
        orientation = 1;
 
206
      } else {
 
207
        orientation = 3;
 
208
      }
 
209
    }
 
210
  } else if ((val =
 
211
     cupsGetOption("orientation-requested",num_options,options)) != 0) {
 
212
   /*
 
213
    * Map IPP orientation values to 0 to 3:
 
214
    *
 
215
    *   3 = 0 degrees   = 0
 
216
    *   4 = 90 degrees  = 1
 
217
    *   5 = -90 degrees = 3
 
218
    *   6 = 180 degrees = 2
 
219
    */
 
220
 
 
221
    orientation = atoi(val) - 3;
 
222
    if (orientation >= 2) {
 
223
      orientation ^= 1;
 
224
    }
 
225
  }
 
226
  if ((val = cupsGetOption("page-left",num_options,options)) != 0) {
 
227
    switch (orientation & 3) {
 
228
      case 0 :
 
229
          pageLeft = (float)atof(val);
 
230
          break;
 
231
      case 1 :
 
232
          pageBottom = (float)atof(val);
 
233
          break;
 
234
      case 2 :
 
235
          pageRight = pageWidth - (float)atof(val);
 
236
          break;
 
237
      case 3 :
 
238
          pageTop = pageLength - (float)atof(val);
 
239
          break;
 
240
    }
 
241
  }
 
242
  if ((val = cupsGetOption("page-right",num_options,options)) != 0) {
 
243
    switch (orientation & 3) {
 
244
      case 0 :
 
245
          pageRight = pageWidth - (float)atof(val);
 
246
          break;
 
247
      case 1 :
 
248
          pageTop = pageLength - (float)atof(val);
 
249
          break;
 
250
      case 2 :
 
251
          pageLeft = (float)atof(val);
 
252
          break;
 
253
      case 3 :
 
254
          pageBottom = (float)atof(val);
 
255
          break;
 
256
    }
 
257
  }
 
258
  if ((val = cupsGetOption("page-bottom",num_options,options)) != 0) {
 
259
    switch (orientation & 3) {
 
260
      case 0 :
 
261
          pageBottom = (float)atof(val);
 
262
          break;
 
263
      case 1 :
 
264
          pageLeft = (float)atof(val);
 
265
          break;
 
266
      case 2 :
 
267
          pageTop = pageLength - (float)atof(val);
 
268
          break;
 
269
      case 3 :
 
270
          pageRight = pageWidth - (float)atof(val);
 
271
          break;
 
272
    }
 
273
  }
 
274
  if ((val = cupsGetOption("page-top",num_options,options)) != 0) {
 
275
    switch (orientation & 3) {
 
276
      case 0 :
 
277
          pageTop = pageLength - (float)atof(val);
 
278
          break;
 
279
      case 1 :
 
280
          pageRight = pageWidth - (float)atof(val);
 
281
          break;
 
282
      case 2 :
 
283
          pageBottom = (float)atof(val);
 
284
          break;
 
285
      case 3 :
 
286
          pageLeft = (float)atof(val);
 
287
          break;
 
288
    }
 
289
  }
 
290
  if (ppdIsMarked(ppd,"Duplex","DuplexNoTumble") ||
 
291
      ppdIsMarked(ppd,"Duplex","DuplexTumble") ||
 
292
      ppdIsMarked(ppd,"JCLDuplex","DuplexNoTumble") ||
 
293
      ppdIsMarked(ppd,"JCLDuplex","DuplexTumble") ||
 
294
      ppdIsMarked(ppd,"EFDuplex","DuplexNoTumble") ||
 
295
      ppdIsMarked(ppd,"EFDuplex","DuplexTumble") ||
 
296
      ppdIsMarked(ppd,"KD03Duplex","DuplexNoTumble") ||
 
297
      ppdIsMarked(ppd,"KD03Duplex","DuplexTumble")) {
 
298
      P2PDoc::options.duplex = gTrue;
 
299
  } else if ((val = cupsGetOption("Duplex",num_options,options)) != 0 &&
 
300
      (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
 
301
       !strcasecmp(val, "yes"))) {
 
302
      /* for compatiblity */
 
303
      if (ppdFindOption(ppd,"Duplex") != NULL) {
 
304
        ppdMarkOption(ppd,"Duplex","True");
 
305
        ppdMarkOption(ppd,"Duplex","On");
 
306
        P2PDoc::options.duplex = gTrue;
 
307
      }
 
308
  } else if ((val = cupsGetOption("sides",num_options,options)) != 0 &&
 
309
      (!strcasecmp(val, "two-sided-long-edge") ||
 
310
       !strcasecmp(val, "two-sided-short-edge"))) {
 
311
      /* for compatiblity */
 
312
      if (ppdFindOption(ppd,"Duplex") != NULL) {
 
313
        ppdMarkOption(ppd,"Duplex","True");
 
314
        ppdMarkOption(ppd,"Duplex","On");
 
315
        P2PDoc::options.duplex = gTrue;
 
316
      }
 
317
  }
 
318
 
 
319
  if ((val = cupsGetOption("number-up",num_options,options)) != 0) {
 
320
    switch (intval = atoi(val)) {
 
321
      case 1 :
 
322
      case 2 :
 
323
      case 4 :
 
324
      case 6 :
 
325
      case 8 :
 
326
      case 9 :
 
327
      case 16 :
 
328
          numberUp = intval;
 
329
          break;
 
330
      default :
 
331
          error(-1,
 
332
                  const_cast<char *>("Unsupported number-up value %d, using number-up=1!\n"),
 
333
                  intval);
 
334
          break;
 
335
    }
 
336
  }
 
337
  if ((val = cupsGetOption("number-up-layout",num_options,options)) != 0) {
 
338
    if (!strcasecmp(val,"lrtb")) {
 
339
      numberUpLayout = PDFTOPDF_LAYOUT_LRTB;
 
340
    } else if (!strcasecmp(val,"lrbt")) {
 
341
      numberUpLayout = PDFTOPDF_LAYOUT_LRBT;
 
342
    } else if (!strcasecmp(val,"rltb")) {
 
343
      numberUpLayout = PDFTOPDF_LAYOUT_RLTB;
 
344
    } else if (!strcasecmp(val,"rlbt")) {
 
345
      numberUpLayout = PDFTOPDF_LAYOUT_RLBT;
 
346
    } else if (!strcasecmp(val,"tblr")) {
 
347
      numberUpLayout = PDFTOPDF_LAYOUT_TBLR;
 
348
    } else if (!strcasecmp(val,"tbrl")) {
 
349
      numberUpLayout = PDFTOPDF_LAYOUT_TBRL;
 
350
    } else if (!strcasecmp(val,"btlr")) {
 
351
      numberUpLayout = PDFTOPDF_LAYOUT_BTLR;
 
352
    } else if (!strcasecmp(val,"btrl")) {
 
353
      numberUpLayout = PDFTOPDF_LAYOUT_BTRL;
 
354
    } else {
 
355
      error(-1, const_cast<char *>("Unsupported number-up-layout value %s,"
 
356
              " using number-up-layout=lrtb!\n"), val);
 
357
    }
 
358
  }
 
359
  if ((val = cupsGetOption("OutputOrder",num_options,options)) != 0) {
 
360
    if (!strcasecmp(val, "Reverse")) {
 
361
      P2PDoc::options.reverse = gTrue;
 
362
    }
 
363
  } else if (ppd) {
 
364
   /*
 
365
    * Figure out the right default output order from the PPD file...
 
366
    */
 
367
 
 
368
    if ((choice = ppdFindMarkedChoice(ppd,"OutputOrder")) != 0) {
 
369
      P2PDoc::options.reverse = !strcasecmp(choice->choice,"Reverse");
 
370
    } else if ((choice = ppdFindMarkedChoice(ppd,"OutputBin")) != 0 &&
 
371
        (attr = ppdFindAttr(ppd,"PageStackOrder",choice->choice)) != 0 &&
 
372
        attr->value) {
 
373
      P2PDoc::options.reverse = !strcasecmp(attr->value,"Reverse");
 
374
    } else if ((attr = ppdFindAttr(ppd,"DefaultOutputOrder",0)) != 0 &&
 
375
             attr->value) {
 
376
      P2PDoc::options.reverse = !strcasecmp(attr->value,"Reverse");
 
377
    }
 
378
  }
 
379
  if ((val = cupsGetOption("page-border",num_options,options)) != 0) {
 
380
    if (!strcasecmp(val,"none")) {
 
381
      pageBorder = PDFTOPDF_BORDERNONE;
 
382
    } else if (!strcasecmp(val,"single")) {
 
383
      pageBorder = PDFTOPDF_BORDERHAIRLINE;
 
384
    } else if (!strcasecmp(val,"single-thick")) {
 
385
      pageBorder = PDFTOPDF_BORDERTHICK;
 
386
    } else if (!strcasecmp(val,"double")) {
 
387
      pageBorder = PDFTOPDF_BORDERDOUBLE | PDFTOPDF_BORDERHAIRLINE;
 
388
    } else if (!strcasecmp(val,"double-thick")) {
 
389
      pageBorder = PDFTOPDF_BORDERDOUBLE | PDFTOPDF_BORDERTHICK;
 
390
    } else {
 
391
      error(-1, const_cast<char *>("Unsupported page-border value %s, using "
 
392
                      "page-border=none!\n"), val);
 
393
    }
 
394
  }
 
395
  P2PDoc::options.pageLabel = cupsGetOption("page-label",num_options,options);
 
396
  P2PDoc::options.pageSet = cupsGetOption("page-set",num_options,options);
 
397
  P2PDoc::options.pageRanges = cupsGetOption("page-ranges",num_options,options);
 
398
 
 
399
  if ((val = cupsGetOption("mirror",num_options,options)) != 0 &&
 
400
      (!strcasecmp(val,"true") || !strcasecmp(val,"on") ||
 
401
       !strcasecmp(val,"yes"))) {
 
402
    mirror = gTrue;
 
403
  }
 
404
  if ((val = cupsGetOption("emit-jcl",num_options,options)) != 0 &&
 
405
      (!strcasecmp(val,"false") || !strcasecmp(val,"off") ||
 
406
       !strcasecmp(val,"no") || !strcmp(val,"0"))) {
 
407
    emitJCL = gFalse;
 
408
  }
 
409
  if ((val = cupsGetOption("position",num_options,options)) != 0) {
 
410
    if (strcasecmp(val,"center") == 0) {
 
411
      xposition = 0;
 
412
      yposition = 0;
 
413
    } else if (strcasecmp(val,"top") == 0) {
 
414
      xposition = 0;
 
415
      yposition = 1;
 
416
    } else if (strcasecmp(val,"left") == 0) {
 
417
      xposition = -1;
 
418
      yposition = 0;
 
419
    } else if (strcasecmp(val,"right") == 0) {
 
420
      xposition = 1;
 
421
      yposition = 0;
 
422
    } else if (strcasecmp(val,"top-left") == 0) {
 
423
      xposition = -1;
 
424
      yposition = 1;
 
425
    } else if (strcasecmp(val,"top-right") == 0) {
 
426
      xposition = 1;
 
427
      yposition = 1;
 
428
    } else if (strcasecmp(val,"bottom") == 0) {
 
429
      xposition = 0;
 
430
      yposition = -1;
 
431
    } else if (strcasecmp(val,"bottom-left") == 0) {
 
432
      xposition = -1;
 
433
      yposition = -1;
 
434
    } else if (strcasecmp(val,"bottom-right") == 0) {
 
435
      xposition = 1;
 
436
      yposition = -1;
 
437
    }
 
438
    position = gTrue;
 
439
  }
 
440
 
 
441
  if ((val = cupsGetOption("multiple-document-handling",num_options,options)) 
 
442
      != 0) {
 
443
    P2PDoc::options.collate =
 
444
      strcasecmp(val,"separate-documents-uncollated-copies") != 0;
 
445
  }
 
446
  if ((val = cupsGetOption("Collate",num_options,options)) != 0) {
 
447
    if (strcasecmp(val,"True") == 0) {
 
448
      P2PDoc::options.collate = gTrue;
 
449
    }
 
450
  } else {
 
451
    if ((choice = ppdFindMarkedChoice(ppd,"Collate")) != NULL
 
452
      && (!strcasecmp(choice->choice,"true")
 
453
        || !strcasecmp(choice->choice, "on")
 
454
        || !strcasecmp(choice->choice, "yes"))) {
 
455
      P2PDoc::options.collate = gTrue;
 
456
    }
 
457
  }
 
458
 
 
459
  if ((val = cupsGetOption("scaling",num_options,options)) != 0) {
 
460
    scaling = atoi(val) * 0.01;
 
461
    fitplot = gTrue;
 
462
  } else if (fitplot) {
 
463
    scaling = 1.0;
 
464
  }
 
465
  if ((val = cupsGetOption("natural-scaling",num_options,options)) != 0) {
 
466
    naturalScaling = atoi(val) * 0.01;
 
467
  }
 
468
  /* adujst to even page when duplex */
 
469
  if (checkFeature("cupsEvenDuplex",num_options,options)) {
 
470
    P2PDoc::options.even = gTrue;
 
471
  }
 
472
 
 
473
  /* embedding fonts into output PDF */
 
474
  if (checkFeature("pdftopdfFontEmbedding",num_options,options)) {
 
475
    P2PDoc::options.fontEmbedding = gTrue;
 
476
  }
 
477
  /* embedding whole font file into output PDF */
 
478
  if (checkFeature("pdftopdfFontEmbeddingWhole",num_options,options)) {
 
479
    P2PDoc::options.fontEmbeddingWhole = gTrue;
 
480
  }
 
481
  /* embedding pre-loaded fonts specified in PPD into output PDF */
 
482
  if (checkFeature("pdftopdfFontEmbeddingPreLoad",num_options,options)) {
 
483
    P2PDoc::options.fontEmbeddingPreLoad = gTrue;
 
484
  }
 
485
  /* compressing embedded fonts */
 
486
  if (checkFeature("pdftopdfFontCompress",num_options,options)) {
 
487
    P2PDoc::options.fontCompress = gTrue;
 
488
  }
 
489
  /* compressing page contents */
 
490
  if (checkFeature("pdftopdfContentsCompress",num_options,options)) {
 
491
    P2PDoc::options.contentsCompress = gTrue;
 
492
  }
 
493
  /* auto rotate */
 
494
  if (cupsGetOption("pdftopdfAutoRotate",num_options,options) != 0 ||
 
495
         ppdFindAttr(ppd,"pdftopdfAutoRotate",0) != 0) {
 
496
      if (!checkFeature("pdftopdfAutoRotate",num_options,options)) {
 
497
        /* disable auto rotate */
 
498
        autoRotate = gFalse;
 
499
      }
 
500
  }
 
501
 
 
502
  /* pre-loaded fonts */
 
503
  if (ppd != 0) {
 
504
    P2PDoc::options.numPreFonts = ppd->num_fonts;
 
505
    P2PDoc::options.preFonts = ppd->fonts;
 
506
  }
 
507
 
 
508
  if (P2PDoc::options.copies == 1) {
 
509
    /* collate is not needed */
 
510
    P2PDoc::options.collate = gFalse;
 
511
    ppdMarkOption(ppd,"Collate","False");
 
512
  }
 
513
  if (!P2PDoc::options.duplex) {
 
514
    /* evenDuplex is not needed */
 
515
    P2PDoc::options.even = gFalse;
 
516
  }
 
517
 
 
518
  /* check collate device */
 
519
  if (P2PDoc::options.collate) {
 
520
    if ((choice = ppdFindMarkedChoice(ppd,"Collate")) != NULL &&
 
521
       !strcasecmp(choice->choice,"true")) {
 
522
      ppd_option_t *opt;
 
523
 
 
524
      if ((opt = ppdFindOption(ppd,"Collate")) != NULL &&
 
525
        !opt->conflicted) {
 
526
        deviceCollate = gTrue;
 
527
      } else {
 
528
        ppdMarkOption(ppd,"Collate","False");
 
529
      }
 
530
    }
 
531
  }
 
532
  /* check OutputOrder device */
 
533
  if (P2PDoc::options.reverse) {
 
534
    if (ppdFindOption(ppd,"OutputOrder") != NULL) {
 
535
      deviceReverse = gTrue;
 
536
    }
 
537
  }
 
538
  if (ppd != NULL &&
 
539
       !ppd->manual_copies && P2PDoc::options.collate && !deviceCollate) {
 
540
    /* Copying by device , software collate is impossible */
 
541
    /* Enable software copying */
 
542
    ppd->manual_copies = 1;
 
543
  }
 
544
  if (P2PDoc::options.copies > 1 && (ppd == NULL || ppd->manual_copies)
 
545
      && P2PDoc::options.duplex) {
 
546
    /* Enable software collate , or same pages are printed in both sides */
 
547
      P2PDoc::options.collate = gTrue;
 
548
      if (deviceCollate) {
 
549
        deviceCollate = gFalse;
 
550
        ppdMarkOption(ppd,"Collate","False");
 
551
      }
 
552
  }
 
553
  if (P2PDoc::options.duplex && P2PDoc::options.collate && !deviceCollate) {
 
554
    /* Enable evenDuplex or the first page may be printed other side of the
 
555
      end of precedings */
 
556
    P2PDoc::options.even = gTrue;
 
557
  }
 
558
  if (P2PDoc::options.duplex && P2PDoc::options.reverse && !deviceReverse) {
 
559
    /* Enable evenDuplex or the first page may be empty. */
 
560
    P2PDoc::options.even = gTrue;
 
561
  }
 
562
  /* change feature for software */
 
563
  if (deviceCollate) {
 
564
    P2PDoc::options.collate = gFalse;
 
565
  }
 
566
  if (deviceReverse) {
 
567
    P2PDoc::options.reverse = gFalse;
 
568
  }
 
569
 
 
570
  if (ppd != NULL) {
 
571
    if (ppd->manual_copies) {
 
572
      /* sure disable hardware copying */
 
573
      ppdMarkOption(ppd,"Copies","1");
 
574
      ppdMarkOption(ppd,"JCLCopies","1");
 
575
    } else {
 
576
      /* change for hardware copying */
 
577
      deviceCopies = P2PDoc::options.copies;
 
578
      P2PDoc::options.copies = 1;
 
579
    }
 
580
  }
 
581
}
 
582
 
 
583
int main(int argc, char *argv[]) {
 
584
  PDFDoc *doc;
 
585
  P2PDoc *p2pdoc;
 
586
  P2POutputStream *str;
 
587
 
 
588
  setErrorFunction(::myErrorFun);
 
589
#ifdef GLOBALPARAMS_HAS_A_ARG
 
590
  globalParams = new GlobalParams(0);
 
591
#else
 
592
  globalParams = new GlobalParams();
 
593
#endif
 
594
  parseOpts(argc, argv);
 
595
 
 
596
  PDFRectangle box(pageLeft,pageBottom,pageRight,pageTop);
 
597
  PDFRectangle mediaBox(0,0,pageWidth,pageLength);
 
598
 
 
599
  if (argc == 6) {
 
600
    /* stdin */
 
601
    int fd;
 
602
    Object obj;
 
603
    BaseStream *str;
 
604
    FILE *fp;
 
605
    char buf[BUFSIZ];
 
606
    int n;
 
607
 
 
608
    fd = cupsTempFd(buf,sizeof(buf));
 
609
    if (fd < 0) {
 
610
      error(-1,const_cast<char *>("Can't create temporary file"));
 
611
      exit(1);
 
612
    }
 
613
    /* remove name */
 
614
    unlink(buf);
 
615
 
 
616
    /* copy stdin to the tmp file */
 
617
    while ((n = read(0,buf,BUFSIZ)) > 0) {
 
618
      if (write(fd,buf,n) != n) {
 
619
        error(-1,const_cast<char *>("Can't copy stdin to temporary file"));
 
620
        close(fd);
 
621
        exit(1);
 
622
      }
 
623
    }
 
624
    if (lseek(fd,0,SEEK_SET) < 0) {
 
625
        error(-1,const_cast<char *>("Can't rewind temporary file"));
 
626
        close(fd);
 
627
        exit(1);
 
628
    }
 
629
 
 
630
    if ((fp = fdopen(fd,"rb")) == 0) {
 
631
        error(-1,const_cast<char *>("Can't fdopen temporary file"));
 
632
        close(fd);
 
633
        exit(1);
 
634
    }
 
635
 
 
636
    obj.initNull();
 
637
    str = new FileStream(fp,0,gFalse,0,&obj);
 
638
    doc = new PDFDoc(str);
 
639
  } else {
 
640
    GooString *fileName = new GooString(argv[6]);
 
641
    /* argc == 7 filenmae is specified */
 
642
    doc = new PDFDoc(fileName,NULL,NULL);
 
643
  }
 
644
 
 
645
  if (!doc->isOk()) {
 
646
    exitCode = 1;
 
647
    goto err1;
 
648
  }
 
649
  if (!doc->okToPrintHighRes() && !doc->okToPrint()) {
 
650
    error(-1,const_cast<char *>("Printing is not allowed\n"));
 
651
    exit(1);
 
652
  }
 
653
  p2pdoc = new P2PDoc(doc);
 
654
  if (mirror) {
 
655
    p2pdoc->mirror();
 
656
  }
 
657
 
 
658
  if (orientation != 0) {
 
659
    p2pdoc->rotate(orientation);
 
660
    p2pdoc->position(&box,xposition,yposition);
 
661
  }
 
662
 
 
663
  if (naturalScaling != 1.0) {
 
664
    p2pdoc->scale(naturalScaling);
 
665
    p2pdoc->position(&box,xposition,yposition);
 
666
  }
 
667
 
 
668
  if (fitplot) {
 
669
    p2pdoc->fit(&box,scaling);
 
670
    p2pdoc->position(&box,xposition,yposition);
 
671
  }
 
672
  if (numberUp != 1) {
 
673
    p2pdoc->nup(numberUp,&box,pageBorder,numberUpLayout,
 
674
      xposition,yposition);
 
675
  } else if (position) {
 
676
    p2pdoc->position(&box,xposition,yposition);
 
677
  }
 
678
 
 
679
  p2pdoc->select();
 
680
 
 
681
  if (autoRotate && orientation == 0
 
682
     && naturalScaling == 1.0 && !fitplot && numberUp == 1 && !position) {
 
683
    /* If no translation is specified, do auto-rotate.
 
684
     * This is for compatibility with pdftops filter.
 
685
     */
 
686
    p2pdoc->autoRotate(&mediaBox);
 
687
  }
 
688
 
 
689
  /* set all pages's mediaBox to the target page size, but only if a page
 
690
   * size is given on the command line or an option which influences the
 
691
   * printout size is used */
 
692
  if (forcePageSize || orientation != 0 ||
 
693
      naturalScaling != 1.0 || fitplot || numberUp != 1 || position) {
 
694
    p2pdoc->setMediaBox(&mediaBox);
 
695
  }
 
696
 
 
697
  if ((P2PDoc::options.collate || deviceCollate)
 
698
      && p2pdoc->getNumberOfPages() == 1
 
699
      && !P2PDoc::options.even) {
 
700
    /* collate is not needed, disable it */
 
701
    /* Number of pages is changed by nup and page-ranges,
 
702
        so check this here */
 
703
    deviceCollate = gFalse;
 
704
    P2PDoc::options.collate = gFalse;
 
705
    ppdMarkOption(ppd,"Collate","False");
 
706
  }
 
707
 
 
708
  ppdEmit(ppd,stdout,PPD_ORDER_EXIT);
 
709
 
 
710
  if (emitJCL) {
 
711
    ppdEmitJCL(ppd,stdout,P2PDoc::options.jobId,P2PDoc::options.user,
 
712
      P2PDoc::options.title);
 
713
    emitJCLOptions(stdout,deviceCopies);
 
714
  }
 
715
  str = new P2POutputStream(stdout); /* PDF start here */
 
716
  p2pdoc->output(str,deviceCopies,deviceCollate);
 
717
#ifndef CUPS_1_1
 
718
  if (emitJCL) {
 
719
    ppdEmitJCLEnd(ppd,stdout);
 
720
  }
 
721
#endif
 
722
 
 
723
  delete str;
 
724
  delete p2pdoc;
 
725
err1:
 
726
  delete doc;
 
727
 
 
728
  // Check for memory leaks
 
729
  Object::memCheck(stderr);
 
730
  gMemReport(stderr);
 
731
 
 
732
  return exitCode;
 
733
}
 
734
 
 
735
/* replace memory allocation methods for memory check */
 
736
 
 
737
void * operator new(size_t size)
 
738
{
 
739
  return gmalloc(size);
 
740
}
 
741
 
 
742
void operator delete(void *p)
 
743
{
 
744
  gfree(p);
 
745
}
 
746
 
 
747
void * operator new[](size_t size)
 
748
{
 
749
  return gmalloc(size);
 
750
}
 
751
 
 
752
void operator delete[](void *p)
 
753
{
 
754
  gfree(p);
 
755
}