Refactor some image traits a bit

- Use `Size<u32>` were applicable.
- Rename `TextureStore` to `image::Storage`.
- Rename `TextureStoreEntry` to `image::storage::Entry`.
- Wire up `viewport_dimensions` to `iced_glow` for `Svg`.
This commit is contained in:
Héctor Ramón Jiménez 2022-11-05 03:13:04 +01:00
parent 5575e6ea08
commit 8ce8d374b1
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
20 changed files with 164 additions and 127 deletions

View file

@ -66,11 +66,11 @@ pub trait Text {
/// A graphics backend that supports image rendering.
pub trait Image {
/// Returns the dimensions of the provided image.
fn dimensions(&self, handle: &image::Handle) -> (u32, u32);
fn dimensions(&self, handle: &image::Handle) -> Size<u32>;
}
/// A graphics backend that supports SVG rendering.
pub trait Svg {
/// Returns the viewport dimensions of the provided SVG.
fn viewport_dimensions(&self, handle: &svg::Handle) -> (u32, u32);
fn viewport_dimensions(&self, handle: &svg::Handle) -> Size<u32>;
}

View file

@ -1,34 +1,10 @@
//! Image loading and caching
use std::fmt::Debug;
//! Render images.
#[cfg(feature = "image_rs")]
pub mod raster;
#[cfg(feature = "svg")]
pub mod vector;
/// Entry in the texture store
pub trait TextureStoreEntry: Debug {
/// Width and height of the entry
fn size(&self) -> (u32, u32);
}
pub mod storage;
/// Stores cached image data for use in rendering
pub trait TextureStore {
/// Entry in the texture store
type Entry: TextureStoreEntry;
/// State passed to upload/remove
type State<'a>;
/// Upload image data
fn upload(
&mut self,
width: u32,
height: u32,
data: &[u8],
state: &mut Self::State<'_>,
) -> Option<Self::Entry>;
/// Remome image from store
fn remove(&mut self, entry: &Self::Entry, state: &mut Self::State<'_>);
}
pub use storage::Storage;

View file

@ -1,15 +1,15 @@
//! Raster image loading and caching
//! Raster image loading and caching.
use crate::image::Storage;
use crate::Size;
use iced_native::image;
use std::collections::{HashMap, HashSet};
use bitflags::bitflags;
use super::{TextureStore, TextureStoreEntry};
use std::collections::{HashMap, HashSet};
/// Entry in cache corresponding to an image handle
#[derive(Debug)]
pub enum Memory<T: TextureStore> {
pub enum Memory<T: Storage> {
/// Image data on host
Host(::image_rs::ImageBuffer<::image_rs::Rgba<u8>, Vec<u8>>),
/// Texture store entry
@ -20,26 +20,32 @@ pub enum Memory<T: TextureStore> {
Invalid,
}
impl<T: TextureStore> Memory<T> {
impl<T: Storage> Memory<T> {
/// Width and height of image
pub fn dimensions(&self) -> (u32, u32) {
pub fn dimensions(&self) -> Size<u32> {
use crate::image::storage::Entry;
match self {
Memory::Host(image) => image.dimensions(),
Memory::Host(image) => {
let (width, height) = image.dimensions();
Size::new(width, height)
}
Memory::Device(entry) => entry.size(),
Memory::NotFound => (1, 1),
Memory::Invalid => (1, 1),
Memory::NotFound => Size::new(1, 1),
Memory::Invalid => Size::new(1, 1),
}
}
}
/// Caches image raster data
#[derive(Debug)]
pub struct Cache<T: TextureStore> {
pub struct Cache<T: Storage> {
map: HashMap<u64, Memory<T>>,
hits: HashSet<u64>,
}
impl<T: TextureStore> Cache<T> {
impl<T: Storage> Cache<T> {
/// Load image
pub fn load(&mut self, handle: &image::Handle) -> &mut Memory<T> {
if self.contains(handle) {
@ -153,7 +159,7 @@ impl<T: TextureStore> Cache<T> {
}
}
impl<T: TextureStore> Default for Cache<T> {
impl<T: Storage> Default for Cache<T> {
fn default() -> Self {
Self {
map: HashMap::new(),

View file

@ -0,0 +1,31 @@
//! Store images.
use crate::Size;
use std::fmt::Debug;
/// Stores cached image data for use in rendering
pub trait Storage {
/// The type of an [`Entry`] in the [`Storage`].
type Entry: Entry;
/// State provided to upload or remove a [`Self::Entry`].
type State<'a>;
/// Upload the image data of a [`Self::Entry`].
fn upload(
&mut self,
width: u32,
height: u32,
data: &[u8],
state: &mut Self::State<'_>,
) -> Option<Self::Entry>;
/// Romve a [`Self::Entry`] from the [`Storage`].
fn remove(&mut self, entry: &Self::Entry, state: &mut Self::State<'_>);
}
/// An entry in some [`Storage`],
pub trait Entry: Debug {
/// The [`Size`] of the [`Entry`].
fn size(&self) -> Size<u32>;
}

View file

@ -1,12 +1,12 @@
//! Vector image loading and caching
use crate::image::Storage;
use iced_native::svg;
use iced_native::Size;
use std::collections::{HashMap, HashSet};
use std::fs;
use super::TextureStore;
/// Entry in cache corresponding to an svg handle
pub enum Svg {
/// Parsed svg
@ -17,28 +17,28 @@ pub enum Svg {
impl Svg {
/// Viewport width and height
pub fn viewport_dimensions(&self) -> (u32, u32) {
pub fn viewport_dimensions(&self) -> Size<u32> {
match self {
Svg::Loaded(tree) => {
let size = tree.svg_node().size;
(size.width() as u32, size.height() as u32)
Size::new(size.width() as u32, size.height() as u32)
}
Svg::NotFound => (1, 1),
Svg::NotFound => Size::new(1, 1),
}
}
}
/// Caches svg vector and raster data
#[derive(Debug)]
pub struct Cache<T: TextureStore> {
pub struct Cache<T: Storage> {
svgs: HashMap<u64, Svg>,
rasterized: HashMap<(u64, u32, u32), T::Entry>,
svg_hits: HashSet<u64>,
rasterized_hits: HashSet<(u64, u32, u32)>,
}
impl<T: TextureStore> Cache<T> {
impl<T: Storage> Cache<T> {
/// Load svg
pub fn load(&mut self, handle: &svg::Handle) -> &Svg {
if self.svgs.contains_key(&handle.id()) {
@ -162,7 +162,7 @@ impl<T: TextureStore> Cache<T> {
}
}
impl<T: TextureStore> Default for Cache<T> {
impl<T: Storage> Default for Cache<T> {
fn default() -> Self {
Self {
svgs: HashMap::new(),

View file

@ -183,7 +183,7 @@ where
{
type Handle = image::Handle;
fn dimensions(&self, handle: &image::Handle) -> (u32, u32) {
fn dimensions(&self, handle: &image::Handle) -> Size<u32> {
self.backend().dimensions(handle)
}
@ -196,7 +196,7 @@ impl<B, T> svg::Renderer for Renderer<B, T>
where
B: Backend + backend::Svg,
{
fn dimensions(&self, handle: &svg::Handle) -> (u32, u32) {
fn dimensions(&self, handle: &svg::Handle) -> Size<u32> {
self.backend().viewport_dimensions(handle)
}