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