11use crate :: core:: svg:: { Data , Handle } ;
2- use crate :: core:: { Rectangle , Size } ;
2+ use crate :: core:: { Color , Rectangle , Size } ;
33
44use resvg:: usvg;
55use rustc_hash:: { FxHashMap , FxHashSet } ;
@@ -29,15 +29,16 @@ impl Pipeline {
2929 pub fn draw (
3030 & mut self ,
3131 handle : & Handle ,
32+ color : Option < Color > ,
3233 bounds : Rectangle ,
3334 pixels : & mut tiny_skia:: PixmapMut < ' _ > ,
3435 clip_mask : Option < & tiny_skia:: ClipMask > ,
3536 ) {
36- if let Some ( image) = self
37- . cache
38- . borrow_mut ( )
39- . draw ( handle , Size :: new ( bounds. width as u32 , bounds. height as u32 ) )
40- {
37+ if let Some ( image) = self . cache . borrow_mut ( ) . draw (
38+ handle ,
39+ color ,
40+ Size :: new ( bounds. width as u32 , bounds. height as u32 ) ,
41+ ) {
4142 pixels. draw_pixmap (
4243 bounds. x as i32 ,
4344 bounds. y as i32 ,
@@ -58,8 +59,15 @@ impl Pipeline {
5859struct Cache {
5960 trees : FxHashMap < u64 , Option < resvg:: usvg:: Tree > > ,
6061 tree_hits : FxHashSet < u64 > ,
61- rasters : FxHashMap < ( u64 , Size < u32 > ) , tiny_skia:: Pixmap > ,
62- raster_hits : FxHashSet < ( u64 , Size < u32 > ) > ,
62+ rasters : FxHashMap < RasterKey , tiny_skia:: Pixmap > ,
63+ raster_hits : FxHashSet < RasterKey > ,
64+ }
65+
66+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
67+ struct RasterKey {
68+ id : u64 ,
69+ color : Option < [ u8 ; 4 ] > ,
70+ size : Size < u32 > ,
6371}
6472
6573impl Cache {
@@ -101,16 +109,21 @@ impl Cache {
101109 fn draw (
102110 & mut self ,
103111 handle : & Handle ,
112+ color : Option < Color > ,
104113 size : Size < u32 > ,
105114 ) -> Option < tiny_skia:: PixmapRef < ' _ > > {
106115 if size. width == 0 || size. height == 0 {
107116 return None ;
108117 }
109118
110- let id = handle. id ( ) ;
119+ let key = RasterKey {
120+ id : handle. id ( ) ,
121+ color : color. map ( Color :: into_rgba8) ,
122+ size,
123+ } ;
111124
112125 #[ allow( clippy:: map_entry) ]
113- if !self . rasters . contains_key ( & ( id , size ) ) {
126+ if !self . rasters . contains_key ( & key ) {
114127 let tree = self . load ( handle) ?;
115128
116129 let mut image = tiny_skia:: Pixmap :: new ( size. width , size. height ) ?;
@@ -126,18 +139,35 @@ impl Cache {
126139 image. as_mut ( ) ,
127140 ) ?;
128141
129- // Swap R and B channels for `softbuffer` presentation
130- for pixel in bytemuck:: cast_slice_mut :: < u8 , u32 > ( image. data_mut ( ) ) {
131- * pixel = * pixel & 0xFF00FF00
132- | ( ( 0x000000FF & * pixel) << 16 )
133- | ( ( 0x00FF0000 & * pixel) >> 16 ) ;
142+ if let Some ( [ r, g, b, a] ) = key. color {
143+ // TODO: Blend alpha
144+ let color = tiny_skia:: ColorU8 :: from_rgba ( b, g, r, a)
145+ . premultiply ( )
146+ . get ( )
147+ & 0x00FFFFFF ;
148+
149+ // Apply color filter
150+ for pixel in
151+ bytemuck:: cast_slice_mut :: < u8 , u32 > ( image. data_mut ( ) )
152+ {
153+ * pixel = * pixel & 0xFF000000 | color;
154+ }
155+ } else {
156+ // Swap R and B channels for `softbuffer` presentation
157+ for pixel in
158+ bytemuck:: cast_slice_mut :: < u8 , u32 > ( image. data_mut ( ) )
159+ {
160+ * pixel = * pixel & 0xFF00FF00
161+ | ( ( 0x000000FF & * pixel) << 16 )
162+ | ( ( 0x00FF0000 & * pixel) >> 16 ) ;
163+ }
134164 }
135165
136- self . rasters . insert ( ( id , size ) , image) ;
166+ self . rasters . insert ( key , image) ;
137167 }
138168
139- self . raster_hits . insert ( ( id , size ) ) ;
140- self . rasters . get ( & ( id , size ) ) . map ( tiny_skia:: Pixmap :: as_ref)
169+ self . raster_hits . insert ( key ) ;
170+ self . rasters . get ( & key ) . map ( tiny_skia:: Pixmap :: as_ref)
141171 }
142172
143173 fn trim ( & mut self ) {
0 commit comments