From 78ccf4f3e657e7f233f7ff3516bb35c2653cfa12 Mon Sep 17 00:00:00 2001 From: Abdelrahman Ashraf Date: Sun, 4 Feb 2024 15:03:41 +0700 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20memory=20access=20out=20o?= =?UTF-8?q?f=20range=20on=20resize?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dotlottie-ffi/emscripten_bindings.cpp | 5 +- dotlottie-ffi/src/dotlottie_player_cpp.udl | 94 +++++++++++----------- dotlottie-rs/src/lottie_renderer/mod.rs | 51 +++++------- dotlottie-rs/src/thorvg.rs | 2 +- 4 files changed, 73 insertions(+), 79 deletions(-) diff --git a/dotlottie-ffi/emscripten_bindings.cpp b/dotlottie-ffi/emscripten_bindings.cpp index 0f7161e9..3c156498 100644 --- a/dotlottie-ffi/emscripten_bindings.cpp +++ b/dotlottie-ffi/emscripten_bindings.cpp @@ -72,6 +72,7 @@ EMSCRIPTEN_BINDINGS(DotLottiePlayer) // .field("version", &Manifest::version); class_("DotLottiePlayer") + .smart_ptr>("DotLottiePlayer") .constructor(&DotLottiePlayer::init, allow_raw_pointers()) .function("buffer", &buffer) .function("clear", &DotLottiePlayer::clear) @@ -98,7 +99,7 @@ EMSCRIPTEN_BINDINGS(DotLottiePlayer) .function("setFrame", &DotLottiePlayer::set_frame) .function("stop", &DotLottiePlayer::stop) .function("totalFrames", &DotLottiePlayer::total_frames) - .function("subscribe", &DotLottiePlayer::subscribe) - .function("unsubscribe", &DotLottiePlayer::unsubscribe) + // .function("subscribe", &DotLottiePlayer::subscribe) + // .function("unsubscribe", &DotLottiePlayer::unsubscribe) .function("isComplete", &DotLottiePlayer::is_complete); } \ No newline at end of file diff --git a/dotlottie-ffi/src/dotlottie_player_cpp.udl b/dotlottie-ffi/src/dotlottie_player_cpp.udl index c7cc5307..d287066f 100644 --- a/dotlottie-ffi/src/dotlottie_player_cpp.udl +++ b/dotlottie-ffi/src/dotlottie_player_cpp.udl @@ -1,18 +1,18 @@ namespace dotlottie_player { }; -[Trait] -interface Observer { - void on_load(); - void on_load_error(); - void on_play(); - void on_pause(); - void on_stop(); - void on_frame(f32 frame_no); - void on_render(f32 frame_no); - void on_loop(u32 loop_count); - void on_complete(); -}; +///[Trait] +///interface Observer { +/// void on_load(); +/// void on_load_error(); +/// void on_play(); +/// void on_pause(); +/// void on_stop(); +/// void on_frame(f32 frame_no); +/// void on_render(f32 frame_no); +/// void on_loop(u32 loop_count); +/// void on_complete(); +///}; enum Mode { "Forward", @@ -31,41 +31,41 @@ dictionary Config { u32 background_color; }; -dictionary ManifestTheme { - string id; - sequence values; -}; +///dictionary ManifestTheme { +/// string id; +/// sequence values; +///}; -dictionary ManifestThemes { - sequence? value; -}; +///dictionary ManifestThemes { +/// sequence? value; +///}; -dictionary ManifestAnimation { - boolean? autoplay; - string? defaultTheme; - i8? direction; - boolean? hover; - string id; - u32? intermission; - boolean? loop; - u32? loop_count; - string? playMode; - u32? speed; - string? themeColor; -}; +///dictionary ManifestAnimation { +/// boolean? autoplay; +/// string? defaultTheme; +/// i8? direction; +/// boolean? hover; +/// string id; +/// u32? intermission; +/// boolean? loop; +/// u32? loop_count; +/// string? playMode; +/// u32? speed; +/// string? themeColor; +///}; -dictionary Manifest { - string? active_animation_id; - sequence animations; - string? author; - string? description; - string? generator; - string? keywords; - u32? revision; - ManifestThemes? themes; - sequence? states; - string? version; -}; +///dictionary Manifest { +/// string? active_animation_id; +/// sequence animations; +/// string? author; +/// string? description; +/// string? generator; +/// string? keywords; +/// u32? revision; +/// ManifestThemes? themes; +/// sequence? states; +/// string? version; +///}; interface DotLottiePlayer { constructor(Config config); @@ -73,7 +73,7 @@ interface DotLottiePlayer { boolean load_animation_path([ByRef] string animation_path, u32 width, u32 height); boolean load_dotlottie_data([ByRef] bytes file_data, u32 width, u32 height); boolean load_animation([ByRef] string animation_id, u32 width, u32 height); - Manifest? manifest(); +/// Manifest? manifest(); string manifest_string(); u64 buffer_ptr(); u64 buffer_len(); @@ -95,7 +95,7 @@ interface DotLottiePlayer { boolean render(); boolean resize(u32 width, u32 height); void clear(); - void subscribe(Observer observer); - void unsubscribe([ByRef] Observer observer); +/// void subscribe(Observer observer); +/// void unsubscribe([ByRef] Observer observer); boolean is_complete(); }; diff --git a/dotlottie-rs/src/lottie_renderer/mod.rs b/dotlottie-rs/src/lottie_renderer/mod.rs index f6cee750..ad14d99e 100644 --- a/dotlottie-rs/src/lottie_renderer/mod.rs +++ b/dotlottie-rs/src/lottie_renderer/mod.rs @@ -23,6 +23,7 @@ pub struct LottieRenderer { thorvg_animation: Option, thorvg_canvas: Option, thorvg_background_shape: Option, + thorvg_picture: Option, picture_width: f32, picture_height: f32, pub width: u32, @@ -37,6 +38,7 @@ impl LottieRenderer { thorvg_animation: None, thorvg_canvas: None, thorvg_background_shape: None, + thorvg_picture: None, buffer: vec![], width: 0, height: 0, @@ -52,18 +54,16 @@ impl LottieRenderer { width: u32, height: u32, ) -> Result<(), LottieRendererError> { - self.thorvg_animation = Some(thorvg::Animation::new()); + let thorvg_animation = thorvg::Animation::new(); + self.thorvg_picture = thorvg_animation.new_picture(); + self.thorvg_animation = Some(thorvg_animation); self.thorvg_background_shape = Some(thorvg::Shape::new()); self.thorvg_canvas = Some(thorvg::Canvas::new(thorvg::TvgEngine::TvgEngineSw, 0)); - self.buffer = vec![0; (width * height * 4) as usize]; self.width = width; self.height = height; - - let thorvg_animation = self - .thorvg_animation - .as_mut() - .ok_or(LottieRendererError::AnimationNotLoaded)?; + self.buffer + .resize((self.width * self.height * 4) as usize, 0); let thorvg_canvas = self .thorvg_canvas @@ -85,7 +85,7 @@ impl LottieRenderer { ) .map_err(LottieRendererError::ThorvgError)?; - if let Some(picture) = &mut thorvg_animation.get_picture() { + if let Some(picture) = &mut self.thorvg_picture { picture.load(path)?; let (pw, ph) = picture.get_size()?; @@ -115,18 +115,16 @@ impl LottieRenderer { height: u32, copy: bool, ) -> Result<(), LottieRendererError> { - self.thorvg_animation = Some(thorvg::Animation::new()); + let thorvg_animation = thorvg::Animation::new(); + self.thorvg_picture = thorvg_animation.new_picture(); + self.thorvg_animation = Some(thorvg_animation); self.thorvg_background_shape = Some(thorvg::Shape::new()); self.thorvg_canvas = Some(thorvg::Canvas::new(thorvg::TvgEngine::TvgEngineSw, 0)); - self.buffer = vec![0; (width * height * 4) as usize]; self.width = width; self.height = height; - - let thorvg_animation = self - .thorvg_animation - .as_mut() - .ok_or(LottieRendererError::AnimationNotLoaded)?; + self.buffer + .resize((self.width * self.height * 4) as usize, 0); let thorvg_canvas = self .thorvg_canvas @@ -148,7 +146,7 @@ impl LottieRenderer { ) .map_err(LottieRendererError::ThorvgError)?; - if let Some(picture) = &mut thorvg_animation.get_picture() { + if let Some(picture) = &mut self.thorvg_picture { picture.load_data(data.as_bytes(), "lottie", copy)?; let (pw, ph) = picture.get_size()?; @@ -249,11 +247,6 @@ impl LottieRenderer { .as_mut() .ok_or(LottieRendererError::AnimationNotLoaded)?; - let thorvg_animation = self - .thorvg_animation - .as_mut() - .ok_or(LottieRendererError::AnimationNotLoaded)?; - if (width, height) == (self.width, self.height) { return Ok(()); } @@ -267,25 +260,25 @@ impl LottieRenderer { self.width = width; self.height = height; - let mut buffer = vec![0; (width * height * 4) as usize]; + self.buffer + .resize((self.width * self.height * 4) as usize, 0); + thorvg_canvas .set_target( - &mut buffer, - width, - width, - height, + &mut self.buffer, + self.width, + self.width, + self.height, thorvg::TvgColorspace::ABGR8888, ) .map_err(LottieRendererError::ThorvgError)?; - if let Some(picture) = &mut thorvg_animation.get_picture() { + if let Some(picture) = &mut self.thorvg_picture { let (pw, ph) = picture.get_size()?; let (scale, shift_x, shift_y) = calculate_scale_and_shift(pw, ph, width, height); picture.scale(scale)?; picture.translate(shift_x, shift_y)?; - - self.buffer = buffer; } Ok(()) diff --git a/dotlottie-rs/src/thorvg.rs b/dotlottie-rs/src/thorvg.rs index 87c039ed..bcb35bbe 100644 --- a/dotlottie-rs/src/thorvg.rs +++ b/dotlottie-rs/src/thorvg.rs @@ -244,7 +244,7 @@ impl Animation { } } - pub fn get_picture(&self) -> Option { + pub fn new_picture(&self) -> Option { let raw_picture = unsafe { tvg_animation_get_picture(self.raw_animation) }; if raw_picture.is_null() {