#![cfg_attr(docsrs, feature(doc_cfg))]
pub extern crate tiny_skia;
#[cfg(feature = "canvas")] mod canvas;
#[cfg(feature = "image")] mod image;
mod sprite;
#[cfg(feature = "svg")] mod svg;
#[cfg(feature = "canvas")]
pub use canvas::{Canvas, CanvasProgram};
#[cfg(feature = "image")] pub use image::Image;
pub use sprite::Sprite;
#[cfg(feature = "svg")] pub use svg::Svg;
use kas::cast::{Conv, ConvFloat};
use kas::geom::{Rect, Vec2};
use kas::impl_scope;
use kas::layout::{AlignPair, AxisInfo, LogicalSize, SizeRules, Stretch};
use kas::theme::{MarginStyle, SizeCx};
#[cfg(feature = "image")]
pub fn window_icon_from_path<P: AsRef<std::path::Path>>(
path: P,
) -> Result<kas::window::icon::Icon, Box<dyn std::error::Error>> {
let im = ::image::ImageReader::open(path)?
.with_guessed_format()?
.decode()?
.into_rgba8();
let (w, h) = im.dimensions();
let icon = kas::window::icon::RgbaIcon::new(im.into_vec(), w, h)?;
Ok(icon.into())
}
impl_scope! {
#[impl_default]
#[derive(Clone, Debug, PartialEq)]
struct Scaling {
pub size: LogicalSize,
pub margins: MarginStyle,
pub fix_aspect: bool = true,
pub stretch: Stretch,
}
}
impl Scaling {
pub fn size_rules(&mut self, cx: &mut SizeCx, axis: AxisInfo) -> SizeRules {
let scale_factor = cx.scale_factor();
let ideal = self.size.to_physical(scale_factor).extract(axis);
SizeRules::new(ideal, ideal, self.stretch)
.with_margins(cx.margins(self.margins).extract(axis))
}
pub fn align(&mut self, rect: Rect, align: AlignPair, scale_factor: f32) -> Rect {
let mut size = rect.size;
if self.stretch == Stretch::None {
let ideal = self.size.to_physical(scale_factor);
size = size.min(ideal);
}
if self.fix_aspect {
let logical_size = Vec2::from(self.size);
let Vec2(rw, rh) = Vec2::conv(size) / logical_size;
if rw < rh {
size.1 = i32::conv_nearest(rw * logical_size.1);
} else if rh < rw {
size.0 = i32::conv_nearest(rh * logical_size.0);
}
}
align.aligned_rect(size, rect)
}
}