When a gradient is larger than roughly 32ki units in the gradient space (not device space), it fails to render. Such gradients are frequently encountered in SVG, as well as when working at large zoom factors in e.g. Inkscape. The fundamental cause is the use of fixed point coordinates in pixman.
Created attachment 40899 [details] Large gradient testcase This is a very simple test case. The program takes a single integer parameter and tries to render a radial gradient with this radius, scaled down to the area of the image surface used (500x500). On my system, the program works correctly only as long as the parameter is <= 32702. Any higher value causes a blank image to be saved to the PNG file.
Created attachment 40900 [details] Output of "./precision 20000"
Created attachment 40901 [details] Output of "./precision 300000"
(In reply to comment #0) > When a gradient is larger than roughly 32ki units in the gradient space (not > device space), it fails to render. Such gradients are frequently encountered in > SVG, as well as when working at large zoom factors in e.g. Inkscape. The > fundamental cause is the use of fixed point coordinates in pixman. Actually the fundamental cause is the incorrect handling of gradients coordinates in Cairo. Cairo is already trying to rescale gradients to fit withing the range accepted by pixman, but it is only doing this for linear gradients and (worse) is doing it incorrectly and inconsistently across different backends. I pushed a branch which improves the handling of gradient coordinates: http://cgit.freedesktop.org/~ranma42/cairo/log/?h=wip/doublepattern Could you test it and check if it fixes your problem?
This improves the situation a lot - I need to create absurdly large gradients to force them not to render. There are still some pathological cases which are not handled correctly though. I attach one of them - it's taken from a gradient definition in a SVG file encountered in the wild.
Created attachment 41223 [details] Pathological large gradient testcase Testcase with an extreme transformation matrix. Such data is known to occur in some Inkscape documents encountered on the web. The gradient appears when I run the program as "./radial-prec 1.8", but disappears with "./radial-prec 1.9".
Created attachment 41224 [details] Output of "./radial-prec 1.8"
(In reply to comment #6) > Created an attachment (id=41223) [details] > Pathological large gradient testcase > > Testcase with an extreme transformation matrix. Such data is known to occur in > some Inkscape documents encountered on the web. The gradient appears when I run > the program as "./radial-prec 1.8", but disappears with "./radial-prec 1.9". This is not a gradient-specific problem. Cairo is not handling the transform matrix in a sufficiently solid way, but you would likely have the same problem with surface patterns.
> This is not a gradient-specific problem. > > Cairo is not handling the transform matrix in a sufficiently solid way, > but you would likely have the same problem with surface patterns. Should I file this as another bug?
(In reply to comment #9) > > This is not a gradient-specific problem. > > > > Cairo is not handling the transform matrix in a sufficiently solid way, > > but you would likely have the same problem with surface patterns. > > Should I file this as another bug? I'm not sure about it. It looks like your second test case is not actually having problems with the transform matrix but simply with the translation so it can be handled correctly by improving my patches. I will update my branch soon.
I pushed a new branch fixing the second problem you noticed: http://cgit.freedesktop.org/~ranma42/cairo/log/?h=wip/doublepattern2 It was actually caused by an incorrect conversion from the cairo matrix to the pixman transformation/offset. This branch should make the handling of transformations in image, xlib and xcb more safe, but there are more overflows to be handled (two of them are easy to fix, so I do it before cleaning up for master). This doesn't make all possible cairo matrices work on pixman (which is basically impossible), but should allow for a much wider range. Would this be enough for inkscape to work correctly? Do you have other patterns failing?
(In reply to comment #11) > Would this be enough for inkscape to work correctly? Do you have other patterns > failing? At the moment, no other failing test cases. Thanks a lot!
(In reply to comment #12) > (In reply to comment #11) > > Would this be enough for inkscape to work correctly? Do you have other patterns > > failing? > > At the moment, no other failing test cases. Thanks a lot! I just pushed to master a branch containing basically the same changes as the branch you tested. The three "interesting" commits are: commit 51594d9787905618de608a367c3a5fc0544c52e3 Author: Andrea Canciani <ranma42@gmail.com> Date: Fri Dec 17 11:04:41 2010 +0100 matrix: Cairo matrix to pixman transform/offset conversion Xlib, XCB and image use the same code to convert a cairo_matrix_t to a backend-specific transform. The code did not handle correctly some matrices, thus a new function that performs the conversion in a more generic way was added and used in the backends instead of fixing the repeated code. Fixes part of https://bugs.freedesktop.org/show_bug.cgi?id=32215 commit 38dce5d14473e1106c8ea7a67b9be0f400d442a2 Author: Andrea Canciani <ranma42@gmail.com> Date: Fri Dec 17 11:03:03 2010 +0100 pattern: Factor out pattern rescaling The same code was duplicated (incorrectly and with some minor differences) in pattern, image, xlib and xcb. _cairo_gradient_pattern_max_val() abstracts that code in a function that can be used whenever a gradients extremes need to be rescaled to fit within a given range. Fixes huge-linear, huge-radial. Fixes part of https://bugs.freedesktop.org/show_bug.cgi?id=32215 commit 200e147322a7a17dec91ad5f678a07fdfaf38de2 Author: Andrea Canciani <ranma42@gmail.com> Date: Fri Dec 17 11:04:53 2010 +0100 pattern: Use double precision for gradient extreme objects Using double precision for gradient extreme objects ensures that they are preserved as specified when constructing the gradient pattern. Fixes huge-linear, huge-radial. Fixes part of https://bugs.freedesktop.org/show_bug.cgi?id=32215 Together they make it possible for backends that can handle the full double range to have any gradient and for pixman-based backends (image,xlib,xcb,fallbacks) to handle a much wider range of gradients and transformation matrices.
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.