mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-23 19:00:59 +00:00
LibWeb: Parse stroke-{linejoin,miterlimit} attributes
Similar to LadybirdBrowser/ladybird#1714. We don't implement the linejoin values `miter-clip` and `arcs`, because according to the SVG 2 spec: > The values miter-clip and arcs of the stroke-linejoin property are at > risk. There are no known browser implementations. See issue Github > issue w3c/svgwg#592. Nothing uses this yet. The next step is to change SVGPathPaintable::paint() to read `graphics_element.stroke_linejoin()` and `graphics_element.stroke_miterlimit()` when painting.
This commit is contained in:
parent
eafcd82e82
commit
421cf8d9bf
Notes:
github-actions[bot]
2024-10-29 22:37:55 +00:00
Author: https://github.com/nico
Commit: 421cf8d9bf
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2030
Reviewed-by: https://github.com/AtkinsSJ ✅
10 changed files with 80 additions and 1 deletions
|
@ -32,6 +32,8 @@ pointer-events: auto
|
||||||
quotes: auto
|
quotes: auto
|
||||||
stroke: none
|
stroke: none
|
||||||
stroke-linecap: butt
|
stroke-linecap: butt
|
||||||
|
stroke-linejoin: miter
|
||||||
|
stroke-miterlimit: 4
|
||||||
stroke-opacity: 1
|
stroke-opacity: 1
|
||||||
stroke-width: 1px
|
stroke-width: 1px
|
||||||
tab-size: 8
|
tab-size: 8
|
||||||
|
@ -121,7 +123,7 @@ grid-row-start: auto
|
||||||
grid-template-areas: none
|
grid-template-areas: none
|
||||||
grid-template-columns: auto
|
grid-template-columns: auto
|
||||||
grid-template-rows: auto
|
grid-template-rows: auto
|
||||||
height: 2091px
|
height: 2125px
|
||||||
inline-size: auto
|
inline-size: auto
|
||||||
inset-block-end: auto
|
inset-block-end: auto
|
||||||
inset-block-start: auto
|
inset-block-start: auto
|
||||||
|
|
|
@ -149,6 +149,8 @@ public:
|
||||||
static CSS::FillRule fill_rule() { return CSS::FillRule::Nonzero; }
|
static CSS::FillRule fill_rule() { return CSS::FillRule::Nonzero; }
|
||||||
static CSS::ClipRule clip_rule() { return CSS::ClipRule::Nonzero; }
|
static CSS::ClipRule clip_rule() { return CSS::ClipRule::Nonzero; }
|
||||||
static CSS::StrokeLinecap stroke_linecap() { return CSS::StrokeLinecap::Butt; }
|
static CSS::StrokeLinecap stroke_linecap() { return CSS::StrokeLinecap::Butt; }
|
||||||
|
static CSS::StrokeLinejoin stroke_linejoin() { return CSS::StrokeLinejoin::Miter; }
|
||||||
|
static float stroke_miterlimit() { return 4.0f; }
|
||||||
static float stroke_opacity() { return 1.0f; }
|
static float stroke_opacity() { return 1.0f; }
|
||||||
static float stop_opacity() { return 1.0f; }
|
static float stop_opacity() { return 1.0f; }
|
||||||
static CSS::TextAnchor text_anchor() { return CSS::TextAnchor::Start; }
|
static CSS::TextAnchor text_anchor() { return CSS::TextAnchor::Start; }
|
||||||
|
@ -473,6 +475,8 @@ public:
|
||||||
Optional<SVGPaint> const& stroke() const { return m_inherited.stroke; }
|
Optional<SVGPaint> const& stroke() const { return m_inherited.stroke; }
|
||||||
float fill_opacity() const { return m_inherited.fill_opacity; }
|
float fill_opacity() const { return m_inherited.fill_opacity; }
|
||||||
CSS::StrokeLinecap stroke_linecap() const { return m_inherited.stroke_linecap; }
|
CSS::StrokeLinecap stroke_linecap() const { return m_inherited.stroke_linecap; }
|
||||||
|
CSS::StrokeLinejoin stroke_linejoin() const { return m_inherited.stroke_linejoin; }
|
||||||
|
NumberOrCalculated stroke_miterlimit() const { return m_inherited.stroke_miterlimit; }
|
||||||
float stroke_opacity() const { return m_inherited.stroke_opacity; }
|
float stroke_opacity() const { return m_inherited.stroke_opacity; }
|
||||||
LengthPercentage const& stroke_width() const { return m_inherited.stroke_width; }
|
LengthPercentage const& stroke_width() const { return m_inherited.stroke_width; }
|
||||||
Color stop_color() const { return m_noninherited.stop_color; }
|
Color stop_color() const { return m_noninherited.stop_color; }
|
||||||
|
@ -569,6 +573,8 @@ protected:
|
||||||
Optional<SVGPaint> stroke;
|
Optional<SVGPaint> stroke;
|
||||||
float fill_opacity { InitialValues::fill_opacity() };
|
float fill_opacity { InitialValues::fill_opacity() };
|
||||||
CSS::StrokeLinecap stroke_linecap { InitialValues::stroke_linecap() };
|
CSS::StrokeLinecap stroke_linecap { InitialValues::stroke_linecap() };
|
||||||
|
CSS::StrokeLinejoin stroke_linejoin { InitialValues::stroke_linejoin() };
|
||||||
|
NumberOrCalculated stroke_miterlimit { InitialValues::stroke_miterlimit() };
|
||||||
float stroke_opacity { InitialValues::stroke_opacity() };
|
float stroke_opacity { InitialValues::stroke_opacity() };
|
||||||
LengthPercentage stroke_width { Length::make_px(1) };
|
LengthPercentage stroke_width { Length::make_px(1) };
|
||||||
CSS::TextAnchor text_anchor { InitialValues::text_anchor() };
|
CSS::TextAnchor text_anchor { InitialValues::text_anchor() };
|
||||||
|
@ -813,6 +819,8 @@ public:
|
||||||
void set_fill_rule(CSS::FillRule value) { m_inherited.fill_rule = value; }
|
void set_fill_rule(CSS::FillRule value) { m_inherited.fill_rule = value; }
|
||||||
void set_fill_opacity(float value) { m_inherited.fill_opacity = value; }
|
void set_fill_opacity(float value) { m_inherited.fill_opacity = value; }
|
||||||
void set_stroke_linecap(CSS::StrokeLinecap value) { m_inherited.stroke_linecap = value; }
|
void set_stroke_linecap(CSS::StrokeLinecap value) { m_inherited.stroke_linecap = value; }
|
||||||
|
void set_stroke_linejoin(CSS::StrokeLinejoin value) { m_inherited.stroke_linejoin = value; }
|
||||||
|
void set_stroke_miterlimit(NumberOrCalculated value) { m_inherited.stroke_miterlimit = value; }
|
||||||
void set_stroke_opacity(float value) { m_inherited.stroke_opacity = value; }
|
void set_stroke_opacity(float value) { m_inherited.stroke_opacity = value; }
|
||||||
void set_stroke_width(LengthPercentage value) { m_inherited.stroke_width = value; }
|
void set_stroke_width(LengthPercentage value) { m_inherited.stroke_width = value; }
|
||||||
void set_stop_color(Color value) { m_noninherited.stop_color = value; }
|
void set_stop_color(Color value) { m_noninherited.stop_color = value; }
|
||||||
|
|
|
@ -422,6 +422,11 @@
|
||||||
"square",
|
"square",
|
||||||
"round"
|
"round"
|
||||||
],
|
],
|
||||||
|
"stroke-linejoin": [
|
||||||
|
"miter",
|
||||||
|
"round",
|
||||||
|
"bevel"
|
||||||
|
],
|
||||||
"text-align": [
|
"text-align": [
|
||||||
"center",
|
"center",
|
||||||
"justify",
|
"justify",
|
||||||
|
|
|
@ -79,6 +79,7 @@
|
||||||
"background",
|
"background",
|
||||||
"backwards",
|
"backwards",
|
||||||
"baseline",
|
"baseline",
|
||||||
|
"bevel",
|
||||||
"bidi-override",
|
"bidi-override",
|
||||||
"blink",
|
"blink",
|
||||||
"block",
|
"block",
|
||||||
|
@ -251,6 +252,7 @@
|
||||||
"middle",
|
"middle",
|
||||||
"min-content",
|
"min-content",
|
||||||
"minimal-ui",
|
"minimal-ui",
|
||||||
|
"miter",
|
||||||
"monospace",
|
"monospace",
|
||||||
"more",
|
"more",
|
||||||
"move",
|
"move",
|
||||||
|
|
|
@ -2414,6 +2414,24 @@
|
||||||
"stroke-linecap"
|
"stroke-linecap"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"stroke-linejoin": {
|
||||||
|
"affects-layout": false,
|
||||||
|
"animation-type": "discrete",
|
||||||
|
"inherited": true,
|
||||||
|
"initial": "miter",
|
||||||
|
"valid-types": [
|
||||||
|
"stroke-linejoin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stroke-miterlimit": {
|
||||||
|
"affects-layout": false,
|
||||||
|
"animation-type": "by-computed-value",
|
||||||
|
"inherited": true,
|
||||||
|
"initial": "4",
|
||||||
|
"valid-types": [
|
||||||
|
"number [0,∞]"
|
||||||
|
]
|
||||||
|
},
|
||||||
"stroke-opacity": {
|
"stroke-opacity": {
|
||||||
"affects-layout": false,
|
"affects-layout": false,
|
||||||
"animation-type": "by-computed-value",
|
"animation-type": "by-computed-value",
|
||||||
|
|
|
@ -326,6 +326,25 @@ Optional<CSS::StrokeLinecap> StyleProperties::stroke_linecap() const
|
||||||
return keyword_to_stroke_linecap(value->to_keyword());
|
return keyword_to_stroke_linecap(value->to_keyword());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<CSS::StrokeLinejoin> StyleProperties::stroke_linejoin() const
|
||||||
|
{
|
||||||
|
auto value = property(CSS::PropertyID::StrokeLinejoin);
|
||||||
|
return keyword_to_stroke_linejoin(value->to_keyword());
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberOrCalculated StyleProperties::stroke_miterlimit() const
|
||||||
|
{
|
||||||
|
auto value = property(CSS::PropertyID::StrokeMiterlimit);
|
||||||
|
|
||||||
|
if (value->is_math()) {
|
||||||
|
auto const& math_value = value->as_math();
|
||||||
|
VERIFY(math_value.resolves_to_number());
|
||||||
|
return NumberOrCalculated { math_value };
|
||||||
|
}
|
||||||
|
|
||||||
|
return NumberOrCalculated { value->as_number().number() };
|
||||||
|
}
|
||||||
|
|
||||||
float StyleProperties::stroke_opacity() const
|
float StyleProperties::stroke_opacity() const
|
||||||
{
|
{
|
||||||
auto value = property(CSS::PropertyID::StrokeOpacity);
|
auto value = property(CSS::PropertyID::StrokeOpacity);
|
||||||
|
|
|
@ -180,6 +180,8 @@ public:
|
||||||
float stop_opacity() const;
|
float stop_opacity() const;
|
||||||
float fill_opacity() const;
|
float fill_opacity() const;
|
||||||
Optional<CSS::StrokeLinecap> stroke_linecap() const;
|
Optional<CSS::StrokeLinecap> stroke_linecap() const;
|
||||||
|
Optional<CSS::StrokeLinejoin> stroke_linejoin() const;
|
||||||
|
NumberOrCalculated stroke_miterlimit() const;
|
||||||
float stroke_opacity() const;
|
float stroke_opacity() const;
|
||||||
Optional<CSS::FillRule> fill_rule() const;
|
Optional<CSS::FillRule> fill_rule() const;
|
||||||
Optional<CSS::ClipRule> clip_rule() const;
|
Optional<CSS::ClipRule> clip_rule() const;
|
||||||
|
|
|
@ -849,6 +849,11 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
|
||||||
computed_values.set_fill_opacity(computed_style.fill_opacity());
|
computed_values.set_fill_opacity(computed_style.fill_opacity());
|
||||||
if (auto stroke_linecap = computed_style.stroke_linecap(); stroke_linecap.has_value())
|
if (auto stroke_linecap = computed_style.stroke_linecap(); stroke_linecap.has_value())
|
||||||
computed_values.set_stroke_linecap(stroke_linecap.value());
|
computed_values.set_stroke_linecap(stroke_linecap.value());
|
||||||
|
if (auto stroke_linejoin = computed_style.stroke_linejoin(); stroke_linejoin.has_value())
|
||||||
|
computed_values.set_stroke_linejoin(stroke_linejoin.value());
|
||||||
|
|
||||||
|
computed_values.set_stroke_miterlimit(computed_style.stroke_miterlimit());
|
||||||
|
|
||||||
computed_values.set_stroke_opacity(computed_style.stroke_opacity());
|
computed_values.set_stroke_opacity(computed_style.stroke_opacity());
|
||||||
computed_values.set_stop_opacity(computed_style.stop_opacity());
|
computed_values.set_stop_opacity(computed_style.stop_opacity());
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,8 @@ void SVGGraphicsElement::apply_presentational_hints(CSS::StyleProperties& style)
|
||||||
// FIXME: The `stroke` attribute and CSS `stroke` property are not the same! But our support is limited enough that they are equivalent for now.
|
// FIXME: The `stroke` attribute and CSS `stroke` property are not the same! But our support is limited enough that they are equivalent for now.
|
||||||
NamedPropertyID(CSS::PropertyID::Stroke),
|
NamedPropertyID(CSS::PropertyID::Stroke),
|
||||||
NamedPropertyID(CSS::PropertyID::StrokeLinecap),
|
NamedPropertyID(CSS::PropertyID::StrokeLinecap),
|
||||||
|
NamedPropertyID(CSS::PropertyID::StrokeLinejoin),
|
||||||
|
NamedPropertyID(CSS::PropertyID::StrokeMiterlimit),
|
||||||
NamedPropertyID(CSS::PropertyID::StrokeWidth),
|
NamedPropertyID(CSS::PropertyID::StrokeWidth),
|
||||||
NamedPropertyID(CSS::PropertyID::FillRule),
|
NamedPropertyID(CSS::PropertyID::FillRule),
|
||||||
NamedPropertyID(CSS::PropertyID::FillOpacity),
|
NamedPropertyID(CSS::PropertyID::FillOpacity),
|
||||||
|
@ -242,6 +244,20 @@ Optional<CSS::StrokeLinecap> SVGGraphicsElement::stroke_linecap() const
|
||||||
return layout_node()->computed_values().stroke_linecap();
|
return layout_node()->computed_values().stroke_linecap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<CSS::StrokeLinejoin> SVGGraphicsElement::stroke_linejoin() const
|
||||||
|
{
|
||||||
|
if (!layout_node())
|
||||||
|
return {};
|
||||||
|
return layout_node()->computed_values().stroke_linejoin();
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<CSS::NumberOrCalculated> SVGGraphicsElement::stroke_miterlimit() const
|
||||||
|
{
|
||||||
|
if (!layout_node())
|
||||||
|
return {};
|
||||||
|
return layout_node()->computed_values().stroke_miterlimit();
|
||||||
|
}
|
||||||
|
|
||||||
Optional<float> SVGGraphicsElement::stroke_opacity() const
|
Optional<float> SVGGraphicsElement::stroke_opacity() const
|
||||||
{
|
{
|
||||||
if (!layout_node())
|
if (!layout_node())
|
||||||
|
|
|
@ -39,6 +39,8 @@ public:
|
||||||
Optional<float> stroke_width() const;
|
Optional<float> stroke_width() const;
|
||||||
Optional<float> fill_opacity() const;
|
Optional<float> fill_opacity() const;
|
||||||
Optional<CSS::StrokeLinecap> stroke_linecap() const;
|
Optional<CSS::StrokeLinecap> stroke_linecap() const;
|
||||||
|
Optional<CSS::StrokeLinejoin> stroke_linejoin() const;
|
||||||
|
Optional<CSS::NumberOrCalculated> stroke_miterlimit() const;
|
||||||
Optional<float> stroke_opacity() const;
|
Optional<float> stroke_opacity() const;
|
||||||
Optional<FillRule> fill_rule() const;
|
Optional<FillRule> fill_rule() const;
|
||||||
Optional<ClipRule> clip_rule() const;
|
Optional<ClipRule> clip_rule() const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue