[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gimp-print-devel
Subject:    [Gimp-print-devel] Dimension options
From:       Robert Krawitz <rlk () alum ! mit ! edu>
Date:       2021-05-15 20:15:49
Message-ID: eb53e0bd-47c9-7ddb-5fbd-002693bd7826 () alum ! mit ! edu
[Download RAW message or body]

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.

["0001-Change-dimension-values-back-to-discrete-values-to-w.patch" (text/x-patch)]

From b1b58448419a495c8fbec3251b4430ae0005be9f Mon Sep 17 00:00:00 2001
From: Robert Krawitz <rlk@alum.mit.edu>
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





_______________________________________________
Gimp-print-devel mailing list
Gimp-print-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gimp-print-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic