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