"Fossies" - the Fresh Open Source Software Archive

Member "cups-filters-1.25.11/filter/common.c" (10 Oct 2019, 15312 Bytes) of package /linux/misc/cups-filters-1.25.11.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "common.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  *   Common filter routines for CUPS.
    3  *
    4  *   Copyright 2007-2011 by Apple Inc.
    5  *   Copyright 1997-2006 by Easy Software Products.
    6  *
    7  *   These coded instructions, statements, and computer programs are the
    8  *   property of Apple Inc. and are protected by Federal copyright
    9  *   law.  Distribution and use rights are outlined in the file "COPYING"
   10  *   which should have been included with this file.
   11  *
   12  * Contents:
   13  *
   14  *   SetCommonOptions() - Set common filter options for media size,
   15  *                        etc.
   16  *   UpdatePageVars()   - Update the page variables for the orientation.
   17  *   WriteComment()     - Write a DSC comment.
   18  *   WriteCommon()      - Write common procedures...
   19  *   WriteLabelProlog() - Write the prolog with the classification
   20  *                        and page label.
   21  *   WriteLabels()      - Write the actual page labels.
   22  */
   23 
   24 /*
   25  * Include necessary headers...
   26  */
   27 
   28 #include "common.h"
   29 #include <locale.h>
   30 
   31 
   32 /*
   33  * Globals...
   34  */
   35 
   36 int Orientation = 0,        /* 0 = portrait, 1 = landscape, etc. */
   37     Duplex = 0,         /* Duplexed? */
   38     LanguageLevel = 1,      /* Language level of printer */
   39     ColorDevice = 1;        /* Do color text? */
   40 float   PageLeft = 18.0f,       /* Left margin */
   41     PageRight = 594.0f,     /* Right margin */
   42     PageBottom = 36.0f,     /* Bottom margin */
   43     PageTop = 756.0f,       /* Top margin */
   44     PageWidth = 612.0f,     /* Total page width */
   45     PageLength = 792.0f;        /* Total page length */
   46 
   47 
   48 /*
   49  * 'SetCommonOptions()' - Set common filter options for media size, etc.
   50  */
   51 
   52 ppd_file_t *                /* O - PPD file */
   53 SetCommonOptions(
   54     int           num_options,      /* I - Number of options */
   55     cups_option_t *options,     /* I - Options */
   56     int           change_size)      /* I - Change page size? */
   57 {
   58   ppd_file_t    *ppd;           /* PPD file */
   59   ppd_size_t    *pagesize;      /* Current page size */
   60   const char    *val;           /* Option value */
   61 
   62 
   63 #ifdef LC_TIME
   64   setlocale(LC_TIME, "");
   65 #endif /* LC_TIME */
   66 
   67   ppd = ppdOpenFile(getenv("PPD"));
   68 
   69   ppdMarkDefaults(ppd);
   70   cupsMarkOptions(ppd, num_options, options);
   71 
   72   if ((pagesize = ppdPageSize(ppd, NULL)) != NULL)
   73   {
   74     int corrected = 0;
   75     if (pagesize->width > 0) 
   76       PageWidth = pagesize->width;
   77     else
   78     {
   79       fprintf(stderr, "ERROR: Invalid value for page width: %.0f\n",
   80           pagesize->width);
   81       corrected = 1;
   82     }
   83     if (pagesize->length > 0) 
   84       PageLength = pagesize->length;
   85     else
   86     {
   87       fprintf(stderr, "ERROR: Invalid value for page length: %.0f\n",
   88           pagesize->length);
   89       corrected = 1;
   90     }
   91     if (pagesize->top >= 0 && pagesize->top <= PageLength) 
   92       PageTop = pagesize->top;
   93     else
   94     {
   95       fprintf(stderr, "ERROR: Invalid value for page top margin: %.0f\n",
   96           pagesize->top);
   97       if (PageLength >= PageBottom)
   98     PageTop = PageLength - PageBottom;
   99       else
  100     PageTop = PageLength;
  101       corrected = 1;
  102     }
  103     if (pagesize->bottom >= 0 && pagesize->bottom <= PageLength) 
  104       PageBottom = pagesize->bottom;
  105     else
  106     {
  107       fprintf(stderr, "ERROR: Invalid value for page bottom margin: %.0f\n",
  108           pagesize->bottom);
  109       if (PageLength <= PageBottom)
  110     PageBottom = 0.0f;
  111       corrected = 1;
  112     }
  113     if (PageBottom == PageTop)
  114     {
  115       fprintf(stderr, "ERROR: Invalid values for page margins: Bottom: %.0f; Top: %.0f\n",
  116           PageBottom, PageTop);
  117       PageTop = PageLength - PageBottom;
  118       if (PageBottom == PageTop)
  119       {
  120     PageBottom = 0.0f;
  121     PageTop = PageLength;
  122       }
  123       corrected = 1;
  124     }
  125     if (PageBottom > PageTop)
  126     {
  127       fprintf(stderr, "ERROR: Invalid values for page margins: Bottom: %.0f; Top: %.0f\n",
  128           PageBottom, PageTop);
  129       float swap = PageBottom;
  130       PageBottom = PageTop;
  131       PageTop = swap;
  132       corrected = 1;
  133     }
  134 
  135     if (pagesize->left >= 0 && pagesize->left <= PageWidth) 
  136       PageLeft = pagesize->left;
  137     else
  138     {
  139       fprintf(stderr, "ERROR: Invalid value for page left margin: %.0f\n",
  140           pagesize->left);
  141       if (PageWidth <= PageLeft)
  142     PageLeft = 0.0f;
  143       corrected = 1;
  144     }
  145     if (pagesize->right >= 0 && pagesize->right <= PageWidth) 
  146       PageRight = pagesize->right;
  147     else
  148     {
  149       fprintf(stderr, "ERROR: Invalid value for page right margin: %.0f\n",
  150           pagesize->right);
  151       if (PageWidth >= PageLeft)
  152     PageRight = PageWidth - PageLeft;
  153       else
  154     PageRight = PageWidth;
  155       corrected = 1;
  156     }
  157     if (PageLeft == PageRight)
  158     {
  159       fprintf(stderr, "ERROR: Invalid values for page margins: Left: %.0f; Right: %.0f\n",
  160           PageLeft, PageRight);
  161       PageRight = PageWidth - PageLeft;
  162       if (PageLeft == PageRight)
  163       {
  164     PageLeft = 0.0f;
  165     PageRight = PageWidth;
  166       }
  167       corrected = 1;
  168     }
  169     if (PageLeft > PageRight)
  170     {
  171       fprintf(stderr, "ERROR: Invalid values for page margins: Left: %.0f; Right: %.0f\n",
  172           PageLeft, PageRight);
  173       float swap = PageLeft;
  174       PageLeft = PageRight;
  175       PageRight = swap;
  176       corrected = 1;
  177     }
  178 
  179     if (corrected)
  180     {
  181       fprintf(stderr, "ERROR: PPD Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
  182           pagesize->width, pagesize->length, pagesize->left, pagesize->bottom, pagesize->right, pagesize->top);
  183       fprintf(stderr, "ERROR: Corrected Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
  184           PageWidth, PageLength, PageLeft, PageBottom, PageRight, PageTop);
  185     }
  186     else
  187       fprintf(stderr, "DEBUG: Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
  188           pagesize->width, pagesize->length, pagesize->left, pagesize->bottom, pagesize->right, pagesize->top);
  189   }
  190 
  191   if (ppd != NULL)
  192   {
  193     ColorDevice   = ppd->color_device;
  194     LanguageLevel = ppd->language_level;
  195   }
  196 
  197   if ((val = cupsGetOption("landscape", num_options, options)) != NULL)
  198   {
  199     if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 &&
  200         strcasecmp(val, "false") != 0)
  201     {
  202       if (ppd && ppd->landscape > 0)
  203         Orientation = 1;
  204       else
  205         Orientation = 3;
  206     }
  207   }
  208   else if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL)
  209   {
  210    /*
  211     * Map IPP orientation values to 0 to 3:
  212     *
  213     *   3 = 0 degrees   = 0
  214     *   4 = 90 degrees  = 1
  215     *   5 = -90 degrees = 3
  216     *   6 = 180 degrees = 2
  217     */
  218 
  219     Orientation = atoi(val) - 3;
  220     if (Orientation >= 2)
  221       Orientation ^= 1;
  222   }
  223 
  224   if ((val = cupsGetOption("page-left", num_options, options)) != NULL)
  225   {
  226     switch (Orientation & 3)
  227     {
  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 
  243   if ((val = cupsGetOption("page-right", num_options, options)) != NULL)
  244   {
  245     switch (Orientation & 3)
  246     {
  247       case 0 :
  248           PageRight = PageWidth - (float)atof(val);
  249       break;
  250       case 1 :
  251           PageTop = PageLength - (float)atof(val);
  252       break;
  253       case 2 :
  254           PageLeft = (float)atof(val);
  255       break;
  256       case 3 :
  257           PageBottom = (float)atof(val);
  258       break;
  259     }
  260   }
  261 
  262   if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL)
  263   {
  264     switch (Orientation & 3)
  265     {
  266       case 0 :
  267           PageBottom = (float)atof(val);
  268       break;
  269       case 1 :
  270           PageLeft = (float)atof(val);
  271       break;
  272       case 2 :
  273           PageTop = PageLength - (float)atof(val);
  274       break;
  275       case 3 :
  276           PageRight = PageWidth - (float)atof(val);
  277       break;
  278     }
  279   }
  280 
  281   if ((val = cupsGetOption("page-top", num_options, options)) != NULL)
  282   {
  283     switch (Orientation & 3)
  284     {
  285       case 0 :
  286           PageTop = PageLength - (float)atof(val);
  287       break;
  288       case 1 :
  289           PageRight = PageWidth - (float)atof(val);
  290       break;
  291       case 2 :
  292           PageBottom = (float)atof(val);
  293       break;
  294       case 3 :
  295           PageLeft = (float)atof(val);
  296       break;
  297     }
  298   }
  299 
  300   if (change_size)
  301     UpdatePageVars();
  302 
  303   if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
  304       ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
  305       ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
  306       ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
  307       ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
  308       ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
  309       ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
  310       ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))
  311     Duplex = 1;
  312 
  313   return (ppd);
  314 }
  315 
  316 
  317 /*
  318  * 'UpdatePageVars()' - Update the page variables for the orientation.
  319  */
  320 
  321 void
  322 UpdatePageVars(void)
  323 {
  324   float     temp;           /* Swapping variable */
  325 
  326 
  327   switch (Orientation & 3)
  328   {
  329     case 0 : /* Portait */
  330         break;
  331 
  332     case 1 : /* Landscape */
  333     temp       = PageLeft;
  334     PageLeft   = PageBottom;
  335     PageBottom = temp;
  336 
  337     temp       = PageRight;
  338     PageRight  = PageTop;
  339     PageTop    = temp;
  340 
  341     temp       = PageWidth;
  342     PageWidth  = PageLength;
  343     PageLength = temp;
  344     break;
  345 
  346     case 2 : /* Reverse Portrait */
  347     temp       = PageWidth - PageLeft;
  348     PageLeft   = PageWidth - PageRight;
  349     PageRight  = temp;
  350 
  351     temp       = PageLength - PageBottom;
  352     PageBottom = PageLength - PageTop;
  353     PageTop    = temp;
  354         break;
  355 
  356     case 3 : /* Reverse Landscape */
  357     temp       = PageWidth - PageLeft;
  358     PageLeft   = PageWidth - PageRight;
  359     PageRight  = temp;
  360 
  361     temp       = PageLength - PageBottom;
  362     PageBottom = PageLength - PageTop;
  363     PageTop    = temp;
  364 
  365     temp       = PageLeft;
  366     PageLeft   = PageBottom;
  367     PageBottom = temp;
  368 
  369     temp       = PageRight;
  370     PageRight  = PageTop;
  371     PageTop    = temp;
  372 
  373     temp       = PageWidth;
  374     PageWidth  = PageLength;
  375     PageLength = temp;
  376     break;
  377   }
  378 }
  379 
  380 
  381 /*
  382  * 'WriteCommon()' - Write common procedures...
  383  */
  384 
  385 void
  386 WriteCommon(void)
  387 {
  388   puts("% x y w h ESPrc - Clip to a rectangle.\n"
  389        "userdict/ESPrc/rectclip where{pop/rectclip load}\n"
  390        "{{newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
  391        "neg 0 rlineto closepath clip newpath}bind}ifelse put");
  392   puts("% x y w h ESPrf - Fill a rectangle.\n"
  393        "userdict/ESPrf/rectfill where{pop/rectfill load}\n"
  394        "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
  395        "neg 0 rlineto closepath fill grestore}bind}ifelse put");
  396   puts("% x y w h ESPrs - Stroke a rectangle.\n"
  397        "userdict/ESPrs/rectstroke where{pop/rectstroke load}\n"
  398        "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
  399        "neg 0 rlineto closepath stroke grestore}bind}ifelse put");
  400 }
  401 
  402 
  403 /*
  404  * 'WriteLabelProlog()' - Write the prolog with the classification
  405  *                        and page label.
  406  */
  407 
  408 void
  409 WriteLabelProlog(const char *label, /* I - Page label */
  410          float      bottom, /* I - Bottom position in points */
  411          float      top,    /* I - Top position in points */
  412          float      width)  /* I - Width in points */
  413 {
  414   const char    *classification;    /* CLASSIFICATION environment variable */
  415   const char    *ptr;           /* Temporary string pointer */
  416 
  417 
  418  /*
  419   * First get the current classification...
  420   */
  421 
  422   if ((classification = getenv("CLASSIFICATION")) == NULL)
  423     classification = "";
  424   if (strcmp(classification, "none") == 0)
  425     classification = "";
  426 
  427  /*
  428   * If there is nothing to show, bind an empty 'write labels' procedure
  429   * and return...
  430   */
  431 
  432   if (!classification[0] && (label == NULL || !label[0]))
  433   {
  434     puts("userdict/ESPwl{}bind put");
  435     return;
  436   }
  437 
  438  /*
  439   * Set the classification + page label string...
  440   */
  441 
  442   printf("userdict");
  443   if (strcmp(classification, "confidential") == 0)
  444     printf("/ESPpl(CONFIDENTIAL");
  445   else if (strcmp(classification, "classified") == 0)
  446     printf("/ESPpl(CLASSIFIED");
  447   else if (strcmp(classification, "secret") == 0)
  448     printf("/ESPpl(SECRET");
  449   else if (strcmp(classification, "topsecret") == 0)
  450     printf("/ESPpl(TOP SECRET");
  451   else if (strcmp(classification, "unclassified") == 0)
  452     printf("/ESPpl(UNCLASSIFIED");
  453   else
  454   {
  455     printf("/ESPpl(");
  456 
  457     for (ptr = classification; *ptr; ptr ++)
  458       if (*ptr < 32 || *ptr > 126)
  459         printf("\\%03o", *ptr);
  460       else if (*ptr == '_')
  461         putchar(' ');
  462       else
  463       {
  464     if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
  465       putchar('\\');
  466 
  467     putchar(*ptr);
  468       }
  469   }
  470 
  471   if (label)
  472   {
  473     if (classification[0])
  474       printf(" - ");
  475 
  476    /*
  477     * Quote the label string as needed...
  478     */
  479 
  480     for (ptr = label; *ptr; ptr ++)
  481       if (*ptr < 32 || *ptr > 126)
  482         printf("\\%03o", *ptr);
  483       else
  484       {
  485     if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
  486       putchar('\\');
  487 
  488     putchar(*ptr);
  489       }
  490   }
  491 
  492   puts(")put");
  493 
  494  /*
  495   * Then get a 14 point Helvetica-Bold font...
  496   */
  497 
  498   puts("userdict/ESPpf /Helvetica-Bold findfont 14 scalefont put");
  499 
  500  /*
  501   * Finally, the procedure to write the labels on the page...
  502   */
  503 
  504   puts("userdict/ESPwl{");
  505   puts("  ESPpf setfont");
  506   printf("  ESPpl stringwidth pop dup 12 add exch -0.5 mul %.0f add\n",
  507          width * 0.5f);
  508   puts("  1 setgray");
  509   printf("  dup 6 sub %.0f 3 index 20 ESPrf\n", bottom - 2.0);
  510   printf("  dup 6 sub %.0f 3 index 20 ESPrf\n", top - 18.0);
  511   puts("  0 setgray");
  512   printf("  dup 6 sub %.0f 3 index 20 ESPrs\n", bottom - 2.0);
  513   printf("  dup 6 sub %.0f 3 index 20 ESPrs\n", top - 18.0);
  514   printf("  dup %.0f moveto ESPpl show\n", bottom + 2.0);
  515   printf("  %.0f moveto ESPpl show\n", top - 14.0);
  516   puts("pop");
  517   puts("}bind put");
  518 }
  519 
  520 
  521 /*
  522  * 'WriteLabels()' - Write the actual page labels.
  523  */
  524 
  525 void
  526 WriteLabels(int orient) /* I - Orientation of the page */
  527 {
  528   float width,      /* Width of page */
  529     length;     /* Length of page */
  530 
  531 
  532   puts("gsave");
  533 
  534   if ((orient ^ Orientation) & 1)
  535   {
  536     width  = PageLength;
  537     length = PageWidth;
  538   }
  539   else
  540   {
  541     width  = PageWidth;
  542     length = PageLength;
  543   }
  544 
  545   switch (orient & 3)
  546   {
  547     case 1 : /* Landscape */
  548         printf("%.1f 0.0 translate 90 rotate\n", length);
  549         break;
  550     case 2 : /* Reverse Portrait */
  551         printf("%.1f %.1f translate 180 rotate\n", width, length);
  552         break;
  553     case 3 : /* Reverse Landscape */
  554         printf("0.0 %.1f translate -90 rotate\n", width);
  555         break;
  556   }
  557 
  558   puts("ESPwl");
  559   puts("grestore");
  560 }
  561 
  562 
  563 /*
  564  * 'WriteTextComment()' - Write a DSC text comment.
  565  */
  566 
  567 void
  568 WriteTextComment(const char *name,  /* I - Comment name ("Title", etc.) */
  569                  const char *value) /* I - Comment value */
  570 {
  571   int   len;                /* Current line length */
  572 
  573 
  574  /*
  575   * DSC comments are of the form:
  576   *
  577   *   %%name: value
  578   *
  579   * The name and value must be limited to 7-bit ASCII for most printers,
  580   * so we escape all non-ASCII and ASCII control characters as described
  581   * in the Adobe Document Structuring Conventions specification.
  582   */
  583 
  584   printf("%%%%%s: (", name);
  585   len = 5 + strlen(name);
  586 
  587   while (*value)
  588   {
  589     if (*value < ' ' || *value >= 127)
  590     {
  591      /*
  592       * Escape this character value...
  593       */
  594 
  595       if (len >= 251)           /* Keep line < 254 chars */
  596         break;
  597 
  598       printf("\\%03o", *value & 255);
  599       len += 4;
  600     }
  601     else if (*value == '\\')
  602     {
  603      /*
  604       * Escape the backslash...
  605       */
  606 
  607       if (len >= 253)           /* Keep line < 254 chars */
  608         break;
  609 
  610       putchar('\\');
  611       putchar('\\');
  612       len += 2;
  613     }
  614     else
  615     {
  616      /*
  617       * Put this character literally...
  618       */
  619 
  620       if (len >= 254)           /* Keep line < 254 chars */
  621         break;
  622 
  623       putchar(*value);
  624       len ++;
  625     }
  626 
  627     value ++;
  628   }
  629 
  630   puts(")");
  631 }
  632