LibWeb: Support percentage values in SVG line element

This commit is contained in:
Edwin Hoksberg 2024-07-21 19:21:29 +02:00 committed by Andreas Kling
commit ac6126e263
Notes: github-actions[bot] 2024-07-21 17:57:27 +00:00
4 changed files with 59 additions and 21 deletions

View file

@ -0,0 +1,23 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x408 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x392 children: inline
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 784x392] baseline: 392
SVGSVGBox <svg> at (8,8) content-size 784x392 [SVG] children: inline
TextNode <#text>
SVGGeometryBox <line> at (6.046875,135.40625) content-size 787.921875x3.921875 children: not-inline
TextNode <#text>
SVGGeometryBox <line> at (6.046875,264.765625) content-size 787.921875x3.921875 children: not-inline
TextNode <#text>
SVGGeometryBox <line> at (264.765625,6.046875) content-size 3.921875x395.921875 children: not-inline
TextNode <#text>
SVGGeometryBox <line> at (523.484375,6.046875) content-size 3.921875x395.921875 children: not-inline
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x408]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x392]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 784x392]
SVGPathPaintable (SVGGeometryBox<line>) [6.046875,135.40625 787.921875x3.921875]
SVGPathPaintable (SVGGeometryBox<line>) [6.046875,264.765625 787.921875x3.921875]
SVGPathPaintable (SVGGeometryBox<line>) [264.765625,6.046875 3.921875x395.921875]
SVGPathPaintable (SVGGeometryBox<line>) [523.484375,6.046875 3.921875x395.921875]

View file

@ -0,0 +1,12 @@
<!doctype html><style>
line {
stroke: red;
}
</style>
<svg viewbox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<line x1="0" y1="33%" x2="100%" y2="33%"></line>
<line x1="0" y1="66%" x2="100%" y2="66%"></line>
<line x1="33%" y1="0" x2="33%" y2="100%"></line>
<line x1="66%" y1="0" x2="66%" y2="100%"></line>
</svg>

View file

@ -30,23 +30,26 @@ void SVGLineElement::attribute_changed(FlyString const& name, Optional<String> c
SVGGeometryElement::attribute_changed(name, old_value, value); SVGGeometryElement::attribute_changed(name, old_value, value);
if (name == SVG::AttributeNames::x1) { if (name == SVG::AttributeNames::x1) {
m_x1 = AttributeParser::parse_coordinate(value.value_or(String {})); m_x1 = AttributeParser::parse_number_percentage(value.value_or(String {}));
} else if (name == SVG::AttributeNames::y1) { } else if (name == SVG::AttributeNames::y1) {
m_y1 = AttributeParser::parse_coordinate(value.value_or(String {})); m_y1 = AttributeParser::parse_number_percentage(value.value_or(String {}));
} else if (name == SVG::AttributeNames::x2) { } else if (name == SVG::AttributeNames::x2) {
m_x2 = AttributeParser::parse_coordinate(value.value_or(String {})); m_x2 = AttributeParser::parse_number_percentage(value.value_or(String {}));
} else if (name == SVG::AttributeNames::y2) { } else if (name == SVG::AttributeNames::y2) {
m_y2 = AttributeParser::parse_coordinate(value.value_or(String {})); m_y2 = AttributeParser::parse_number_percentage(value.value_or(String {}));
} }
} }
Gfx::Path SVGLineElement::get_path(CSSPixelSize) Gfx::Path SVGLineElement::get_path(CSSPixelSize viewport_size)
{ {
auto const viewport_width = viewport_size.width().to_float();
auto const viewport_height = viewport_size.height().to_float();
Gfx::Path path; Gfx::Path path;
float x1 = m_x1.value_or(0); float const x1 = m_x1.value_or({ 0, false }).resolve_relative_to(viewport_width);
float y1 = m_y1.value_or(0); float const y1 = m_y1.value_or({ 0, false }).resolve_relative_to(viewport_height);
float x2 = m_x2.value_or(0); float const x2 = m_x2.value_or({ 0, false }).resolve_relative_to(viewport_width);
float y2 = m_y2.value_or(0); float const y2 = m_y2.value_or({ 0, false }).resolve_relative_to(viewport_height);
// 1. perform an absolute moveto operation to absolute location (x1,y1) // 1. perform an absolute moveto operation to absolute location (x1,y1)
path.move_to({ x1, y1 }); path.move_to({ x1, y1 });
@ -62,8 +65,8 @@ JS::NonnullGCPtr<SVGAnimatedLength> SVGLineElement::x1() const
{ {
// FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Populate the unit type when it is parsed (0 here is "unknown").
// FIXME: Create a proper animated value when animations are supported. // FIXME: Create a proper animated value when animations are supported.
auto base_length = SVGLength::create(realm(), 0, m_x1.value_or(0)); auto base_length = SVGLength::create(realm(), 0, m_x1.value_or({ 0, false }).value());
auto anim_length = SVGLength::create(realm(), 0, m_x1.value_or(0)); auto anim_length = SVGLength::create(realm(), 0, m_x1.value_or({ 0, false }).value());
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
} }
@ -72,8 +75,8 @@ JS::NonnullGCPtr<SVGAnimatedLength> SVGLineElement::y1() const
{ {
// FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Populate the unit type when it is parsed (0 here is "unknown").
// FIXME: Create a proper animated value when animations are supported. // FIXME: Create a proper animated value when animations are supported.
auto base_length = SVGLength::create(realm(), 0, m_y1.value_or(0)); auto base_length = SVGLength::create(realm(), 0, m_y1.value_or({ 0, false }).value());
auto anim_length = SVGLength::create(realm(), 0, m_y1.value_or(0)); auto anim_length = SVGLength::create(realm(), 0, m_y1.value_or({ 0, false }).value());
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
} }
@ -82,8 +85,8 @@ JS::NonnullGCPtr<SVGAnimatedLength> SVGLineElement::x2() const
{ {
// FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Populate the unit type when it is parsed (0 here is "unknown").
// FIXME: Create a proper animated value when animations are supported. // FIXME: Create a proper animated value when animations are supported.
auto base_length = SVGLength::create(realm(), 0, m_x2.value_or(0)); auto base_length = SVGLength::create(realm(), 0, m_x2.value_or({ 0, false }).value());
auto anim_length = SVGLength::create(realm(), 0, m_x2.value_or(0)); auto anim_length = SVGLength::create(realm(), 0, m_x2.value_or({ 0, false }).value());
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
} }
@ -92,8 +95,8 @@ JS::NonnullGCPtr<SVGAnimatedLength> SVGLineElement::y2() const
{ {
// FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Populate the unit type when it is parsed (0 here is "unknown").
// FIXME: Create a proper animated value when animations are supported. // FIXME: Create a proper animated value when animations are supported.
auto base_length = SVGLength::create(realm(), 0, m_y2.value_or(0)); auto base_length = SVGLength::create(realm(), 0, m_y2.value_or({ 0, false }).value());
auto anim_length = SVGLength::create(realm(), 0, m_y2.value_or(0)); auto anim_length = SVGLength::create(realm(), 0, m_y2.value_or({ 0, false }).value());
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
} }

View file

@ -32,10 +32,10 @@ private:
virtual void initialize(JS::Realm&) override; virtual void initialize(JS::Realm&) override;
Optional<float> m_x1; Optional<NumberPercentage> m_x1;
Optional<float> m_y1; Optional<NumberPercentage> m_y1;
Optional<float> m_x2; Optional<NumberPercentage> m_x2;
Optional<float> m_y2; Optional<NumberPercentage> m_y2;
}; };
} }