~ubuntu-branches/debian/experimental/cups-filters/experimental

« back to all changes in this revision

Viewing changes to filter/pdftopdf/pdftopdf.cc

  • Committer: Package Import Robot
  • Author(s): Didier Raboud
  • Date: 2015-01-15 18:06:05 UTC
  • mfrom: (1.2.25)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: package-import@ubuntu.com-20150115180605-fnfbqv85k3y5zggk
Tags: upstream-1.0.62
ImportĀ upstreamĀ versionĀ 1.0.62

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
// Copyright (c) 2006-2011, BBR Inc.  All rights reserved.
4
4
// MIT Licensed.
5
5
 
6
 
// TODO: check ppd==NULL (?)
7
 
 
8
6
#include <stdio.h>
9
7
#include <assert.h>
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
 
12
#endif
 
13
#ifdef HAVE_CUPS_1_7
 
14
#include <cups/pwg.h>
 
15
#endif /* HAVE_CUPS_1_7 */
 
16
#include <iomanip>
 
17
#include <sstream>
12
18
#include <memory>
13
19
 
14
20
#include "pdftopdf_processor.h"
49
55
  if ( (choice=ppdFindMarkedChoice(ppd,"MirrorPrint")) != NULL) {
50
56
    choice->marked=0;
51
57
  }
52
 
 
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");
58
 
  }
59
58
}
60
59
 
61
60
// for choice, only overwrites ret if found in ppd
119
118
 
120
119
static bool ppdGetDuplex(ppd_file_t *ppd) // {{{
121
120
{
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[] = {
 
123
    "Duplex",
 
124
    "JCLDuplex",
 
125
    "EFDuplex",
 
126
    "KD03Duplex",
 
127
    NULL
 
128
  };
 
129
  const char *choice_names[] = {
 
130
    "DuplexNoTumble",
 
131
    "DuplexTumble",
 
132
    "LongEdge",
 
133
    "ShortEdge",
 
134
    "Top",
 
135
    "Bottom",
 
136
    NULL
 
137
  };
 
138
  for (option = option_names; *option; option ++)
 
139
    for (choice = choice_names; *choice; choice ++)
 
140
      if (ppdIsMarked(ppd, *option, *choice))
 
141
        return 1;
 
142
  return 0;
130
143
}
131
144
// }}}
132
145
 
172
185
    */
173
186
    return (strcasecmp(val,"separate-documents-uncollated-copies")!=0);
174
187
  }
 
188
 
 
189
  if ( (val=cupsGetOption("sheet-collate",num_options,options)) != NULL) {
 
190
    return (strcasecmp(val,"uncollated")!=0);
 
191
  }
 
192
 
175
193
  return false;
176
194
}
177
195
// }}}
280
298
 
281
299
void getParameters(ppd_file_t *ppd,int num_options,cups_option_t *options,ProcessingParameters &param) // {{{
282
300
{
 
301
  const char *val;
 
302
 
 
303
  if ((val = cupsGetOption("copies",num_options,options)) != NULL) {
 
304
    int copies = atoi(val);
 
305
    if (copies > 0)
 
306
      param.numCopies = copies;
 
307
  }
283
308
  // param.numCopies initially from commandline
284
309
  if (param.numCopies==1) {
285
310
    ppdGetInt(ppd,"Copies",&param.numCopies);
288
313
    param.numCopies=1;
289
314
  }
290
315
 
291
 
  const char *val;
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));
299
323
 
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;
 
326
  } else {
301
327
    param.normal_landscape=ROT_90;
302
 
  } else {
303
 
    param.normal_landscape=ROT_270;
304
328
  }
305
329
 
306
330
  int ipprot;
331
355
    param.page.width=pagesize->width;
332
356
    param.page.height=pagesize->length;
333
357
  }
 
358
#ifdef HAVE_CUPS_1_7
 
359
  else {
 
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);
 
377
      }
 
378
      else
 
379
        fprintf(stderr, "DEBUG: Unsupported page size %s.\n", val);
 
380
    }
 
381
  }
 
382
#endif /* HAVE_CUPS_1_7 */
 
383
 
334
384
  param.paper_is_landscape=(param.page.width>param.page.height);
