diff --git a/Libraries/LibGfx/FloatPoint.h b/Libraries/LibGfx/FloatPoint.h index ef50987e0b..59b10a06c0 100644 --- a/Libraries/LibGfx/FloatPoint.h +++ b/Libraries/LibGfx/FloatPoint.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace Gfx { @@ -38,12 +39,25 @@ class FloatRect; class FloatPoint { public: FloatPoint() { } + + FloatPoint(int x, int y) + : m_x(x) + , m_y(y) + { + } + FloatPoint(float x, float y) : m_x(x) , m_y(y) { } + FloatPoint(double x, double y) + : m_x(x) + , m_y(y) + { + } + explicit FloatPoint(const IntPoint& other) : m_x(other.x()) , m_y(other.y()) @@ -96,6 +110,7 @@ public: FloatPoint operator-() const { return { -m_x, -m_y }; } + FloatPoint operator-(float number) const { return { m_x - number, m_y - number }; } FloatPoint operator-(const FloatPoint& other) const { return { m_x - other.m_x, m_y - other.m_y }; } FloatPoint& operator-=(const FloatPoint& other) { @@ -104,14 +119,24 @@ public: return *this; } + FloatPoint operator+(float number) const { return { m_x + number, m_y + number }; } + FloatPoint operator+(const FloatPoint& other) const { return { m_x + other.m_x, m_y + other.m_y }; } FloatPoint& operator+=(const FloatPoint& other) { m_x += other.m_x; m_y += other.m_y; return *this; } - FloatPoint operator+(const FloatPoint& other) const { return { m_x + other.m_x, m_y + other.m_y }; } + FloatPoint operator*(float factor) const { return { m_x * factor, m_y * factor }; } + FloatPoint& operator*=(float factor) + { + m_x *= factor; + m_y *= factor; + return *this; + } + + FloatPoint operator/(float factor) const { return { m_x / factor, m_y / factor }; } FloatPoint& operator/=(float factor) { m_x /= factor; @@ -119,6 +144,13 @@ public: return *this; } + float distance_from(const FloatPoint& other) const + { + if (*this == other) + return 0; + return sqrtf(powf(m_x - other.m_x, 2.0f) + powf(m_y - other.m_y, 2.0f)); + } + String to_string() const { return String::format("[%g,%g]", x(), y()); } bool is_null() const { return !m_x && !m_y; } diff --git a/Libraries/LibGfx/Painter.cpp b/Libraries/LibGfx/Painter.cpp index c80356ad33..770f5f03de 100644 --- a/Libraries/LibGfx/Painter.cpp +++ b/Libraries/LibGfx/Painter.cpp @@ -1565,7 +1565,7 @@ void Painter::fill_path(Path& path, Color color, WindingRule winding_rule) #ifdef FILL_PATH_DEBUG size_t i { 0 }; for (auto& segment : segments) - draw_line(IntPoint(segment.from.x(), segment.from.y()), IntPoint(segment.to.x(), segment.to.y()), Color::from_hsv(++i / segments.size() * 255, 255, 255), 1); + draw_line(segment.from, segment.to, Color::from_hsv(++i / segments.size() * 255, 255, 255), 1); #endif } diff --git a/Libraries/LibWeb/DOM/HTMLPathElement.cpp b/Libraries/LibWeb/DOM/HTMLPathElement.cpp index 8c5326d71c..a86c213fd5 100644 --- a/Libraries/LibWeb/DOM/HTMLPathElement.cpp +++ b/Libraries/LibWeb/DOM/HTMLPathElement.cpp @@ -434,25 +434,29 @@ void HTMLPathElement::paint(const SvgPaintingContext& context, Gfx::Painter& pai #endif switch (instruction.type) { - case PathInstructionType::Move: + case PathInstructionType::Move: { + Gfx::FloatPoint point = { data[0], data[1] }; if (absolute) { - path.move_to({ data[0], data[1] }); + path.move_to(point); } else { ASSERT(!path.segments().is_empty()); - path.move_to(Gfx::FloatPoint { data[0], data[1] } + path.segments().last().point()); + path.move_to(point + path.segments().last().point()); } break; + } case PathInstructionType::ClosePath: path.close(); break; - case PathInstructionType::Line: + case PathInstructionType::Line: { + Gfx::FloatPoint point = { data[0], data[1] }; if (absolute) { - path.line_to({ data[0], data[1] }); + path.line_to(point); } else { ASSERT(!path.segments().is_empty()); - path.line_to(Gfx::FloatPoint { data[0], data[1] } + path.segments().last().point()); + path.line_to(point + path.segments().last().point()); } break; + } case PathInstructionType::HorizontalLine: { ASSERT(!path.segments().is_empty()); auto last_point = path.segments().last().point(); @@ -467,9 +471,9 @@ void HTMLPathElement::paint(const SvgPaintingContext& context, Gfx::Painter& pai ASSERT(!path.segments().is_empty()); auto last_point = path.segments().last().point(); if (absolute) { - path.line_to(Gfx::FloatPoint{ last_point.x(), data[0] }); + path.line_to(Gfx::FloatPoint { last_point.x(), data[0] }); } else { - path.line_to(Gfx::FloatPoint{ last_point.x(), data[0] + last_point.y() }); + path.line_to(Gfx::FloatPoint { last_point.x(), data[0] + last_point.y() }); } break; } @@ -560,15 +564,19 @@ void HTMLPathElement::paint(const SvgPaintingContext& context, Gfx::Painter& pai break; } - case PathInstructionType::QuadraticBezierCurve: + case PathInstructionType::QuadraticBezierCurve: { + Gfx::FloatPoint through = { data[0], data[1] }; + Gfx::FloatPoint point = { data[2], data[3] }; + if (absolute) { - path.quadratic_bezier_curve_to({ data[0], data[1] }, { data[2], data[3] }); + path.quadratic_bezier_curve_to(through, point); } else { ASSERT(!path.segments().is_empty()); auto last_point = path.segments().last().point(); - path.quadratic_bezier_curve_to({ data[0] + last_point.x(), data[1] + last_point.y() }, { data[2] + last_point.x(), data[3] + last_point.y() }); + path.quadratic_bezier_curve_to(through + last_point, point + last_point); } break; + } case PathInstructionType::Curve: case PathInstructionType::SmoothCurve: case PathInstructionType::SmoothQuadraticBezierCurve: diff --git a/Libraries/LibWeb/Layout/LineBox.cpp b/Libraries/LibWeb/Layout/LineBox.cpp index fe6da58712..9e49c0b6bf 100644 --- a/Libraries/LibWeb/Layout/LineBox.cpp +++ b/Libraries/LibWeb/Layout/LineBox.cpp @@ -42,7 +42,7 @@ void LineBox::add_fragment(const LayoutNode& layout_node, int start, int length, m_fragments.last().m_length = (start - m_fragments.last().m_start) + length; m_fragments.last().set_width(m_fragments.last().width() + width); } else { - m_fragments.append(make(layout_node, start, length, Gfx::FloatPoint(m_width, 0), Gfx::FloatSize(width, height))); + m_fragments.append(make(layout_node, start, length, Gfx::FloatPoint(m_width, 0.0f), Gfx::FloatSize(width, height))); } m_width += width;