Dimension options

Robert Krawitz <[email protected]>
Newsgroups gmane.linux.printing.gimp-print.devel
Message-ID <[email protected]>
Just to bring everyone up to speed on what's going on, many versions of OS X choke on custom values
for dimension-valued settings for items other than media size.  However, units of full points turn
out to be a bit too coarse for CD printing, particularly for the hub.  It's possible to have a worst
case error of 1/100"(*), which if you're trying to print to the very edge of the hub, has proven to
be visible.

Matt, Steve, and I have looked at various solutions.  Broadly speaking they are:

1) Punt altogether: we know that that's dissatisfying to some people.

2) Accept that OS X won't print with printers that support CDs.  Nope.

3) Treat dimensions as floats, with the fine adjustment.  That proves to be somewhat complex to
handle with cups-genppdupdate.

4) Use a finer adjustment than a full point.  This increases the number of choices, but lets us
reduce the worst error.

My proposal is #4, using units of 0.5 point.  This reduces the worst case error to 1/200", which I
suspect (read: hope) will prove sufficient.  This can be made compatible in the PPD files by
printing the tags as integers for full integer point values, and as 1_0 for 1.0 (replacing the .,
which is not a valid character in PPD tags, with _).  Patch is attached.  I've tested the PPD files
for conformance, and one printer that uses CDs and one that doesn't.

* 1/100" worst case error is calculated as follows: with precision of 1/72", the worst case error in
the X and Y dimensions is 1/144" (the hub being exactly halfway between point boundaries).  If
you're unlucky and both dimensions are off, the error works out to just under 1/100" by the
Pythagorean theorem.

_______________________________________________
Gimp-print-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gimp-print-devel
0001-Change-dimension-values-back-to-discrete-values-to-w.patch (text/x-patch, 7.5 KB)
From b1b58448419a495c8fbec3251b4430ae0005be9f Mon Sep 17 00:00:00 2001
From: Robert Krawitz <[email protected]>
Date: Sat, 15 May 2021 16:10:51 -0400
Subject: [PATCH] Change dimension values back to discrete values to work
 around issue with many versions of OS X and fractional dimension values. This
 uses units of -.5 point.

---
 NEWS                                |  5 +++
 src/cups/genppd.c                   | 61 ++++++++++++++++++++++++-----
 src/cups/rastertogutenprint.c       | 21 +++++++---
 src/cups/test-rastertogutenprint.in |  3 ++
 4 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/NEWS b/NEWS
index 56fc4480..d31dd346 100644
--- a/NEWS
+++ b/NEWS
@@ -91,6 +91,11 @@ II) MAJOR CHANGES FROM PREVIOUS RELEASES
      want to use Gutenprint, you should stick with 10.14 (Mojave) or
      below.
 
+     Also on OS X, many releases of OS X cannot properly handle
+     dimensions other than paper with custom values.  Dimensions
+     (other than paper) will be presented as discrete choices, at
+     intervals of 0.5 point.
+
   2) A long-standing gamma correction bug affecting all dye-sublimation
      printers has been corrected, resulting in visibly improved contrast,
      tonal range, and color fidelity.  However, users upgrading from older
diff --git a/src/cups/genppd.c b/src/cups/genppd.c
index aa47aad8..06b78341 100644
--- a/src/cups/genppd.c
+++ b/src/cups/genppd.c
@@ -76,6 +76,12 @@ int use_base_version = 0;
 int cups_ppd_ps_level = CUPS_PPD_PS_LEVEL;
 int localize_numbers = 0;
 
+/*
+ * Fraction of a point to use for dimension units
+ */
+
+static const double dimension_subdivision_points = 2;
+
 /*
  * File handling stuff...
  */
@@ -784,6 +790,20 @@ print_group_open(
   print_group(fp, "Open", p_class, p_level, language ? language : "C", po);
 }
 
