diff options
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/Cargo.toml | 4 | ||||
-rw-r--r-- | graphics/src/image/storage.rs | 2 | ||||
-rw-r--r-- | graphics/src/image/vector.rs | 38 | ||||
-rw-r--r-- | graphics/src/layer.rs | 7 | ||||
-rw-r--r-- | graphics/src/layer/image.rs | 6 | ||||
-rw-r--r-- | graphics/src/layer/quad.rs | 2 | ||||
-rw-r--r-- | graphics/src/primitive.rs | 5 | ||||
-rw-r--r-- | graphics/src/renderer.rs | 17 |
8 files changed, 60 insertions, 21 deletions
diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index b601f37c..823a05f4 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_graphics" -version = "0.4.0" +version = "0.5.0" authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"] edition = "2021" description = "A bunch of backend-agnostic types that can be leveraged to build a renderer for Iced" @@ -44,7 +44,7 @@ version = "1.4" features = ["derive"] [dependencies.iced_native] -version = "0.6" +version = "0.7" path = "../native" [dependencies.iced_style] diff --git a/graphics/src/image/storage.rs b/graphics/src/image/storage.rs index 2098c7b2..1b5b5c35 100644 --- a/graphics/src/image/storage.rs +++ b/graphics/src/image/storage.rs @@ -20,7 +20,7 @@ pub trait Storage { state: &mut Self::State<'_>, ) -> Option<Self::Entry>; - /// Romve a [`Self::Entry`] from the [`Storage`]. + /// Remove a [`Self::Entry`] from the [`Storage`]. fn remove(&mut self, entry: &Self::Entry, state: &mut Self::State<'_>); } diff --git a/graphics/src/image/vector.rs b/graphics/src/image/vector.rs index 42f4b500..82d77aff 100644 --- a/graphics/src/image/vector.rs +++ b/graphics/src/image/vector.rs @@ -1,5 +1,6 @@ //! Vector image loading and caching use crate::image::Storage; +use crate::Color; use iced_native::svg; use iced_native::Size; @@ -33,11 +34,13 @@ impl Svg { #[derive(Debug)] pub struct Cache<T: Storage> { svgs: HashMap<u64, Svg>, - rasterized: HashMap<(u64, u32, u32), T::Entry>, + rasterized: HashMap<(u64, u32, u32, ColorFilter), T::Entry>, svg_hits: HashSet<u64>, - rasterized_hits: HashSet<(u64, u32, u32)>, + rasterized_hits: HashSet<(u64, u32, u32, ColorFilter)>, } +type ColorFilter = Option<[u8; 4]>; + impl<T: Storage> Cache<T> { /// Load svg pub fn load(&mut self, handle: &svg::Handle) -> &Svg { @@ -76,6 +79,7 @@ impl<T: Storage> Cache<T> { pub fn upload( &mut self, handle: &svg::Handle, + color: Option<Color>, [width, height]: [f32; 2], scale: f32, state: &mut T::State<'_>, @@ -88,15 +92,18 @@ impl<T: Storage> Cache<T> { (scale * height).ceil() as u32, ); + let color = color.map(Color::into_rgba8); + let key = (id, width, height, color); + // TODO: Optimize! // We currently rerasterize the SVG when its size changes. This is slow // as heck. A GPU rasterizer like `pathfinder` may perform better. // It would be cool to be able to smooth resize the `svg` example. - if self.rasterized.contains_key(&(id, width, height)) { + if self.rasterized.contains_key(&key) { let _ = self.svg_hits.insert(id); - let _ = self.rasterized_hits.insert((id, width, height)); + let _ = self.rasterized_hits.insert(key); - return self.rasterized.get(&(id, width, height)); + return self.rasterized.get(&key); } match self.load(handle) { @@ -121,15 +128,26 @@ impl<T: Storage> Cache<T> { img.as_mut(), )?; - let allocation = - storage.upload(width, height, img.data(), state)?; + let mut rgba = img.take(); + + if let Some(color) = color { + rgba.chunks_exact_mut(4).for_each(|rgba| { + if rgba[3] > 0 { + rgba[0] = color[0]; + rgba[1] = color[1]; + rgba[2] = color[2]; + } + }); + } + + let allocation = storage.upload(width, height, &rgba, state)?; log::debug!("allocating {} {}x{}", id, width, height); let _ = self.svg_hits.insert(id); - let _ = self.rasterized_hits.insert((id, width, height)); - let _ = self.rasterized.insert((id, width, height), allocation); + let _ = self.rasterized_hits.insert(key); + let _ = self.rasterized.insert(key, allocation); - self.rasterized.get(&(id, width, height)) + self.rasterized.get(&key) } Svg::NotFound => None, } diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs index fd670f48..1d453caa 100644 --- a/graphics/src/layer.rs +++ b/graphics/src/layer.rs @@ -251,11 +251,16 @@ impl<'a> Layer<'a> { bounds: *bounds + translation, }); } - Primitive::Svg { handle, bounds } => { + Primitive::Svg { + handle, + color, + bounds, + } => { let layer = &mut layers[current_layer]; layer.images.push(Image::Vector { handle: handle.clone(), + color: *color, bounds: *bounds + translation, }); } diff --git a/graphics/src/layer/image.rs b/graphics/src/layer/image.rs index 045ec665..3eff2397 100644 --- a/graphics/src/layer/image.rs +++ b/graphics/src/layer/image.rs @@ -1,4 +1,5 @@ -use crate::Rectangle; +use crate::{Color, Rectangle}; + use iced_native::{image, svg}; /// A raster or vector image. @@ -17,6 +18,9 @@ pub enum Image { /// The handle of a vector image. handle: svg::Handle, + /// The [`Color`] filter + color: Option<Color>, + /// The bounds of the image. bounds: Rectangle, }, diff --git a/graphics/src/layer/quad.rs b/graphics/src/layer/quad.rs index 4def8427..0d8bde9d 100644 --- a/graphics/src/layer/quad.rs +++ b/graphics/src/layer/quad.rs @@ -17,7 +17,7 @@ pub struct Quad { pub border_color: [f32; 4], /// The border radius of the [`Quad`]. - pub border_radius: f32, + pub border_radius: [f32; 4], /// The border width of the [`Quad`]. pub border_width: f32, diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs index 9759d97a..5a163a2f 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -42,7 +42,7 @@ pub enum Primitive { /// The background of the quad background: Background, /// The border radius of the quad - border_radius: f32, + border_radius: [f32; 4], /// The border width of the quad border_width: f32, /// The border color of the quad @@ -60,6 +60,9 @@ pub enum Primitive { /// The path of the SVG file handle: svg::Handle, + /// The [`Color`] filter + color: Option<Color>, + /// The bounds of the viewport bounds: Rectangle, }, diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 036b398c..aabdf7fc 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -6,7 +6,7 @@ use iced_native::layout; use iced_native::renderer; use iced_native::svg; use iced_native::text::{self, Text}; -use iced_native::{Background, Element, Font, Point, Rectangle, Size}; +use iced_native::{Background, Color, Element, Font, Point, Rectangle, Size}; pub use iced_native::renderer::Style; @@ -109,7 +109,7 @@ where self.primitives.push(Primitive::Quad { bounds: quad.bounds, background: background.into(), - border_radius: quad.border_radius, + border_radius: quad.border_radius.into(), border_width: quad.border_width, border_color: quad.border_color, }); @@ -200,7 +200,16 @@ where self.backend().viewport_dimensions(handle) } - fn draw(&mut self, handle: svg::Handle, bounds: Rectangle) { - self.draw_primitive(Primitive::Svg { handle, bounds }) + fn draw( + &mut self, + handle: svg::Handle, + color: Option<Color>, + bounds: Rectangle, + ) { + self.draw_primitive(Primitive::Svg { + handle, + color, + bounds, + }) } } |