cbf-compositor 0.1.0-alpha.9

Scene-based browser surface compositor for CBF applications.
Documentation
use crate::model::{HitTestCoordinateSpace, HitTestRegionMode, HitTestRegionSnapshot};

#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) struct ItemLocalCssPoint {
    pub(crate) x: f64,
    pub(crate) y: f64,
}

impl ItemLocalCssPoint {
    pub(crate) const fn new(x: f64, y: f64) -> Self {
        Self { x, y }
    }
}

pub(crate) fn snapshot_contains_point(
    snapshot: &HitTestRegionSnapshot,
    point: ItemLocalCssPoint,
) -> bool {
    let matched = match snapshot.coordinate_space {
        HitTestCoordinateSpace::ItemLocalCssPx => snapshot.regions.iter().any(|region| {
            point.x >= f64::from(region.x)
                && point.y >= f64::from(region.y)
                && point.x <= f64::from(region.x + region.width)
                && point.y <= f64::from(region.y + region.height)
        }),
    };

    match snapshot.mode {
        HitTestRegionMode::ConsumeListedRegions => matched,
        HitTestRegionMode::PassthroughListedRegions => !matched,
    }
}

#[cfg(test)]
mod tests {
    use crate::model::{
        HitTestCoordinateSpace, HitTestRegion, HitTestRegionMode, HitTestRegionSnapshot,
    };

    use super::{ItemLocalCssPoint, snapshot_contains_point};

    fn snapshot(mode: HitTestRegionMode) -> HitTestRegionSnapshot {
        HitTestRegionSnapshot {
            snapshot_id: 1,
            coordinate_space: HitTestCoordinateSpace::ItemLocalCssPx,
            mode,
            regions: vec![HitTestRegion::new(10.0, 15.0, 20.0, 25.0)],
        }
    }

    #[test]
    fn snapshot_contains_point_uses_top_left_item_local_coordinates() {
        let snapshot = snapshot(HitTestRegionMode::ConsumeListedRegions);

        assert!(snapshot_contains_point(
            &snapshot,
            ItemLocalCssPoint::new(15.0, 20.0)
        ));
        assert!(!snapshot_contains_point(
            &snapshot,
            ItemLocalCssPoint::new(15.0, 90.0)
        ));
    }

    #[test]
    fn snapshot_contains_point_supports_passthrough_listed_regions() {
        let snapshot = snapshot(HitTestRegionMode::PassthroughListedRegions);

        assert!(!snapshot_contains_point(
            &snapshot,
            ItemLocalCssPoint::new(15.0, 20.0)
        ));
        assert!(snapshot_contains_point(
            &snapshot,
            ItemLocalCssPoint::new(15.0, 90.0)
        ));
    }
}