diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2022-08-11 17:38:35 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-08-14 11:30:40 +0200 |
commit | 389f1ee6f54a089aa9b7b0618ed477f8a7cfd4c1 (patch) | |
tree | ab6296353428fce9130e7387d399d5eda25dae75 | |
parent | 2ec52bbbd57cabf56ec2f5b61e3846640c358146 (diff) | |
download | serenity-389f1ee6f54a089aa9b7b0618ed477f8a7cfd4c1.zip |
LibGfx: Add method for copying a Path with a transform applied
The Web's CanvasRenderingContext2D needs a way to draw a path with a
transform applied to it, without modifying the original path, so here
it is. :^)
-rw-r--r-- | Userland/Libraries/LibGfx/Path.cpp | 44 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/Path.h | 2 |
2 files changed, 46 insertions, 0 deletions
diff --git a/Userland/Libraries/LibGfx/Path.cpp b/Userland/Libraries/LibGfx/Path.cpp index f84d071609..81209f5252 100644 --- a/Userland/Libraries/LibGfx/Path.cpp +++ b/Userland/Libraries/LibGfx/Path.cpp @@ -332,4 +332,48 @@ void Path::segmentize_path() m_bounding_box = Gfx::FloatRect { min_x, min_y, max_x - min_x, max_y - min_y }; } +Path Path::copy_transformed(Gfx::AffineTransform const& transform) const +{ + Path result; + + for (auto const& segment : m_segments) { + switch (segment.type()) { + case Segment::Type::MoveTo: + result.move_to(transform.map(segment.point())); + break; + case Segment::Type::LineTo: { + result.line_to(transform.map(segment.point())); + break; + } + case Segment::Type::QuadraticBezierCurveTo: { + auto const& quadratic_segment = static_cast<QuadraticBezierCurveSegment const&>(segment); + result.quadratic_bezier_curve_to(transform.map(quadratic_segment.through()), transform.map(segment.point())); + break; + } + case Segment::Type::CubicBezierCurveTo: { + auto const& cubic_segment = static_cast<CubicBezierCurveSegment const&>(segment); + result.cubic_bezier_curve_to(transform.map(cubic_segment.through_0()), transform.map(cubic_segment.through_1()), transform.map(segment.point())); + break; + } + case Segment::Type::EllipticalArcTo: { + auto const& arc_segment = static_cast<EllipticalArcSegment const&>(segment); + result.elliptical_arc_to( + transform.map(segment.point()), + transform.map(arc_segment.center()), + transform.map(arc_segment.radii()), + arc_segment.x_axis_rotation(), + arc_segment.theta_1(), + arc_segment.theta_delta(), + arc_segment.large_arc(), + arc_segment.sweep()); + break; + } + case Segment::Type::Invalid: + VERIFY_NOT_REACHED(); + } + } + + return result; +} + } diff --git a/Userland/Libraries/LibGfx/Path.h b/Userland/Libraries/LibGfx/Path.h index 7c0ba83090..662edb3732 100644 --- a/Userland/Libraries/LibGfx/Path.h +++ b/Userland/Libraries/LibGfx/Path.h @@ -243,6 +243,8 @@ public: return m_bounding_box.value(); } + Path copy_transformed(AffineTransform const&) const; + String to_string() const; private: |