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