335
385
 
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);
342
392
 
 
393
  if ((val = cupsGetOption("media-top-margin", num_options, options))
 
394
      != NULL)
 
395
    tmp.top = atof(val) * 72.0 / 2540.0; 
 
396
  if ((val = cupsGetOption("media-left-margin", num_options, options))
 
397
      != NULL)
 
398
    tmp.left = atof(val) * 72.0 / 2540.0; 
 
399
  if ((val = cupsGetOption("media-right-margin", num_options, options))
 
400
      != NULL)
 
401
    tmp.right = atof(val) * 72.0 / 2540.0; 
 
402
  if ((val = cupsGetOption("media-bottom-margin", num_options, options))
 
403
      != NULL)
 
404
    tmp.bottom = atof(val) * 72.0 / 2540.0; 
 
405
 
343
406
  if ( (param.orientation==ROT_90)||(param.orientation==ROT_270) ) { // unrotate page
344
407
    // NaN stays NaN
345
408
    tmp.right=param.page.height-tmp.right;
396
459
    }
397
460
  }
398
461
 
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);
403
467
  }
404
468
 
405
 
  // TODO: pageLabel  (not used)
406
 
  // param.pageLabel=cupsGetOption("page-label",num_options,options);  // strdup?
 
469
  std::string rawlabel;
 
470
  char *classification = getenv("CLASSIFICATION");
 
471
  if (classification)
 
472
    rawlabel.append (classification);
 
473
 
 
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));
 
478
  }
 
479
 
 
480
  std::ostringstream cookedlabel;
 
481
  for (std::string::iterator it = rawlabel.begin();
 
482
       it != rawlabel.end ();
 
483
       ++it) {
 
484
    if (*it < 32 || *it > 126)
 
485
      cookedlabel << "\\" << std::oct << std::setfill('0') << std::setw(3) << (unsigned int) *it;
 
486
    else
 
487
      cookedlabel.put (*it);
 
488
  }
 
489
  param.pageLabel = cookedlabel.str ();
407
490
 
408
491
  if ( (val=cupsGetOption("page-set",num_options,options)) != NULL) {
409
492
    if (strcasecmp(val,"even")==0) {
488
571
// }}}
489
572
*/
490
573
 
491
 
  // make pages a multiple of two (only considered when duplex is on). 
 
574
  // make pages a multiple of two (only considered when duplex is on).
492
575
  // i.e. printer has hardware-duplex, but needs pre-inserted filler pages
493
576
  // FIXME? pdftopdf also supports it as cmdline option (via checkFeature())
494
577
  ppd_attr_t *attr;
534
617
    }
535
618
  }
536
619
 
537
 
#if 1    // for now
538
 
  // enable hardware copy generation
539
 
  if (ppd) {
540
 
    if (!ppd->manual_copies) {
541
 
      // use hardware copying
542
 
      param.deviceCopies=param.numCopies;
543
 
      param.numCopies=1;
544
 
    } else {
545
 
      param.deviceCopies=1;
546
 
    }
547
 
  }
548
 
#endif
549
 
 
550
620
  setFinalPPD(ppd,param);
551
621
 
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
559
 
    param.collate=true;
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;
 
634
      }
 
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
 
640
      param.collate=true;
 
641
      param.deviceCollate=false;
 
642
    }
 
643
  }
 
644
 
 
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");
 
650
  } else { // hw copy
 
651
    param.numCopies=1; // disable sw copy
566
652
  }
567
653
 
568
654
  if ( (param.collate)&&(!param.deviceCollate) ) { // software collate
576
662
}
577
663
// }}}
578
664
 
579
 
// reads from stdin into temporary file. returns FILE *  or NULL on error 
 
665
// reads from stdin into temporary file. returns FILE *  or NULL on error
580
666
// TODO? to extra file (also used in pdftoijs, e.g.)
581
667
FILE *copy_stdin_to_temp() // {{{
582
668
{
637
723
/*
638
724
*/
639
725
//param.nup.yalign=TOP;
640
 
param.border=BorderType::ONE;
 
726
param.border=BorderType::NONE;
641
727
//param.mirror=true;
642
728
//param.reverse=true;
643
729
//param.numCopies=3;
698
784
/* TODO
699
785
    // color management
700
786
--- PPD:
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(...,...);
708
794
    }