Skip to main content

rosace_render/
image.rs

1/// Image cache policy controlling when the local cache is consulted.
2#[derive(Debug, Clone, Copy)]
3pub enum CachePolicy {
4    /// Fetch from the network; fall back to cache on failure.
5    NetworkFirst,
6    /// Use the cache if available; fetch from network otherwise.
7    CacheFirst,
8    /// Never use the cache; always fetch from the network.
9    NoCache,
10}
11
12/// Controls how an image fills its layout bounds.
13#[derive(Debug, Clone, Copy)]
14pub enum ImageFit {
15    /// Stretch to fill the bounds, ignoring aspect ratio.
16    Fill,
17    /// Scale uniformly to fit within the bounds, preserving aspect ratio.
18    Contain,
19    /// Scale uniformly to cover the bounds, clipping if necessary.
20    Cover,
21    /// Like [`Contain`], but never upscales below natural size.
22    ///
23    /// [`Contain`]: ImageFit::Contain
24    ScaleDown,
25    /// Render at the image's natural pixel size; no scaling.
26    None,
27}
28
29/// A decoded image ready for rendering.
30///
31/// Full decode and cache support will be implemented in Phase 2.  Phase 1
32/// supports PNG decoding via `tiny-skia`.
33#[derive(Debug, Clone)]
34pub struct ImageHandle {
35    /// Image width in pixels.
36    pub width: u32,
37    /// Image height in pixels.
38    pub height: u32,
39    /// Raw RGBA pixel data, row-major, 4 bytes per pixel.
40    pub pixels: Vec<u8>,
41}
42
43impl ImageHandle {
44    /// Decode a PNG image from raw bytes.
45    ///
46    /// Returns `None` if the bytes are not valid PNG data.
47    pub fn from_png_bytes(bytes: &[u8]) -> Option<Self> {
48        let pixmap = tiny_skia::Pixmap::decode_png(bytes).ok()?;
49        Some(Self {
50            width: pixmap.width(),
51            height: pixmap.height(),
52            pixels: pixmap.data().to_vec(),
53        })
54    }
55}