Bug 34994

Summary: cairo bitmapped (png) results do not fill self-intersecting boundaries correctly
Product: cairo Reporter: Alan W. Irwin <Alan.W.Irwin1234>
Component: png functionsAssignee: Carl Worth <cworth>
Status: RESOLVED NOTOURBUG QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: medium    
Version: 1.8.10   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

Description Alan W. Irwin 2011-03-03 17:01:58 UTC
The PLplot development team have just implemented a demanding 2D fill rendering test where we modify our standard example 27 (see http://plplot.sourceforge.net/examples.php?demo=27) to change from drawing the boundary line of "spirographic" (e.g., hypotrochoid and epitrochoid) curves to filling those curves.  In general, on Linux (specifically Debian Squeeze) the X results for these self-intersecting boundaries are not filled correctly (either for the even-odd or non-zero winding number fill rules), and I have made the appropriate bug report at https://bugs.freedesktop.org/show_bug.cgi?id=34877 concerning those X fill issues.

Along with the pure X "xwin" device driver, PLplot also has a device driver based on the pango/cairo library stack that provides the following devices on Linux: "xcairo" (X backend), "svgcairo" (SVG backend), "pscairo" (PostScript backend), "pdfcairo" (PDF backend), and "pngcairo" (bitmapped surface for cairo).  All these cairo devices show exactly the same two classes of fill errors for the two different filling rules as the "xwin" device.  Most of these can be dismissed as exactly the same X error as reported above since xcairo obviously uses X, and svgcairo, pscairo, and pdfcairo produce files that are viewed using a viewer that presumably ultimately renders the fills using X.  But I am not sure whether the same argument can be made for pngcairo since that is a bitmapped result.  In that case cairo (or possibly some independent library such as X) must render the fills (incorrectly for both the odd-even and non-zero filling rules) before the resulting png file is viewed.

If you want to verify this bitmapped fill error for yourself, follow the PLplot svn trunk CMake-based build instructions given in the above bug report (which should only take a few minutes), but instead of building the xwin device, you build all the cairo devices with

make cairo

and the 27th example with

make x27c

Afterwards you run that example as follows from the build tree:

# even-odd filling rule:
examples/c/x27c -dev pngcairo -o testeo.pngcairo -fam -eofill

# non-zero filling rule:
examples/c/x27c -dev pngcairo -o test.pngcairo -fam

(The purpose of the -fam option is to separate the various pages of the example into separate files and the purpose of the -eofill option is to specify the even-odd filling rule as opposed to the non-zero winding number fill rule that is used if that option is not specified.)  Then view the results using, e.g.,

display testeo.pngcairo.14

(to display the 14th page [which shows major filling errors] of the example that uses the even-odd fill rule).

If it turns out that even the bitmapped pngcairo results have fills done with X, then this bug should be closed so that everybody with an interest in correcting these fill problems for self-intersecting boundaries can concentrate on the above X bug report.  On the other hand, my understanding is that the cairo developers have lots of rendering expertise so regardless of that issue I hope they help to figure out not only the current pngcairo fill problem discussed here, but also the general X fill problems.
Comment 1 M Joonas Pihlaja 2011-03-03 20:01:07 UTC
I looked at the cairo trace for the fourth figure and noticed that the path is not closed.  Adding some printfs to x27c shows that while the phi parameter does goes from 0 to 160*pi, the phiw goes from 0 to roughly 226.67*pi, so that's the cause of the path being open.  Is this intentional?  Your bug report doesn't spell it out, so could you clarify what the problem in the rendering of the fourth figure is?  Thanks.
Comment 2 Alan W. Irwin 2011-03-04 09:58:19 UTC
> Is this (non-closed path) intentional?

Good catch.  I assumed all pages were closed (this example not originally programmed by me), but pages 11-13 are closed while pages 14 and above are obviously _not_ closed.  For the latter pages this obviously introduces an
extra large last segment in the boundary back to the starting position.  I am still investigating the effect of changing the loop termination so that all figures all have a predefined last segment corresponding to some
angle (which may be zero) before complete closure.  More about this later.

> Your bug report doesn't spell it out, so could you clarify what the problem in the rendering of the fourth figure is?  Thanks.

I made those comments in the X bug report I referred to, but for completeness I should state it here as well.  For the even-odd filling rule (-eofill) the filled and unfilled areas in the figures should essentially alternate.  Instead, for pages 11-13, no filling occurs at all (that should be impossible for these closed figures), while for pages 14 and beyond certain of the areas that should be filled are not, and vice versa.  (The large last segment of the boundary must have some effect here, but the fills obviously do not alternate as they should.)  For the non-zero winding number fill rule (no -eofill option), pages 11-13 are filled correctly, but for pages 14 and beyond there are asymmetries in the results on the right-hand sides of the plots (which are probably due to the large last boundary segment referred to above, but I am still investigating).  So in sum, there are obvious fill errors for the even-off fill rule, while it is possible there are no fill errors for the non-zero winding number fill rule since the asymmetries you see in that case could be an artifact of the last large segment of the boundary.
Comment 3 Alan W. Irwin 2011-03-04 13:51:41 UTC
As of revision 11591 of PLplot svn trunk, I have changed example 27 so that the maximum phi and phiw values are the smallest possible integers times 2 pi.  The previous incorrect maximum values for these numbers so complicated the boundary (with many duplicate boundaries) that correct fills were being generated that looked incorrect for the -eofill case.  The incorrect maximums also caused a large last boundary segment that introduced small but noticable asymmetries into the case without -eofill.

Now these example 27 issues have been fixed, the results with -eofill are not only correct but also beautiful (see, for example, revised testeo.pngcairo.19) while results without -eofill are also correct (symmetrical).

Accordingly I am changing the status of the "bug" to RESOLVED/NOTOURBUG.  My thanks to M Joonas Pihlaja for a strong hint that lead me to a solution for these initial extremely puzzling fill results for the self-intersecting boundary case.

One final topic is could someone comment here (just to satisfy my curiosity) on what library is the source of the fill code when cairo fills the png surface before the bitmapped png file is produced?
Comment 4 M Joonas Pihlaja 2011-03-04 17:44:00 UTC
The new example images in plplot look great.

(In reply to comment #3)

> One final topic is could someone comment here (just to satisfy my curiosity) on
> what library is the source of the fill code when cairo fills the png surface
> before the bitmapped png file is produced?

Cairo does that itself.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.