2024-01-03 20:59:39 +00:00
|
|
|
use crate::{size, DevicePixels, Result, SharedString, Size};
|
2024-05-30 01:06:45 +00:00
|
|
|
|
2024-04-02 19:12:38 +00:00
|
|
|
use image::{Bgra, ImageBuffer};
|
2024-01-03 20:59:39 +00:00
|
|
|
use std::{
|
|
|
|
borrow::Cow,
|
|
|
|
fmt,
|
|
|
|
hash::Hash,
|
|
|
|
sync::atomic::{AtomicUsize, Ordering::SeqCst},
|
|
|
|
};
|
2021-03-18 19:13:31 +00:00
|
|
|
|
2024-01-21 02:31:31 +00:00
|
|
|
/// A source of assets for this app to use.
|
2021-08-02 21:55:27 +00:00
|
|
|
pub trait AssetSource: 'static + Send + Sync {
|
2024-01-21 02:31:31 +00:00
|
|
|
/// Load the given asset from the source path.
|
2024-05-30 01:06:45 +00:00
|
|
|
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>>;
|
2024-01-21 02:31:31 +00:00
|
|
|
|
|
|
|
/// List the assets at the given path.
|
2024-01-03 20:59:39 +00:00
|
|
|
fn list(&self, path: &str) -> Result<Vec<SharedString>>;
|
2021-03-18 19:13:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AssetSource for () {
|
2024-05-30 01:06:45 +00:00
|
|
|
fn load(&self, _path: &str) -> Result<Option<Cow<'static, [u8]>>> {
|
|
|
|
Ok(None)
|
2021-03-18 19:13:31 +00:00
|
|
|
}
|
2021-08-02 21:55:27 +00:00
|
|
|
|
2024-01-03 20:59:39 +00:00
|
|
|
fn list(&self, _path: &str) -> Result<Vec<SharedString>> {
|
|
|
|
Ok(vec![])
|
2021-08-02 21:55:27 +00:00
|
|
|
}
|
2021-03-18 19:13:31 +00:00
|
|
|
}
|
|
|
|
|
2024-01-21 02:31:31 +00:00
|
|
|
/// A unique identifier for the image cache
|
2024-01-03 20:59:39 +00:00
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
|
|
pub struct ImageId(usize);
|
|
|
|
|
2024-03-30 00:09:49 +00:00
|
|
|
#[derive(PartialEq, Eq, Hash, Clone)]
|
|
|
|
pub(crate) struct RenderImageParams {
|
|
|
|
pub(crate) image_id: ImageId,
|
|
|
|
}
|
|
|
|
|
2024-01-21 02:31:31 +00:00
|
|
|
/// A cached and processed image.
|
2024-01-03 20:59:39 +00:00
|
|
|
pub struct ImageData {
|
2024-01-21 02:31:31 +00:00
|
|
|
/// The ID associated with this image
|
2024-01-03 20:59:39 +00:00
|
|
|
pub id: ImageId,
|
2024-04-02 19:12:38 +00:00
|
|
|
data: ImageBuffer<Bgra<u8>, Vec<u8>>,
|
2021-03-18 19:13:31 +00:00
|
|
|
}
|
|
|
|
|
2024-01-03 20:59:39 +00:00
|
|
|
impl ImageData {
|
2024-01-21 02:31:31 +00:00
|
|
|
/// Create a new image from the given data.
|
2024-04-02 19:12:38 +00:00
|
|
|
pub fn new(data: ImageBuffer<Bgra<u8>, Vec<u8>>) -> Self {
|
2024-01-03 20:59:39 +00:00
|
|
|
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
|
2021-03-18 19:13:31 +00:00
|
|
|
Self {
|
2024-01-03 20:59:39 +00:00
|
|
|
id: ImageId(NEXT_ID.fetch_add(1, SeqCst)),
|
|
|
|
data,
|
2021-04-06 11:44:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-21 02:31:31 +00:00
|
|
|
/// Convert this image into a byte slice.
|
2024-01-03 20:59:39 +00:00
|
|
|
pub fn as_bytes(&self) -> &[u8] {
|
|
|
|
&self.data
|
2021-03-18 19:13:31 +00:00
|
|
|
}
|
2023-03-06 18:39:35 +00:00
|
|
|
|
2024-01-21 02:31:31 +00:00
|
|
|
/// Get the size of this image, in pixels
|
2024-01-03 20:59:39 +00:00
|
|
|
pub fn size(&self) -> Size<DevicePixels> {
|
|
|
|
let (width, height) = self.data.dimensions();
|
|
|
|
size(width.into(), height.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for ImageData {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
f.debug_struct("ImageData")
|
|
|
|
.field("id", &self.id)
|
|
|
|
.field("size", &self.data.dimensions())
|
|
|
|
.finish()
|
2023-03-06 18:39:35 +00:00
|
|
|
}
|
2021-03-18 19:13:31 +00:00
|
|
|
}
|