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