-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: correctly handle fill/stroke opacity properties
Previously, the fill-opacity and stroke-opacity properties were being treated like the opacity property in that they were applied to all their children. It's correct that opacity on an element should apply to its children, and another opacity property on a child should multiply the opacity of its parent. But fill-opacity and stroke-opacity are different in that the value is inherited and any change to a child's values must overwrite their parent's value. This bug was spotted because `fill-opacity="0"` was being declared at the top level of a document, with `fill-opacity="1"` on its children. With the old code, 0 was multiplied with 1, giving an opacity of 0. With the new code, the child's 1 value overrides the parent's 0 value. Fixes #177
- Loading branch information
Showing
5 changed files
with
69 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,30 @@ | ||
module Prawn::SVG::Attributes::Opacity | ||
def parse_opacity_attributes_and_call | ||
# We can't do nested opacities quite like the SVG requires, but this is close enough. | ||
opacity = properties.opacity.to_f.clamp(0, 1) if properties.opacity | ||
fill_opacity = properties.fill_opacity.to_f.clamp(0, 1) if properties.fill_opacity | ||
stroke_opacity = properties.stroke_opacity.to_f.clamp(0, 1) if properties.stroke_opacity | ||
# The opacity property is not inherited, but the opacity applies to all children underneath the element. | ||
# | ||
# Having an opacity property on a parent, and again on a child, multiplies the parent and child's opacities | ||
# when drawing the children. | ||
# | ||
# The fill-opacity and stroke-opacity properties are inherited, but children which have a different value | ||
# are displayed at that opacity rather than multiplying the parent's fill/stroke opacity with the child's. | ||
# | ||
# opacity and fill/stroke opacity can both be applied to the same element, and they multiply together. | ||
|
||
opacity = computed_properties.opacity&.to_f&.clamp(0, 1) | ||
fill_opacity = computed_properties.fill_opacity.to_f.clamp(0, 1) | ||
stroke_opacity = computed_properties.stroke_opacity.to_f.clamp(0, 1) | ||
|
||
if opacity || fill_opacity || stroke_opacity | ||
state.fill_opacity *= [opacity || 1, fill_opacity || 1].min | ||
state.stroke_opacity *= [opacity || 1, stroke_opacity || 1].min | ||
state.opacity *= opacity if opacity | ||
|
||
fill_opacity = (fill_opacity || 1) * state.opacity | ||
stroke_opacity = (stroke_opacity || 1) * state.opacity | ||
|
||
add_call_and_enter 'transparent', state.fill_opacity, state.stroke_opacity | ||
if state.last_fill_opacity != fill_opacity || state.last_stroke_opacity != stroke_opacity | ||
state.last_fill_opacity = fill_opacity | ||
state.last_stroke_opacity = stroke_opacity | ||
add_call_and_enter 'transparent', fill_opacity, stroke_opacity | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters