mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:07:34 +00:00
LibWeb: Add SVG <polyline>
element and test case :^)
This commit is contained in:
parent
17912330c4
commit
116a1f485c
13 changed files with 141 additions and 1 deletions
|
@ -45,6 +45,7 @@ namespace Web::SVG::AttributeNames {
|
|||
E(patternContentUnits) \
|
||||
E(patternTransform) \
|
||||
E(patternUnits) \
|
||||
E(points) \
|
||||
E(pointsAtX) \
|
||||
E(pointsAtY) \
|
||||
E(pointsAtZ) \
|
||||
|
|
|
@ -64,6 +64,32 @@ Optional<float> AttributeParser::parse_positive_length(StringView input)
|
|||
return result;
|
||||
}
|
||||
|
||||
Vector<Gfx::FloatPoint> AttributeParser::parse_points(StringView input)
|
||||
{
|
||||
AttributeParser parser { input };
|
||||
|
||||
parser.parse_whitespace();
|
||||
|
||||
// FIXME: "If an odd number of coordinates is provided, then the element is in error, with the same user agent behavior
|
||||
// as occurs with an incorrectly specified ‘path’ element. In such error cases the user agent will drop the last,
|
||||
// odd coordinate and otherwise render the shape."
|
||||
// The parser currently doesn't notice that there is a missing coordinate, so make it notice!
|
||||
auto coordinate_pair_sequence = parser.parse_coordinate_pair_sequence();
|
||||
|
||||
parser.parse_whitespace();
|
||||
if (!parser.done())
|
||||
return {};
|
||||
|
||||
// FIXME: This is awkward. Can we return Gfx::FloatPoints from some of these parsing methods instead of Vector<float>?
|
||||
Vector<Gfx::FloatPoint> points;
|
||||
points.ensure_capacity(coordinate_pair_sequence.size());
|
||||
|
||||
for (auto const& pair : coordinate_pair_sequence)
|
||||
points.empend(pair[0], pair[1]);
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
void AttributeParser::parse_drawto()
|
||||
{
|
||||
if (match('M') || match('m')) {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibGfx/Point.h>
|
||||
|
||||
namespace Web::SVG {
|
||||
|
||||
|
@ -42,6 +43,7 @@ public:
|
|||
static Optional<float> parse_coordinate(StringView input);
|
||||
static Optional<float> parse_length(StringView input);
|
||||
static Optional<float> parse_positive_length(StringView input);
|
||||
static Vector<Gfx::FloatPoint> parse_points(StringView input);
|
||||
|
||||
private:
|
||||
void parse_drawto();
|
||||
|
|
51
Userland/Libraries/LibWeb/SVG/SVGPolylineElement.cpp
Normal file
51
Userland/Libraries/LibWeb/SVG/SVGPolylineElement.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "SVGPolylineElement.h"
|
||||
#include <LibWeb/SVG/AttributeNames.h>
|
||||
#include <LibWeb/SVG/AttributeParser.h>
|
||||
|
||||
namespace Web::SVG {
|
||||
|
||||
SVGPolylineElement::SVGPolylineElement(DOM::Document& document, QualifiedName qualified_name)
|
||||
: SVGGeometryElement(document, qualified_name)
|
||||
{
|
||||
}
|
||||
|
||||
void SVGPolylineElement::parse_attribute(FlyString const& name, String const& value)
|
||||
{
|
||||
SVGGeometryElement::parse_attribute(name, value);
|
||||
|
||||
if (name == SVG::AttributeNames::points) {
|
||||
m_points = AttributeParser::parse_points(value);
|
||||
m_path.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Gfx::Path& SVGPolylineElement::get_path()
|
||||
{
|
||||
if (m_path.has_value())
|
||||
return m_path.value();
|
||||
|
||||
Gfx::Path path;
|
||||
|
||||
if (m_points.is_empty()) {
|
||||
m_path = move(path);
|
||||
return m_path.value();
|
||||
}
|
||||
|
||||
// 1. perform an absolute moveto operation to the first coordinate pair in the list of points
|
||||
path.move_to(m_points.first());
|
||||
|
||||
// 2. for each subsequent coordinate pair, perform an absolute lineto operation to that coordinate pair.
|
||||
for (size_t point_index = 1; point_index < m_points.size(); ++point_index)
|
||||
path.line_to(m_points[point_index]);
|
||||
|
||||
m_path = move(path);
|
||||
return m_path.value();
|
||||
}
|
||||
|
||||
}
|
30
Userland/Libraries/LibWeb/SVG/SVGPolylineElement.h
Normal file
30
Userland/Libraries/LibWeb/SVG/SVGPolylineElement.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/SVG/SVGGeometryElement.h>
|
||||
|
||||
namespace Web::SVG {
|
||||
|
||||
class SVGPolylineElement final : public SVGGeometryElement {
|
||||
public:
|
||||
using WrapperType = Bindings::SVGPolylineElementWrapper;
|
||||
|
||||
SVGPolylineElement(DOM::Document&, QualifiedName);
|
||||
virtual ~SVGPolylineElement() override = default;
|
||||
|
||||
virtual void parse_attribute(FlyString const& name, String const& value) override;
|
||||
|
||||
virtual Gfx::Path& get_path() override;
|
||||
|
||||
private:
|
||||
Optional<Gfx::Path> m_path;
|
||||
|
||||
Vector<Gfx::FloatPoint> m_points;
|
||||
};
|
||||
|
||||
}
|
5
Userland/Libraries/LibWeb/SVG/SVGPolylineElement.idl
Normal file
5
Userland/Libraries/LibWeb/SVG/SVGPolylineElement.idl
Normal file
|
@ -0,0 +1,5 @@
|
|||
[Exposed=Window]
|
||||
interface SVGPolylineElement : SVGGeometryElement {
|
||||
};
|
||||
|
||||
// SVGPolylineElement includes SVGAnimatedPoints;
|
|
@ -16,6 +16,7 @@ namespace Web::SVG::TagNames {
|
|||
__ENUMERATE_SVG_TAG(g) \
|
||||
__ENUMERATE_SVG_TAG(line) \
|
||||
__ENUMERATE_SVG_TAG(path) \
|
||||
__ENUMERATE_SVG_TAG(polyline) \
|
||||
__ENUMERATE_SVG_TAG(rect) \
|
||||
__ENUMERATE_SVG_TAG(svg)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue