diff --git a/rlottie-sys/Cargo.toml b/rlottie-sys/Cargo.toml index bfd49283..8f7d743e 100644 --- a/rlottie-sys/Cargo.toml +++ b/rlottie-sys/Cargo.toml @@ -5,7 +5,7 @@ workspace = ".." name = "rlottie-sys" version = "0.2.4" license = "MIT" -include = ["src/**/*.rs", "/build.rs", "/wrapper.h", "/LICENSE"] +include = ["src/**/*.rs", "/build.rs", "/wrapper.h", "/wrapper.hpp", "/wrapper.cpp", "/LICENSE"] description = "A platform independent standalone library that plays Lottie Animation" repository = "https://github.com/msrd0/rlottie-rs" @@ -18,3 +18,7 @@ links = "rlottie" [build-dependencies] bindgen = { version = "0.61.0", features = ["runtime"], default-features = false } pkg-config = "0.3.22" +cc = "1.0.73" + +[features] +tg = [] \ No newline at end of file diff --git a/rlottie-sys/build.rs b/rlottie-sys/build.rs index 20b065db..cc016638 100644 --- a/rlottie-sys/build.rs +++ b/rlottie-sys/build.rs @@ -5,10 +5,22 @@ fn main() { .probe("rlottie") .expect("Unable to find rlottie"); - println!("cargo:rerun-if-changed=wrapper.h"); + let header = if cfg!(feature = "tg") { + println!("cargo:rerun-if-changed=wrapper_tg.hpp"); + println!("cargo:rerun-if-changed=wrapper_tg.cpp"); + "wrapper_tg.hpp" + } else { + println!("cargo:rerun-if-changed=wrapper.h"); + "wrapper.h" + }; + let bindings = bindgen::Builder::default() .rustfmt_bindings(false) - .header("wrapper.h") + .header(header) + .clang_arg("-I.") + .clang_arg("-std=c++17") + .clang_arg("-x") + .clang_arg("c++") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .newtype_enum(".*") .size_t_is_usize(true) @@ -20,4 +32,9 @@ fn main() { bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); + + cc::Build::new() + .cpp(true) + .file("wrapper_tg.cpp") + .compile("lib_my_lib.a"); } diff --git a/rlottie-sys/wrapper_tg.cpp b/rlottie-sys/wrapper_tg.cpp new file mode 100644 index 00000000..8d70a2dc --- /dev/null +++ b/rlottie-sys/wrapper_tg.cpp @@ -0,0 +1,24 @@ +#include "wrapper_tg.hpp" + +#include "rlottie.h" + +using rlottie::Animation; +using rlottie::Surface; +// using rlottie::Lottie_Animation_S; +// using rlottie::FitzModifier; + +struct Lottie_Animation_S { + std::unique_ptr mAnimation; + std::future mRenderTask; + uint32_t* mBufferRef; +}; + +LOT_EXPORT Lottie_Animation* lottie_animation_from_data_tg(const char* data, const char* key, const char* resourcePath, FitzModifier fitzModifier) { + if (auto animation = Animation::loadFromData(data, key, resourcePath, true, {}, rlottie::FitzModifier(fitzModifier))) { + Lottie_Animation_S* handle = new Lottie_Animation_S(); + handle->mAnimation = std::move(animation); + return handle; + } else { + return nullptr; + } +} \ No newline at end of file diff --git a/rlottie-sys/wrapper_tg.hpp b/rlottie-sys/wrapper_tg.hpp new file mode 100644 index 00000000..84d7d9bd --- /dev/null +++ b/rlottie-sys/wrapper_tg.hpp @@ -0,0 +1,26 @@ +#include "wrapper.h" + +#if defined _WIN32 || defined __CYGWIN__ +#ifdef LOT_BUILD +#define LOT_EXPORT __declspec(dllexport) +#else +#define LOT_EXPORT __declspec(dllimport) +#endif +#else +#ifdef LOT_BUILD +#define LOT_EXPORT __attribute__ ((visibility ("default"))) +#else +#define LOT_EXPORT +#endif +#endif + +enum class FitzModifier { + None, + Type12, + Type3, + Type4, + Type5, + Type6 +}; + +LOT_EXPORT Lottie_Animation* lottie_animation_from_data_tg(const char* data, const char* key, const char* resource_path, FitzModifier fitz_modifier); \ No newline at end of file diff --git a/rlottie/Cargo.toml b/rlottie/Cargo.toml index e2e671af..ddc2967c 100644 --- a/rlottie/Cargo.toml +++ b/rlottie/Cargo.toml @@ -17,3 +17,6 @@ rust-version = "1.56" [dependencies] rgb = { version = "0.8.32", default-features = false } rlottie-sys = { path = "../rlottie-sys", version = "0.2" } + +[features] +tg = ["rlottie-sys/tg"] \ No newline at end of file diff --git a/rlottie/src/lib.rs b/rlottie/src/lib.rs index 4fff8b5e..b32a7f85 100644 --- a/rlottie/src/lib.rs +++ b/rlottie/src/lib.rs @@ -34,21 +34,22 @@ use std::{ os::unix::ffi::OsStrExt, path::Path, ptr::NonNull, - slice + slice, }; +#[cfg(feature = "tg")] +pub use rlottie_sys::FitzModifier; + pub type Bgra = BGRA; pub type Rgb = RGB; fn color_is_valid(Rgb { r, g, b }: Rgb) -> bool { - (0.0 ..= 1.0).contains(&r) - && (0.0 ..= 1.0).contains(&g) - && (0.0 ..= 1.0).contains(&b) + (0.0..=1.0).contains(&r) && (0.0..=1.0).contains(&g) && (0.0..=1.0).contains(&b) } fn path_to_cstr

(path: P) -> CString where - P: AsRef + P: AsRef, { let bytes = path.as_ref().as_os_str().as_bytes().to_vec(); CString::new(bytes).expect("path must not contain nul") @@ -58,7 +59,7 @@ where #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct Size { pub width: usize, - pub height: usize + pub height: usize, } impl Size { @@ -97,7 +98,7 @@ mod bgra8_size { /// the surface. pub struct Surface { data: Vec, - size: Size + size: Size, } impl Surface { @@ -105,7 +106,7 @@ impl Surface { pub fn new(size: Size) -> Self { Self { data: Vec::with_capacity(size.width * size.height), - size + size, } } @@ -142,7 +143,7 @@ impl Surface { unsafe { slice::from_raw_parts( self.data.as_ptr() as *const u8, - self.data.len() * mem::size_of::() + self.data.len() * mem::size_of::(), ) } } @@ -206,7 +207,7 @@ impl Animation { /// Note that the rlottie library might cache the file and/or its resources. pub fn from_file

(path: P) -> Option where - P: AsRef + P: AsRef, { let path = path_to_cstr(path); let ptr = unsafe { lottie_animation_from_file(path.as_ptr()) }; @@ -223,12 +224,12 @@ impl Animation { pub fn from_data( json_data: D, cache_key: K, - resource_path: P + resource_path: P, ) -> Option where D: Into>, K: Into>, - P: AsRef + P: AsRef, { let json_data = CString::new(json_data).expect("json_data must not contain nul"); @@ -238,7 +239,34 @@ impl Animation { lottie_animation_from_data( json_data.as_ptr(), cache_key.as_ptr(), - resource_path.as_ptr() + resource_path.as_ptr(), + ) + }; + Self::from_ptr(ptr) + } + + #[cfg(feature = "tg")] + pub fn from_data_tg( + json_data: D, + cache_key: K, + resource_path: P, + fitz_modifier: FitzModifier, + ) -> Option + where + D: Into>, + K: Into>, + P: AsRef, + { + let json_data = + CString::new(json_data).expect("json_data must not contain nul"); + let cache_key = CString::new(cache_key).expect("key must not contain nul"); + let resource_path = path_to_cstr(resource_path); + let ptr = unsafe { + lottie_animation_from_data_tg( + json_data.as_ptr(), + cache_key.as_ptr(), + resource_path.as_ptr(), + fitz_modifier, ) }; Self::from_ptr(ptr) @@ -248,13 +276,13 @@ impl Animation { pub fn size(&self) -> Size { let mut size = Size { width: 0, - height: 0 + height: 0, }; unsafe { lottie_animation_get_size( self.0.as_ptr(), &mut size.width, - &mut size.height + &mut size.height, ); } size @@ -289,7 +317,7 @@ impl Animation { surface.as_mut_ptr(), surface.width(), surface.height(), - surface.width() * 4 + surface.width() * 4, ); surface.set_len(); } @@ -313,7 +341,7 @@ impl Animation { pub fn set_fill_opacity(&mut self, keypath: &str, opacity: f64) { assert!( - (0.0 ..= 100.0).contains(&opacity), + (0.0..=100.0).contains(&opacity), "opacity values must be between 0.0 and 100.0" ); let keypath = CString::new(keypath).unwrap(); @@ -345,7 +373,7 @@ impl Animation { pub fn set_stroke_opacity(&mut self, keypath: &str, opacity: f64) { assert!( - (0.0 ..= 100.0).contains(&opacity), + (0.0..=100.0).contains(&opacity), "opacity values must be between 0.0 and 100.0" ); let keypath = CString::new(keypath).unwrap();