LibGfx+LibWeb: Add new Path class with Skia backend, use for 2D canvas

This thing is essentially a wrapper around an SkPath, although we do
some indirection via a PathImpl class to keep the door open for
alternative rasterizer/path backends in the future.

We also update the 2D canvas code, since that was the only code that
used Painter+DeprecatedPath, and this allows us to just drop that
code instead of temporarily supporting it until the next commit.
This commit is contained in:
Andreas Kling 2024-08-08 15:12:29 +02:00 committed by Andreas Kling
commit a3cc03f180
Notes: github-actions[bot] 2024-08-20 07:38:18 +00:00
15 changed files with 417 additions and 93 deletions

View file

@ -71,7 +71,7 @@ JS::NonnullGCPtr<HTMLCanvasElement> CanvasRenderingContext2D::canvas_for_binding
return *m_element;
}
Gfx::DeprecatedPath CanvasRenderingContext2D::rect_path(float x, float y, float width, float height)
Gfx::Path CanvasRenderingContext2D::rect_path(float x, float y, float width, float height)
{
auto& drawing_state = this->drawing_state();
@ -80,13 +80,12 @@ Gfx::DeprecatedPath CanvasRenderingContext2D::rect_path(float x, float y, float
auto bottom_left = drawing_state.transform.map(Gfx::FloatPoint(x, y + height));
auto bottom_right = drawing_state.transform.map(Gfx::FloatPoint(x + width, y + height));
Gfx::DeprecatedPath path;
Gfx::Path path;
path.move_to(top_left);
path.line_to(top_right);
path.line_to(bottom_right);
path.line_to(bottom_left);
path.line_to(top_left);
return path;
}
@ -191,7 +190,7 @@ Gfx::Painter* CanvasRenderingContext2D::painter()
return m_painter.ptr();
}
Gfx::DeprecatedPath CanvasRenderingContext2D::text_path(StringView text, float x, float y, Optional<double> max_width)
Gfx::Path CanvasRenderingContext2D::text_path(StringView text, float x, float y, Optional<double> max_width)
{
if (max_width.has_value() && max_width.value() <= 0)
return {};
@ -199,7 +198,7 @@ Gfx::DeprecatedPath CanvasRenderingContext2D::text_path(StringView text, float x
auto& drawing_state = this->drawing_state();
auto font = current_font();
Gfx::DeprecatedPath path;
Gfx::Path path;
path.move_to({ x, y });
path.text(Utf8View { text }, *font);
@ -241,8 +240,7 @@ Gfx::DeprecatedPath CanvasRenderingContext2D::text_path(StringView text, float x
}
transform = Gfx::AffineTransform { drawing_state.transform }.multiply(transform);
path = path.copy_transformed(transform);
return path;
return path.copy_transformed(transform);
}
void CanvasRenderingContext2D::fill_text(StringView text, float x, float y, Optional<double> max_width)
@ -260,7 +258,7 @@ void CanvasRenderingContext2D::begin_path()
path().clear();
}
void CanvasRenderingContext2D::stroke_internal(Gfx::DeprecatedPath const& path)
void CanvasRenderingContext2D::stroke_internal(Gfx::Path const& path)
{
auto* painter = this->painter();
if (!painter)
@ -298,7 +296,7 @@ static Gfx::WindingRule parse_fill_rule(StringView fill_rule)
return Gfx::WindingRule::Nonzero;
}
void CanvasRenderingContext2D::fill_internal(Gfx::DeprecatedPath const& path, Gfx::WindingRule winding_rule)
void CanvasRenderingContext2D::fill_internal(Gfx::Path const& path, Gfx::WindingRule winding_rule)
{
auto* painter = this->painter();
if (!painter)
@ -543,15 +541,17 @@ CanvasRenderingContext2D::PreparedText CanvasRenderingContext2D::prepare_text(By
return prepared_text;
}
void CanvasRenderingContext2D::clip_internal(Gfx::DeprecatedPath& path, Gfx::WindingRule winding_rule)
void CanvasRenderingContext2D::clip_internal(Gfx::Path& path, Gfx::WindingRule winding_rule)
{
// FIXME: This should calculate the new clip path by intersecting the given path with the current one.
// See: https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-clip-dev
path.close_all_subpaths();
if (drawing_state().clip.has_value()) {
dbgln("FIXME: CRC2D: Calculate the new clip path by intersecting the given path with the current one.");
auto& current_clip = drawing_state().clip->path;
current_clip.intersect(path);
return;
}
drawing_state().clip = Gfx::ClipPath { path, winding_rule };
drawing_state().clip = CanvasState::ClipPath { path, winding_rule };
}
void CanvasRenderingContext2D::clip(StringView fill_rule)