diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index ce7503a09..cd3ebbeb5 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -50,12 +50,16 @@ (def GRID-LAYOUT-ROW-ENTRY-SIZE 5) (def GRID-LAYOUT-COLUMN-ENTRY-SIZE 5) (def GRID-LAYOUT-CELL-ENTRY-SIZE 37) -(def GRADIENT-STOP-SIZE 5) -(def LINEAR-FILL-BASE-SIZE 21) + (defn gradient-stop-get-entries-size [stops] - (mem/get-list-size stops GRADIENT-STOP-SIZE)) + (mem/get-list-size stops sr-fills/GRADIENT-STOP-SIZE)) + +(defn gradient-byte-size + [gradient] + (let [stops (:stops gradient)] + (+ sr-fills/GRADIENT-BASE-SIZE (* (count stops) sr-fills/GRADIENT-STOP-SIZE)))) (defn modifier-get-entries-size "Returns the list of a modifier list in bytes" @@ -232,8 +236,7 @@ (some? gradient) (case (:type gradient) :linear - (let [stops (:stops gradient) - size (+ LINEAR-FILL-BASE-SIZE (* (count stops) GRADIENT-STOP-SIZE)) + (let [size (gradient-byte-size gradient) offset (mem/alloc-bytes size) heap (mem/get-heap-u8)] (sr-fills/serialize-linear-fill gradient opacity heap offset) diff --git a/frontend/src/app/render_wasm/serializers.cljs b/frontend/src/app/render_wasm/serializers.cljs index 0574b850a..e42ff8c45 100644 --- a/frontend/src/app/render_wasm/serializers.cljs +++ b/frontend/src/app/render_wasm/serializers.cljs @@ -10,8 +10,6 @@ [app.common.uuid :as uuid] [cuerdas.core :as str])) - - (defn u8 [value] (let [u8-arr (js/Uint8Array. 1)] diff --git a/frontend/src/app/render_wasm/serializers/fills.cljs b/frontend/src/app/render_wasm/serializers/fills.cljs index 3864cb642..194080d23 100644 --- a/frontend/src/app/render_wasm/serializers/fills.cljs +++ b/frontend/src/app/render_wasm/serializers/fills.cljs @@ -3,6 +3,9 @@ [app.common.data.macros :as dm] [app.render-wasm.serializers.color :as clr])) +(def GRADIENT-STOP-SIZE 5) +(def GRADIENT-BASE-SIZE 24) + (defn serialize-linear-fill [gradient opacity heap-u8 offset] (let [dview (js/DataView. (.-buffer heap-u8)) @@ -10,13 +13,14 @@ start-y (dm/get-prop gradient :start-y) end-x (dm/get-prop gradient :end-x) end-y (dm/get-prop gradient :end-y) - stops (dm/get-prop gradient :stops)] + stops (dm/get-prop gradient :stops) + width 0] (.setFloat32 dview offset start-x true) (.setFloat32 dview (+ offset 4) start-y true) (.setFloat32 dview (+ offset 8) end-x true) (.setFloat32 dview (+ offset 12) end-y true) (.setFloat32 dview (+ offset 16) opacity true) - (.setUint8 dview (+ offset 20) (count stops)) + (.setFloat32 dview (+ offset 20) width true) (loop [stops (seq stops) idx 0] (when-not (empty? stops) (let [stop (first stops) @@ -24,7 +28,7 @@ opacity (dm/get-prop stop :opacity) rgba (clr/hex->u32argb hex-color opacity) stop-offset (* 100 (dm/get-prop stop :offset)) - dview-offset (+ (* idx 5) offset 21)] + dview-offset (+ (* idx 5) offset 24)] (.setUint32 dview dview-offset rgba true) (.setUint8 dview (+ dview-offset 4) stop-offset) (recur (rest stops) (+ idx 1))))))) \ No newline at end of file diff --git a/render-wasm/src/main.rs b/render-wasm/src/main.rs index 839c94f25..291d76e79 100644 --- a/render-wasm/src/main.rs +++ b/render-wasm/src/main.rs @@ -17,8 +17,8 @@ mod wasm; use crate::mem::SerializableResult; use crate::shapes::{ - BoolType, ConstraintH, ConstraintV, StructureEntry, TransformEntry, Type, - RAW_LINEAR_FILL_DATA_SIZE, RAW_STOP_DATA_SIZE, + BoolType, ConstraintH, ConstraintV, StructureEntry, TransformEntry, Type, RAW_FILL_DATA_SIZE, + RAW_STOP_DATA_SIZE, }; use crate::utils::uuid_from_u32_quartet; use crate::uuid::Uuid; @@ -260,12 +260,11 @@ pub extern "C" fn add_shape_solid_fill(raw_color: u32) { #[no_mangle] pub extern "C" fn add_shape_linear_fill() { with_current_shape!(state, |shape: &mut Shape| { - let stops_offset = RAW_LINEAR_FILL_DATA_SIZE; let bytes = mem::bytes(); - let raw_fill_data: [u8; RAW_LINEAR_FILL_DATA_SIZE] = - bytes[0..stops_offset].try_into().unwrap(); - let raw_fill = shapes::RawLinearFillData::from(raw_fill_data); - let stops: Vec = bytes[stops_offset..] + let raw_gradient_bytes: [u8; RAW_FILL_DATA_SIZE] = + bytes[0..RAW_FILL_DATA_SIZE].try_into().unwrap(); + let raw_gradient = shapes::RawGradientData::from(raw_gradient_bytes); + let stops: Vec = bytes[RAW_FILL_DATA_SIZE..] .chunks(RAW_STOP_DATA_SIZE) .map(|chunk| { let data: [u8; RAW_STOP_DATA_SIZE] = chunk.try_into().unwrap(); @@ -274,9 +273,9 @@ pub extern "C" fn add_shape_linear_fill() { .collect(); shape.add_fill(shapes::Fill::new_linear_gradient_with_stops( - raw_fill.start(), - raw_fill.end(), - raw_fill.opacity(), + raw_gradient.start(), + raw_gradient.end(), + raw_gradient.opacity(), stops, )); }); diff --git a/render-wasm/src/mem.rs b/render-wasm/src/mem.rs index b70bd42f4..0b0edfd9c 100644 --- a/render-wasm/src/mem.rs +++ b/render-wasm/src/mem.rs @@ -20,7 +20,7 @@ pub extern "C" fn alloc_bytes(len: usize) -> *mut u8 { if ptr.is_null() { panic!("Allocation failed"); } - // TODO: Esto quizá se podría eliminar. + // TODO: Maybe this could be removed. ptr::write_bytes(ptr, 0, len); *guard = Some(Box::new(Vec::from_raw_parts(ptr, len, len))); ptr diff --git a/render-wasm/src/shapes/fills.rs b/render-wasm/src/shapes/fills.rs index 870425263..af6daa84a 100644 --- a/render-wasm/src/shapes/fills.rs +++ b/render-wasm/src/shapes/fills.rs @@ -3,33 +3,33 @@ use skia_safe::{self as skia, Rect}; use super::Color; use crate::uuid::Uuid; -pub const RAW_LINEAR_FILL_DATA_SIZE: usize = 21; +pub const RAW_FILL_DATA_SIZE: usize = 24; #[derive(Debug)] #[repr(C)] -pub struct RawLinearFillData { +pub struct RawGradientData { start_x: f32, start_y: f32, end_x: f32, end_y: f32, opacity: f32, - stop_count: u8, + width: f32, } -impl From<[u8; 21]> for RawLinearFillData { - fn from(bytes: [u8; 21]) -> Self { +impl From<[u8; RAW_FILL_DATA_SIZE]> for RawGradientData { + fn from(bytes: [u8; RAW_FILL_DATA_SIZE]) -> Self { Self { start_x: f32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]), start_y: f32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]), end_x: f32::from_le_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]), end_y: f32::from_le_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]), opacity: f32::from_le_bytes([bytes[16], bytes[17], bytes[18], bytes[19]]), - stop_count: bytes[20], + width: f32::from_le_bytes([bytes[20], bytes[21], bytes[22], bytes[23]]), } } } -impl RawLinearFillData { +impl RawGradientData { pub fn start(&self) -> (f32, f32) { (self.start_x, self.start_y) }