♻️ Refactor image fills

This commit is contained in:
Belén Albeza 2024-12-03 14:34:07 +01:00
parent 7105e49ac2
commit 58c4e53ee4
4 changed files with 44 additions and 28 deletions

View file

@ -9,7 +9,6 @@ mod view;
use skia_safe as skia; use skia_safe as skia;
use crate::shapes::Image;
use crate::state::State; use crate::state::State;
use crate::utils::uuid_from_u32_quartet; use crate::utils::uuid_from_u32_quartet;
@ -201,18 +200,15 @@ pub extern "C" fn store_image(a: u32, b: u32, c: u32, d: u32, ptr: *mut u8, size
panic!("Invalid data, null pointer or zero size"); panic!("Invalid data, null pointer or zero size");
} }
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
let render_state = state.render_state();
let id = uuid_from_u32_quartet(a, b, c, d); let id = uuid_from_u32_quartet(a, b, c, d);
unsafe { unsafe {
let image_bytes = Vec::<u8>::from_raw_parts(ptr, size as usize, size as usize); let image_bytes = Vec::<u8>::from_raw_parts(ptr, size as usize, size as usize);
let image_data = skia::Data::new_copy(&*image_bytes); match state.render_state().add_image(id, &image_bytes) {
match Image::from_encoded(image_data) { Err(msg) => {
Some(image) => { eprintln!("{}", msg);
render_state.images.insert(id.to_string(), image);
}
None => {
eprintln!("Error on image decoding");
} }
_ => {}
} }
mem::free(ptr as *mut u8, size as usize * std::mem::size_of::<u8>()); mem::free(ptr as *mut u8, size as usize * std::mem::size_of::<u8>());
} }
@ -221,9 +217,8 @@ pub extern "C" fn store_image(a: u32, b: u32, c: u32, d: u32, ptr: *mut u8, size
#[no_mangle] #[no_mangle]
pub extern "C" fn is_image_cached(a: u32, b: u32, c: u32, d: u32) -> bool { pub extern "C" fn is_image_cached(a: u32, b: u32, c: u32, d: u32) -> bool {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
let render_state = state.render_state();
let id = uuid_from_u32_quartet(a, b, c, d); let id = uuid_from_u32_quartet(a, b, c, d);
render_state.images.contains_key(&id.to_string()) state.render_state().has_image(&id)
} }
#[no_mangle] #[no_mangle]
@ -233,8 +228,8 @@ pub extern "C" fn add_shape_image_fill(
c: u32, c: u32,
d: u32, d: u32,
alpha: f32, alpha: f32,
width: f32, width: i32,
height: f32, height: i32,
) { ) {
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
let id = uuid_from_u32_quartet(a, b, c, d); let id = uuid_from_u32_quartet(a, b, c, d);
@ -242,8 +237,7 @@ pub extern "C" fn add_shape_image_fill(
shape.add_fill(shapes::Fill::new_image_fill( shape.add_fill(shapes::Fill::new_image_fill(
id, id,
(alpha * 0xff as f32).floor() as u8, (alpha * 0xff as f32).floor() as u8,
height, (width, height),
width,
)); ));
} }
} }

View file

@ -98,7 +98,7 @@ pub(crate) struct RenderState {
pub cached_surface_image: Option<CachedSurfaceImage>, pub cached_surface_image: Option<CachedSurfaceImage>,
options: RenderOptions, options: RenderOptions,
pub viewbox: Viewbox, pub viewbox: Viewbox,
pub images: HashMap<String, Image>, images: HashMap<Uuid, Image>,
} }
impl RenderState { impl RenderState {
@ -125,6 +125,18 @@ impl RenderState {
} }
} }
pub fn add_image(&mut self, id: Uuid, image_data: &[u8]) -> Result<(), String> {
let image_data = skia::Data::new_copy(image_data);
let image = Image::from_encoded(image_data).ok_or("Error decoding image data")?;
self.images.insert(id, image);
Ok(())
}
pub fn has_image(&mut self, id: &Uuid) -> bool {
self.images.contains_key(id)
}
pub fn set_debug_flags(&mut self, debug: u32) { pub fn set_debug_flags(&mut self, debug: u32) {
self.options.debug_flags = debug; self.options.debug_flags = debug;
} }
@ -214,12 +226,12 @@ impl RenderState {
for fill in shape.fills().rev() { for fill in shape.fills().rev() {
if let Fill::Image(image_fill) = fill { if let Fill::Image(image_fill) = fill {
let image = self.images.get(&image_fill.id.to_string()); let image = self.images.get(&image_fill.id());
if let Some(image) = image { if let Some(image) = image {
draw_image_in_container( draw_image_in_container(
&self.drawing_surface.canvas(), &self.drawing_surface.canvas(),
&image, &image,
(image_fill.width, image_fill.height), image_fill.size(),
shape.selrect, shape.selrect,
&fill.to_paint(&shape.selrect), &fill.to_paint(&shape.selrect),
); );

View file

@ -60,10 +60,20 @@ impl Gradient {
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct ImageFill { pub struct ImageFill {
pub id: Uuid, id: Uuid,
pub alpha: u8, opacity: u8,
pub height: f32, height: i32,
pub width: f32, width: i32,
}
impl ImageFill {
pub fn size(&self) -> (i32, i32) {
(self.width, self.height)
}
pub fn id(&self) -> Uuid {
self.id
}
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -84,10 +94,10 @@ impl Fill {
}) })
} }
pub fn new_image_fill(id: Uuid, alpha: u8, height: f32, width: f32) -> Self { pub fn new_image_fill(id: Uuid, opacity: u8, (width, height): (i32, i32)) -> Self {
Self::Image(ImageFill { Self::Image(ImageFill {
id, id,
alpha, opacity,
height, height,
width, width,
}) })
@ -116,7 +126,7 @@ impl Fill {
p.set_style(skia::PaintStyle::Fill); p.set_style(skia::PaintStyle::Fill);
p.set_anti_alias(true); p.set_anti_alias(true);
p.set_blend_mode(skia::BlendMode::SrcOver); p.set_blend_mode(skia::BlendMode::SrcOver);
p.set_alpha(image_fill.alpha); p.set_alpha(image_fill.opacity);
p p
} }
} }

View file

@ -6,12 +6,12 @@ pub type Image = skia::Image;
pub fn draw_image_in_container( pub fn draw_image_in_container(
canvas: &skia::Canvas, canvas: &skia::Canvas,
image: &Image, image: &Image,
size: (f32, f32), size: (i32, i32),
container: skia::Rect, container: skia::Rect,
paint: &skia::Paint, paint: &skia::Paint,
) { ) {
let width = size.0; let width = size.0 as f32;
let height = size.1; let height = size.1 as f32;
let image_aspect_ratio = width / height; let image_aspect_ratio = width / height;
// Container size // Container size