[cairo] [PATCH]A cairo-ps-surface.c issue for modern finicky versions of ghostscript

Alan W. Irwin irwin at beluga.phys.uvic.ca
Thu Nov 29 19:07:52 PST 2007


I have just installed Debian testing on a new box, and ghostscript (gs-gpl
version 8.56) errors out with a "/rangecheck in --xyshow" message for
PostScript results (see attached postscript file) produced with pango-cairo
and cairo via the PLplot pscairo device driver.  The full error message
(produced by gv --noquiet on the attached file) is

Error: /rangecheck in --xyshow--GPL Ghostscript 8.56: Unrecoverable error, exit code 1

Operand stack:
    (\002\001)   --nostringval--
Execution stack:
    %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push   1797   1   3   %oparray_pop   1796   1   3   %oparray_pop   1792   1   3   %oparray_pop   1675   1   3   %oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--
Dictionary stack:
    --dict:1086/1123(ro)(G)--   --dict:0/20(G)--   --dict:80/200(L)--
Current allocation mode is local

I don't understand PostScript that well, but the xyS alias of xyshow always
appears with a certain pattern which I believe is incorrect.  Let's take
two instructive instances:

% _cairo_ps_surface_show_glyphs
....
<0201>
[-4.670898 -8.090233 0 ] xyS

% _cairo_ps_surface_show_glyphs
....
<050701>
[4.670898 -8.090233 4.670898 -8.090233 0 ] xyS

In each case you have an array of N hexadecimal characters followed by a
zero-terminated array of N-1/2 x,y pairs of positions.  ghostscript quits
complaining and produces a good-looking plot consistent with the results we
get for this example from our pdfcairo, pngcairo, and xcairo device drivers
if you add an extra 0 to the end of the array for N x,y pairs, i.e,
terminate the array with a dummy pair of x,y values, and not just a dummy x
value.  (see http://plplot.sourceforge.net/examples/demo03.php for
the pngcairo PNG result equivalent to the attached postscript file.)

If you look at the PostScript Reference manual for the xyshow description,
it claims it reads an x,y pair out of the array _after_ each character
is painted so it appears the sequence is write the first character
at the current position, the second character at the first _differential_
x,y position specified in the array, and so on.  Thus, for the last character
in the string there needs to be _two_ dummy values in the array so you
don't get a rangecheck error for modern ghostscript versions.

Here is a patch to deal with this issue:

--- cairo-ps-surface.c_original	2007-11-29 18:43:33.000000000 -0800
+++ cairo-ps-surface.c	2007-11-29 18:45:35.000000000 -0800
@@ -2274,7 +2274,7 @@
              if (horizontal) {
                  for (j = i; j < last+1; j++) {
                      if (j == num_glyphs_unsigned - 1)
-                        _cairo_output_stream_printf (word_wrap, "0 ");
+                        _cairo_output_stream_printf (word_wrap, "0 0 ");
                      else
                          _cairo_output_stream_printf (word_wrap,
                                                       "%f ", glyphs[j + 1].x - glyphs[j].x);
@@ -2283,7 +2283,7 @@
              } else if (vertical) {
                  for (j = i; j < last+1; j++) {
                      if (j == num_glyphs_unsigned - 1)
-                        _cairo_output_stream_printf (word_wrap, "0 ");
+                        _cairo_output_stream_printf (word_wrap, "0 0 ");
                      else
                          _cairo_output_stream_printf (word_wrap,
                                                       "%f ", glyphs[j + 1].y - glyphs[j].y);
@@ -2292,7 +2292,7 @@
              } else {
                  for (j = i; j < last+1; j++) {
                      if (j == num_glyphs_unsigned - 1)
-                        _cairo_output_stream_printf (word_wrap, "0 ");
+                        _cairo_output_stream_printf (word_wrap, "0 0 ");
                      else
                          _cairo_output_stream_printf (word_wrap,
                                                       "%f %f ",

I derived this patch from cairo version 1.4.6 source code, but I have also
found the problem for PLplot results generated with the Debian testing
version of cairo (1.4.10), and other PLplot users have noticed the same
problem with the Ubuntu gutsy version of cairo (also 1.4.10).

N.B. Older ghostscript versions (e.g., version 7.07.1 from Debian oldstable)
do not give a rangecheck error for the attached PostScript plot.  But I
think it is a case of that older version being less careful about the final
dummy read of two values from the array compared to what occurs for modern
ghostscript.

Alan
__________________________
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state implementation
for stellar interiors (freeeos.sf.net); PLplot scientific plotting software
package (plplot.org); the libLASi project (unifont.org/lasi); the Loads of
Linux Links project (loll.sf.net); and the Linux Brochure Project
(lbproject.sf.net).
__________________________

Linux-powered Science
__________________________
-------------- next part --------------
A non-text attachment was scrubbed...
Name: x03c.pscairo.gz
Type: application/octet-stream
Size: 45564 bytes
Desc: compressed example of the generated PostScript issue
Url : http://lists.cairographics.org/archives/cairo/attachments/20071129/aeebdf03/attachment-0001.obj 


More information about the cairo mailing list