Bug 14408 - Spectacular gradient failure
Summary: Spectacular gradient failure
Status: RESOLVED FIXED
Alias: None
Product: poppler
Classification: Unclassified
Component: general (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: Jeff Muizelaar
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-02-06 15:52 UTC by Carl Worth
Modified: 2009-11-18 02:19 UTC (History)
5 users (show)

See Also:
i915 platform:
i915 features:


Attachments
A simple, gradient-filled SVG file (627 bytes, text/plain)
2008-02-06 15:53 UTC, Carl Worth
Details
The buggy PDF file (converted from the svg with svg2pdf) (3.12 KB, image/pdf)
2008-02-06 15:53 UTC, Carl Worth
Details
A correct rendering of the rectangle (from the SVG with svg2png) (1.23 KB, image/png)
2008-02-06 15:54 UTC, Carl Worth
Details
The buggy rendering of the PDF file (with a poppler-based pdf2png) (2.57 KB, image/png)
2008-02-06 15:55 UTC, Carl Worth
Details
Begin adding support for using cairo gradients to paint gradients. (4.13 KB, patch)
2008-02-22 12:15 UTC, Jeff Muizelaar
Details | Splinter Review

Description Carl Worth 2008-02-06 15:52:45 UTC
Background: I recently generated slides for a talk (originally SVG, then converted to PDF with librsvg+cairo), but they appeared as full-page, black smears when viewed with evince (poppler+cairo).

Diagnosis: I was able to trim down the failure to a single, small, gradient-filled rectangle. I'll attach an SVG version of the rectangle, which was written by hand and is trivial to verify as correct. I'll also attach a PDF version of the rectanlge. I haven't manually verified this as correct, but it does render correctly with acroread. Finally, I'll attach PNG files showing a correct rendering of the SVG file (from a librsvg-based svg2png), and the incorrect rendering by poppler of the PDF file, (from a poppler-based pdf2png).

Finally, I want to point out that the bakground of the -pdf2png.png file is coming out white, but in the evince (0.8.3) rendering of the PDF file, the output is black, (with some gray stripes).

Recommendation: It's likely time to bite the bullet and implement poppler gradients as cairo gradients, (at least when using the cairo backend). That would certainly be sufficient to make me happy, and should eliminate bugs like this.

-Carl
Comment 1 Carl Worth 2008-02-06 15:53:27 UTC
Created attachment 14183 [details]
A simple, gradient-filled SVG file
Comment 2 Carl Worth 2008-02-06 15:53:53 UTC
Created attachment 14184 [details]
The buggy PDF file (converted from the svg with svg2pdf)
Comment 3 Carl Worth 2008-02-06 15:54:27 UTC
Created attachment 14185 [details]
A correct rendering of the rectangle (from the SVG with svg2png)
Comment 4 Carl Worth 2008-02-06 15:55:02 UTC
Created attachment 14186 [details]
The buggy rendering of the PDF file (with a poppler-based pdf2png)
Comment 5 Jeff Muizelaar 2008-02-21 20:54:34 UTC
One of the difficulties in implementing pdf gradients with cairo is how to deal with Postscript functions. For example axial gradients have a linearly varying parameter but the actual color values are expressed in terms of an arbitrary Postscript function. ie. the following is a valid axial gradient, r=sin(t), g=cos(t), b=0, where t varies linearly.
Comment 6 Carl Worth 2008-02-22 09:51:22 UTC
(In reply to comment #5)
> One of the difficulties in implementing pdf gradients with cairo is how to deal
> with Postscript functions. For example axial gradients have a linearly varying
> parameter but the actual color values are expressed in terms of an arbitrary
> Postscript function. ie. the following is a valid axial gradient, r=sin(t),
> g=cos(t), b=0, where t varies linearly.

Yeah, that could be tricky. One could punt and just call the existing code in a case like that, (meaning that many of these cases will still draw garbage, but hopefully the actual usage is rare). Or one could sample that function at various points in order to compute a static color-stop array suitable for passing to cairo.

If it can be an arbitrary function though, I suppose it doesn't give you any guarantees about how smooth it is so that you can know when you've sampled it enough?

-Carl
Comment 7 Jeff Muizelaar 2008-02-22 12:15:29 UTC
Created attachment 14507 [details] [review]
Begin adding support for using cairo gradients to paint gradients.

Here's a lightly tested patch that does axial shading using cairo's linear gradients.
Comment 8 Albert Astals Cid 2008-02-23 03:48:12 UTC
Jeff, please keep the list in CC if you assign yourself a bug.
Comment 9 Adrian Johnson 2008-02-23 05:00:28 UTC
(In reply to comment #7)
> Created an attachment (id=14507) [details]
> Begin adding support for using cairo gradients to paint gradients.
> 
> Here's a lightly tested patch that does axial shading using cairo's linear
> gradients.
> 

I made a start on this recently as well but never got any further than you have. 

My plan for the stitching and exponential functions was to go over each function to get the boundary points and use these as gradient stops. If the exponential function has N=1 there is nothing further to do. If N!=1, bisect the stops  until the color error is less than some predefined tolerance.

For Type 0 Sample functions, use each sample as a stop.

For the Type 4 Postscript functions, I was planning on sampling values at a number of points. I wanted to avoid anything like the existing code that bisects the sample points until the color difference is less than some tolerance. This has the flaw that the bisection stops when two almost identical colors are found even though the sample points may be widely spaced apart with further color changes between these points. Keeping the sampling interval small would give best results and should be ok for PS/PDF printing since we are using a linear gradient between stops rather the the solid color the existing code uses. Further optimization to reduce the number of stops can be done by checking if multiple consecutive sample values can be approximated with a linear gradient.

When shading->getExtend0() != shading->getExtend1() I was planning to add an extra stop top extend the gradient out to the bounding box on one side.
Comment 10 Carlos Garcia Campos 2009-11-18 02:19:22 UTC
This bug is fixed since poppler 0.12.


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.