diff options
| author | 2022-12-06 05:15:16 +0100 | |
|---|---|---|
| committer | 2022-12-06 05:15:16 +0100 | |
| commit | f38e7fcac2e3505d11577ade1757a77ca2a544ea (patch) | |
| tree | 84b3dc6c88aa555cf931482adcf4e7be35614b72 /graphics/src | |
| parent | 28f0beee52f258af6bbaf8a0d9867863d7513c9b (diff) | |
| parent | f99d24e0850b63194b7976ec66d547ea2ff6bfc8 (diff) | |
| download | iced-f38e7fcac2e3505d11577ade1757a77ca2a544ea.tar.gz iced-f38e7fcac2e3505d11577ade1757a77ca2a544ea.tar.bz2 iced-f38e7fcac2e3505d11577ade1757a77ca2a544ea.zip | |
Merge pull request #1578 from iced-rs/svg-styling
Svg styling
Diffstat (limited to '')
| -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/primitive.rs | 3 | ||||
| -rw-r--r-- | graphics/src/renderer.rs | 15 | 
5 files changed, 54 insertions, 15 deletions
| 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/primitive.rs b/graphics/src/primitive.rs index 6f1b6f26..5a163a2f 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -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 65350037..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; @@ -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, +        })      }  } | 
