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