Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track transformations and apply to gradients' matrices #894

Merged
merged 4 commits into from
Aug 11, 2015

Conversation

mogest
Copy link

@mogest mogest commented Jul 19, 2015

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.

This commit tracks transformations applied to the document, and multiplies
the gradient matrix with this tracked transformation matrix so that the
gradient appears in the correct place in the document.

This has been created in response to issue #891.

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.

This commit tracks transformations applied to the document, and multiplies
the gradient matrix with this tracked transformation matrix so that the
gradient appears in the correct place in the document.
@mogest
Copy link
Author

mogest commented Jul 19, 2015

Rubocop wants .map(&:to_f) instead of .map { |n| n.to_f }, but I was just following the style of the surrounding code. Happy to change.

@pointlessone
Copy link
Member

@mogest Please do.

Code seems clean enough but I haven't got to actually try it out yet. Hopefully will have some time this week.

@packetmonkey
Copy link
Contributor

My main concern with this, beyond trying to find the time to truly understand this change, is any backwards compatibility implications.

From my basic understanding, it looks like it a user could be relying on the broken behavior of their gradient's not being rotated, and this change would alter their behavior if they upgraded.

Am I understanding correctly?

@mojavelinux
Copy link
Contributor

is any backwards compatibility implications.

If that's a major concern, why not just add an option at the top-level to use legacy or compliant gradient logic?

One thing is for certain. We have to get past this or else gradients in SVGs embedded in PDFs (which is a major use case for a PDF generator) is never going to work correctly.

@packetmonkey
Copy link
Contributor

I was thinking something similar. For that to work we would have to let users opt into the new correct behavior, deprecate the old broken behavior, then when we release prawn 3 at some point in the future we can remove the old code and the logic for handling it's optional use and just use the correct new behavior.

I don't believe Prawn has done something like that before so I want to make sure that a breaking change is transitioned correctly, there are a lot of people possibly using the bad behavior and not knowing it.

The other option is that merging this PR necessitates the next version of prawn released is 3.0, but I'm not personally comfortable releasing a breaking 3.0 right now so soon after 2.0.

I would love ideas and any discussion on the ramifications of those choices.

@mojavelinux
Copy link
Contributor

For that to work we would have to let users opt into the new correct behavior, deprecate the old broken behavior, then when we release prawn 3 at some point in the future we can remove the old code and the logic for handling it's optional use and just use the correct new behavior.

Precisely how I envisioned it.

there are a lot of people possibly using the bad behavior and not knowing it.

Do you really think there are that many people using gradients directly? I've been using Prawn for almost 2 years and I never saw a need for it (the need comes in the form of the infrastructure necessary for libraries like prawn-svg to work).

I tend to agree that it is too soon for Prawn 3, so the best path forward (if the agreement is that this is a critical breaking change) is to allow it to be opt-in. prawn-svg could even cause this switch to be enabled when activated (that's up to prawn-svg).

@pointlessone
Copy link
Member

I use both prawn-svg and gradients in my documents. But I don't use transformations.

I don't think changing core behaviour in prawn-svg is a nice thing to do. Probably, we can create a new gem for this very specific thing. Warn in Prawn when gradients used with transformations that it's going to change in 3.0 and that there's this one gem you should use to get correct behaviour. prawn-svg can warn users too when incorrect behaviour is evoked (but prawn would probably detect it anyway).

@mogest
Copy link
Author

mogest commented Jul 30, 2015

I feel like the external gem might be a bit fiddly given the change touches three separate classes. I'd suggest that we add an option to the fill_gradient/stroke_gradient call, something like apply_transformations: true. It'll initially default to false, and maybe log a warning if you don't explicitly set it false or true.

As you suggest @packetmonkey, it'd make sense to change the default to true in prawn 3.

Downside to the approach is the apply_transformations option hangs around afterwards. It's a pretty simple switch, so I don't think it'll negatively impact code complexity to keep it there.

@mojavelinux
Copy link
Contributor

mojavelinux commented Jul 30, 2015 via email

@packetmonkey
Copy link
Contributor

I think this sounds like the best plan, lets make the new behavior opt-in for now and when we cut prawn v3 we will make it the default behavior and remove the old.

This also introduces a new question, how do we mark it as deprecated. I'm inclined to throw a Kernel#warn call in the legacy code path with a link to a wiki page describing the change and what they should do to enable the new behavior. Normally I would also mark the method as deprecated in the docs but we aren't changing that, so we may want to add a note there as well in case they look at the docs.

Thoughts?

@pointlessone
Copy link
Member

+1 on throw. +1 on wiki. +1 on docs.

mogest pushed a commit to mogest/prawn that referenced this pull request Aug 5, 2015
As discussed on prawnpdf#894, we don't want to break existing code that uses Prawn
where the coder has manually calculated and applied the transformation to
the gradient co-ordinate arguments.  We add an :apply_transformations option
that defaults to false and a warning when the option is not supplied and a
transformation has been carried out.  It's expected this will default to
true in Prawn v3.
As discussed on prawnpdf#894, we don't want to break existing code that uses Prawn
where the coder has manually calculated and applied the transformation to
the gradient co-ordinate arguments.  We add an :apply_transformations option
that defaults to false and a warning when the option is not supplied and a
transformation has been carried out.  It's expected this will default to
true in Prawn v3.
@mogest
Copy link
Author

mogest commented Aug 5, 2015

OK, :apply_transformations option added, warn displayed if option not explicitly supplied and a transformation was made (no point warning the user if turning on the option wouldn't result in different behaviour, IMO.) Added some info to the method comments, and a link to a non-existent wiki page!

@packetmonkey
Copy link
Contributor

Alright I took some time to check out the branch and play with it. Everything is looking good in my tests when I used a scale block and a rotate block.

I think this is working as good as it can be.

I went ahead and set up the wiki page. I'm open to any feedback / edits on making that easier for developers to understand as this is the first time we are really executing a deprecation migration plan in Prawn, so if there is a precedent we want to set, now is the time.

I'm looking for another 👍 or two but I think this is ready to go in, for sure before the next prawn release.

@cheba Agree?

@mogest Just throwing it out there that you rock :) Thanks a ton for pulling this together.

@packetmonkey
Copy link
Contributor

@mogest Also please add an entry to the CHANGELOG for this.

@mojavelinux
Copy link
Contributor

Great job on the wiki page @packetmonkey and another big thumbs up to @mogest for implementing the new behavior. Great teamwork!

@pointlessone
Copy link
Member

@mogest Well done!

@mogest
Copy link
Author

mogest commented Aug 11, 2015

Thanks everyone! And thanks for the great contributing experience.

Wiki page looks great, changelog committed, ready to roll hopefully!

packetmonkey added a commit that referenced this pull request Aug 11, 2015
Track transformations and apply to gradients' matrices
@packetmonkey packetmonkey merged commit 1723005 into prawnpdf:master Aug 11, 2015
@packetmonkey
Copy link
Contributor

Aaannddddd merged :)

All glory to prawn-svg

giphy

Thanks again!

tomprats pushed a commit to tomprats/prawn that referenced this pull request Feb 24, 2016
As discussed on prawnpdf#894, we don't want to break existing code that uses Prawn
where the coder has manually calculated and applied the transformation to
the gradient co-ordinate arguments.  We add an :apply_transformations option
that defaults to false and a warning when the option is not supplied and a
transformation has been carried out.  It's expected this will default to
true in Prawn v3.
tomprats pushed a commit to tomprats/prawn that referenced this pull request Feb 24, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants