2
Copyright (c) 2006-2011, BBR Inc. All rights reserved.
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:
12
The above copyright notice and this permission notice shall be included
13
in all copies or substantial portions of the Software.
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.
32
#ifdef HAVE_CPP_POPPLER_VERSION_H
33
#include "cpp/poppler-version.h"
35
#include "goo/GooString.h"
41
#include "P2POutputStream.h"
42
#include <cups/cups.h>
46
#include "GlobalParams.h"
47
#include "PDFFTrueTypeFont.h"
52
GBool fitplot = gFalse;
53
GBool mirror = gFalse;
55
unsigned int numberUpLayout = PDFTOPDF_LAYOUT_LRTB;
56
unsigned int pageBorder = PDFTOPDF_BORDERNONE;
57
double pageLeft = 18.0;
58
double pageRight = 594.0;
59
double pageBottom = 36.0;
60
double pageTop = 756.0;
61
double pageWidth = 612.0;
62
double pageLength = 792.0;
63
GBool emitJCL = gTrue;
67
GBool position = gFalse;
70
double naturalScaling = 1.0;
72
GBool deviceCollate = gFalse;
73
GBool deviceReverse = gFalse;
74
GBool autoRotate = gTrue;
75
GBool forcePageSize = gFalse;
78
#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
79
void CDECL myErrorFun(void *data, ErrorCategory category,
83
fprintf(stderr, "ERROR (%d): ", pos);
85
fprintf(stderr, "ERROR: ");
87
fprintf(stderr, "%s\n",msg);
91
void CDECL myErrorFun(int pos, char *msg, va_list args)
94
fprintf(stderr, "ERROR (%d): ", pos);
96
fprintf(stderr, "ERROR: ");
98
vfprintf(stderr, msg, args);
99
fprintf(stderr, "\n");
104
GBool checkFeature(const char *feature, int num_options, cups_option_t *options)
109
return ((val = cupsGetOption(feature,num_options,options)) != 0 &&
110
(!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
111
!strcasecmp(val, "yes"))) ||
112
((attr = ppdFindAttr(ppd,feature,0)) != 0 &&
113
(!strcasecmp(attr->value, "true")
114
|| !strcasecmp(attr->value, "on") ||
115
!strcasecmp(attr->value, "yes")));
118
void emitJCLOptions(FILE *fp, int copies)
121
ppd_choice_t **choices;
128
if (ppd == 0) return;
129
if ((attr = ppdFindAttr(ppd,"pdftopdfJCLBegin",NULL)) != NULL) {
130
int n = strlen(attr->value);
132
for (i = 0;i < n;i++) {
133
if (attr->value[i] == '\r' || attr->value[i] == '\n') {
137
fputc(attr->value[i],fp);
142
snprintf(buf,sizeof(buf),"%d",copies);
143
if (ppdFindOption(ppd,"Copies") != NULL) {
144
ppdMarkOption(ppd,"Copies",buf);
146
if ((attr = ppdFindAttr(ppd,"pdftopdfJCLCopies",buf)) != NULL) {
147
fputs(attr->value,fp);
149
} else if (pdftoopvp) {
150
fprintf(fp,"Copies=%d;",copies);
154
for (section = (int)PPD_ORDER_ANY;
155
section <= (int)PPD_ORDER_PROLOG;section++) {
158
n = ppdCollect(ppd,(ppd_section_t)section,&choices);
159
for (i = 0;i < n;i++) {
160
snprintf(buf,sizeof(buf),"pdftopdfJCL%s",
161
((ppd_option_t *)(choices[i]->option))->keyword);
162
if ((attr = ppdFindAttr(ppd,buf,choices[i]->choice)) != NULL) {
163
fputs(attr->value,fp);
165
} else if (pdftoopvp) {
167
((ppd_option_t *)(choices[i]->option))->keyword,
173
if (datawritten) fputc('\n',fp);
176
void parseOpts(int argc, char **argv)
179
cups_option_t *options;
182
ppd_choice_t *choice;
183
ppd_size_t *pagesize;
186
if (argc < 6 || argc > 7) {
187
p2pError(-1,const_cast<char *>("%s job-id user title copies options [file]"),
191
P2PDoc::options.jobId = atoi(argv[1]);
192
P2PDoc::options.user = argv[2];
193
P2PDoc::options.title = argv[3];
194
P2PDoc::options.copies = atoi(argv[4]);
196
ppd = ppdOpenFile(getenv("PPD"));
197
ppdMarkDefaults(ppd);
199
num_options = cupsParseOptions(argv[5],0,&options);
200
cupsMarkOptions(ppd,num_options,options);
201
if (P2PDoc::options.copies == 1
202
&& (choice = ppdFindMarkedChoice(ppd,"Copies")) != NULL) {
203
P2PDoc::options.copies = atoi(choice->choice);
205
if (P2PDoc::options.copies == 0) P2PDoc::options.copies = 1;
206
if ((val = cupsGetOption("fitplot", num_options, options)) == NULL) {
207
if ((val = cupsGetOption("fit-to-page", num_options, options)) == NULL) {
208
val = cupsGetOption("ipp-attribute-fidelity", num_options, options);
211
if (val && strcasecmp(val, "no") && strcasecmp(val, "off") &&
212
strcasecmp(val, "false"))
214
if ((pagesize = ppdPageSize(ppd,0)) != 0) {
215
pageWidth = pagesize->width;
216
pageLength = pagesize->length;
217
pageTop = pagesize->top;
218
pageBottom = pagesize->bottom;
219
pageLeft = pagesize->left;
220
pageRight = pagesize->right;
221
forcePageSize = fitplot;
223
if ((val = cupsGetOption("landscape",num_options,options)) != 0) {
224
if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 &&
225
strcasecmp(val, "false") != 0) {
226
if (ppd && ppd->landscape > 0) {
233
cupsGetOption("orientation-requested",num_options,options)) != 0) {
235
* Map IPP orientation values to 0 to 3:
239
* 5 = -90 degrees = 3
240
* 6 = 180 degrees = 2
243
orientation = atoi(val) - 3;
244
if (orientation >= 2) {
248
if ((val = cupsGetOption("page-left",num_options,options)) != 0) {
249
switch (orientation & 3) {
251
pageLeft = (float)atof(val);
254
pageBottom = (float)atof(val);
257
pageRight = pageWidth - (float)atof(val);
260
pageTop = pageLength - (float)atof(val);
264
if ((val = cupsGetOption("page-right",num_options,options)) != 0) {
265
switch (orientation & 3) {
267
pageRight = pageWidth - (float)atof(val);
270
pageTop = pageLength - (float)atof(val);
273
pageLeft = (float)atof(val);
276
pageBottom = (float)atof(val);
280
if ((val = cupsGetOption("page-bottom",num_options,options)) != 0) {
281
switch (orientation & 3) {
283
pageBottom = (float)atof(val);
286
pageLeft = (float)atof(val);
289
pageTop = pageLength - (float)atof(val);
292
pageRight = pageWidth - (float)atof(val);
296
if ((val = cupsGetOption("page-top",num_options,options)) != 0) {
297
switch (orientation & 3) {
299
pageTop = pageLength - (float)atof(val);
302
pageRight = pageWidth - (float)atof(val);
305
pageBottom = (float)atof(val);
308
pageLeft = (float)atof(val);
312
if (ppdIsMarked(ppd,"Duplex","DuplexNoTumble") ||
313
ppdIsMarked(ppd,"Duplex","DuplexTumble") ||
314
ppdIsMarked(ppd,"JCLDuplex","DuplexNoTumble") ||
315
ppdIsMarked(ppd,"JCLDuplex","DuplexTumble") ||
316
ppdIsMarked(ppd,"EFDuplex","DuplexNoTumble") ||
317
ppdIsMarked(ppd,"EFDuplex","DuplexTumble") ||
318
ppdIsMarked(ppd,"KD03Duplex","DuplexNoTumble") ||
319
ppdIsMarked(ppd,"KD03Duplex","DuplexTumble")) {
320
P2PDoc::options.duplex = gTrue;
321
} else if ((val = cupsGetOption("Duplex",num_options,options)) != 0 &&
322
(!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
323
!strcasecmp(val, "yes"))) {
324
/* for compatiblity */
325
if (ppdFindOption(ppd,"Duplex") != NULL) {
326
ppdMarkOption(ppd,"Duplex","True");
327
ppdMarkOption(ppd,"Duplex","On");
328
P2PDoc::options.duplex = gTrue;
330
} else if ((val = cupsGetOption("sides",num_options,options)) != 0 &&
331
(!strcasecmp(val, "two-sided-long-edge") ||
332
!strcasecmp(val, "two-sided-short-edge"))) {
333
/* for compatiblity */
334
if (ppdFindOption(ppd,"Duplex") != NULL) {
335
ppdMarkOption(ppd,"Duplex","True");
336
ppdMarkOption(ppd,"Duplex","On");
337
P2PDoc::options.duplex = gTrue;
341
if ((val = cupsGetOption("number-up",num_options,options)) != 0) {
342
switch (intval = atoi(val)) {
354
const_cast<char *>("Unsupported number-up value %d, using number-up=1!\n"),
359
if ((val = cupsGetOption("number-up-layout",num_options,options)) != 0) {
360
if (!strcasecmp(val,"lrtb")) {
361
numberUpLayout = PDFTOPDF_LAYOUT_LRTB;
362
} else if (!strcasecmp(val,"lrbt")) {
363
numberUpLayout = PDFTOPDF_LAYOUT_LRBT;
364
} else if (!strcasecmp(val,"rltb")) {
365
numberUpLayout = PDFTOPDF_LAYOUT_RLTB;
366
} else if (!strcasecmp(val,"rlbt")) {
367
numberUpLayout = PDFTOPDF_LAYOUT_RLBT;
368
} else if (!strcasecmp(val,"tblr")) {
369
numberUpLayout = PDFTOPDF_LAYOUT_TBLR;
370
} else if (!strcasecmp(val,"tbrl")) {
371
numberUpLayout = PDFTOPDF_LAYOUT_TBRL;
372
} else if (!strcasecmp(val,"btlr")) {
373
numberUpLayout = PDFTOPDF_LAYOUT_BTLR;
374
} else if (!strcasecmp(val,"btrl")) {
375
numberUpLayout = PDFTOPDF_LAYOUT_BTRL;
377
p2pError(-1, const_cast<char *>("Unsupported number-up-layout value %s,"
378
" using number-up-layout=lrtb!\n"), val);
381
if ((val = cupsGetOption("OutputOrder",num_options,options)) != 0) {
382
if (!strcasecmp(val, "Reverse")) {
383
P2PDoc::options.reverse = gTrue;
387
* Figure out the right default output order from the PPD file...
390
if ((choice = ppdFindMarkedChoice(ppd,"OutputOrder")) != 0) {
391
P2PDoc::options.reverse = !strcasecmp(choice->choice,"Reverse");
392
} else if ((choice = ppdFindMarkedChoice(ppd,"OutputBin")) != 0 &&
393
(attr = ppdFindAttr(ppd,"PageStackOrder",choice->choice)) != 0 &&
395
P2PDoc::options.reverse = !strcasecmp(attr->value,"Reverse");
396
} else if ((attr = ppdFindAttr(ppd,"DefaultOutputOrder",0)) != 0 &&
398
P2PDoc::options.reverse = !strcasecmp(attr->value,"Reverse");
401
if ((val = cupsGetOption("page-border",num_options,options)) != 0) {
402
if (!strcasecmp(val,"none")) {
403
pageBorder = PDFTOPDF_BORDERNONE;
404
} else if (!strcasecmp(val,"single")) {
405
pageBorder = PDFTOPDF_BORDERHAIRLINE;
406
} else if (!strcasecmp(val,"single-thick")) {
407
pageBorder = PDFTOPDF_BORDERTHICK;
408
} else if (!strcasecmp(val,"double")) {
409
pageBorder = PDFTOPDF_BORDERDOUBLE | PDFTOPDF_BORDERHAIRLINE;
410
} else if (!strcasecmp(val,"double-thick")) {
411
pageBorder = PDFTOPDF_BORDERDOUBLE | PDFTOPDF_BORDERTHICK;
413
p2pError(-1, const_cast<char *>("Unsupported page-border value %s, using "
414
"page-border=none!\n"), val);
417
P2PDoc::options.pageLabel = cupsGetOption("page-label",num_options,options);
418
P2PDoc::options.pageSet = cupsGetOption("page-set",num_options,options);
419
P2PDoc::options.pageRanges = cupsGetOption("page-ranges",num_options,options);
421
if ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL) {
422
val = choice->choice;
424
if (val && (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
425
!strcasecmp(val, "yes"))) {
428
} else if ((val = cupsGetOption("mirror",num_options,options)) != 0 &&
429
(!strcasecmp(val,"true") || !strcasecmp(val,"on") ||
430
!strcasecmp(val,"yes"))) {
433
if ((val = cupsGetOption("emit-jcl",num_options,options)) != 0 &&
434
(!strcasecmp(val,"false") || !strcasecmp(val,"off") ||
435
!strcasecmp(val,"no") || !strcmp(val,"0"))) {
438
if ((val = cupsGetOption("position",num_options,options)) != 0) {
439
if (strcasecmp(val,"center") == 0) {
442
} else if (strcasecmp(val,"top") == 0) {
445
} else if (strcasecmp(val,"left") == 0) {
448
} else if (strcasecmp(val,"right") == 0) {
451
} else if (strcasecmp(val,"top-left") == 0) {
454
} else if (strcasecmp(val,"top-right") == 0) {
457
} else if (strcasecmp(val,"bottom") == 0) {
460
} else if (strcasecmp(val,"bottom-left") == 0) {
463
} else if (strcasecmp(val,"bottom-right") == 0) {
470
if ((val = cupsGetOption("multiple-document-handling",num_options,options))
472
P2PDoc::options.collate =
473
strcasecmp(val,"separate-documents-uncollated-copies") != 0;
475
if ((val = cupsGetOption("Collate",num_options,options)) != 0) {
476
if (strcasecmp(val,"True") == 0) {
477
P2PDoc::options.collate = gTrue;
480
if ((choice = ppdFindMarkedChoice(ppd,"Collate")) != NULL
481
&& (!strcasecmp(choice->choice,"true")
482
|| !strcasecmp(choice->choice, "on")
483
|| !strcasecmp(choice->choice, "yes"))) {
484
P2PDoc::options.collate = gTrue;
488
if ((val = cupsGetOption("scaling",num_options,options)) != 0) {
489
scaling = atoi(val) * 0.01;
491
} else if (fitplot) {
494
if ((val = cupsGetOption("natural-scaling",num_options,options)) != 0) {
495
naturalScaling = atoi(val) * 0.01;
497
/* adujst to even page when duplex */
498
if (checkFeature("cupsEvenDuplex",num_options,options)) {
499
P2PDoc::options.even = gTrue;
502
/* embedding fonts into output PDF */
503
if (checkFeature("pdftopdfFontEmbedding",num_options,options)) {
504
P2PDoc::options.fontEmbedding = gTrue;
506
/* embedding whole font file into output PDF */
507
if (checkFeature("pdftopdfFontEmbeddingWhole",num_options,options)) {
508
P2PDoc::options.fontEmbeddingWhole = gTrue;
510
/* embedding pre-loaded fonts specified in PPD into output PDF */
511
if (checkFeature("pdftopdfFontEmbeddingPreLoad",num_options,options)) {
512
P2PDoc::options.fontEmbeddingPreLoad = gTrue;
514
/* compressing embedded fonts */
515
if (checkFeature("pdftopdfFontCompress",num_options,options)) {
516
P2PDoc::options.fontCompress = gTrue;
518
/* compressing page contents */
519
if (checkFeature("pdftopdfContentsCompress",num_options,options)) {
520
P2PDoc::options.contentsCompress = gTrue;
523
if (cupsGetOption("pdftopdfAutoRotate",num_options,options) != 0 ||
524
ppdFindAttr(ppd,"pdftopdfAutoRotate",0) != 0) {
525
if (!checkFeature("pdftopdfAutoRotate",num_options,options)) {
526
/* disable auto rotate */
531
/* pre-loaded fonts */
533
P2PDoc::options.numPreFonts = ppd->num_fonts;
534
P2PDoc::options.preFonts = ppd->fonts;
537
if (P2PDoc::options.copies == 1) {
538
/* collate is not needed */
539
P2PDoc::options.collate = gFalse;
540
ppdMarkOption(ppd,"Collate","False");
542
if (!P2PDoc::options.duplex) {
543
/* evenDuplex is not needed */
544
P2PDoc::options.even = gFalse;
547
/* check collate device */
548
if (P2PDoc::options.collate && !ppd->manual_copies) {
549
if ((choice = ppdFindMarkedChoice(ppd,"Collate")) != NULL &&
550
!strcasecmp(choice->choice,"true")) {
553
if ((opt = ppdFindOption(ppd,"Collate")) != NULL &&
555
deviceCollate = gTrue;
557
ppdMarkOption(ppd,"Collate","False");
561
/* check OutputOrder device */
562
if (P2PDoc::options.reverse) {
563
if (ppdFindOption(ppd,"OutputOrder") != NULL) {
564
deviceReverse = gTrue;
568
!ppd->manual_copies && P2PDoc::options.collate && !deviceCollate) {
569
/* Copying by device , software collate is impossible */
570
/* Enable software copying */
571
ppd->manual_copies = 1;
573
if (P2PDoc::options.copies > 1 && (ppd == NULL || ppd->manual_copies)
574
&& P2PDoc::options.duplex) {
575
/* Enable software collate , or same pages are printed in both sides */
576
P2PDoc::options.collate = gTrue;
578
deviceCollate = gFalse;
579
ppdMarkOption(ppd,"Collate","False");
582
if (P2PDoc::options.duplex && P2PDoc::options.collate && !deviceCollate) {
583
/* Enable evenDuplex or the first page may be printed other side of the
585
P2PDoc::options.even = gTrue;
587
if (P2PDoc::options.duplex && P2PDoc::options.reverse && !deviceReverse) {
588
/* Enable evenDuplex or the first page may be empty. */
589
P2PDoc::options.even = gTrue;
591
/* change feature for software */
593
P2PDoc::options.collate = gFalse;
596
P2PDoc::options.reverse = gFalse;
600
if (ppd->manual_copies) {
601
/* sure disable hardware copying */
602
ppdMarkOption(ppd,"Copies","1");
603
ppdMarkOption(ppd,"JCLCopies","1");
605
/* change for hardware copying */
606
deviceCopies = P2PDoc::options.copies;
607
P2PDoc::options.copies = 1;
613
/* Copied ppd_decode() from CUPS which is not exported to the API */
615
static int /* O - Length of decoded string */
616
ppd_decode(char *string) /* I - String to decode */
618
char *inptr, /* Input pointer */
619
*outptr; /* Output pointer */
625
while (*inptr != '\0')
626
if (*inptr == '<' && isxdigit(inptr[1] & 255))
629
* Convert hex to 8-bit values...
633
while (isxdigit(*inptr & 255))
636
*outptr = (tolower(*inptr) - 'a' + 10) << 4;
638
*outptr = (*inptr - '0') << 4;
642
if (!isxdigit(*inptr & 255))
646
*outptr |= tolower(*inptr) - 'a' + 10;
648
*outptr |= *inptr - '0';
654
while (*inptr != '>' && *inptr != '\0')
656
while (*inptr == '>')
660
*outptr++ = *inptr++;
664
return ((int)(outptr - string));
667
int main(int argc, char *argv[]) {
670
P2POutputStream *str;
672
#if POPPLER_VERSION_MAJOR > 0 || POPPLER_VERSION_MINOR >= 19
673
setErrorCallback(::myErrorFun,NULL);
675
setErrorFunction(::myErrorFun);
677
globalParams = new GlobalParams();
678
parseOpts(argc, argv);
680
PDFRectangle box(pageLeft,pageBottom,pageRight,pageTop);
681
PDFRectangle mediaBox(0,0,pageWidth,pageLength);
692
fd = cupsTempFd(buf,sizeof(buf));
694
p2pError(-1,const_cast<char *>("Can't create temporary file"));
700
/* copy stdin to the tmp file */
701
while ((n = read(0,buf,BUFSIZ)) > 0) {
702
if (write(fd,buf,n) != n) {
703
p2pError(-1,const_cast<char *>("Can't copy stdin to temporary file"));
708
if (lseek(fd,0,SEEK_SET) < 0) {
709
p2pError(-1,const_cast<char *>("Can't rewind temporary file"));
714
if ((fp = fdopen(fd,"rb")) == 0) {
715
p2pError(-1,const_cast<char *>("Can't fdopen temporary file"));
721
str = new FileStream(fp,0,gFalse,0,&obj);
722
doc = new PDFDoc(str);
724
GooString *fileName = new GooString(argv[6]);
725
/* argc == 7 filenmae is specified */
726
doc = new PDFDoc(fileName,NULL,NULL);
733
if (!doc->okToPrintHighRes() && !doc->okToPrint()) {
734
p2pError(-1,const_cast<char *>("Printing is not allowed\n"));
737
p2pdoc = new P2PDoc(doc);
742
if (orientation != 0) {
743
p2pdoc->rotate(orientation);
744
p2pdoc->position(&box,xposition,yposition);
747
if (naturalScaling != 1.0) {
748
p2pdoc->scale(naturalScaling);
749
p2pdoc->position(&box,xposition,yposition);
753
p2pdoc->fit(&box,scaling);
754
p2pdoc->position(&box,xposition,yposition);
757
p2pdoc->nup(numberUp,&box,pageBorder,numberUpLayout,
758
xposition,yposition);
759
} else if (position) {
760
p2pdoc->position(&box,xposition,yposition);
765
if (autoRotate && orientation == 0
766
&& naturalScaling == 1.0 && !fitplot && numberUp == 1 && !position) {
767
/* If no translation is specified, do auto-rotate.
768
* This is for compatibility with pdftops filter.
770
p2pdoc->autoRotate(&mediaBox);
773
/* set all pages's mediaBox to the target page size, but only if a page
774
* size is given on the command line or an option which influences the
775
* printout size is used */
776
if (forcePageSize || orientation != 0 ||
777
naturalScaling != 1.0 || fitplot || numberUp != 1 || position) {
778
p2pdoc->setMediaBox(&mediaBox);
781
if ((P2PDoc::options.collate || deviceCollate)
782
&& p2pdoc->getNumberOfPages() == 1
783
&& !P2PDoc::options.even) {
784
/* collate is not needed, disable it */
785
/* Number of pages is changed by nup and page-ranges,
786
so check this here */
787
deviceCollate = gFalse;
788
P2PDoc::options.collate = gFalse;
789
ppdMarkOption(ppd,"Collate","False");
792
ppdEmit(ppd,stdout,PPD_ORDER_EXIT);
794
if (ppd != NULL && emitJCL) {
795
/* pdftopdf only adds JCL to the job if the printer is a native PDF
796
printer and the PPD is for this mode, having the "*JCLToPDFInterpreter:"
797
keyword. We need to read this keyword manually from the PPD and replace
798
the content of ppd->jcl_ps by the value of this keyword, so that
799
ppdEmitJCL() actalually adds JCL based on the presence on
800
"*JCLToPDFInterpreter:". */
802
if ((attr = ppdFindAttr(ppd,"JCLToPDFInterpreter",NULL)) != NULL) {
803
ppd->jcl_ps = strdup(attr->value);
804
ppd_decode(ppd->jcl_ps);
805
P2PDoc::options.pdfPrinter = gTrue;
808
P2PDoc::options.pdfPrinter = gFalse;
810
ppdEmitJCL(ppd,stdout,P2PDoc::options.jobId,P2PDoc::options.user,
811
P2PDoc::options.title);
812
emitJCLOptions(stdout,deviceCopies);
814
str = new P2POutputStream(stdout); /* PDF start here */
815
p2pdoc->output(str,deviceCopies,deviceCollate);
818
ppdEmitJCLEnd(ppd,stdout);
827
// Check for memory leaks
828
Object::memCheck(stderr);
834
/* replace memory allocation methods for memory check */
836
void * operator new(size_t size) throw(std::bad_alloc)
838
return gmalloc(size);
841
void operator delete(void *p) throw()
846
void * operator new[](size_t size) throw(std::bad_alloc)
848
return gmalloc(size);
851
void operator delete[](void *p) throw()