use tiny_skia::{ Paint, PathBuilder, Stroke, Transform };
use crate::types::{ Color, Corners, Rect };
use super::helpers::build_rounded_rect;
use super::SoftwareCanvas;
impl SoftwareCanvas
{
pub fn clear( &mut self )
{
self.pixmap.fill( tiny_skia::Color::TRANSPARENT );
}
pub fn fill( &mut self, color: Color )
{
if self.clip_mask.is_none()
{
self.pixmap.fill( color.to_tiny_skia() );
return;
}
let w = self.pixmap.width() as f32;
let h = self.pixmap.height() as f32;
let Some( ts_rect ) = tiny_skia::Rect::from_ltrb( 0.0, 0.0, w, h ) else { return };
let mut paint = Paint::default();
paint.set_color( color.to_tiny_skia() );
self.pixmap.fill_rect( ts_rect, &paint, Transform::identity(), self.clip_mask.as_ref() );
}
pub fn fill_rect( &mut self, rect: Rect, color: Color, corners: Corners )
{
let pw = self.pixmap.width() as f32;
let ph = self.pixmap.height() as f32;
if rect.x + rect.width < 0.0 || rect.x > pw
|| rect.y + rect.height < 0.0 || rect.y > ph { return; }
let Some( ts_rect ) = rect.to_tiny_skia() else { return };
let mut paint = Paint::default();
let adjusted_color = Color::rgba( color.r, color.g, color.b, color.a * self.global_alpha );
paint.set_color( adjusted_color.to_tiny_skia() );
paint.anti_alias = true;
if !corners.is_zero()
{
if let Some( path ) = build_rounded_rect( ts_rect, corners )
{
self.pixmap.fill_path(
&path,
&paint,
tiny_skia::FillRule::Winding,
Transform::identity(),
self.clip_mask.as_ref(),
);
}
} else {
self.pixmap.fill_rect( ts_rect, &paint, Transform::identity(), self.clip_mask.as_ref() );
}
}
pub fn stroke_rect( &mut self, rect: Rect, color: Color, width: f32, corners: Corners )
{
let Some( ts_rect ) = rect.to_tiny_skia() else { return };
let mut paint = Paint::default();
let adjusted_color = Color::rgba( color.r, color.g, color.b, color.a * self.global_alpha );
paint.set_color( adjusted_color.to_tiny_skia() );
paint.anti_alias = true;
let mut stroke = Stroke::default();
stroke.width = width;
if !corners.is_zero()
{
if let Some( path ) = build_rounded_rect( ts_rect, corners )
{
self.pixmap.stroke_path( &path, &paint, &stroke, Transform::identity(), self.clip_mask.as_ref() );
}
} else {
let path = PathBuilder::from_rect( ts_rect );
self.pixmap.stroke_path( &path, &paint, &stroke, Transform::identity(), self.clip_mask.as_ref() );
}
}
pub fn draw_line( &mut self, x0: f32, y0: f32, x1: f32, y1: f32, color: Color, width: f32 )
{
let mut pb = PathBuilder::new();
pb.move_to( x0, y0 );
pb.line_to( x1, y1 );
let Some( path ) = pb.finish() else { return };
let mut paint = Paint::default();
let adjusted_color = Color::rgba( color.r, color.g, color.b, color.a * self.global_alpha );
paint.set_color( adjusted_color.to_tiny_skia() );
paint.anti_alias = true;
let mut stroke = Stroke::default();
stroke.width = width;
self.pixmap.stroke_path( &path, &paint, &stroke, Transform::identity(), self.clip_mask.as_ref() );
}
}