Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Gradients don't work when user space has been transformed #891
I'm the author of prawn-svg, an SVG to PDF renderer that uses prawn, and have had a few requests to implement SVG gradients. @mojavelinux is interested in this for his asciidoctor-pdf project.
Unfortunately, prawn doesn't implement gradients quite right. PDF gradients/patterns take coordinates in the coordinate space of the document, not the "user space", so if you perform a scale/rotate/translate and then paint a gradient inside, it doesn't render correctly.
I have a working solution to this, but it's not super elegant, so I thought I'd bring it up here for discussion before I tidy it enough to be presentable.
The idea is that all calls to transformation_matrix result in the matrix being pushed on to a document-scope stack, and save_graphics_state and restore_graphics_state do what you'd expect them to do with the stack before passing the call on to PDF::Core.
The gradient code has then been extended to matrix multiply the transformations on the stack together, and pass to the PDF Matrix attribute in the shading pattern, instead of using an identity matrix as it currently does.
It works, but is a substantial change. It also means we'd be able to implement a working version of skew, I believe.
Any objections to the approach before I submit a PR?
Thanks for the info @mogest, to be honest I'm not 100% comfortable with that code or that part of the spec so I'll take your word at that it's wrong :)
My first question is would implementing your change break backwards compatibility? If so we would need to implement your fix in a way that we can enable the new correct behavior while preserving the old behavior until we release Prawn 3.0 and remove the deprecated wrong code.
I would say throw open a PR so we can look over what you have and see what can be done. I'll try to become more knowledgeable about the area as well so we can come up with the right solution.
@mogest Is my understanding correct that the problem is here: https://github.com/prawnpdf/prawn/blob/master/lib/prawn/graphics/patterns.rb#L65-L66 (and the relevant calls in the other branch)?
referenced this issue
Jul 19, 2015
@cheba, it's actually the Matrix that's passed on https://github.com/prawnpdf/prawn/blob/master/lib/prawn/graphics/patterns.rb#L124 that's causing the problem. The matrix has to match the current transformations that have been effected in the document.
I've created a pull request @packetmonkey. I'd love to hear what everyone thinks, as I feel like it might be a bit of a contentious solution.