LibWeb: Account for transforms in isPointInPath()

This commit is contained in:
Tim Ledbetter 2025-10-21 14:52:16 +01:00 committed by Jelle Raaijmakers
parent d17f666a8c
commit 494fcc40ac
9 changed files with 165 additions and 4 deletions

View File

@ -774,19 +774,22 @@ void CanvasRenderingContext2D::clip(Path2D& path, StringView fill_rule)
clip_internal(path.path(), parse_fill_rule(fill_rule));
}
static bool is_point_in_path_internal(Gfx::Path path, double x, double y, StringView fill_rule)
static bool is_point_in_path_internal(Gfx::Path path, Gfx::AffineTransform const& transform, double x, double y, StringView fill_rule)
{
return path.contains(Gfx::FloatPoint(x, y), parse_fill_rule(fill_rule));
auto point = Gfx::FloatPoint(x, y);
if (auto inverse_transform = transform.inverse(); inverse_transform.has_value())
point = inverse_transform->map(point);
return path.contains(point, parse_fill_rule(fill_rule));
}
bool CanvasRenderingContext2D::is_point_in_path(double x, double y, StringView fill_rule)
{
return is_point_in_path_internal(path(), x, y, fill_rule);
return is_point_in_path_internal(path(), drawing_state().transform, x, y, fill_rule);
}
bool CanvasRenderingContext2D::is_point_in_path(Path2D const& path, double x, double y, StringView fill_rule)
{
return is_point_in_path_internal(path.path(), x, y, fill_rule);
return is_point_in_path_internal(path.path(), drawing_state().transform, x, y, fill_rule);
}
// https://html.spec.whatwg.org/multipage/canvas.html#check-the-usability-of-the-image-argument

View File

@ -0,0 +1,6 @@
Harness status: OK
Found 1 tests
1 Pass
Pass isPointInPath() handles transformations correctly

View File

@ -0,0 +1,6 @@
Harness status: OK
Found 1 tests
1 Pass
Pass isPointInPath() handles transformations correctly

View File

@ -0,0 +1,6 @@
Harness status: OK
Found 1 tests
1 Pass
Pass isPointInPath() handles transformations correctly

View File

@ -0,0 +1,6 @@
Harness status: OK
Found 1 tests
1 Pass
Pass isPointInPath() handles transformations correctly

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<meta charset="UTF-8">
<title>Canvas test: 2d.path.isPointInPath.transform.1</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.path.isPointInPath.transform.1</h1>
<p class="desc">isPointInPath() handles transformations correctly</p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<ul id="d"></ul>
<script>
var t = async_test("isPointInPath() handles transformations correctly");
_addTest(function(canvas, ctx) {
ctx.translate(50, 0);
ctx.rect(0, 0, 20, 20);
_assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
_assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
_assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
_assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
_assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
_assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
});
</script>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<meta charset="UTF-8">
<title>Canvas test: 2d.path.isPointInPath.transform.2</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.path.isPointInPath.transform.2</h1>
<p class="desc">isPointInPath() handles transformations correctly</p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<ul id="d"></ul>
<script>
var t = async_test("isPointInPath() handles transformations correctly");
_addTest(function(canvas, ctx) {
ctx.rect(50, 0, 20, 20);
ctx.translate(50, 0);
_assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
_assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
_assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
_assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
_assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
_assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
});
</script>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<meta charset="UTF-8">
<title>Canvas test: 2d.path.isPointInPath.transform.3</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.path.isPointInPath.transform.3</h1>
<p class="desc">isPointInPath() handles transformations correctly</p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<ul id="d"></ul>
<script>
var t = async_test("isPointInPath() handles transformations correctly");
_addTest(function(canvas, ctx) {
ctx.scale(-1, 1);
ctx.rect(-70, 0, 20, 20);
_assertSame(ctx.isPointInPath(-40, 10), false, "ctx.isPointInPath(-40, 10)", "false");
_assertSame(ctx.isPointInPath(10, 10), false, "ctx.isPointInPath(10, 10)", "false");
_assertSame(ctx.isPointInPath(49, 10), false, "ctx.isPointInPath(49, 10)", "false");
_assertSame(ctx.isPointInPath(51, 10), true, "ctx.isPointInPath(51, 10)", "true");
_assertSame(ctx.isPointInPath(69, 10), true, "ctx.isPointInPath(69, 10)", "true");
_assertSame(ctx.isPointInPath(71, 10), false, "ctx.isPointInPath(71, 10)", "false");
});
</script>

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
<meta charset="UTF-8">
<title>Canvas test: 2d.path.isPointInPath.transform.4</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<script src="../../../../html/canvas/resources/canvas-tests.js"></script>
<link rel="stylesheet" href="../../../../html/canvas/resources/canvas-tests.css">
<body class="show_output">
<h1>2d.path.isPointInPath.transform.4</h1>
<p class="desc">isPointInPath() handles transformations correctly</p>
<p class="output">Actual output:</p>
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<ul id="d"></ul>
<script>
var t = async_test("isPointInPath() handles transformations correctly");
_addTest(function(canvas, ctx) {
ctx.translate(50, 0);
ctx.rect(50, 0, 20, 20);
ctx.translate(0, 50);
_assertSame(ctx.isPointInPath(60, 10), false, "ctx.isPointInPath(60, 10)", "false");
_assertSame(ctx.isPointInPath(110, 10), true, "ctx.isPointInPath(110, 10)", "true");
_assertSame(ctx.isPointInPath(110, 60), false, "ctx.isPointInPath(110, 60)", "false");
});
</script>