use tiny_skia::{ Path, PathBuilder };
use crate::types::{ Corners, PathCmd };
const KAPPA: f32 = 0.5523_f32;
pub ( crate ) fn build_ts_path( cmds: &[ PathCmd ] ) -> Option<Path>
{
let mut pb = PathBuilder::new();
for cmd in cmds
{
match *cmd
{
PathCmd::MoveTo( x, y ) => pb.move_to( x, y ),
PathCmd::LineTo( x, y ) => pb.line_to( x, y ),
PathCmd::QuadTo( x1, y1, x, y ) => pb.quad_to( x1, y1, x, y ),
PathCmd::CubicTo( x1, y1, x2, y2, x, y ) => pb.cubic_to( x1, y1, x2, y2, x, y ),
PathCmd::Close => pb.close(),
}
}
pb.finish()
}
pub ( crate ) fn validate_rgba_dims( backend: &str, data: &[u8], img_w: u32, img_h: u32 ) -> bool
{
let expected = ( img_w as usize ).saturating_mul( img_h as usize ).saturating_mul( 4 );
if img_w == 0 || img_h == 0 || data.len() != expected
{
eprintln!(
"[ltk] {}::draw_image_data: refusing draw — {}×{} declared, {} bytes provided, expected {}",
backend, img_w, img_h, data.len(), expected,
);
return false;
}
true
}
pub ( super ) fn build_rounded_rect( rect: tiny_skia::Rect, corners: Corners ) -> Option<Path>
{
let c = corners.clamp_to_size( rect.width(), rect.height() );
let tl = c.tl;
let tr = c.tr;
let br = c.br;
let bl = c.bl;
let x0 = rect.left();
let y0 = rect.top();
let x1 = rect.right();
let y1 = rect.bottom();
let mut pb = PathBuilder::new();
pb.move_to( x0 + tl, y0 );
pb.line_to( x1 - tr, y0 );
if tr > 0.0
{
let kk = tr * KAPPA;
pb.cubic_to( x1 - tr + kk, y0, x1, y0 + tr - kk, x1, y0 + tr );
}
pb.line_to( x1, y1 - br );
if br > 0.0
{
let kk = br * KAPPA;
pb.cubic_to( x1, y1 - br + kk, x1 - br + kk, y1, x1 - br, y1 );
}
pb.line_to( x0 + bl, y1 );
if bl > 0.0
{
let kk = bl * KAPPA;
pb.cubic_to( x0 + bl - kk, y1, x0, y1 - bl + kk, x0, y1 - bl );
}
pb.line_to( x0, y0 + tl );
if tl > 0.0
{
let kk = tl * KAPPA;
pb.cubic_to( x0, y0 + tl - kk, x0 + tl - kk, y0, x0 + tl, y0 );
}
pb.close();
pb.finish()
}