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