| 
									
										
										
										
											2024-08-08 15:12:29 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2024, Andreas Kling <andreas@ladybird.org> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <AK/Forward.h>
 | 
					
						
							|  |  |  | #include <AK/NonnullOwnPtr.h>
 | 
					
						
							|  |  |  | #include <AK/Utf8View.h>
 | 
					
						
							| 
									
										
										
										
											2024-11-20 17:37:15 +04:00
										 |  |  | #include <LibGfx/AffineTransform.h>
 | 
					
						
							| 
									
										
										
										
											2024-08-08 15:12:29 +02:00
										 |  |  | #include <LibGfx/Forward.h>
 | 
					
						
							| 
									
										
										
										
											2024-11-20 17:37:15 +04:00
										 |  |  | #include <LibGfx/Point.h>
 | 
					
						
							|  |  |  | #include <LibGfx/Rect.h>
 | 
					
						
							| 
									
										
										
										
											2024-08-08 15:12:29 +02:00
										 |  |  | #include <LibGfx/WindingRule.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Gfx { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PathImpl { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     static NonnullOwnPtr<Gfx::PathImpl> create(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual ~PathImpl(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual void clear() = 0; | 
					
						
							|  |  |  |     virtual void move_to(Gfx::FloatPoint const&) = 0; | 
					
						
							|  |  |  |     virtual void line_to(Gfx::FloatPoint const&) = 0; | 
					
						
							|  |  |  |     virtual void close_all_subpaths() = 0; | 
					
						
							|  |  |  |     virtual void close() = 0; | 
					
						
							|  |  |  |     virtual void elliptical_arc_to(FloatPoint point, FloatSize radii, float x_axis_rotation, bool large_arc, bool sweep) = 0; | 
					
						
							|  |  |  |     virtual void arc_to(FloatPoint point, float radius, bool large_arc, bool sweep) = 0; | 
					
						
							|  |  |  |     virtual void quadratic_bezier_curve_to(FloatPoint through, FloatPoint point) = 0; | 
					
						
							|  |  |  |     virtual void cubic_bezier_curve_to(FloatPoint c1, FloatPoint c2, FloatPoint p2) = 0; | 
					
						
							|  |  |  |     virtual void text(Utf8View, Font const&) = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     virtual void append_path(Gfx::Path const&) = 0; | 
					
						
							|  |  |  |     virtual void intersect(Gfx::Path const&) = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] virtual bool is_empty() const = 0; | 
					
						
							|  |  |  |     virtual Gfx::FloatPoint last_point() const = 0; | 
					
						
							|  |  |  |     virtual Gfx::FloatRect bounding_box() const = 0; | 
					
						
							| 
									
										
										
										
											2024-10-28 13:51:23 +11:00
										 |  |  |     virtual void set_fill_type(Gfx::WindingRule winding_rule) = 0; | 
					
						
							| 
									
										
										
										
											2024-09-18 10:51:26 +02:00
										 |  |  |     virtual bool contains(FloatPoint point, Gfx::WindingRule) const = 0; | 
					
						
							| 
									
										
										
										
											2024-08-08 15:12:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     virtual NonnullOwnPtr<PathImpl> clone() const = 0; | 
					
						
							|  |  |  |     virtual NonnullOwnPtr<PathImpl> copy_transformed(Gfx::AffineTransform const&) const = 0; | 
					
						
							| 
									
										
										
										
											2024-08-09 14:00:10 +02:00
										 |  |  |     virtual NonnullOwnPtr<PathImpl> place_text_along(Utf8View text, Font const&) const = 0; | 
					
						
							| 
									
										
										
										
											2024-08-08 15:12:29 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Path { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     Path() = default; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Path(Path const& other) | 
					
						
							|  |  |  |         : m_impl(other.impl().clone()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Path& operator=(Path const& other) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (this != &other) | 
					
						
							|  |  |  |             m_impl = other.impl().clone(); | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Path(Path&& other) = default; | 
					
						
							|  |  |  |     Path& operator=(Path&& other) = default; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void clear() { impl().clear(); } | 
					
						
							|  |  |  |     void move_to(Gfx::FloatPoint const& point) { impl().move_to(point); } | 
					
						
							|  |  |  |     void line_to(Gfx::FloatPoint const& point) { impl().line_to(point); } | 
					
						
							|  |  |  |     void close_all_subpaths() { impl().close_all_subpaths(); } | 
					
						
							|  |  |  |     void close() { impl().close(); } | 
					
						
							| 
									
										
										
										
											2024-11-21 15:09:31 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     enum class CapStyle { | 
					
						
							|  |  |  |         Butt, | 
					
						
							|  |  |  |         Round, | 
					
						
							|  |  |  |         Square, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enum class JoinStyle { | 
					
						
							|  |  |  |         Miter, | 
					
						
							|  |  |  |         Round, | 
					
						
							|  |  |  |         Bevel, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-08 15:12:29 +02:00
										 |  |  |     void elliptical_arc_to(FloatPoint point, FloatSize radii, float x_axis_rotation, bool large_arc, bool sweep) { impl().elliptical_arc_to(point, radii, x_axis_rotation, large_arc, sweep); } | 
					
						
							|  |  |  |     void arc_to(FloatPoint point, float radius, bool large_arc, bool sweep) { impl().arc_to(point, radius, large_arc, sweep); } | 
					
						
							|  |  |  |     void quadratic_bezier_curve_to(FloatPoint through, FloatPoint point) { impl().quadratic_bezier_curve_to(through, point); } | 
					
						
							|  |  |  |     void cubic_bezier_curve_to(FloatPoint c1, FloatPoint c2, FloatPoint p2) { impl().cubic_bezier_curve_to(c1, c2, p2); } | 
					
						
							|  |  |  |     void text(Utf8View text, Font const& font) { impl().text(text, font); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-09 14:00:10 +02:00
										 |  |  |     void horizontal_line_to(float x) { line_to({ x, last_point().y() }); } | 
					
						
							|  |  |  |     void vertical_line_to(float y) { line_to({ last_point().x(), y }); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-08 15:12:29 +02:00
										 |  |  |     void append_path(Gfx::Path const& other) { impl().append_path(other); } | 
					
						
							|  |  |  |     void intersect(Gfx::Path const& other) { impl().intersect(other); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [[nodiscard]] bool is_empty() const { return impl().is_empty(); } | 
					
						
							|  |  |  |     Gfx::FloatPoint last_point() const { return impl().last_point(); } | 
					
						
							|  |  |  |     Gfx::FloatRect bounding_box() const { return impl().bounding_box(); } | 
					
						
							| 
									
										
										
										
											2024-09-18 10:51:26 +02:00
										 |  |  |     bool contains(FloatPoint point, Gfx::WindingRule winding_rule) const { return impl().contains(point, winding_rule); } | 
					
						
							| 
									
										
										
										
											2024-10-28 13:51:23 +11:00
										 |  |  |     void set_fill_type(Gfx::WindingRule winding_rule) { impl().set_fill_type(winding_rule); } | 
					
						
							| 
									
										
										
										
											2024-08-08 15:12:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Gfx::Path clone() const { return Gfx::Path { impl().clone() }; } | 
					
						
							|  |  |  |     Gfx::Path copy_transformed(Gfx::AffineTransform const& transform) const { return Gfx::Path { impl().copy_transformed(transform) }; } | 
					
						
							| 
									
										
										
										
											2024-08-09 14:00:10 +02:00
										 |  |  |     Gfx::Path place_text_along(Utf8View text, Font const& font) const { return Gfx::Path { impl().place_text_along(text, font) }; } | 
					
						
							| 
									
										
										
										
											2024-08-08 15:12:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void transform(Gfx::AffineTransform const& transform) { m_impl = impl().copy_transformed(transform); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PathImpl& impl() { return *m_impl; } | 
					
						
							|  |  |  |     PathImpl const& impl() const { return *m_impl; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     explicit Path(NonnullOwnPtr<PathImpl>&& impl) | 
					
						
							|  |  |  |         : m_impl(move(impl)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NonnullOwnPtr<PathImpl> m_impl { PathImpl::create() }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |