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