]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
b19ccc9e | 2 | * "$Id: page.c 7791 2008-07-24 00:55:30Z mike $" |
ef416fc2 | 3 | * |
71e16022 | 4 | * Page size functions for CUPS. |
ef416fc2 | 5 | * |
f8b3a85b | 6 | * Copyright 2007-2010 by Apple Inc. |
b86bc4cf | 7 | * Copyright 1997-2007 by Easy Software Products, all rights reserved. |
ef416fc2 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 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/". | |
ef416fc2 | 14 | * |
15 | * PostScript is a trademark of Adobe Systems, Inc. | |
16 | * | |
17 | * This file is subject to the Apple OS-Developed Software exception. | |
18 | * | |
19 | * Contents: | |
20 | * | |
b0f6947b MS |
21 | * ppdPageSize() - Get the page size record for the given size. |
22 | * ppdPageSizeLimits() - Return the custom page size limits. | |
23 | * ppdPageWidth() - Get the page width for the given size. | |
24 | * ppdPageLength() - Get the page length for the given size. | |
ef416fc2 | 25 | */ |
26 | ||
27 | /* | |
28 | * Include necessary headers... | |
29 | */ | |
30 | ||
71e16022 MS |
31 | #include "string-private.h" |
32 | #include "debug-private.h" | |
ef416fc2 | 33 | #include "ppd.h" |
ef416fc2 | 34 | |
35 | ||
36 | /* | |
37 | * 'ppdPageSize()' - Get the page size record for the given size. | |
38 | */ | |
39 | ||
757d2cad | 40 | ppd_size_t * /* O - Size record for page or NULL */ |
41 | ppdPageSize(ppd_file_t *ppd, /* I - PPD file record */ | |
42 | const char *name) /* I - Size name */ | |
ef416fc2 | 43 | { |
757d2cad | 44 | int i; /* Looping var */ |
b86bc4cf | 45 | ppd_size_t *size; /* Current page size */ |
54afec33 | 46 | double w, l; /* Width and length of page */ |
757d2cad | 47 | char *nameptr; /* Pointer into name */ |
48 | struct lconv *loc; /* Locale data */ | |
b86bc4cf | 49 | ppd_coption_t *coption; /* Custom option for page size */ |
50 | ppd_cparam_t *cparam; /* Custom option parameter */ | |
ef416fc2 | 51 | |
52 | ||
f11a948a | 53 | DEBUG_printf(("2ppdPageSize(ppd=%p, name=\"%s\")", ppd, name)); |
d1c13e16 | 54 | |
757d2cad | 55 | if (!ppd) |
d1c13e16 | 56 | { |
f11a948a | 57 | DEBUG_puts("3ppdPageSize: Bad PPD pointer, returning NULL..."); |
ef416fc2 | 58 | return (NULL); |
d1c13e16 | 59 | } |
ef416fc2 | 60 | |
757d2cad | 61 | if (name) |
ef416fc2 | 62 | { |
757d2cad | 63 | if (!strncmp(name, "Custom.", 7) && ppd->variable_sizes) |
ef416fc2 | 64 | { |
65 | /* | |
66 | * Find the custom page size... | |
67 | */ | |
68 | ||
b86bc4cf | 69 | for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) |
70 | if (!strcmp("Custom", size->name)) | |
ef416fc2 | 71 | break; |
72 | ||
b86bc4cf | 73 | if (!i) |
d1c13e16 | 74 | { |
f11a948a | 75 | DEBUG_puts("3ppdPageSize: No custom sizes, returning NULL..."); |
ef416fc2 | 76 | return (NULL); |
d1c13e16 | 77 | } |
ef416fc2 | 78 | |
79 | /* | |
80 | * Variable size; size name can be one of the following: | |
81 | * | |
82 | * Custom.WIDTHxLENGTHin - Size in inches | |
54afec33 | 83 | * Custom.WIDTHxLENGTHft - Size in feet |
ef416fc2 | 84 | * Custom.WIDTHxLENGTHcm - Size in centimeters |
85 | * Custom.WIDTHxLENGTHmm - Size in millimeters | |
54afec33 | 86 | * Custom.WIDTHxLENGTHm - Size in meters |
ef416fc2 | 87 | * Custom.WIDTHxLENGTH[pt] - Size in points |
88 | */ | |
89 | ||
757d2cad | 90 | loc = localeconv(); |
54afec33 | 91 | w = _cupsStrScand(name + 7, &nameptr, loc); |
757d2cad | 92 | if (!nameptr || *nameptr != 'x') |
ef416fc2 | 93 | return (NULL); |
94 | ||
54afec33 | 95 | l = _cupsStrScand(nameptr + 1, &nameptr, loc); |
757d2cad | 96 | if (!nameptr) |
97 | return (NULL); | |
98 | ||
99 | if (!strcasecmp(nameptr, "in")) | |
ef416fc2 | 100 | { |
54afec33 MS |
101 | w *= 72.0; |
102 | l *= 72.0; | |
ef416fc2 | 103 | } |
b86bc4cf | 104 | else if (!strcasecmp(nameptr, "ft")) |
ef416fc2 | 105 | { |
54afec33 MS |
106 | w *= 12.0 * 72.0; |
107 | l *= 12.0 * 72.0; | |
ef416fc2 | 108 | } |
757d2cad | 109 | else if (!strcasecmp(nameptr, "mm")) |
ef416fc2 | 110 | { |
54afec33 MS |
111 | w *= 72.0 / 25.4; |
112 | l *= 72.0 / 25.4; | |
b86bc4cf | 113 | } |
114 | else if (!strcasecmp(nameptr, "cm")) | |
115 | { | |
54afec33 MS |
116 | w *= 72.0 / 2.54; |
117 | l *= 72.0 / 2.54; | |
ef416fc2 | 118 | } |
b86bc4cf | 119 | else if (!strcasecmp(nameptr, "m")) |
ef416fc2 | 120 | { |
54afec33 MS |
121 | w *= 72.0 / 0.0254; |
122 | l *= 72.0 / 0.0254; | |
ef416fc2 | 123 | } |
124 | ||
54afec33 MS |
125 | size->width = (float)w; |
126 | size->length = (float)l; | |
b86bc4cf | 127 | size->left = ppd->custom_margins[0]; |
128 | size->bottom = ppd->custom_margins[1]; | |
54afec33 MS |
129 | size->right = (float)(w - ppd->custom_margins[2]); |
130 | size->top = (float)(l - ppd->custom_margins[3]); | |
b86bc4cf | 131 | |
132 | /* | |
133 | * Update the custom option records for the page size, too... | |
134 | */ | |
135 | ||
136 | if ((coption = ppdFindCustomOption(ppd, "PageSize")) != NULL) | |
137 | { | |
138 | if ((cparam = ppdFindCustomParam(coption, "Width")) != NULL) | |
7cf5915e | 139 | cparam->current.custom_points = (float)w; |
b86bc4cf | 140 | |
141 | if ((cparam = ppdFindCustomParam(coption, "Height")) != NULL) | |
7cf5915e | 142 | cparam->current.custom_points = (float)l; |
b86bc4cf | 143 | } |
144 | ||
145 | /* | |
146 | * Return the page size... | |
147 | */ | |
148 | ||
f11a948a | 149 | DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size, |
d1c13e16 MS |
150 | size->name, size->width, size->length)); |
151 | ||
b86bc4cf | 152 | return (size); |
ef416fc2 | 153 | } |
154 | else | |
155 | { | |
156 | /* | |
157 | * Lookup by name... | |
158 | */ | |
159 | ||
b86bc4cf | 160 | for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) |
d1c13e16 MS |
161 | if (!strcasecmp(name, size->name)) |
162 | { | |
f11a948a | 163 | DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size, |
d1c13e16 MS |
164 | size->name, size->width, size->length)); |
165 | ||
b86bc4cf | 166 | return (size); |
d1c13e16 | 167 | } |
ef416fc2 | 168 | } |
169 | } | |
170 | else | |
171 | { | |
172 | /* | |
173 | * Find default... | |
174 | */ | |
175 | ||
b86bc4cf | 176 | for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) |
177 | if (size->marked) | |
d1c13e16 | 178 | { |
f11a948a | 179 | DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size, |
d1c13e16 MS |
180 | size->name, size->width, size->length)); |
181 | ||
b86bc4cf | 182 | return (size); |
d1c13e16 | 183 | } |
ef416fc2 | 184 | } |
185 | ||
f11a948a | 186 | DEBUG_puts("3ppdPageSize: Size not found, returning NULL"); |
d1c13e16 | 187 | |
ef416fc2 | 188 | return (NULL); |
189 | } | |
190 | ||
191 | ||
005dd1eb MS |
192 | /* |
193 | * 'ppdPageSizeLimits()' - Return the custom page size limits. | |
194 | * | |
195 | * This function returns the minimum and maximum custom page sizes and printable | |
196 | * areas based on the currently-marked (selected) options. | |
197 | * | |
198 | * If the specified PPD file does not support custom page sizes, both | |
199 | * "minimum" and "maximum" are filled with zeroes. | |
200 | * | |
178cb736 | 201 | * @since CUPS 1.4/Mac OS X 10.6@ |
005dd1eb MS |
202 | */ |
203 | ||
204 | int /* O - 1 if custom sizes are supported, 0 otherwise */ | |
205 | ppdPageSizeLimits(ppd_file_t *ppd, /* I - PPD file record */ | |
206 | ppd_size_t *minimum, /* O - Minimum custom size */ | |
207 | ppd_size_t *maximum) /* O - Maximum custom size */ | |
208 | { | |
209 | ppd_choice_t *qualifier2, /* Second media qualifier */ | |
210 | *qualifier3; /* Third media qualifier */ | |
211 | ppd_attr_t *attr; /* Attribute */ | |
212 | float width, /* Min/max width */ | |
213 | length; /* Min/max length */ | |
214 | char spec[PPD_MAX_NAME]; /* Selector for min/max */ | |
215 | ||
216 | ||
217 | /* | |
218 | * Range check input... | |
219 | */ | |
220 | ||
221 | if (!ppd || !ppd->variable_sizes || !minimum || !maximum) | |
222 | { | |
223 | if (minimum) | |
224 | memset(minimum, 0, sizeof(ppd_size_t)); | |
225 | ||
226 | if (maximum) | |
227 | memset(maximum, 0, sizeof(ppd_size_t)); | |
228 | ||
229 | return (0); | |
230 | } | |
231 | ||
232 | /* | |
233 | * See if we have the cupsMediaQualifier2 and cupsMediaQualifier3 attributes... | |
234 | */ | |
235 | ||
236 | cupsArraySave(ppd->sorted_attrs); | |
237 | ||
238 | if ((attr = ppdFindAttr(ppd, "cupsMediaQualifier2", NULL)) != NULL && | |
239 | attr->value) | |
240 | qualifier2 = ppdFindMarkedChoice(ppd, attr->value); | |
241 | else | |
242 | qualifier2 = NULL; | |
243 | ||
244 | if ((attr = ppdFindAttr(ppd, "cupsMediaQualifier3", NULL)) != NULL && | |
245 | attr->value) | |
246 | qualifier3 = ppdFindMarkedChoice(ppd, attr->value); | |
247 | else | |
248 | qualifier3 = NULL; | |
249 | ||
250 | /* | |
251 | * Figure out the current minimum width and length... | |
252 | */ | |
253 | ||
f8b3a85b MS |
254 | width = ppd->custom_min[0]; |
255 | length = ppd->custom_min[1]; | |
256 | ||
005dd1eb MS |
257 | if (qualifier2) |
258 | { | |
259 | /* | |
260 | * Try getting cupsMinSize... | |
261 | */ | |
262 | ||
263 | if (qualifier3) | |
264 | { | |
265 | snprintf(spec, sizeof(spec), ".%s.%s", qualifier2->choice, | |
266 | qualifier3->choice); | |
267 | attr = ppdFindAttr(ppd, "cupsMinSize", spec); | |
268 | } | |
269 | else | |
270 | attr = NULL; | |
271 | ||
272 | if (!attr) | |
273 | { | |
274 | snprintf(spec, sizeof(spec), ".%s.", qualifier2->choice); | |
275 | attr = ppdFindAttr(ppd, "cupsMinSize", spec); | |
276 | } | |
277 | ||
278 | if (!attr && qualifier3) | |
279 | { | |
280 | snprintf(spec, sizeof(spec), "..%s", qualifier3->choice); | |
281 | attr = ppdFindAttr(ppd, "cupsMinSize", spec); | |
282 | } | |
283 | ||
41681883 MS |
284 | if ((attr && attr->value && |
285 | sscanf(attr->value, "%f%f", &width, &length) != 2) || !attr) | |
005dd1eb MS |
286 | { |
287 | width = ppd->custom_min[0]; | |
288 | length = ppd->custom_min[1]; | |
289 | } | |
290 | } | |
005dd1eb MS |
291 | |
292 | minimum->width = width; | |
293 | minimum->length = length; | |
294 | minimum->left = ppd->custom_margins[0]; | |
295 | minimum->bottom = ppd->custom_margins[1]; | |
296 | minimum->right = width - ppd->custom_margins[2]; | |
297 | minimum->top = length - ppd->custom_margins[3]; | |
298 | ||
299 | /* | |
300 | * Figure out the current maximum width and length... | |
301 | */ | |
302 | ||
f8b3a85b MS |
303 | width = ppd->custom_max[0]; |
304 | length = ppd->custom_max[1]; | |
305 | ||
005dd1eb MS |
306 | if (qualifier2) |
307 | { | |
308 | /* | |
309 | * Try getting cupsMaxSize... | |
310 | */ | |
311 | ||
312 | if (qualifier3) | |
313 | { | |
314 | snprintf(spec, sizeof(spec), ".%s.%s", qualifier2->choice, | |
315 | qualifier3->choice); | |
316 | attr = ppdFindAttr(ppd, "cupsMaxSize", spec); | |
317 | } | |
318 | else | |
319 | attr = NULL; | |
320 | ||
321 | if (!attr) | |
322 | { | |
323 | snprintf(spec, sizeof(spec), ".%s.", qualifier2->choice); | |
324 | attr = ppdFindAttr(ppd, "cupsMaxSize", spec); | |
325 | } | |
326 | ||
327 | if (!attr && qualifier3) | |
328 | { | |
329 | snprintf(spec, sizeof(spec), "..%s", qualifier3->choice); | |
330 | attr = ppdFindAttr(ppd, "cupsMaxSize", spec); | |
331 | } | |
332 | ||
333 | if (!attr || | |
334 | (attr->value && sscanf(attr->value, "%f%f", &width, &length) != 2)) | |
335 | { | |
336 | width = ppd->custom_max[0]; | |
337 | length = ppd->custom_max[1]; | |
338 | } | |
339 | } | |
005dd1eb MS |
340 | |
341 | maximum->width = width; | |
342 | maximum->length = length; | |
343 | maximum->left = ppd->custom_margins[0]; | |
344 | maximum->bottom = ppd->custom_margins[1]; | |
345 | maximum->right = width - ppd->custom_margins[2]; | |
346 | maximum->top = length - ppd->custom_margins[3]; | |
347 | ||
348 | /* | |
349 | * Return the min and max... | |
350 | */ | |
351 | ||
352 | cupsArrayRestore(ppd->sorted_attrs); | |
353 | ||
354 | return (1); | |
355 | } | |
356 | ||
357 | ||
ef416fc2 | 358 | /* |
359 | * 'ppdPageWidth()' - Get the page width for the given size. | |
360 | */ | |
361 | ||
362 | float /* O - Width of page in points or 0.0 */ | |
363 | ppdPageWidth(ppd_file_t *ppd, /* I - PPD file record */ | |
364 | const char *name) /* I - Size name */ | |
365 | { | |
366 | ppd_size_t *size; /* Page size */ | |
367 | ||
368 | ||
369 | if ((size = ppdPageSize(ppd, name)) == NULL) | |
370 | return (0.0); | |
371 | else | |
372 | return (size->width); | |
373 | } | |
374 | ||
375 | ||
376 | /* | |
377 | * 'ppdPageLength()' - Get the page length for the given size. | |
378 | */ | |
379 | ||
380 | float /* O - Length of page in points or 0.0 */ | |
381 | ppdPageLength(ppd_file_t *ppd, /* I - PPD file */ | |
382 | const char *name) /* I - Size name */ | |
383 | { | |
384 | ppd_size_t *size; /* Page size */ | |
385 | ||
386 | ||
387 | if ((size = ppdPageSize(ppd, name)) == NULL) | |
388 | return (0.0); | |
389 | else | |
390 | return (size->length); | |
391 | } | |
392 | ||
393 | ||
394 | /* | |
b19ccc9e | 395 | * End of "$Id: page.c 7791 2008-07-24 00:55:30Z mike $". |
ef416fc2 | 396 | */ |