+static void
+ppd_dimension_tag(char *buffer, size_t buflen, int base, int fraction, int divisor)
+{
+  if (fraction == 0)
+    snprintf(buffer, buflen, "%d", base);
+  else
+    {
+      snprintf(buffer, buflen, "%.1f", (stp_dimension_t) base + ((stp_dimension_t) fraction / divisor));
+      char *dotpos = strchr(buffer, '.');
+      if (dotpos)
+	*dotpos = '_';
+    }
+}
+
 static void
 print_one_option(gpFile fp, stp_vars_t *v, const stp_string_list_t *po,
 		 ppd_type_t ppd_type, const stp_parameter_t *lparam,
@@ -795,6 +815,7 @@ print_one_option(gpFile fp, stp_vars_t *v, const stp_string_list_t *po,
   int printed_default_value = 0;
   int simplified = ppd_type == PPD_SIMPLIFIED;
   char		dimstr[255];		/* Dimension string */
+  char		dimtagstr[255];		/* PPD tag for dimensions */
   int print_close_ui = 1;
   int is_color_opt = stp_parameter_has_category_value(v, desc, "Color", "Yes");
   int skip_color = (ppd_type == PPD_NO_COLOR_OPTS && is_color_opt);
@@ -976,18 +997,29 @@ print_one_option(gpFile fp, stp_vars_t *v, const stp_string_list_t *po,
 	}
       if (!skip_color)
 	{
-	  for (i = (int) desc->bounds.dimension.lower;
-	       i <= (int) desc->bounds.dimension.upper; i++)
+	  for (i = (int) (desc->bounds.dimension.lower);
+	       i <= (int) (desc->bounds.dimension.upper); i++)
 	    {
-	      snprintf(dimstr, sizeof(dimstr), _("%.1f mm"),
-		       (double)i * 25.4 / 72.0);
-	      gpprintf(fp, "*Stp%s %d/%s: \"\"\n", desc->name, i, dimstr);
+	      int j;
+	      for (j = 0; j < dimension_subdivision_points; j++)
+		{
+		  snprintf(dimstr, sizeof(dimstr), _("%.1f mm"),
+			   ((double)i + ((double) j / dimension_subdivision_points)) * 25.4 / 72.0);
+		  ppd_dimension_tag(dimtagstr, sizeof(dimtagstr),
+				    i, j, dimension_subdivision_points);
+		  gpprintf(fp, "*Stp%s %s/%s: \"\"\n", desc->name,
+			   dimtagstr, dimstr);
+		}
 	    }
 	}
 
       print_close_ui = 0;
       gpprintf(fp, "*CloseUI: *Stp%s\n\n", desc->name);
 
+#if 0
+      /*
+       * #ifdef'ed out because this does not work on many Mac releases.
+       */
       /*
        * Add custom option code and value parameter...
        */
@@ -996,6 +1028,7 @@ print_one_option(gpFile fp, stp_vars_t *v, const stp_string_list_t *po,
       gpprintf(fp, "*ParamCustomStp%s Value/%s: 1 points %d %d\n\n",
 	       desc->name, _("Value"), (int) desc->bounds.dimension.lower,
 	       (int) desc->bounds.dimension.upper);
+#endif
 
       break;
     case STP_PARAMETER_TYPE_INT:
@@ -1047,6 +1080,7 @@ print_one_localization(gpFile fp, const stp_string_list_t *po,
   int i;
   const stp_param_string_t *opt;
   char		dimstr[255];		/* Dimension string */
+  char		dimtagstr[255];		/* PPD Dimension tag */
 
   gpprintf(fp, "*%s.Translation Stp%s/%s: \"\"\n", lang,
 	   desc->name, stp_i18n_lookup(po, desc->text));
@@ -1115,13 +1149,22 @@ print_one_localization(gpFile fp, const stp_string_list_t *po,
       for (i = (int) desc->bounds.dimension.lower;
 	   i <= (int) desc->bounds.dimension.upper; i++)
 	{
-	  snprintf(dimstr, sizeof(dimstr), _("%.1f mm"),
-		   (double)i * 25.4 / 72.0);
-	  gpprintf(fp, "*%s.Stp%s %d/%s: \"\"\n", lang,
-		   desc->name, i, dimstr);
+	  int j;
+	  for (j = 0; j < dimension_subdivision_points; j++)
+	    {
+	      snprintf(dimstr, sizeof(dimstr), _("%.1f mm"),
+		       ((double)i + ((double) j / dimension_subdivision_points)) * 25.4 / 72.0);
+	      ppd_dimension_tag(dimtagstr, sizeof(dimtagstr),
+				i, j, dimension_subdivision_points);
+	      gpprintf(fp, "*%s.Stp%s %s/%s: \"\"\n", lang,
+		       desc->name, dimtagstr, dimstr);
+	    }
 	}
+#if 0
+      /* Does not work correctly on OS X */
       gpprintf(fp, "*%s.ParamCustomStp%s Value/%s: \"\"\n", lang,
 	       desc->name, _("Value"));
+#endif
       break;
 
     case STP_PARAMETER_TYPE_INT:
diff --git a/src/cups/rastertogutenprint.c b/src/cups/rastertogutenprint.c
index 5e6e8bae..0b0fb59c 100644
--- a/src/cups/rastertogutenprint.c
+++ b/src/cups/rastertogutenprint.c
@@ -760,6 +760,9 @@ set_all_options(stp_vars_t *v, cups_option_t *options, int num_options,
 	    {
 	      stp_curve_t *curve;
 	      stp_raw_t *raw;
+	      stp_dimension_t dimval;
+	      char *decimal_pt;
+	      char dimbuf[255];	/* For parsing dimensions */
 	      switch (desc.p_type)
 		{
 		case STP_PARAMETER_TYPE_STRING_LIST:
@@ -781,11 +784,19 @@ set_all_options(stp_vars_t *v, cups_option_t *options, int num_options,
                   if (!strncasecmp(val, "Custom.", 7))
 		    val += 7;
 
-		  if (! suppress_messages)
-		    fprintf(stderr, "DEBUG: Gutenprint:   Set dimension %s to %s (%d)\n",
-			    desc.name, val, atoi(val));
-
-		  stp_set_dimension_parameter(v, desc.name, atoi(val));
+		  dimval = 0.0;
+		  (void) strncpy(dimbuf, val, sizeof(dimbuf) - 1);
+		  decimal_pt = strchr(dimbuf, '_');
+		  if (decimal_pt)
+		    *decimal_pt = '.';
+		  dimval = strtod(dimbuf, &decimal_pt);
+		  if (decimal_pt == dimbuf)
+		    fprintf(stderr, "WARNING: Gutenprint: unparseable dimension string %s, ignored\n", val);
+		  else
+		    if (! suppress_messages)
+		      fprintf(stderr, "DEBUG: Gutenprint:   Set dimension %s to %s (%f)\n",
+			      desc.name, val, dimval);
+		  stp_set_dimension_parameter(v, desc.name, dimval);
 		  break;
 		case STP_PARAMETER_TYPE_BOOLEAN:
 		  if (! suppress_messages)
diff --git a/src/cups/test-rastertogutenprint.in b/src/cups/test-rastertogutenprint.in
index 0d9f761a..ccd11982 100644
--- a/src/cups/test-rastertogutenprint.in
+++ b/src/cups/test-rastertogutenprint.in
@@ -217,6 +217,9 @@ esac
 #cupsargs='PageSize=w324h495 Resolution=180dpi'
 #cupsargs='PageSize=A8'
 
+# As of 2021-05-15, I'm not seeing any leaks from this --rlk
+cupsargs='StpCDYAdjustment=7_5 StpCDXAdjustment=-0_5 StpCDOuterDiameter=328_5 StpCDInnerDiameter=122'
+
 get_ppds() {
     if [[ -n $* ]] ; then
 	for f in "$@" ; do
-- 
2.31.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.