Skip to main content

ferroui_base/rendering/composition/hit_testing/
geometry_composition_hit_tester.rs

1use super::{is_hit, ICompositionHitTester};
2use crate::media::{Geometry, IntersectionResult, MatrixTransform};
3use crate::platform::{IGeometryImpl, LtrbRect};
4use crate::rendering::composition::CompositionVisual;
5use crate::{Matrix, Rect, Ref, Size};
6
7/// Hit testing with a geometry.
8pub struct GeometryCompositionHitTester;
9
10impl ICompositionHitTester for GeometryCompositionHitTester {
11    type Input = Ref<Geometry>;
12
13    fn transform(input: &Ref<Geometry>, matrix: Matrix) -> Ref<Geometry> {
14        let result = input.clone_geometry();
15        let current = input.transform().map_or(Matrix::IDENTITY, |transform| transform.value());
16        result.set_transform(MatrixTransform::with_matrix(current * matrix));
17        result
18    }
19
20    fn hit_test(visual: &CompositionVisual, input: &Ref<Geometry>) -> IntersectionResult {
21        visual.hit_test_geometry(input)
22    }
23
24    fn transformed_sub_tree_bounds_match(bounds: LtrbRect, input: &Ref<Geometry>) -> bool {
25        let geometry_render_bounds = input.bounds();
26        bounds.intersects(LtrbRect::from_rect(geometry_render_bounds))
27    }
28
29    fn clipped_bounds_match(visual: &CompositionVisual, input: &Ref<Geometry>) -> bool {
30        let bounds = input.bounds();
31        let size = visual.size();
32        bounds.width > 0.0 && bounds.height > 0.0 && bounds.intersects(Rect::from_size(Size::new(size.x, size.y)))
33    }
34
35    fn clip_matches(clip: &dyn IGeometryImpl, input: &Ref<Geometry>) -> bool {
36        input.platform_impl().is_some_and(|geometry_impl| is_hit(clip.get_fill_intersection_result(&*geometry_impl)))
37    }
38}