WeasyPrint icon indicating copy to clipboard operation
WeasyPrint copied to clipboard

Color hinting in gradients not recognized

Open Gayo opened this issue 2 years ago • 4 comments

It seems that the parser doesn't recognize the color-hint term in gradient definitions. This is a bare percentage that may be specified between any two adjacent stops to fine-tune the interpolation. See here for a minimal example. It looks to me as though the code anticipates that it can apply parse_color_stop to each comma-separated item of the stop list, and thus throws an error on the color hint.

Gayo avatar Sep 10 '23 06:09 Gayo

Hi!

Thanks for the report. Color hints have been added in Images Level 4, that’s why they’re not supported yet.

The fix is not easy, as it requires to change some code at different places, but it should be possible for people with a solid Python experience, even if they don’t know how WeasyPrint works. I can give hints if anybody is interested!

liZe avatar Sep 10 '23 08:09 liZe

(Also related to #1372)

liZe avatar Sep 10 '23 08:09 liZe

I think they are actually from Level 3 -- you can see the interpolation algorithm here for instance, and the syntax is included in the level-3 color-stop definitions. Level 4 seems to have added a finer-grained support for interpolation methods, but that doesn't seem like too big a deal.

I might take a shot at this myself, actually, since I've been looking at it, but I'm pretty slow so it'll surely be a bit! I'll check in if I have any questions.

Gayo avatar Sep 11 '23 01:09 Gayo

I think they are actually from Level 3 -- you can see the interpolation algorithm here for instance, and the syntax is included in the level-3 color-stop definitions. Level 4 seems to have added a finer-grained support for interpolation methods, but that doesn't seem like too big a deal.

Oh, you’re right! They’ve been added in the 2019 update.

I might take a shot at this myself, actually, since I've been looking at it, but I'm pretty slow so it'll surely be a bit! I'll check in if I have any questions.

No problem, thanks a lot 💜! Here are some steps you can follow:

  1. Update parse_*_gradient_parameters functions used in get_image to get hints.
  2. Change LinearGradient.__init__ and RadialGradient.__init__ (and actually Gradient.__init__) to get and store these hints.
  3. Change LinearGradient.layout, RadialGradient.layout and Gradient.draw to include the hints in the PDF. Maybe changing the n value (that’s currently always 1) is what we want. The same has to be done for alpha values (1 is set here but should be stored in alpha_couples instead, just as it’s stored in color_couples).
  4. Add tests! 😄

If you want to know more about how gradients are stored in PDF, you can get the PDF 2.0 specification and read chapters 7.10 and 8.7.4.5. But you can also just start with steps 1 and 2 (and even 4) and let me fight with the PDF specification!

Don’t hesitate to ask, I’ll be happy to help.

liZe avatar Sep 11 '23 08:09 liZe