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