]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/ppd-page.c
More tweaks for IPP Everywhere support in web interface.
[thirdparty/cups.git] / cups / ppd-page.c
CommitLineData
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 31ppd_size_t * /* O - Size record for page or NULL */
32ppdPageSize(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
195int /* O - 1 if custom sizes are supported, 0 otherwise */
196ppdPageSizeLimits(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
353float /* O - Width of page in points or 0.0 */
354ppdPageWidth(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
371float /* O - Length of page in points or 0.0 */
372ppdPageLength(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}