From 6c7c5b3e4f3567e486eef234a9ac9e471cc8d4d8 Mon Sep 17 00:00:00 2001 From: Michael R Sweet Date: Tue, 13 Aug 2024 22:39:43 -0400 Subject: [PATCH] Fix cupsGetDestMediaByName and friends (Issue #993) --- cups/dest-options.c | 23 ++++++++++---------- cups/ppd-cache.c | 7 +++--- cups/pwg-media.c | 53 +++++++++++++++++++++++++-------------------- cups/pwg-private.h | 9 +++++++- 4 files changed, 53 insertions(+), 39 deletions(-) diff --git a/cups/dest-options.c b/cups/dest-options.c index 434937349b..b4ccfcc70e 100644 --- a/cups/dest-options.c +++ b/cups/dest-options.c @@ -8,10 +8,6 @@ * information. */ -/* - * Include necessary headers... - */ - #include "cups-private.h" #include "debug-internal.h" @@ -2414,7 +2410,6 @@ cups_create_media_db( *media_attr, /* media-xxx */ *x_dimension, /* x-dimension */ *y_dimension; /* y-dimension */ - pwg_media_t *pwg; /* PWG media info */ cups_array_t *db; /* New media database array */ _cups_media_db_t mdb; /* Media entry */ char media_key[256]; /* Synthesized media-key value */ @@ -2550,8 +2545,12 @@ cups_create_media_db( if (!mdb.key) { - if (!mdb.size_name && (pwg = pwgMediaForSize(mdb.width, mdb.length)) != NULL) - mdb.size_name = (char *)pwg->pwg; + pwg_media_t pwg; /* PWG media info */ + char keyword[128], /* PWG size keyword */ + ppdname[41]; /* PPD size name */ + + if (!mdb.size_name && _pwgMediaNearSize(&pwg, keyword, sizeof(keyword), ppdname, sizeof(ppdname), mdb.width, mdb.length, _PWG_EPSILON)) + mdb.size_name = keyword; if (!mdb.size_name) { @@ -2658,24 +2657,26 @@ cups_create_media_db( i > 0; i --, val ++) { + pwg_media_t *pwg; /* PWG media information */ + if ((pwg = pwgMediaForPWG(val->string.text)) == NULL) + { if ((pwg = pwgMediaForLegacy(val->string.text)) == NULL) { DEBUG_printf("3cups_create_media_db: Ignoring unknown size '%s'.", val->string.text); continue; } + } mdb.width = pwg->width; mdb.length = pwg->length; - if (flags != CUPS_MEDIA_FLAGS_READY && - !strncmp(val->string.text, "custom_min_", 11)) + if (flags != CUPS_MEDIA_FLAGS_READY && !strncmp(val->string.text, "custom_min_", 11)) { mdb.size_name = NULL; dinfo->min_size = mdb; } - else if (flags != CUPS_MEDIA_FLAGS_READY && - !strncmp(val->string.text, "custom_max_", 11)) + else if (flags != CUPS_MEDIA_FLAGS_READY && !strncmp(val->string.text, "custom_max_", 11)) { mdb.size_name = NULL; dinfo->max_size = mdb; diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c index 36261ec083..4819634832 100644 --- a/cups/ppd-cache.c +++ b/cups/ppd-cache.c @@ -1043,7 +1043,8 @@ _ppdCacheCreateWithPPD( ppd_name[PPD_MAX_NAME]; /* Normalized PPD name */ const char *pwg_name; /* Standard PWG media name */ - pwg_media_t *pwg_media; /* PWG media data */ + pwg_media_t *pwg_media, /* PWG media data */ + pwg_mediatemp; /* PWG media data buffer */ _pwg_print_color_mode_t pwg_print_color_mode; /* print-color-mode index */ _pwg_print_quality_t pwg_print_quality; @@ -1162,9 +1163,7 @@ _ppdCacheCreateWithPPD( * dimensions that are <= 0... */ - if ((pwg_media = _pwgMediaNearSize(PWG_FROM_POINTS(ppd_size->width), - PWG_FROM_POINTS(ppd_size->length), - 0)) == NULL) + if ((pwg_media = _pwgMediaNearSize(&pwg_mediatemp, /*keyword*/NULL, /*keysize*/0, /*ppdname*/NULL, /*ppdsize*/0, PWG_FROM_POINTS(ppd_size->width), PWG_FROM_POINTS(ppd_size->length), /*epsilon*/0)) == NULL) continue; new_width = pwg_media->width; diff --git a/cups/pwg-media.c b/cups/pwg-media.c index 10092fdec3..24f5b4d5ee 100644 --- a/cups/pwg-media.c +++ b/cups/pwg-media.c @@ -23,7 +23,6 @@ #define _PWG_MEDIA_IN(p,l,a,x,y) {p, l, a, (int)(x * 2540), (int)(y * 2540)} #define _PWG_MEDIA_MM(p,l,a,x,y) {p, l, a, (int)(x * 100), (int)(y * 100)} -#define _PWG_EPSILON 50 /* Matching tolerance */ /* @@ -953,13 +952,16 @@ pwg_media_t * /* O - PWG media name */ pwgMediaForSize(int width, /* I - Width in hundredths of millimeters */ int length) /* I - Length in hundredths of millimeters */ { + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + /* * Adobe uses a size matching algorithm with an epsilon of 5 points, which * is just about 176/2540ths... But a lot of international media sizes are * very close so use 0.5mm (50/2540ths) as the maximum delta. */ - return (_pwgMediaNearSize(width, length, _PWG_EPSILON)); + return (_pwgMediaNearSize(&cg->pwg_media, cg->pwg_name, sizeof(cg->pwg_name), cg->ppd_name, sizeof(cg->ppd_name), width, length, _PWG_EPSILON)); } @@ -967,10 +969,15 @@ pwgMediaForSize(int width, /* I - Width in hundredths of millimeters */ * '_pwgMediaNearSize()' - Get the PWG media size within the given tolerance. */ -pwg_media_t * /* O - PWG media name */ -_pwgMediaNearSize(int width, /* I - Width in hundredths of millimeters */ - int length, /* I - Length in hundredths of millimeters */ - int epsilon) /* I - Match within this tolernace. PWG units */ +pwg_media_t * /* O - PWG media */ +_pwgMediaNearSize(pwg_media_t *pwg, /* I - Media buffer */ + char *keyword, /* I - Media keyword buffer */ + size_t keysize, /* I - Size of media keyword buffer */ + char *ppdname, /* I - PPD name buffer */ + size_t ppdsize, /* I - Size of PPD name buffer */ + int width, /* I - Width in hundredths of millimeters */ + int length, /* I - Length in hundredths of millimeters */ + int epsilon) /* I - Match within this tolernace. PWG units */ { int i; /* Looping var */ pwg_media_t *media, /* Current media */ @@ -979,7 +986,6 @@ _pwgMediaNearSize(int width, /* I - Width in hundredths of millimeters * best_dw = 999, /* Best difference in width and length */ best_dl = 999; char wstr[32], lstr[32]; /* Width and length as strings */ - _cups_globals_t *cg = _cupsGlobals(); /* Global data */ /* @@ -993,17 +999,15 @@ _pwgMediaNearSize(int width, /* I - Width in hundredths of millimeters * * Look for a standard size... */ - for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])), - media = (pwg_media_t *)cups_pwg_media; - i > 0; - i --, media ++) + for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])), media = (pwg_media_t *)cups_pwg_media; i > 0; i --, media ++) { - dw = abs(media->width - width); dl = abs(media->length - length); if (!dw && !dl) + { return (media); + } else if (dw <= epsilon && dl <= epsilon) { if (dw <= best_dw && dl <= best_dl) @@ -1024,20 +1028,23 @@ _pwgMediaNearSize(int width, /* I - Width in hundredths of millimeters * * custom_WIDTHxHEIGHTuu_WIDTHxHEIGHTuu */ - pwgFormatSizeName(cg->pwg_name, sizeof(cg->pwg_name), "custom", NULL, width, - length, NULL); + if (keyword) + pwgFormatSizeName(keyword, keysize, "custom", NULL, width, length, NULL); - cg->pwg_media.pwg = cg->pwg_name; - cg->pwg_media.width = width; - cg->pwg_media.length = length; + if (ppdname) + { + if ((width % 635) == 0 && (length % 635) == 0) + snprintf(ppdname, ppdsize, "%sx%s", pwg_format_inches(wstr, sizeof(wstr), width), pwg_format_inches(lstr, sizeof(lstr), length)); + else + snprintf(ppdname, ppdsize, "%sx%smm", pwg_format_millimeters(wstr, sizeof(wstr), width), pwg_format_millimeters(lstr, sizeof(lstr), length)); + } - if ((width % 635) == 0 && (length % 635) == 0) - snprintf(cg->ppd_name, sizeof(cg->ppd_name), "%sx%s", pwg_format_inches(wstr, sizeof(wstr), width), pwg_format_inches(lstr, sizeof(lstr), length)); - else - snprintf(cg->ppd_name, sizeof(cg->ppd_name), "%sx%smm", pwg_format_millimeters(wstr, sizeof(wstr), width), pwg_format_millimeters(lstr, sizeof(lstr), length)); - cg->pwg_media.ppd = cg->ppd_name; + pwg->pwg = keyword; + pwg->ppd = ppdname; + pwg->width = width; + pwg->length = length; - return (&(cg->pwg_media)); + return (pwg); } diff --git a/cups/pwg-private.h b/cups/pwg-private.h index 041bd8f52e..d66c6653a0 100644 --- a/cups/pwg-private.h +++ b/cups/pwg-private.h @@ -17,6 +17,13 @@ extern "C" { # endif // __cplusplus +// +// Constants... +// + +#define _PWG_EPSILON 50 // Matching tolerance in hundredths of millimeters + + // // Functions... // @@ -24,7 +31,7 @@ extern "C" { extern void _pwgGenerateSize(char *keyword, size_t keysize, const char *prefix, const char *name, int width, int length) _CUPS_INTERNAL_MSG("Use pwgFormatSizeName instead."); extern int _pwgInitSize(pwg_size_t *size, ipp_t *job, int *margins_set) _CUPS_INTERNAL_MSG("Use pwgInitSize instead."); extern const pwg_media_t *_pwgMediaTable(size_t *num_media) _CUPS_PRIVATE; -extern pwg_media_t *_pwgMediaNearSize(int width, int length, int epsilon) _CUPS_PRIVATE; +extern pwg_media_t *_pwgMediaNearSize(pwg_media_t *pwg, char *keyword, size_t keysize, char *ppdname, size_t ppdsize, int width, int length, int epsilon) _CUPS_PRIVATE; # ifdef __cplusplus -- 2.47.2