diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 610ce8951..79cd2b922 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -84,6 +84,18 @@ [clip-content] (h/call internal-module "_set_shape_clip_content" clip-content)) +(defn set-shape-type + [type] + (cond + (= type :circle) + (h/call internal-module "_set_shape_kind_circle") + + (= type :path) + (h/call internal-module "_set_shape_kind_path") + + :else + (h/call internal-module "_set_shape_kind_rect"))) + (defn set-shape-selrect [selrect] (h/call internal-module "_set_shape_selrect" @@ -260,10 +272,10 @@ (loop [index 0 pending []] (if (< index total-shapes) (let [shape (nth shapes index) - type (dm/get-prop shape :type) id (dm/get-prop shape :id) - clip-content (not (dm/get-prop shape :show-content)) + type (dm/get-prop shape :type) selrect (dm/get-prop shape :selrect) + clip-content (not (dm/get-prop shape :show-content)) rotation (dm/get-prop shape :rotation) transform (dm/get-prop shape :transform) fills (if (= type :group) @@ -275,6 +287,7 @@ content (dm/get-prop shape :content)] (use-shape id) + (set-shape-type type) (set-shape-clip-content clip-content) (set-shape-selrect selrect) (set-shape-rotation rotation) diff --git a/frontend/src/app/render_wasm/shape.cljs b/frontend/src/app/render_wasm/shape.cljs index 65c48da3f..582c61103 100644 --- a/frontend/src/app/render_wasm/shape.cljs +++ b/frontend/src/app/render_wasm/shape.cljs @@ -111,6 +111,7 @@ (when ^boolean shape/*wasm-sync* (api/use-shape (:id self)) (case k + :type (api/set-shape-type v) :selrect (api/set-shape-selrect v) :show-content (api/set-shape-clip-content (not v)) :rotation (api/set-shape-rotation v) diff --git a/render-wasm/src/main.rs b/render-wasm/src/main.rs index 6a55357df..f15d3232f 100644 --- a/render-wasm/src/main.rs +++ b/render-wasm/src/main.rs @@ -7,6 +7,8 @@ mod state; mod utils; mod view; +use crate::shapes::Kind; +use crate::shapes::Path; use skia_safe as skia; use crate::state::State; @@ -102,6 +104,33 @@ pub extern "C" fn use_shape(a: u32, b: u32, c: u32, d: u32) { state.use_shape(id); } +#[no_mangle] +pub unsafe extern "C" fn set_shape_kind_circle() { + let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); + + if let Some(shape) = state.current_shape() { + shape.kind = Kind::Circle(math::Rect::new_empty()); + } +} + +#[no_mangle] +pub unsafe extern "C" fn set_shape_kind_rect() { + let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); + + if let Some(shape) = state.current_shape() { + shape.kind = Kind::Rect(math::Rect::new_empty()); + } +} + +#[no_mangle] +pub unsafe extern "C" fn set_shape_kind_path() { + let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); + if let Some(shape) = state.current_shape() { + let p = Path::try_from(Vec::new()).unwrap(); + shape.kind = Kind::Path(p); + } +} + #[no_mangle] pub extern "C" fn set_shape_selrect(left: f32, top: f32, right: f32, bottom: f32) { let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index a3fa7fe4b..4b89e0659 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -300,6 +300,11 @@ impl RenderState { .canvas() .draw_rect(rect, &fill.to_paint(&selrect)); } + (_, Kind::Circle(rect)) => { + self.drawing_surface + .canvas() + .draw_oval(rect, &fill.to_paint(&selrect)); + } (_, Kind::Path(path)) => { self.drawing_surface .canvas() diff --git a/render-wasm/src/shapes.rs b/render-wasm/src/shapes.rs index ad708a32d..5362c6d4f 100644 --- a/render-wasm/src/shapes.rs +++ b/render-wasm/src/shapes.rs @@ -14,6 +14,7 @@ pub use paths::*; #[derive(Debug, Clone, PartialEq)] pub enum Kind { Rect(math::Rect), + Circle(math::Rect), Path(Path), } @@ -77,9 +78,15 @@ impl Shape { pub fn set_selrect(&mut self, left: f32, top: f32, right: f32, bottom: f32) { self.selrect.set_ltrb(left, top, right, bottom); - if let Kind::Rect(_) = self.kind { - self.kind = Kind::Rect(self.selrect.to_owned()); - } + match self.kind { + Kind::Rect(_) => { + self.kind = Kind::Rect(self.selrect.to_owned()); + } + Kind::Circle(_) => { + self.kind = Kind::Circle(self.selrect.to_owned()); + } + _ => {} + }; } pub fn translation(&self) -> (f32, f32) { diff --git a/render-wasm/src/shapes/images.rs b/render-wasm/src/shapes/images.rs index 85b96d1e2..50980027a 100644 --- a/render-wasm/src/shapes/images.rs +++ b/render-wasm/src/shapes/images.rs @@ -1,10 +1,9 @@ use crate::math; +use crate::shapes::Kind; use skia_safe as skia; pub type Image = skia::Image; -use crate::shapes::Kind; - pub fn draw_image_in_container( canvas: &skia::Canvas, image: &Image, @@ -18,6 +17,7 @@ pub fn draw_image_in_container( let container = match kind { Kind::Rect(r) => r.to_owned(), + Kind::Circle(r) => r.to_owned(), Kind::Path(p) => p.to_skia_path().bounds().to_owned(), }; @@ -53,6 +53,11 @@ pub fn draw_image_in_container( Kind::Rect(_) => { canvas.clip_rect(container, skia::ClipOp::Intersect, true); } + Kind::Circle(_) => { + let mut oval_path = skia::Path::new(); + oval_path.add_oval(container, None); + canvas.clip_path(&oval_path, skia::ClipOp::Intersect, true); + } Kind::Path(p) => { canvas.clip_path(&p.to_skia_path(), skia::ClipOp::Intersect, true); }