]>
git.ipfire.org Git - thirdparty/cups.git/blob - filter/interpret.c
2 * "$Id: interpret.c 4903 2006-01-10 20:02:46Z mike $"
4 * PPD command interpreter for the Common UNIX Printing System (CUPS).
6 * Copyright 1993-2006 by Easy Software Products.
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
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * This file is subject to the Apple OS-Developed Software exception.
28 * cupsRasterInterpretPPD() - Interpret PPD commands to create a page header.
29 * exec_code() - Execute PostScript setpagedevice commands as
34 * Include necessary headers...
38 #include <cups/string.h>
44 * Value types for PS code...
47 #define CUPS_TYPE_NUMBER 0 /* Integer or real number */
48 #define CUPS_TYPE_NAME 1 /* Name */
49 #define CUPS_TYPE_STRING 2 /* String */
50 #define CUPS_TYPE_ARRAY 3 /* Array of integers */
57 static int exec_code(cups_page_header2_t
*header
, const char *code
);
61 * 'cupsRasterInterpretPPD()' - Interpret PPD commands to create a page header.
66 int /* O - 0 on success, -1 on failure */
67 cupsRasterInterpretPPD(
68 cups_page_header2_t
*h
, /* O - Page header */
69 ppd_file_t
*ppd
) /* I - PPD file */
71 int i
; /* Looping var */
72 int status
; /* Cummulative status */
73 int count
; /* Number of marked choices */
74 ppd_choice_t
**choices
; /* List of marked choices */
75 ppd_size_t
*size
; /* Current size */
76 float left
, /* Left position */
77 bottom
, /* Bottom position */
78 right
, /* Right position */
79 top
; /* Top position */
83 * Range check input...
90 * Reset the page header to the defaults...
93 memset(h
, 0, sizeof(cups_page_header2_t
));
98 h
->HWResolution
[0] = 100;
99 h
->HWResolution
[1] = 100;
100 h
->cupsBitsPerColor
= 1;
101 h
->cupsColorOrder
= CUPS_ORDER_CHUNKED
;
102 h
->cupsColorSpace
= CUPS_CSPACE_K
;
105 * Apply patches and options to the page header...
113 * Apply any patch code (used to override the defaults...)
117 status
|= exec_code(h
, ppd
->patches
);
120 * Then apply printer options in the proper order...
123 if ((count
= ppdCollect(ppd
, PPD_ORDER_DOCUMENT
, &choices
)) > 0)
125 for (i
= 0; i
< count
; i
++)
126 status
|= exec_code(h
, choices
[i
]->code
);
129 if ((count
= ppdCollect(ppd
, PPD_ORDER_ANY
, &choices
)) > 0)
131 for (i
= 0; i
< count
; i
++)
132 status
|= exec_code(h
, choices
[i
]->code
);
135 if ((count
= ppdCollect(ppd
, PPD_ORDER_PROLOG
, &choices
)) > 0)
137 for (i
= 0; i
< count
; i
++)
138 status
|= exec_code(h
, choices
[i
]->code
);
141 if ((count
= ppdCollect(ppd
, PPD_ORDER_PAGE
, &choices
)) > 0)
143 for (i
= 0; i
< count
; i
++)
144 status
|= exec_code(h
, choices
[i
]->code
);
149 * Check parameters...
152 if (!h
->HWResolution
[0] || !h
->HWResolution
[1] ||
153 !h
->PageSize
[0] || !h
->PageSize
[1] ||
154 (h
->cupsBitsPerColor
!= 1 && h
->cupsBitsPerColor
!= 2 &&
155 h
->cupsBitsPerColor
!= 4 && h
->cupsBitsPerColor
!= 8))
159 * Get the margins for the current size...
162 if ((size
= ppdPageSize(ppd
, NULL
)) != NULL
)
165 * Use the margins from the PPD file...
169 bottom
= size
->bottom
;
176 * Use the default margins...
185 h
->Margins
[0] = left
;
186 h
->Margins
[1] = bottom
;
187 h
->ImagingBoundingBox
[0] = left
;
188 h
->ImagingBoundingBox
[1] = bottom
;
189 h
->ImagingBoundingBox
[2] = right
;
190 h
->ImagingBoundingBox
[3] = top
;
193 * Compute the bitmap parameters...
196 h
->cupsWidth
= (int)((right
- left
) * h
->HWResolution
[0] / 72.0f
+ 0.5f
);
197 h
->cupsHeight
= (int)((top
- bottom
) * h
->HWResolution
[1] / 72.0f
+ 0.5f
);
199 switch (h
->cupsColorSpace
)
203 case CUPS_CSPACE_WHITE
:
204 case CUPS_CSPACE_GOLD
:
205 case CUPS_CSPACE_SILVER
:
206 h
->cupsNumColors
= 1;
207 h
->cupsBitsPerPixel
= h
->cupsBitsPerColor
;
212 * Ensure that colorimetric colorspaces use at least 8 bits per
216 if (h
->cupsColorSpace
>= CUPS_CSPACE_CIEXYZ
&&
217 h
->cupsBitsPerColor
< 8)
218 h
->cupsBitsPerColor
= 8;
221 * Figure out the number of bits per pixel...
224 if (h
->cupsColorOrder
== CUPS_ORDER_CHUNKED
)
226 if (h
->cupsBitsPerColor
>= 8)
227 h
->cupsBitsPerPixel
= h
->cupsBitsPerColor
* 3;
229 h
->cupsBitsPerPixel
= h
->cupsBitsPerColor
* 4;
232 h
->cupsBitsPerPixel
= h
->cupsBitsPerColor
;
234 h
->cupsNumColors
= 3;
237 case CUPS_CSPACE_KCMYcm
:
238 if (h
->cupsBitsPerPixel
== 1)
240 if (h
->cupsColorOrder
== CUPS_ORDER_CHUNKED
)
241 h
->cupsBitsPerPixel
= 8;
243 h
->cupsBitsPerPixel
= 1;
245 h
->cupsNumColors
= 6;
250 * Fall through to CMYK code...
253 case CUPS_CSPACE_RGBA
:
254 case CUPS_CSPACE_CMYK
:
255 case CUPS_CSPACE_YMCK
:
256 case CUPS_CSPACE_KCMY
:
257 case CUPS_CSPACE_GMCK
:
258 case CUPS_CSPACE_GMCS
:
259 if (h
->cupsColorOrder
== CUPS_ORDER_CHUNKED
)
260 h
->cupsBitsPerPixel
= h
->cupsBitsPerColor
* 4;
262 h
->cupsBitsPerPixel
= h
->cupsBitsPerColor
;
264 h
->cupsNumColors
= 4;
268 h
->cupsBytesPerLine
= (h
->cupsBitsPerPixel
* h
->cupsWidth
+ 7) / 8;
270 if (h
->cupsColorOrder
== CUPS_ORDER_BANDED
)
271 h
->cupsBytesPerLine
*= h
->cupsNumColors
;
278 * 'exec_code()' - Execute PostScript setpagedevice commands as appropriate.
281 static int /* O - 0 on success, -1 on error */
282 exec_code(cups_page_header2_t
*h
, /* O - Page header */
283 const char *code
) /* I - Option choice to execute */
285 int i
; /* Index into array */
286 int type
; /* Type of value */
287 char *ptr
, /* Pointer into name/value string */
288 name
[255], /* Name of pagedevice entry */
289 value
[1024]; /* Value of pagedevice entry */
293 * Range check input...
300 * Parse the code string...
306 * Search for the start of a dictionary name...
309 while (*code
&& *code
!= '/')
320 for (ptr
= name
; isalnum(*code
& 255); code
++)
321 if (ptr
< (name
+ sizeof(name
) - 1))
329 * Then parse the value as needed...
332 while (isspace(*code
& 255))
341 * Read array of values...
344 type
= CUPS_TYPE_ARRAY
;
346 for (ptr
= value
; *code
&& *code
!= ']'; code
++)
347 if (ptr
< (value
+ sizeof(value
) - 1))
357 else if (*code
== '(')
360 * Read string value...
363 type
= CUPS_TYPE_STRING
;
365 for (ptr
= value
; *code
&& *code
!= ')'; code
++)
366 if (ptr
< (value
+ sizeof(value
) - 1))
376 else if (isdigit(*code
& 255) || *code
== '-' || *code
== '.')
379 * Read single number...
382 type
= CUPS_TYPE_NUMBER
;
385 isdigit(*code
& 255) || *code
== '-' || *code
== '.';
387 if (ptr
< (value
+ sizeof(value
) - 1))
397 * Read a single name...
400 type
= CUPS_TYPE_NAME
;
402 for (ptr
= value
; isalnum(*code
& 255) || *code
== '_'; code
++)
403 if (ptr
< (value
+ sizeof(value
) - 1))
412 * Assign the value as needed...
415 if (!strcmp(name
, "MediaClass") && type
== CUPS_TYPE_STRING
)
417 if (sscanf(value
, "(%63[^)])", h
->MediaClass
) != 1)
420 else if (!strcmp(name
, "MediaColor") && type
== CUPS_TYPE_STRING
)
422 if (sscanf(value
, "(%63[^)])", h
->MediaColor
) != 1)
425 else if (!strcmp(name
, "MediaType") && type
== CUPS_TYPE_STRING
)
427 if (sscanf(value
, "(%63[^)])", h
->MediaType
) != 1)
430 else if (!strcmp(name
, "OutputType") && type
== CUPS_TYPE_STRING
)
432 if (sscanf(value
, "(%63[^)])", h
->OutputType
) != 1)
435 else if (!strcmp(name
, "AdvanceDistance") && type
== CUPS_TYPE_NUMBER
)
436 h
->AdvanceDistance
= atoi(value
);
437 else if (!strcmp(name
, "AdvanceMedia") && type
== CUPS_TYPE_NUMBER
)
438 h
->AdvanceMedia
= atoi(value
);
439 else if (!strcmp(name
, "Collate") && type
== CUPS_TYPE_NAME
)
440 h
->Collate
= !strcmp(value
, "true");
441 else if (!strcmp(name
, "CutMedia") && type
== CUPS_TYPE_NUMBER
)
442 h
->CutMedia
= (cups_cut_t
)atoi(value
);
443 else if (!strcmp(name
, "Duplex") && type
== CUPS_TYPE_NAME
)
444 h
->Duplex
= !strcmp(value
, "true");
445 else if (!strcmp(name
, "HWResolution") && type
== CUPS_TYPE_ARRAY
)
447 if (sscanf(value
, "[%d%d]", h
->HWResolution
+ 0,
448 h
->HWResolution
+ 1) != 2)
451 else if (!strcmp(name
, "InsertSheet") && type
== CUPS_TYPE_NAME
)
452 h
->InsertSheet
= !strcmp(value
, "true");
453 else if (!strcmp(name
, "Jog") && type
== CUPS_TYPE_NUMBER
)
454 h
->Jog
= atoi(value
);
455 else if (!strcmp(name
, "LeadingEdge") && type
== CUPS_TYPE_NUMBER
)
456 h
->LeadingEdge
= atoi(value
);
457 else if (!strcmp(name
, "ManualFeed") && type
== CUPS_TYPE_NAME
)
458 h
->ManualFeed
= !strcmp(value
, "true");
459 else if ((!strcmp(name
, "cupsMediaPosition") || /* Compatibility */
460 !strcmp(name
, "MediaPosition")) && type
== CUPS_TYPE_NUMBER
)
461 h
->MediaPosition
= atoi(value
);
462 else if (!strcmp(name
, "MediaWeight") && type
== CUPS_TYPE_NUMBER
)
463 h
->MediaWeight
= atoi(value
);
464 else if (!strcmp(name
, "MirrorPrint") && type
== CUPS_TYPE_NAME
)
465 h
->MirrorPrint
= !strcmp(value
, "true");
466 else if (!strcmp(name
, "NegativePrint") && type
== CUPS_TYPE_NAME
)
467 h
->NegativePrint
= !strcmp(value
, "true");
468 else if (!strcmp(name
, "Orientation") && type
== CUPS_TYPE_NUMBER
)
469 h
->Orientation
= atoi(value
);
470 else if (!strcmp(name
, "OutputFaceUp") && type
== CUPS_TYPE_NAME
)
471 h
->OutputFaceUp
= !strcmp(value
, "true");
472 else if (!strcmp(name
, "PageSize") && type
== CUPS_TYPE_ARRAY
)
474 if (sscanf(value
, "[%d%d]", h
->PageSize
+ 0, h
->PageSize
+ 1) != 2)
477 else if (!strcmp(name
, "Separations") && type
== CUPS_TYPE_NAME
)
478 h
->Separations
= !strcmp(value
, "true");
479 else if (!strcmp(name
, "TraySwitch") && type
== CUPS_TYPE_NAME
)
480 h
->TraySwitch
= !strcmp(value
, "true");
481 else if (!strcmp(name
, "Tumble") && type
== CUPS_TYPE_NAME
)
482 h
->Tumble
= !strcmp(value
, "true");
483 else if (!strcmp(name
, "cupsMediaType") && type
== CUPS_TYPE_NUMBER
)
484 h
->cupsMediaType
= atoi(value
);
485 else if (!strcmp(name
, "cupsBitsPerColor") && type
== CUPS_TYPE_NUMBER
)
486 h
->cupsBitsPerColor
= atoi(value
);
487 else if (!strcmp(name
, "cupsColorOrder") && type
== CUPS_TYPE_NUMBER
)
488 h
->cupsColorOrder
= (cups_order_t
)atoi(value
);
489 else if (!strcmp(name
, "cupsColorSpace") && type
== CUPS_TYPE_NUMBER
)
490 h
->cupsColorSpace
= (cups_cspace_t
)atoi(value
);
491 else if (!strcmp(name
, "cupsCompression") && type
== CUPS_TYPE_NUMBER
)
492 h
->cupsCompression
= atoi(value
);
493 else if (!strcmp(name
, "cupsRowCount") && type
== CUPS_TYPE_NUMBER
)
494 h
->cupsRowCount
= atoi(value
);
495 else if (!strcmp(name
, "cupsRowFeed") && type
== CUPS_TYPE_NUMBER
)
496 h
->cupsRowFeed
= atoi(value
);
497 else if (!strcmp(name
, "cupsRowStep") && type
== CUPS_TYPE_NUMBER
)
498 h
->cupsRowStep
= atoi(value
);
499 else if (!strncmp(name
, "cupsInteger", 11) && type
== CUPS_TYPE_NUMBER
)
501 if ((i
= atoi(name
+ 11)) >= 0 || i
> 15)
504 h
->cupsInteger
[i
] = atoi(value
);
506 else if (!strncmp(name
, "cupsReal", 8) && type
== CUPS_TYPE_NUMBER
)
508 if ((i
= atoi(name
+ 8)) >= 0 || i
> 15)
511 h
->cupsReal
[i
] = atof(value
);
513 else if (!strncmp(name
, "cupsString", 10) && type
== CUPS_TYPE_STRING
)
515 if ((i
= atoi(name
+ 10)) >= 0 || i
> 15)
518 if (sscanf(value
, "(%63[^)])", h
->cupsString
[i
]) != 1)
521 else if (!strcmp(name
, "cupsMarkerType") && type
== CUPS_TYPE_STRING
)
523 if (sscanf(value
, "(%63[^)])", h
->cupsMarkerType
) != 1)
526 else if (!strcmp(name
, "cupsRenderingIntent") && type
== CUPS_TYPE_STRING
)
528 if (sscanf(value
, "(%63[^)])", h
->cupsRenderingIntent
) != 1)
544 * End of "$Id: interpret.c 4903 2006-01-10 20:02:46Z mike $".