-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
LibWeb: Apply CSS filters on SVGs #2248
LibWeb: Apply CSS filters on SVGs #2248
Conversation
@gotlougit |
Thanks for the review, I had some more follow-up questions. |
I ended up creating the ApplyFilters command in a similar manner to what ApplyOpacity does, and this modified method now indeed works to fix the reported SVG filter bug. Hopefully this is more in line with what we need, but I am not as sure about the CSS side of things, would be open to helping fix that one up too. |
Hello! One or more of the commit messages in this PR do not match the Ladybird code submission policy, please check the |
4b2c19b
to
1aa6d5b
Compare
93cc506
to
664f091
Compare
The Also, please remove the |
664f091
to
2600171
Compare
Seems like the CI now passes properly, due to the fact that StackingContext calls ApplyFilters now instead of doing the filter stuff inside push_stacking_context. This helped keep the same behavior as before and still allows code reuse for implementing SVG filters properly. |
@@ -1103,6 +1077,41 @@ void DisplayListPlayerSkia::apply_opacity(ApplyOpacity const& command) | |||
canvas.saveLayer(nullptr, &paint); | |||
} | |||
|
|||
void DisplayListPlayerSkia::apply_filters(ApplyFilters const& command) | |||
{ | |||
if (command.filter.is_none()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this work when command.opacity < 1
and filters are set? Is the opacity applied twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ladybird seems to report opacity correctly when testing with an SVG and with a <div>
with some text inside it (same filter applied to both).
The code duplication can create confusion though. What we could do is get rid of ApplyOpacity by itself and merge that into ApplyFilters, or alternatively, get rid of the duplication here. I guess it depends on the scope of what we'd like to keep as a "filter". I would be open to either approach, although my personal preference would be for the second option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: checking the opacity is less than one could probably be promoted to checking for non-trivial filters being applied (i.e. those introducing a substantial visual change, e.g. opacity < 1
or hue ≠ 0°
etc.) as an optimisation. not sure if that is the correct moment to update, or whether it is a good place for an optimisation either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rearrange changes in commits such that any specific commit does not introduce a regression:
- LibWeb: Add ApplyFilters command for both CSS and SVGs
- LibWeb: Remove filter from PushStackingContext <-- at this point filters has regressed for stacking contexts
- LibWeb: Use apply_filters() in StackingContext
I would expect to see commits in the following order:
- move filters application from PushStackingContext into ApplyFiltes
- reuse ApplyFilters for SVG
context.display_list_recorder().apply_opacity(computed_values.opacity()); | ||
} | ||
|
||
context.display_list_recorder().apply_filters(paintable.computed_values().opacity(), paintable.computed_values().filter()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems like we no longer need apply_opacity()
here if apply_filters()
is responsible for both filters and opacity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty similar to #2248 (comment), I am open for discussion on what to do next.
This helps reuse this code in other areas, such as for filters for SVGs
602f847
to
29cc289
Compare
The opacity is still being set separately by using ApplyOpacity for both CSS and SVG
I ended up removing the opacity code from the new ApplyFilters command since the paint code seems to call ApplyOpacity. Locally tests pass on my machine, so I think this is a decent enough change. |
This made it so that any content drawn after an SVG with a filter is also affected by that filter. |
The code largely mirrors the one in StackingContext::paint() for applying CSS filters to a generic context, with some minor changes.
There's a weird compile issue where
matrix_with_scaled_translation()
is not being found by the compiler, even though StackingContext::paint() uses it with no issues. PaintableBox also has the relevant header file imported as well, so it is not like it is missing somewhere down in an inherited object either.Compile log (with matrix_with_scaled_translation):
Fixes #2015