diff options
Diffstat (limited to 'components/script/dom/htmlareaelement.rs')
-rw-r--r-- | components/script/dom/htmlareaelement.rs | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/components/script/dom/htmlareaelement.rs b/components/script/dom/htmlareaelement.rs index a9d94cbd7b2..535d296a29f 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<f32>, }, } @@ -203,8 +205,28 @@ 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 + // https://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm + 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 + }, } } |