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