use crate::uuid::Uuid; use crate::view::Viewbox; use indexmap::IndexSet; use skia_safe as skia; use std::collections::{HashMap, HashSet}; pub type Tile = (i32, i32); pub const TILE_SIZE: f32 = 512.; pub fn get_tile_dimensions() -> skia::ISize { (TILE_SIZE as i32, TILE_SIZE as i32).into() } pub fn get_tiles_for_rect(rect: skia::Rect, tile_size: f32) -> (i32, i32, i32, i32) { // start let sx = (rect.left / tile_size).floor() as i32; let sy = (rect.top / tile_size).floor() as i32; // end let ex = (rect.right / tile_size).floor() as i32; let ey = (rect.bottom / tile_size).floor() as i32; (sx, sy, ex, ey) } pub fn get_tiles_for_viewbox(viewbox: Viewbox) -> (i32, i32, i32, i32) { let tile_size = get_tile_size(viewbox); get_tiles_for_rect(viewbox.area, tile_size) } pub fn get_tile_pos(viewbox: Viewbox, (x, y): Tile) -> (f32, f32) { ( x as f32 * get_tile_size(viewbox), y as f32 * get_tile_size(viewbox), ) } pub fn get_tile_size(viewbox: Viewbox) -> f32 { // TODO: * self.options.dpr() too? 1. / viewbox.zoom * TILE_SIZE } pub fn get_tile_rect(viewbox: Viewbox, tile: Tile) -> skia::Rect { let (tx, ty) = get_tile_pos(viewbox, tile); let ts = get_tile_size(viewbox); skia::Rect::from_xywh(tx, ty, ts, ts) } // This structure is usseful to keep all the shape uuids by shape id. pub struct TileHashMap { grid: HashMap>, index: HashMap>, } impl TileHashMap { pub fn new() -> Self { TileHashMap { grid: HashMap::new(), index: HashMap::new(), } } pub fn get_shapes_at(&mut self, tile: Tile) -> Option<&IndexSet> { return self.grid.get(&tile); } pub fn remove_shape_at(&mut self, tile: Tile, id: Uuid) { if let Some(shapes) = self.grid.get_mut(&tile) { shapes.shift_remove(&id); } } pub fn get_tiles_of(&mut self, shape_id: Uuid) -> Option<&HashSet> { self.index.get(&shape_id) } pub fn add_shape_at(&mut self, tile: Tile, shape_id: Uuid) { if !self.grid.contains_key(&tile) { self.grid.insert(tile, IndexSet::new()); } if !self.index.contains_key(&shape_id) { self.index.insert(shape_id, HashSet::new()); } let tile_set = self.grid.get_mut(&tile).unwrap(); tile_set.insert(shape_id); let index_set = self.index.get_mut(&shape_id).unwrap(); index_set.insert(tile); } pub fn invalidate(&mut self) { self.grid.clear(); self.index.clear(); } }