]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/common.c
b097d5749fa33c38127ad48726675e5e3bc83f47
[thirdparty/cups.git] / filter / common.c
1 /*
2 * "$Id$"
3 *
4 * Common filter routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2005 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * This file is subject to the Apple OS-Developed Software exception.
25 *
26 * Contents:
27 *
28 * SetCommonOptions() - Set common filter options for media size,
29 * etc.
30 * UpdatePageVars() - Update the page variables for the orientation.
31 * WriteCommon() - Write common procedures...
32 * WriteLabelProlog() - Write the prolog with the classification
33 * and page label.
34 * WriteLabels() - Write the actual page labels.
35 */
36
37 /*
38 * Include necessary headers...
39 */
40
41 #include "common.h"
42 #include <locale.h>
43
44
45 /*
46 * Globals...
47 */
48
49 int Orientation = 0, /* 0 = portrait, 1 = landscape, etc. */
50 Duplex = 0, /* Duplexed? */
51 LanguageLevel = 1, /* Language level of printer */
52 ColorDevice = 1; /* Do color text? */
53 float PageLeft = 18.0f, /* Left margin */
54 PageRight = 594.0f, /* Right margin */
55 PageBottom = 36.0f, /* Bottom margin */
56 PageTop = 756.0f, /* Top margin */
57 PageWidth = 612.0f, /* Total page width */
58 PageLength = 792.0f; /* Total page length */
59
60
61 /*
62 * 'SetCommonOptions()' - Set common filter options for media size, etc.
63 */
64
65 ppd_file_t * /* O - PPD file */
66 SetCommonOptions(int num_options, /* I - Number of options */
67 cups_option_t *options, /* I - Options */
68 int change_size) /* I - Change page size? */
69 {
70 ppd_file_t *ppd; /* PPD file */
71 ppd_size_t *pagesize; /* Current page size */
72 const char *val; /* Option value */
73
74
75 #ifdef LC_TIME
76 setlocale(LC_TIME, "");
77 #endif /* LC_TIME */
78
79 ppd = ppdOpenFile(getenv("PPD"));
80
81 ppdMarkDefaults(ppd);
82 cupsMarkOptions(ppd, num_options, options);
83
84 if ((pagesize = ppdPageSize(ppd, NULL)) != NULL)
85 {
86 PageWidth = pagesize->width;
87 PageLength = pagesize->length;
88 PageTop = pagesize->top;
89 PageBottom = pagesize->bottom;
90 PageLeft = pagesize->left;
91 PageRight = pagesize->right;
92
93 fprintf(stderr, "DEBUG: Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n",
94 PageWidth, PageLength, PageLeft, PageBottom, PageRight, PageTop);
95 }
96
97 if (ppd != NULL)
98 {
99 ColorDevice = ppd->color_device;
100 LanguageLevel = ppd->language_level;
101 }
102
103 if ((val = cupsGetOption("landscape", num_options, options)) != NULL)
104 {
105 if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 &&
106 strcasecmp(val, "false") != 0)
107 {
108 if (ppd && ppd->landscape > 0)
109 Orientation = 1;
110 else
111 Orientation = 3;
112 }
113 }
114 else if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL)
115 {
116 /*
117 * Map IPP orientation values to 0 to 3:
118 *
119 * 3 = 0 degrees = 0
120 * 4 = 90 degrees = 1
121 * 5 = -90 degrees = 3
122 * 6 = 180 degrees = 2
123 */
124
125 Orientation = atoi(val) - 3;
126 if (Orientation >= 2)
127 Orientation ^= 1;
128 }
129
130 if ((val = cupsGetOption("page-left", num_options, options)) != NULL)
131 {
132 switch (Orientation & 3)
133 {
134 case 0 :
135 PageLeft = (float)atof(val);
136 break;
137 case 1 :
138 PageBottom = (float)atof(val);
139 break;
140 case 2 :
141 PageRight = PageWidth - (float)atof(val);
142 break;
143 case 3 :
144 PageTop = PageLength - (float)atof(val);
145 break;
146 }
147 }
148
149 if ((val = cupsGetOption("page-right", num_options, options)) != NULL)
150 {
151 switch (Orientation & 3)
152 {
153 case 0 :
154 PageRight = PageWidth - (float)atof(val);
155 break;
156 case 1 :
157 PageTop = PageLength - (float)atof(val);
158 break;
159 case 2 :
160 PageLeft = (float)atof(val);
161 break;
162 case 3 :
163 PageBottom = (float)atof(val);
164 break;
165 }
166 }
167
168 if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL)
169 {
170 switch (Orientation & 3)
171 {
172 case 0 :
173 PageBottom = (float)atof(val);
174 break;
175 case 1 :
176 PageLeft = (float)atof(val);
177 break;
178 case 2 :
179 PageTop = PageLength - (float)atof(val);
180 break;
181 case 3 :
182 PageRight = PageWidth - (float)atof(val);
183 break;
184 }
185 }
186
187 if ((val = cupsGetOption("page-top", num_options, options)) != NULL)
188 {
189 switch (Orientation & 3)
190 {
191 case 0 :
192 PageTop = PageLength - (float)atof(val);
193 break;
194 case 1 :
195 PageRight = PageWidth - (float)atof(val);
196 break;
197 case 2 :
198 PageBottom = (float)atof(val);
199 break;
200 case 3 :
201 PageLeft = (float)atof(val);
202 break;
203 }
204 }
205
206 if (change_size)
207 UpdatePageVars();
208
209 if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") ||
210 ppdIsMarked(ppd, "Duplex", "DuplexTumble") ||
211 ppdIsMarked(ppd, "JCLDuplex", "DuplexNoTumble") ||
212 ppdIsMarked(ppd, "JCLDuplex", "DuplexTumble") ||
213 ppdIsMarked(ppd, "EFDuplex", "DuplexNoTumble") ||
214 ppdIsMarked(ppd, "EFDuplex", "DuplexTumble") ||
215 ppdIsMarked(ppd, "KD03Duplex", "DuplexNoTumble") ||
216 ppdIsMarked(ppd, "KD03Duplex", "DuplexTumble"))
217 Duplex = 1;
218
219 return (ppd);
220 }
221
222
223 /*
224 * 'UpdatePageVars()' - Update the page variables for the orientation.
225 */
226
227 void
228 UpdatePageVars(void)
229 {
230 float temp; /* Swapping variable */
231
232
233 switch (Orientation & 3)
234 {
235 case 0 : /* Portait */
236 break;
237
238 case 1 : /* Landscape */
239 temp = PageLeft;
240 PageLeft = PageBottom;
241 PageBottom = temp;
242
243 temp = PageRight;
244 PageRight = PageTop;
245 PageTop = temp;
246
247 temp = PageWidth;
248 PageWidth = PageLength;
249 PageLength = temp;
250 break;
251
252 case 2 : /* Reverse Portrait */
253 temp = PageWidth - PageLeft;
254 PageLeft = PageWidth - PageRight;
255 PageRight = temp;
256
257 temp = PageLength - PageBottom;
258 PageBottom = PageLength - PageTop;
259 PageTop = temp;
260 break;
261
262 case 3 : /* Reverse Landscape */
263 temp = PageWidth - PageLeft;
264 PageLeft = PageWidth - PageRight;
265 PageRight = temp;
266
267 temp = PageLength - PageBottom;
268 PageBottom = PageLength - PageTop;
269 PageTop = temp;
270
271 temp = PageLeft;
272 PageLeft = PageBottom;
273 PageBottom = temp;
274
275 temp = PageRight;
276 PageRight = PageTop;
277 PageTop = temp;
278
279 temp = PageWidth;
280 PageWidth = PageLength;
281 PageLength = temp;
282 break;
283 }
284 }
285
286
287 /*
288 * 'WriteCommon()' - Write common procedures...
289 */
290
291 void
292 WriteCommon(void)
293 {
294 puts("% x y w h ESPrc - Clip to a rectangle.\n"
295 "userdict/ESPrc/rectclip where{pop/rectclip load}\n"
296 "{{newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
297 "neg 0 rlineto closepath clip newpath}bind}ifelse put");
298 puts("% x y w h ESPrf - Fill a rectangle.\n"
299 "userdict/ESPrf/rectfill where{pop/rectfill load}\n"
300 "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
301 "neg 0 rlineto closepath fill grestore}bind}ifelse put");
302 puts("% x y w h ESPrs - Stroke a rectangle.\n"
303 "userdict/ESPrs/rectstroke where{pop/rectstroke load}\n"
304 "{{gsave newpath 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto\n"
305 "neg 0 rlineto closepath stroke grestore}bind}ifelse put");
306 }
307
308
309 /*
310 * 'WriteLabelProlog()' - Write the prolog with the classification
311 * and page label.
312 */
313
314 void
315 WriteLabelProlog(const char *label, /* I - Page label */
316 float bottom, /* I - Bottom position in points */
317 float top, /* I - Top position in points */
318 float width) /* I - Width in points */
319 {
320 const char *classification; /* CLASSIFICATION environment variable */
321 const char *ptr; /* Temporary string pointer */
322
323
324 /*
325 * First get the current classification...
326 */
327
328 if ((classification = getenv("CLASSIFICATION")) == NULL)
329 classification = "";
330 if (strcmp(classification, "none") == 0)
331 classification = "";
332
333 /*
334 * If there is nothing to show, bind an empty 'write labels' procedure
335 * and return...
336 */
337
338 if (!classification[0] && (label == NULL || !label[0]))
339 {
340 puts("userdict/ESPwl{}bind put");
341 return;
342 }
343
344 /*
345 * Set the classification + page label string...
346 */
347
348 printf("userdict");
349 if (strcmp(classification, "confidential") == 0)
350 printf("/ESPpl(CONFIDENTIAL");
351 else if (strcmp(classification, "classified") == 0)
352 printf("/ESPpl(CLASSIFIED");
353 else if (strcmp(classification, "secret") == 0)
354 printf("/ESPpl(SECRET");
355 else if (strcmp(classification, "topsecret") == 0)
356 printf("/ESPpl(TOP SECRET");
357 else if (strcmp(classification, "unclassified") == 0)
358 printf("/ESPpl(UNCLASSIFIED");
359 else
360 {
361 printf("/ESPpl(");
362
363 for (ptr = classification; *ptr; ptr ++)
364 if (*ptr < 32 || *ptr > 126)
365 printf("\\%03o", *ptr);
366 else if (*ptr == '_')
367 putchar(' ');
368 else
369 {
370 if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
371 putchar('\\');
372
373 putchar(*ptr);
374 }
375 }
376
377 if (label)
378 {
379 if (classification[0])
380 printf(" - ");
381
382 /*
383 * Quote the label string as needed...
384 */
385
386 for (ptr = label; *ptr; ptr ++)
387 if (*ptr < 32 || *ptr > 126)
388 printf("\\%03o", *ptr);
389 else
390 {
391 if (*ptr == '(' || *ptr == ')' || *ptr == '\\')
392 putchar('\\');
393
394 putchar(*ptr);
395 }
396 }
397
398 puts(")put");
399
400 /*
401 * Then get a 14 point Helvetica-Bold font...
402 */
403
404 puts("userdict/ESPpf /Helvetica-Bold findfont 14 scalefont put");
405
406 /*
407 * Finally, the procedure to write the labels on the page...
408 */
409
410 puts("userdict/ESPwl{");
411 puts(" ESPpf setfont");
412 printf(" ESPpl stringwidth pop dup 12 add exch -0.5 mul %.0f add\n",
413 width * 0.5f);
414 puts(" 1 setgray");
415 printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", bottom - 2.0);
416 printf(" dup 6 sub %.0f 3 index 20 ESPrf\n", top - 18.0);
417 puts(" 0 setgray");
418 printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", bottom - 2.0);
419 printf(" dup 6 sub %.0f 3 index 20 ESPrs\n", top - 18.0);
420 printf(" dup %.0f moveto ESPpl show\n", bottom + 2.0);
421 printf(" %.0f moveto ESPpl show\n", top - 14.0);
422 puts("pop");
423 puts("}bind put");
424 }
425
426
427 /*
428 * 'WriteLabels()' - Write the actual page labels.
429 */
430
431 void
432 WriteLabels(int orient) /* I - Orientation of the page */
433 {
434 float width, /* Width of page */
435 length; /* Length of page */
436
437
438 puts("gsave");
439
440 if ((orient ^ Orientation) & 1)
441 {
442 width = PageLength;
443 length = PageWidth;
444 }
445 else
446 {
447 width = PageWidth;
448 length = PageLength;
449 }
450
451 switch (orient & 3)
452 {
453 case 1 : /* Landscape */
454 printf("%.1f 0.0 translate 90 rotate\n", length);
455 break;
456 case 2 : /* Reverse Portrait */
457 printf("%.1f %.1f translate 180 rotate\n", width, length);
458 break;
459 case 3 : /* Reverse Landscape */
460 printf("0.0 %.1f translate -90 rotate\n", width);
461 break;
462 }
463
464 puts("ESPwl");
465 puts("grestore");
466 }
467
468
469 /*
470 * End of "$Id$".
471 */