1#![cfg_attr(docsrs, feature(doc_cfg))]
15
16pub extern crate tiny_skia;
17
18#[cfg(feature = "canvas")] mod canvas;
19#[cfg(feature = "image")] mod image;
20mod sprite;
21#[cfg(feature = "svg")] mod svg;
22
23#[cfg(feature = "canvas")]
24pub use canvas::{Canvas, CanvasProgram};
25#[cfg(feature = "image")] pub use image::Image;
26pub use sprite::Sprite;
27#[cfg(feature = "svg")] pub use svg::Svg;
28
29use kas::cast::{Conv, ConvFloat};
30use kas::geom::{Rect, Vec2};
31use kas::impl_scope;
32use kas::layout::{AlignPair, AxisInfo, LogicalSize, SizeRules, Stretch};
33use kas::theme::{MarginStyle, SizeCx};
34
35#[cfg(feature = "image")]
37pub fn window_icon_from_path<P: AsRef<std::path::Path>>(
38 path: P,
39) -> Result<kas::window::icon::Icon, Box<dyn std::error::Error>> {
40 let im = ::image::ImageReader::open(path)?
43 .with_guessed_format()?
44 .decode()?
45 .into_rgba8();
46 let (w, h) = im.dimensions();
47 let icon = kas::window::icon::RgbaIcon::new(im.into_vec(), w, h)?;
48 Ok(icon.into())
49}
50
51impl_scope! {
52 #[impl_default]
54 #[derive(Clone, Debug, PartialEq)]
55 struct Scaling {
56 pub size: LogicalSize,
60 pub margins: MarginStyle,
62 pub fix_aspect: bool = true,
66 pub stretch: Stretch,
72 }
73}
74
75impl Scaling {
76 pub fn size_rules(&mut self, cx: &mut SizeCx, axis: AxisInfo) -> SizeRules {
78 let scale_factor = cx.scale_factor();
79 let ideal = self.size.to_physical(scale_factor).extract(axis);
80 SizeRules::new(ideal, ideal, self.stretch)
81 .with_margins(cx.margins(self.margins).extract(axis))
82 }
83
84 pub fn align(&mut self, rect: Rect, align: AlignPair, scale_factor: f32) -> Rect {
89 let mut size = rect.size;
90
91 if self.stretch == Stretch::None {
92 let ideal = self.size.to_physical(scale_factor);
93 size = size.min(ideal);
94 }
95
96 if self.fix_aspect {
97 let logical_size = Vec2::from(self.size);
98 let Vec2(rw, rh) = Vec2::conv(size) / logical_size;
99
100 if rw < rh {
102 size.1 = i32::conv_nearest(rw * logical_size.1);
103 } else if rh < rw {
104 size.0 = i32::conv_nearest(rh * logical_size.0);
105 }
106 }
107
108 align.aligned_rect(size, rect)
109 }
110}