#![allow(clippy::cast_precision_loss)]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use crate::{CoreError, Rect};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct TileWindow {
pub col: u32,
pub row: u32,
pub x0: u32,
pub y0: u32,
pub width: u32,
pub height: u32,
}
pub fn generate_tiles(
frame_w: u32,
frame_h: u32,
tile: u32,
overlap: u32,
) -> Result<Vec<TileWindow>, CoreError> {
if frame_w == 0 || frame_h == 0 || tile == 0 || overlap >= tile {
return Err(CoreError::InvalidThreshold);
}
let stride = tile - overlap;
let mut out = Vec::new();
let mut row = 0_u32;
let mut y = 0_u32;
loop {
let y0 = y.min(frame_h.saturating_sub(tile));
let height = tile.min(frame_h.saturating_sub(y0));
let mut col = 0_u32;
let mut x = 0_u32;
loop {
let x0 = x.min(frame_w.saturating_sub(tile));
let width = tile.min(frame_w.saturating_sub(x0));
out.push(TileWindow {
col,
row,
x0,
y0,
width,
height,
});
if x0 + width >= frame_w {
break;
}
x = x.saturating_add(stride);
col = col.saturating_add(1);
}
if y0 + height >= frame_h {
break;
}
y = y.saturating_add(stride);
row = row.saturating_add(1);
}
Ok(out)
}
pub fn tile_to_global(tile: TileWindow, local: Rect) -> Result<Rect, CoreError> {
let dx = tile.x0 as f32;
let dy = tile.y0 as f32;
Rect::new(
local.left() + dx,
local.top() + dy,
local.right() + dx,
local.bottom() + dy,
)
.map_err(|_| CoreError::NonFinite)
}