summaryrefslogtreecommitdiff
path: root/cups/pwg-ppd.c
diff options
context:
space:
mode:
Diffstat (limited to 'cups/pwg-ppd.c')
-rw-r--r--cups/pwg-ppd.c175
1 files changed, 153 insertions, 22 deletions
diff --git a/cups/pwg-ppd.c b/cups/pwg-ppd.c
index 071eb7b17..9cd27f6e2 100644
--- a/cups/pwg-ppd.c
+++ b/cups/pwg-ppd.c
@@ -48,6 +48,13 @@
/*
+ * Macro to test for two almost-equal PWG measurements.
+ */
+
+#define _PWG_EQUIVALENT(x, y) (abs((x)-(y)) < 2)
+
+
+/*
* Local functions...
*/
@@ -62,7 +69,7 @@ static void pwg_unppdize_name(const char *ppd, char *name, size_t namesize);
_pwg_t * /* O - PWG mapping data */
_pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
{
- int i, j; /* Looping vars */
+ int i, j, k; /* Looping vars */
_pwg_t *pwg; /* PWG mapping data */
ppd_option_t *input_slot, /* InputSlot option */
*media_type, /* MediaType option */
@@ -85,6 +92,19 @@ _pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
_pwg_output_mode_t pwg_output_mode;/* output-mode index */
_pwg_print_quality_t pwg_print_quality;
/* print-quality index */
+ int similar; /* Are the old and new size similar? */
+ _pwg_size_t *old_size; /* Current old size */
+ int old_imageable, /* Old imageable length in 2540ths */
+ old_borderless; /* Old borderless state */
+ int new_width, /* New width in 2540ths */
+ new_length, /* New length in 2540ths */
+ new_left, /* New left margin in 2540ths */
+ new_bottom, /* New bottom margin in 2540ths */
+ new_right, /* New right margin in 2540ths */
+ new_top, /* New top margin in 2540ths */
+ new_imageable, /* New imageable length in 2540ths */
+ new_borderless; /* New borderless state */
+ _pwg_size_t *new_size; /* New size to add, if any */
DEBUG_printf(("_pwgCreateWithPPD(ppd=%p)", ppd));
@@ -133,7 +153,7 @@ _pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
if (!strcasecmp(ppd_size->name, "Custom"))
continue;
-
+
/*
* Convert the PPD size name to the corresponding PWG keyword name.
*/
@@ -162,6 +182,7 @@ _pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
}
else
{
+
/*
* Not a standard name; convert it to a PWG vendor name of the form:
*
@@ -177,20 +198,71 @@ _pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
}
/*
- * Save this size...
+ * If we have a similar paper with non-zero margins then we only
+ * want to keep it if it has a larger imageable area length.
*/
- pwg_size->map.ppd = _cupsStrAlloc(ppd_size->name);
- pwg_size->map.pwg = _cupsStrAlloc(pwg_name);
- pwg_size->width = _PWG_FROMPTS(ppd_size->width);
- pwg_size->length = _PWG_FROMPTS(ppd_size->length);
- pwg_size->left = _PWG_FROMPTS(ppd_size->left);
- pwg_size->bottom = _PWG_FROMPTS(ppd_size->bottom);
- pwg_size->right = _PWG_FROMPTS(ppd_size->width - ppd_size->right);
- pwg_size->top = _PWG_FROMPTS(ppd_size->length - ppd_size->top);
-
- pwg->num_sizes ++;
- pwg_size ++;
+ new_width = _PWG_FROMPTS(ppd_size->width);
+ new_length = _PWG_FROMPTS(ppd_size->length);
+ new_left = _PWG_FROMPTS(ppd_size->left);
+ new_bottom = _PWG_FROMPTS(ppd_size->bottom);
+ new_right = _PWG_FROMPTS(ppd_size->width - ppd_size->right);
+ new_top = _PWG_FROMPTS(ppd_size->length - ppd_size->top);
+ new_imageable = new_length - new_top - new_bottom;
+ new_borderless = new_bottom == 0 && new_top == 0 &&
+ new_left == 0 && new_right == 0;
+
+ for (k = pwg->num_sizes, similar = 0, old_size = pwg->sizes, new_size = NULL;
+ k > 0 && !similar;
+ k --, old_size ++)
+ {
+ old_imageable = old_size->length - old_size->top - old_size->bottom;
+ old_borderless = old_size->left == 0 && old_size->bottom == 0 &&
+ old_size->right == 0 && old_size->top == 0;
+
+ similar = old_borderless == new_borderless &&
+ _PWG_EQUIVALENT(old_size->width, new_width) &&
+ _PWG_EQUIVALENT(old_size->length, new_length);
+
+ if (similar && new_imageable > old_imageable)
+ {
+ /*
+ * The new paper has a larger imageable area so it will replace
+ * the older paper.
+ */
+
+ new_size = old_size;
+ _cupsStrFree(old_size->map.ppd);
+ _cupsStrFree(old_size->map.pwg);
+ }
+ }
+
+ if (!similar)
+ {
+ /*
+ * The paper was unique enough to deserve its own entry so add it to the
+ * end.
+ */
+
+ new_size = pwg_size ++;
+ pwg->num_sizes ++;
+ }
+
+ if (new_size)
+ {
+ /*
+ * Save this size...
+ */
+
+ new_size->map.ppd = _cupsStrAlloc(ppd_size->name);
+ new_size->map.pwg = _cupsStrAlloc(pwg_name);
+ new_size->width = new_width;
+ new_size->length = new_length;
+ new_size->left = new_left;
+ new_size->bottom = new_bottom;
+ new_size->right = new_right;
+ new_size->top = new_top;
+ }
}
if (ppd->variable_sizes)
@@ -387,7 +459,9 @@ _pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
const char *quality, /* com.apple.print.preset.quality value */
*output_mode, /* com.apple.print.preset.output-mode value */
- *color_model_val; /* ColorModel choice */
+ *color_model_val, /* ColorModel choice */
+ *graphics_type, /* com.apple.print.preset.graphicsType value */
+ *paper_coating; /* com.apple.print.preset.media-front-coating value */
do
@@ -410,6 +484,31 @@ _pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
pwg_print_quality = _PWG_PRINT_QUALITY_NORMAL;
/*
+ * Ignore graphicsType "Photo" presets that are not high quality.
+ */
+
+ graphics_type = cupsGetOption("com.apple.print.preset.graphicsType",
+ num_options, options);
+
+ if (pwg_print_quality != _PWG_PRINT_QUALITY_HIGH && graphics_type &&
+ !strcmp(graphics_type, "Photo"))
+ continue;
+
+ /*
+ * Ignore presets for normal and draft quality where the coating
+ * isn't "none" or "autodetect".
+ */
+
+ paper_coating = cupsGetOption(
+ "com.apple.print.preset.media-front-coating",
+ num_options, options);
+
+ if (pwg_print_quality != _PWG_PRINT_QUALITY_HIGH && paper_coating &&
+ strcmp(paper_coating, "none") &&
+ strcmp(paper_coating, "autodetect"))
+ continue;
+
+ /*
* Get the output mode for this preset...
*/
@@ -804,6 +903,7 @@ _pwgGetPageSize(_pwg_t *pwg, /* I - PWG mapping data */
dtop, /* Difference in top margins */
dmin, /* Minimum difference */
dclosest; /* Closest difference */
+ const char *ppd_name; /* PPD media name */
/*
@@ -816,6 +916,36 @@ _pwgGetPageSize(_pwg_t *pwg, /* I - PWG mapping data */
if (exact)
*exact = 0;
+ ppd_name = keyword;
+
+ if (job)
+ {
+ /*
+ * Try getting the PPD media name from the job attributes...
+ */
+
+ ipp_attribute_t *attr; /* Job attribute */
+
+ if ((attr = ippFindAttribute(job, "PageSize", IPP_TAG_ZERO)) == NULL)
+ if ((attr = ippFindAttribute(job, "PageRegion", IPP_TAG_ZERO)) == NULL)
+ attr = ippFindAttribute(job, "media", IPP_TAG_ZERO);
+
+ if (attr && (attr->value_tag == IPP_TAG_NAME ||
+ attr->value_tag == IPP_TAG_KEYWORD))
+ ppd_name = attr->values[0].string.text;
+ }
+
+ if (ppd_name)
+ {
+ /*
+ * Try looking up the named PPD size first...
+ */
+
+ for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
+ if (!strcasecmp(ppd_name, size->map.ppd))
+ return (ppd_name);
+ }
+
if (job && !keyword)
{
/*
@@ -837,7 +967,8 @@ _pwgGetPageSize(_pwg_t *pwg, /* I - PWG mapping data */
if ((media = _pwgMediaForPWG(keyword)) == NULL)
if ((media = _pwgMediaForLegacy(keyword)) == NULL)
- return (NULL);
+ if ((media = _pwgMediaForPPD(keyword)) == NULL)
+ return (NULL);
jobsize.width = media->width;
jobsize.length = media->length;
@@ -1223,7 +1354,7 @@ _pwgPageSizeForMedia(
else if (!media->pwg || !strncmp(media->pwg, "custom_", 7) ||
(sizeptr = strchr(media->pwg, '_')) == NULL ||
(dimptr = strchr(sizeptr + 1, '_')) == NULL ||
- (dimptr - sizeptr) > namesize)
+ (size_t)(dimptr - sizeptr) > namesize)
{
/*
* Use a name of the form "wNNNhNNN"...
@@ -1263,7 +1394,7 @@ pwg_ppdize_name(const char *ipp, /* I - IPP keyword */
for (ptr = name + 1, end = name + namesize - 1; *ipp && ptr < end;)
{
- if (*ipp == '-' && isalpha(ipp[1] & 255))
+ if (*ipp == '-' && _cups_isalpha(ipp[1]))
{
ipp ++;
*ptr++ = toupper(*ipp++ & 255);
@@ -1291,13 +1422,13 @@ pwg_unppdize_name(const char *ppd, /* I - PPD keyword */
for (ptr = name, end = name + namesize - 1; *ppd && ptr < end; ppd ++)
{
- if (isalnum(*ppd & 255) || *ppd == '-' || *ppd == '.')
+ if (_cups_isalnum(*ppd) || *ppd == '-')
*ptr++ = tolower(*ppd & 255);
- else if (*ppd == '_')
+ else if (*ppd == '_' || *ppd == '.')
*ptr++ = '-';
- if (!isupper(*ppd & 255) && isalnum(*ppd & 255) &&
- isupper(ppd[1] & 255) && ptr < end)
+ if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) &&
+ _cups_isupper(ppd[1]) && ptr < end)
*ptr++ = '-';
}