3
3
// Copyright (c) 2006-2011, BBR Inc. All rights reserved.
6
// TODO: check ppd==NULL (?)
10
8
#include <cups/cups.h>
11
9
#include <cups/ppd.h>
10
#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 6)
11
#define HAVE_CUPS_1_7 1
15
#endif /* HAVE_CUPS_1_7 */
14
20
#include "pdftopdf_processor.h"
49
55
if ( (choice=ppdFindMarkedChoice(ppd,"MirrorPrint")) != NULL) {
53
// TODO: FIXME: unify code with emitJCLOptions, which does this "by-hand" now (and makes this code superfluous)
54
if (param.deviceCopies==1) {
55
// make sure any hardware copying is disabled
56
ppdMarkOption(ppd,"Copies","1");
57
ppdMarkOption(ppd,"JCLCopies","1");
61
60
// for choice, only overwrites ret if found in ppd
120
119
static bool ppdGetDuplex(ppd_file_t *ppd) // {{{
122
return ppdIsMarked(ppd,"Duplex","DuplexNoTumble")||
123
ppdIsMarked(ppd,"Duplex","DuplexTumble")||
124
ppdIsMarked(ppd,"JCLDuplex","DuplexNoTumble")||
125
ppdIsMarked(ppd,"JCLDuplex","DuplexTumble")||
126
ppdIsMarked(ppd,"EFDuplex","DuplexNoTumble")||
127
ppdIsMarked(ppd,"EFDuplex","DuplexTumble")||
128
ppdIsMarked(ppd,"KD03Duplex","DuplexNoTumble")||
129
ppdIsMarked(ppd,"KD03Duplex","DuplexTumble");
121
const char **option, **choice;
122
const char *option_names[] = {
129
const char *choice_names[] = {
138
for (option = option_names; *option; option ++)
139
for (choice = choice_names; *choice; choice ++)
140
if (ppdIsMarked(ppd, *option, *choice))
281
299
void getParameters(ppd_file_t *ppd,int num_options,cups_option_t *options,ProcessingParameters ¶m) // {{{
303
if ((val = cupsGetOption("copies",num_options,options)) != NULL) {
304
int copies = atoi(val);
306
param.numCopies = copies;
283
308
// param.numCopies initially from commandline
284
309
if (param.numCopies==1) {
285
310
ppdGetInt(ppd,"Copies",¶m.numCopies);
288
313
param.numCopies=1;
292
316
if ( (val=cupsGetOption("fitplot",num_options,options)) == NULL) {
293
317
if ( (val=cupsGetOption("fit-to-page",num_options,options)) == NULL) {
294
318
val=cupsGetOption("ipp-attribute-fidelity",num_options,options);
297
321
// TODO? pstops checks =="true", pdftops !is_false ... pstops says: fitplot only for PS (i.e. not for PDF, cmp. cgpdftopdf)
298
322
param.fitplot=(val)&&(!is_false(val));
300
if ( (ppd)&&(ppd->landscape>0) ) { // direction the printer rotates landscape (90 or -90)
324
if (ppd && (ppd->landscape < 0)) { // direction the printer rotates landscape (90 or -90)
325
param.normal_landscape=ROT_270;
301
327
param.normal_landscape=ROT_90;
303
param.normal_landscape=ROT_270;
331
355
param.page.width=pagesize->width;
332
356
param.page.height=pagesize->length;
360
if ((val = cupsGetOption("media-size", num_options, options)) != NULL ||
361
(val = cupsGetOption("MediaSize", num_options, options)) != NULL ||
362
(val = cupsGetOption("page-size", num_options, options)) != NULL ||
363
(val = cupsGetOption("PageSize", num_options, options)) != NULL) {
364
pwg_media_t *size_found = NULL;
365
fprintf(stderr, "DEBUG: Page size from command line: %s\n", val);
366
if ((size_found = pwgMediaForPWG(val)) == NULL)
367
if ((size_found = pwgMediaForPPD(val)) == NULL)
368
size_found = pwgMediaForLegacy(val);
369
if (size_found != NULL) {
370
param.page.width = size_found->width * 72.0 / 2540.0;
371
param.page.height = size_found->length * 72.0 / 2540.0;
372
param.page.top=param.page.bottom=36.0;
373
param.page.right=param.page.left=18.0;
374
param.page.right=param.page.width-param.page.right;
375
param.page.top=param.page.height-param.page.top;
376
fprintf(stderr, "DEBUG: Width: %f, Length: %f\n", param.page.width, param.page.height);
379
fprintf(stderr, "DEBUG: Unsupported page size %s.\n", val);
382
#endif /* HAVE_CUPS_1_7 */
334
384
param.paper_is_landscape=(param.page.width>param.page.height);
336
386
PageRect tmp; // borders (before rotation)
340
390
optGetFloat("page-right",num_options,options,&tmp.right);
341
391
optGetFloat("page-bottom",num_options,options,&tmp.bottom);
393
if ((val = cupsGetOption("media-top-margin", num_options, options))
395
tmp.top = atof(val) * 72.0 / 2540.0;
396
if ((val = cupsGetOption("media-left-margin", num_options, options))
398
tmp.left = atof(val) * 72.0 / 2540.0;
399
if ((val = cupsGetOption("media-right-margin", num_options, options))
401
tmp.right = atof(val) * 72.0 / 2540.0;
402
if ((val = cupsGetOption("media-bottom-margin", num_options, options))
404
tmp.bottom = atof(val) * 72.0 / 2540.0;
343
406
if ( (param.orientation==ROT_90)||(param.orientation==ROT_270) ) { // unrotate page
345
408
tmp.right=param.page.height-tmp.right;
399
if ( (val=cupsGetOption("OutputOrder",num_options,options)) != NULL) {
462
if ( (val=cupsGetOption("OutputOrder",num_options,options)) != NULL ||
463
(val=cupsGetOption("page-delivery",num_options,options)) != NULL ) {
400
464
param.reverse=(strcasecmp(val,"Reverse")==0);
401
465
} else if (ppd) {
402
466
param.reverse=ppdDefaultOrder(ppd);
405
// TODO: pageLabel (not used)
406
// param.pageLabel=cupsGetOption("page-label",num_options,options); // strdup?
469
std::string rawlabel;
470
char *classification = getenv("CLASSIFICATION");
472
rawlabel.append (classification);
474
if ( (val=cupsGetOption("page-label", num_options, options)) != NULL) {
475
if (!rawlabel.empty())
476
rawlabel.append (" - ");
477
rawlabel.append(cupsGetOption("page-label",num_options,options));
480
std::ostringstream cookedlabel;
481
for (std::string::iterator it = rawlabel.begin();
482
it != rawlabel.end ();
484
if (*it < 32 || *it > 126)
485
cookedlabel << "\\" << std::oct << std::setfill('0') << std::setw(3) << (unsigned int) *it;
487
cookedlabel.put (*it);
489
param.pageLabel = cookedlabel.str ();
408
491
if ( (val=cupsGetOption("page-set",num_options,options)) != NULL) {
409
492
if (strcasecmp(val,"even")==0) {
538
// enable hardware copy generation
540
if (!ppd->manual_copies) {
541
// use hardware copying
542
param.deviceCopies=param.numCopies;
545
param.deviceCopies=1;
550
620
setFinalPPD(ppd,param);
552
if ( (param.numCopies==1)&&(param.deviceCopies==1) ) {
553
// collate is never needed for a single page
554
param.collate=false; // (this does not make a big difference for us)
555
param.deviceCollate=false;
556
} else if ( (param.deviceCopies==1)&&(param.duplex) ) { // i.e. (numCopies>1), in software
557
// duplex printing of multiple software copies:
558
// collate + evenDuplex must be forced to prevent copies on the backsides
560
param.deviceCollate=false; // either (!ppd) or (ppd->manual_copies)
561
} else if (param.collate) { // collate requested by user
562
// check collate device, with current/final(!) ppd settings
563
param.deviceCollate=printerWillCollate(ppd);
564
} else { // (!param.collate)
565
param.deviceCollate=false;
622
if (param.numCopies==1) {
623
param.deviceCopies=1;
624
// collate is never needed for a single copy
625
param.collate=false; // (does not make a big difference for us)
626
} else if ( (ppd)&&(!ppd->manual_copies) ) { // hw copy generation available
627
param.deviceCopies=param.numCopies;
628
if (param.collate) { // collate requested by user
629
// check collate device, with current/final(!) ppd settings
630
param.deviceCollate=printerWillCollate(ppd);
631
if (!param.deviceCollate) {
632
// printer can't hw collate -> we must copy collated in sw
633
param.deviceCopies=1;
635
} // else: printer copies w/o collate and takes care of duplex/evenDuplex
636
} else { // sw copies
637
param.deviceCopies=1;
638
if (param.duplex) { // &&(numCopies>1)
639
// sw collate + evenDuplex must be forced to prevent copies on the backsides
641
param.deviceCollate=false;
645
// TODO? FIXME: unify code with emitJCLOptions, which does this "by-hand" now (and makes this code superfluous)
646
if (param.deviceCopies==1) {
647
// make sure any hardware copying is disabled
648
ppdMarkOption(ppd,"Copies","1");
649
ppdMarkOption(ppd,"JCLCopies","1");
651
param.numCopies=1; // disable sw copy
568
654
if ( (param.collate)&&(!param.deviceCollate) ) { // software collate
699
785
// color management
701
copyPPDLine_(fp_dest, fp_src, "*PPD-Adobe: ");
702
copyPPDLine_(fp_dest, fp_src, "*cupsICCProfile ");
787
copyPPDLine_(fp_dest, fp_src, "*PPD-Adobe: ");
788
copyPPDLine_(fp_dest, fp_src, "*cupsICCProfile ");
703
789
copyPPDLine_(fp_dest, fp_src, "*Manufacturer:");
704
790
copyPPDLine_(fp_dest, fp_src, "*ColorDevice:");
705
copyPPDLine_(fp_dest, fp_src, "*DefaultColorSpace:");
791
copyPPDLine_(fp_dest, fp_src, "*DefaultColorSpace:");
706
792
if (cupsICCProfile) {
707
793
proc.addCM(...,...);