You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
378 lines
8.9 KiB
378 lines
8.9 KiB
/*
|
|
* Page size functions for CUPS.
|
|
*
|
|
* Copyright 2007-2015 by Apple Inc.
|
|
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
|
|
*
|
|
* Licensed under Apache License v2.0. See the file "LICENSE" for more
|
|
* information.
|
|
*
|
|
* PostScript is a trademark of Adobe Systems, Inc.
|
|
*/
|
|
|
|
/*
|
|
* Include necessary headers...
|
|
*/
|
|
|
|
#include "string-private.h"
|
|
#include "debug-internal.h"
|
|
#include "ppd.h"
|
|
|
|
|
|
/*
|
|
* 'ppdPageSize()' - Get the page size record for the named size.
|
|
*/
|
|
|
|
ppd_size_t * /* O - Size record for page or NULL */
|
|
ppdPageSize(ppd_file_t *ppd, /* I - PPD file record */
|
|
const char *name) /* I - Size name */
|
|
{
|
|
int i; /* Looping var */
|
|
ppd_size_t *size; /* Current page size */
|
|
double w, l; /* Width and length of page */
|
|
char *nameptr; /* Pointer into name */
|
|
struct lconv *loc; /* Locale data */
|
|
ppd_coption_t *coption; /* Custom option for page size */
|
|
ppd_cparam_t *cparam; /* Custom option parameter */
|
|
|
|
|
|
DEBUG_printf(("2ppdPageSize(ppd=%p, name=\"%s\")", ppd, name));
|
|
|
|
if (!ppd)
|
|
{
|
|
DEBUG_puts("3ppdPageSize: Bad PPD pointer, returning NULL...");
|
|
return (NULL);
|
|
}
|
|
|
|
if (name)
|
|
{
|
|
if (!strncmp(name, "Custom.", 7) && ppd->variable_sizes)
|
|
{
|
|
/*
|
|
* Find the custom page size...
|
|
*/
|
|
|
|
for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
|
|
if (!strcmp("Custom", size->name))
|
|
break;
|
|
|
|
if (!i)
|
|
{
|
|
DEBUG_puts("3ppdPageSize: No custom sizes, returning NULL...");
|
|
return (NULL);
|
|
}
|
|
|
|
/*
|
|
* Variable size; size name can be one of the following:
|
|
*
|
|
* Custom.WIDTHxLENGTHin - Size in inches
|
|
* Custom.WIDTHxLENGTHft - Size in feet
|
|
* Custom.WIDTHxLENGTHcm - Size in centimeters
|
|
* Custom.WIDTHxLENGTHmm - Size in millimeters
|
|
* Custom.WIDTHxLENGTHm - Size in meters
|
|
* Custom.WIDTHxLENGTH[pt] - Size in points
|
|
*/
|
|
|
|
loc = localeconv();
|
|
w = _cupsStrScand(name + 7, &nameptr, loc);
|
|
if (!nameptr || *nameptr != 'x')
|
|
return (NULL);
|
|
|
|
l = _cupsStrScand(nameptr + 1, &nameptr, loc);
|
|
if (!nameptr)
|
|
return (NULL);
|
|
|
|
if (!_cups_strcasecmp(nameptr, "in"))
|
|
{
|
|
w *= 72.0;
|
|
l *= 72.0;
|
|
}
|
|
else if (!_cups_strcasecmp(nameptr, "ft"))
|
|
{
|
|
w *= 12.0 * 72.0;
|
|
l *= 12.0 * 72.0;
|
|
}
|
|
else if (!_cups_strcasecmp(nameptr, "mm"))
|
|
{
|
|
w *= 72.0 / 25.4;
|
|
l *= 72.0 / 25.4;
|
|
}
|
|
else if (!_cups_strcasecmp(nameptr, "cm"))
|
|
{
|
|
w *= 72.0 / 2.54;
|
|
l *= 72.0 / 2.54;
|
|
}
|
|
else if (!_cups_strcasecmp(nameptr, "m"))
|
|
{
|
|
w *= 72.0 / 0.0254;
|
|
l *= 72.0 / 0.0254;
|
|
}
|
|
|
|
size->width = (float)w;
|
|
size->length = (float)l;
|
|
size->left = ppd->custom_margins[0];
|
|
size->bottom = ppd->custom_margins[1];
|
|
size->right = (float)(w - ppd->custom_margins[2]);
|
|
size->top = (float)(l - ppd->custom_margins[3]);
|
|
|
|
/*
|
|
* Update the custom option records for the page size, too...
|
|
*/
|
|
|
|
if ((coption = ppdFindCustomOption(ppd, "PageSize")) != NULL)
|
|
{
|
|
if ((cparam = ppdFindCustomParam(coption, "Width")) != NULL)
|
|
cparam->current.custom_points = (float)w;
|
|
|
|
if ((cparam = ppdFindCustomParam(coption, "Height")) != NULL)
|
|
cparam->current.custom_points = (float)l;
|
|
}
|
|
|
|
/*
|
|
* Return the page size...
|
|
*/
|
|
|
|
DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size,
|
|
size->name, size->width, size->length));
|
|
|
|
return (size);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* Lookup by name...
|
|
*/
|
|
|
|
for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
|
|
if (!_cups_strcasecmp(name, size->name))
|
|
{
|
|
DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size,
|
|
size->name, size->width, size->length));
|
|
|
|
return (size);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* Find default...
|
|
*/
|
|
|
|
for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
|
|
if (size->marked)
|
|
{
|
|
DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size,
|
|
size->name, size->width, size->length));
|
|
|
|
return (size);
|
|
}
|
|
}
|
|
|
|
DEBUG_puts("3ppdPageSize: Size not found, returning NULL");
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
|
|
/*
|
|
* 'ppdPageSizeLimits()' - Return the custom page size limits.
|
|
*
|
|
* This function returns the minimum and maximum custom page sizes and printable
|
|
* areas based on the currently-marked (selected) options.
|
|
*
|
|
* If the specified PPD file does not support custom page sizes, both
|
|
* "minimum" and "maximum" are filled with zeroes.
|
|
*
|
|
* @since CUPS 1.4/macOS 10.6@
|
|
*/
|
|
|
|
int /* O - 1 if custom sizes are supported, 0 otherwise */
|
|
ppdPageSizeLimits(ppd_file_t *ppd, /* I - PPD file record */
|
|
ppd_size_t *minimum, /* O - Minimum custom size */
|
|
ppd_size_t *maximum) /* O - Maximum custom size */
|
|
{
|
|
ppd_choice_t *qualifier2, /* Second media qualifier */
|
|
*qualifier3; /* Third media qualifier */
|
|
ppd_attr_t *attr; /* Attribute */
|
|
float width, /* Min/max width */
|
|
length; /* Min/max length */
|
|
char spec[PPD_MAX_NAME]; /* Selector for min/max */
|
|
|
|
|
|
/*
|
|
* Range check input...
|
|
*/
|
|
|
|
if (!ppd || !ppd->variable_sizes || !minimum || !maximum)
|
|
{
|
|
if (minimum)
|
|
memset(minimum, 0, sizeof(ppd_size_t));
|
|
|
|
if (maximum)
|
|
memset(maximum, 0, sizeof(ppd_size_t));
|
|
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* See if we have the cupsMediaQualifier2 and cupsMediaQualifier3 attributes...
|
|
*/
|
|
|
|
cupsArraySave(ppd->sorted_attrs);
|
|
|
|
if ((attr = ppdFindAttr(ppd, "cupsMediaQualifier2", NULL)) != NULL &&
|
|
attr->value)
|
|
qualifier2 = ppdFindMarkedChoice(ppd, attr->value);
|
|
else
|
|
qualifier2 = NULL;
|
|
|
|
if ((attr = ppdFindAttr(ppd, "cupsMediaQualifier3", NULL)) != NULL &&
|
|
attr->value)
|
|
qualifier3 = ppdFindMarkedChoice(ppd, attr->value);
|
|
else
|
|
qualifier3 = NULL;
|
|
|
|
/*
|
|
* Figure out the current minimum width and length...
|
|
*/
|
|
|
|
width = ppd->custom_min[0];
|
|
length = ppd->custom_min[1];
|
|
|
|
if (qualifier2)
|
|
{
|
|
/*
|
|
* Try getting cupsMinSize...
|
|
*/
|
|
|
|
if (qualifier3)
|
|
{
|
|
snprintf(spec, sizeof(spec), ".%s.%s", qualifier2->choice,
|
|
qualifier3->choice);
|
|
attr = ppdFindAttr(ppd, "cupsMinSize", spec);
|
|
}
|
|
else
|
|
attr = NULL;
|
|
|
|
if (!attr)
|
|
{
|
|
snprintf(spec, sizeof(spec), ".%s.", qualifier2->choice);
|
|
attr = ppdFindAttr(ppd, "cupsMinSize", spec);
|
|
}
|
|
|
|
if (!attr && qualifier3)
|
|
{
|
|
snprintf(spec, sizeof(spec), "..%s", qualifier3->choice);
|
|
attr = ppdFindAttr(ppd, "cupsMinSize", spec);
|
|
}
|
|
|
|
if ((attr && attr->value &&
|
|
sscanf(attr->value, "%f%f", &width, &length) != 2) || !attr)
|
|
{
|
|
width = ppd->custom_min[0];
|
|
length = ppd->custom_min[1];
|
|
}
|
|
}
|
|
|
|
minimum->width = width;
|
|
minimum->length = length;
|
|
minimum->left = ppd->custom_margins[0];
|
|
minimum->bottom = ppd->custom_margins[1];
|
|
minimum->right = width - ppd->custom_margins[2];
|
|
minimum->top = length - ppd->custom_margins[3];
|
|
|
|
/*
|
|
* Figure out the current maximum width and length...
|
|
*/
|
|
|
|
width = ppd->custom_max[0];
|
|
length = ppd->custom_max[1];
|
|
|
|
if (qualifier2)
|
|
{
|
|
/*
|
|
* Try getting cupsMaxSize...
|
|
*/
|
|
|
|
if (qualifier3)
|
|
{
|
|
snprintf(spec, sizeof(spec), ".%s.%s", qualifier2->choice,
|
|
qualifier3->choice);
|
|
attr = ppdFindAttr(ppd, "cupsMaxSize", spec);
|
|
}
|
|
else
|
|
attr = NULL;
|
|
|
|
if (!attr)
|
|
{
|
|
snprintf(spec, sizeof(spec), ".%s.", qualifier2->choice);
|
|
attr = ppdFindAttr(ppd, "cupsMaxSize", spec);
|
|
}
|
|
|
|
if (!attr && qualifier3)
|
|
{
|
|
snprintf(spec, sizeof(spec), "..%s", qualifier3->choice);
|
|
attr = ppdFindAttr(ppd, "cupsMaxSize", spec);
|
|
}
|
|
|
|
if (!attr ||
|
|
(attr->value && sscanf(attr->value, "%f%f", &width, &length) != 2))
|
|
{
|
|
width = ppd->custom_max[0];
|
|
length = ppd->custom_max[1];
|
|
}
|
|
}
|
|
|
|
maximum->width = width;
|
|
maximum->length = length;
|
|
maximum->left = ppd->custom_margins[0];
|
|
maximum->bottom = ppd->custom_margins[1];
|
|
maximum->right = width - ppd->custom_margins[2];
|
|
maximum->top = length - ppd->custom_margins[3];
|
|
|
|
/*
|
|
* Return the min and max...
|
|
*/
|
|
|
|
cupsArrayRestore(ppd->sorted_attrs);
|
|
|
|
return (1);
|
|
}
|
|
|
|
|
|
/*
|
|
* 'ppdPageWidth()' - Get the page width for the given size.
|
|
*/
|
|
|
|
float /* O - Width of page in points or 0.0 */
|
|
ppdPageWidth(ppd_file_t *ppd, /* I - PPD file record */
|
|
const char *name) /* I - Size name */
|
|
{
|
|
ppd_size_t *size; /* Page size */
|
|
|
|
|
|
if ((size = ppdPageSize(ppd, name)) == NULL)
|
|
return (0.0);
|
|
else
|
|
return (size->width);
|
|
}
|
|
|
|
|
|
/*
|
|
* 'ppdPageLength()' - Get the page length for the given size.
|
|
*/
|
|
|
|
float /* O - Length of page in points or 0.0 */
|
|
ppdPageLength(ppd_file_t *ppd, /* I - PPD file */
|
|
const char *name) /* I - Size name */
|
|
{
|
|
ppd_size_t *size; /* Page size */
|
|
|
|
|
|
if ((size = ppdPageSize(ppd, name)) == NULL)
|
|
return (0.0);
|
|
else
|
|
return (size->length);
|
|
}
|