From 4fd818d46d3093054dc8cb97388c55ef71c5dee9 Mon Sep 17 00:00:00 2001 From: Ashwin Naren Date: Wed, 21 May 2025 00:13:08 -0700 Subject: [PATCH] hit_test for HtmlAreaElement polygons Signed-off-by: Ashwin Naren --- components/script/dom/htmlareaelement.rs | 25 ++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/components/script/dom/htmlareaelement.rs b/components/script/dom/htmlareaelement.rs index a9d94cbd7b2..a342e0ab2dd 100644 --- a/components/script/dom/htmlareaelement.rs +++ b/components/script/dom/htmlareaelement.rs @@ -46,6 +46,8 @@ pub enum Area { bottom_right: (f32, f32), }, Polygon { + /// Stored as a flat array of coordinates + /// e.g. [x1, y1, x2, y2, x3, y3] for a triangle points: Vec, }, } @@ -203,8 +205,27 @@ impl Area { p.y >= top_left.1 }, - //TODO polygon hit_test - _ => false, + Area::Polygon { ref points } => { + // Ray-casting algorithm to determine if point is inside polygon + let mut inside = false; + + debug_assert!(points.len() % 2 == 0); + let vertices = points.len() / 2; + + for i in 0..vertices { + let next_i = if i + 1 == vertices { 0 } else { i + 1 }; + + let xi = points[2 * i]; + let yi = points[2 * i + 1]; + let xj = points[2 * next_i]; + let yj = points[2 * next_i + 1]; + + if (yi > p.y) != (yj > p.y) && p.x < (xj - xi) * (p.y - yi) / (yj - yi) + xi { + inside = !inside; + } + } + inside + }, } }