2 * "$Id: common.c 9793 2011-05-20 03:49:49Z mike $"
4 * Common filter routines for CUPS.
6 * Copyright 2007-2011 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * SetCommonOptions() - Set common filter options for media size,
21 * UpdatePageVars() - Update the page variables for the orientation.
22 * WriteComment() - Write a DSC comment.
23 * WriteCommon() - Write common procedures...
24 * WriteLabelProlog() - Write the prolog with the classification
26 * WriteLabels() - Write the actual page labels.
30 * Include necessary headers...
41 int Orientation = 0, /* 0 = portrait, 1 = landscape, etc. */
42 Duplex = 0, /* Duplexed? */
43 LanguageLevel = 1, /* Language level of printer */
44 ColorDevice = 1; /* Do color text? */
45 float PageLeft = 18.0f, /* Left margin */
46 PageRight = 594.0f, /* Right margin */
47 PageBottom = 36.0f, /* Bottom margin */
48 PageTop = 756.0f, /* Top margin */
49 PageWidth = 612.0f, /* Total page width */
50 PageLength = 792.0f; /* Total page length */
54 * 'SetCommonOptions()' - Set common filter options for media size, etc.
57 ppd_file_t * /* O - PPD file */
59 int num_options, /* I - Number of options */
60 cups_option_t *options, /* I - Options */
61 int change_size) /* I - Change page size? */
63 ppd_file_t *ppd; /* PPD file */
64 ppd_size_t *pagesize; /* Current page size */
65 const char *val; /* Option value */
69 setlocale(LC_TIME, "");
72 ppd = ppdOpenFile(getenv("PPD"));
75 cupsMarkOptions(ppd, num_options, options);
77 if ((pagesize = ppdPageSize(ppd, NULL)) != NULL)
79 PageWidth = pagesize->width;
80 PageLength = pagesize->length;
81 PageTop = pagesize->top;
82 PageBottom = pagesize->bottom;
83 PageLeft = pagesize->left;
84 PageRight = pagesize->right;
86 fprintf(stderr, "DEBUG: Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
87 PageWidth, PageLength, PageLeft, PageBottom, PageRight, PageTop);
92 ColorDevice = ppd->color_device;
93 LanguageLevel = ppd->language_level;
96 if ((val = cupsGetOption("landscape", num_options, options)) != NULL)
98 if (_cups_strcasecmp(val, "no") != 0 && _cups_strcasecmp(val, "off") != 0 &&
99 _cups_strcasecmp(val, "false") != 0)
101 if (ppd && ppd->landscape > 0)
107 else if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL)
110 * Map IPP orientation values to 0 to 3:
114 * 5 = -90 degrees = 3
115 * 6 = 180 degrees = 2
118 Orientation = atoi(val) - 3;
119 if (Orientation >= 2)
123 if ((val = cupsGetOption("page-left", num_options, options)) != NULL)
125 switch (Orientation & 3)
128 PageLeft = (float)atof(val);
131 PageBottom = (float)atof(val);
134 PageRight = PageWidth - (float)atof(val);
137 PageTop = PageLength - (float)atof(val);
142 if ((val = cupsGetOption("page-right", num_options, options)) != NULL)
144 switch (Orientation & 3)
147 PageRight = PageWidth - (float)atof(val);
150 PageTop = PageLength - (float)atof(val);
153 PageLeft = (float)atof(val);
156 PageBottom = (float)atof(val);
161 if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL)
163 switch (Orientation & 3)
166 PageBottom = (float)atof(val);
169 PageLeft = (float)atof(val);
172 PageTop = PageLength - (float)atof(val);
175 PageRight = PageWidth - (float)atof(val);
180 if ((val = cupsGetOption("page-top", num_options, options)) != NULL)
182 switch (Orientation & 3)
185 PageTop = PageLength - (float)atof(val);
188 PageRight = PageWidth - (float)atof(val);
191 PageBottom = (float)atof(val);
194 PageLeft = (float)atof(val);
202 if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
203 ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
204 ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
205 ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
206 ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
207 ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
208 ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
209 ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))
217 * 'UpdatePageVars()' - Update the page variables for the orientation.
223 float temp; /* Swapping variable */
226 switch (Orientation & 3)
228 case 0 : /* Portait */
231 case 1 : /* Landscape */
233 PageLeft = PageBottom;
241 PageWidth = PageLength;
245 case 2 : /* Reverse Portrait */
246 temp = PageWidth - PageLeft;
247 PageLeft = PageWidth - PageRight;
250 temp = PageLength - PageBottom;
251 PageBottom = PageLength - PageTop;
255 case 3 : /* Reverse Landscape */
256 temp = PageWidth - PageLeft;
257 PageLeft = PageWidth - PageRight;
260 temp = PageLength - PageBottom;
261 PageBottom = PageLength - PageTop;
265 PageLeft = PageBottom;
273 PageWidth = PageLength;
281 * 'WriteCommon()' - Write common procedures...
287 puts("% x y w h ESPrc - Clip to a rectangle.\n"
288 "userdict/ESPrc/rectclip where{pop/rectclip load}\n"
289 "{{newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
290 "neg 0 rlineto closepath clip newpath}bind}ifelse put");
291 puts("% x y w h ESPrf - Fill a rectangle.\n"
292 "userdict/ESPrf/rectfill where{pop/rectfill load}\n"
293 "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
294 "neg 0 rlineto closepath fill grestore}bind}ifelse put");
295 puts("% x y w h ESPrs - Stroke a rectangle.\n"
296 "userdict/ESPrs/rectstroke where{pop/rectstroke load}\n"
297 "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
298 "neg 0 rlineto closepath stroke grestore}bind}ifelse put");
303 * 'WriteLabelProlog()' - Write the prolog with the classification
308 WriteLabelProlog(const char *label, /* I - Page label */
309 float bottom, /* I - Bottom position in points */
310 float top, /* I - Top position in points */
311 float width) /* I - Width in points */
313 const char *classification; /* CLASSIFICATION environment variable */
314 const char *ptr; /* Temporary string pointer */
318 * First get the current classification...
321 if ((classification = getenv("CLASSIFICATION")) == NULL)
323 if (strcmp(classification, "none") == 0)
327 * If there is nothing to show, bind an empty 'write labels' procedure
331 if (!classification[0] && (label == NULL || !label[0]))
333 puts("userdict/ESPwl{}bind put");
338 * Set the classification + page label string...
342 if (strcmp(classification, "confidential") == 0)
343 printf("/ESPpl(CONFIDENTIAL");
344 else if (strcmp(classification, "classified") == 0)
345 printf("/ESPpl(CLASSIFIED");
346 else if (strcmp(classification, "secret") == 0)
347 printf("/ESPpl(SECRET");
348 else if (strcmp(classification, "topsecret") == 0)
349 printf("/ESPpl(TOP SECRET");
350 else if (strcmp(classification, "unclassified") == 0)
351 printf("/ESPpl(UNCLASSIFIED");
356 for (ptr = classification; *ptr; ptr ++)
357 if (*ptr < 32 || *ptr > 126)
358 printf("\\%03o", *ptr);
359 else if (*ptr == '_')
363 if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
372 if (classification[0])
376 * Quote the label string as needed...
379 for (ptr = label; *ptr; ptr ++)
380 if (*ptr < 32 || *ptr > 126)
381 printf("\\%03o", *ptr);
384 if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
394 * Then get a 14 point Helvetica-Bold font...
397 puts("userdict/ESPpf /Helvetica-Bold findfont 14 scalefont put");
400 * Finally, the procedure to write the labels on the page...
403 puts("userdict/ESPwl{");
404 puts(" ESPpf setfont");
405 printf(" ESPpl stringwidth pop dup 12 add exch -0.5 mul %.0f add\n",
408 printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", bottom - 2.0);
409 printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", top - 18.0);
411 printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", bottom - 2.0);
412 printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", top - 18.0);
413 printf(" dup %.0f moveto ESPpl show\n", bottom + 2.0);
414 printf(" %.0f moveto ESPpl show\n", top - 14.0);
421 * 'WriteLabels()' - Write the actual page labels.
425 WriteLabels(int orient) /* I - Orientation of the page */
427 float width, /* Width of page */
428 length; /* Length of page */
433 if ((orient ^ Orientation) & 1)
446 case 1 : /* Landscape */
447 printf("%.1f 0.0 translate 90 rotate\n", length);
449 case 2 : /* Reverse Portrait */
450 printf("%.1f %.1f translate 180 rotate\n", width, length);
452 case 3 : /* Reverse Landscape */
453 printf("0.0 %.1f translate -90 rotate\n", width);
463 * 'WriteTextComment()' - Write a DSC text comment.
467 WriteTextComment(const char *name, /* I - Comment name ("Title", etc.) */
468 const char *value) /* I - Comment value */
470 int len; /* Current line length */
474 * DSC comments are of the form:
478 * The name and value must be limited to 7-bit ASCII for most printers,
479 * so we escape all non-ASCII and ASCII control characters as described
480 * in the Adobe Document Structuring Conventions specification.
483 printf("%%%%%s: (", name);
484 len = 5 + strlen(name);
488 if (*value < ' ' || *value >= 127)
491 * Escape this character value...
494 if (len >= 251) /* Keep line < 254 chars */
497 printf("\\%03o", *value & 255);
500 else if (*value == '\\')
503 * Escape the backslash...
506 if (len >= 253) /* Keep line < 254 chars */
516 * Put this character literally...
519 if (len >= 254) /* Keep line < 254 chars */
534 * End of "$Id: common.c 9793 2011-05-20 03:49:49Z mike $".