mirror of
https://github.com/penpot/penpot.git
synced 2025-01-21 06:02:32 -05:00
🎉 Serialize data in clojure
This commit is contained in:
parent
f564b4e66d
commit
22b01c63b5
6 changed files with 121 additions and 8 deletions
|
@ -9,6 +9,7 @@
|
|||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.math :as mth]
|
||||
[app.common.svg.path :as path]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cf]
|
||||
[app.render-wasm.helpers :as h]
|
||||
|
@ -186,6 +187,18 @@
|
|||
(store-image id))))))
|
||||
fills))
|
||||
|
||||
(defn set-shape-path-content
|
||||
[content]
|
||||
(let [buffer (path/content->buffer content)
|
||||
size (.-byteLength buffer)
|
||||
ptr (h/call internal-module "_alloc_bytes" size)
|
||||
heap (gobj/get ^js internal-module "HEAPU8")
|
||||
mem (js/Uint8Array. (.-buffer heap) ptr size)]
|
||||
(.set mem (js/Uint8Array. buffer)
|
||||
(h/call internal-module "_set_shape_path_content" (count content))
|
||||
(js/console.log mem)
|
||||
(js/console.log buffer))))
|
||||
|
||||
(defn- translate-blend-mode
|
||||
[blend-mode]
|
||||
(case blend-mode
|
||||
|
@ -237,6 +250,7 @@
|
|||
(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)
|
||||
selrect (dm/get-prop shape :selrect)
|
||||
rotation (dm/get-prop shape :rotation)
|
||||
|
@ -245,7 +259,8 @@
|
|||
children (dm/get-prop shape :shapes)
|
||||
blend-mode (dm/get-prop shape :blend-mode)
|
||||
opacity (dm/get-prop shape :opacity)
|
||||
hidden (dm/get-prop shape :hidden)]
|
||||
hidden (dm/get-prop shape :hidden)
|
||||
content (dm/get-prop shape :content)]
|
||||
|
||||
(use-shape id)
|
||||
(set-shape-selrect selrect)
|
||||
|
@ -255,6 +270,7 @@
|
|||
(set-shape-children children)
|
||||
(set-shape-opacity opacity)
|
||||
(set-shape-hidden hidden)
|
||||
(when (and (some? content) (= type :path)) (set-shape-path-content content))
|
||||
(let [pending-fills (doall (set-shape-fills fills))]
|
||||
(recur (inc index) (into pending pending-fills))))
|
||||
pending))]
|
||||
|
@ -282,9 +298,9 @@
|
|||
|
||||
(defn- debug-flags
|
||||
[]
|
||||
(let [debug-options 0]
|
||||
(when (dbg/enabled? :wasm-viewbox)
|
||||
(bit-or debug-options 2r00000000000000000000000000000001))))
|
||||
(cond-> 0
|
||||
(dbg/enabled? :wasm-viewbox)
|
||||
(bit-or 2r00000000000000000000000000000001)))
|
||||
|
||||
(defn assign-canvas
|
||||
[canvas]
|
||||
|
|
72
frontend/src/app/render_wasm/path.cljs
Normal file
72
frontend/src/app/render_wasm/path.cljs
Normal file
|
@ -0,0 +1,72 @@
|
|||
(ns app.render-wasm.path)
|
||||
|
||||
(def command-size 28)
|
||||
|
||||
#_(defn content->buffer
|
||||
"Converts the path content into binary format."
|
||||
[content]
|
||||
(let [total (count content)
|
||||
buffer (new js/ArrayBuffer (* total command-size))
|
||||
dview (new js/DataView buffer)]
|
||||
(loop [index 0]
|
||||
(when (< index total)
|
||||
(let [segment (nth content index)
|
||||
offset (* index command-size)]
|
||||
(case (:command segment)
|
||||
:move-to
|
||||
(let [{:keys [x y]} (:params segment)]
|
||||
(.setUint16 dview (+ offset 0) 1)
|
||||
(.setFloat32 dview (+ offset 20) x)
|
||||
(.setFloat32 dview (+ offset 24) y))
|
||||
:line-to
|
||||
(let [{:keys [x y]} (:params segment)]
|
||||
(.setUint16 dview (+ offset 0) 2)
|
||||
(.setFloat32 dview (+ offset 20) x)
|
||||
(.setFloat32 dview (+ offset 24) y))
|
||||
:curve-to
|
||||
(let [{:keys [c1x c1y c2x c2y x y]} (:params segment)]
|
||||
(.setUint16 dview (+ offset 0) 3)
|
||||
(.setFloat32 dview (+ offset 4) c1x)
|
||||
(.setFloat32 dview (+ offset 8) c1y)
|
||||
(.setFloat32 dview (+ offset 12) c2x)
|
||||
(.setFloat32 dview (+ offset 16) c2y)
|
||||
(.setFloat32 dview (+ offset 20) x)
|
||||
(.setFloat32 dview (+ offset 24) y))
|
||||
|
||||
:close-path
|
||||
(.setUint16 dview (+ offset 0) 4))
|
||||
(recur (inc index)))))
|
||||
buffer))
|
||||
|
||||
#_(defn buffer->content
|
||||
"Converts the a buffer to a path content vector"
|
||||
[buffer]
|
||||
(assert (instance? js/ArrayBuffer buffer) "expected ArrayBuffer instance")
|
||||
(let [total (/ (.-byteLength buffer) command-size)
|
||||
dview (new js/DataView buffer)]
|
||||
(loop [index 0
|
||||
result []]
|
||||
(if (< index total)
|
||||
(let [offset (* index command-size)
|
||||
type (.getUint16 dview (+ offset 0))
|
||||
command (case type
|
||||
1 :move-to
|
||||
2 :line-to
|
||||
3 :curve-to
|
||||
4 :close-path)
|
||||
params (case type
|
||||
1 {:x (.getFloat32 dview (+ offset 20))
|
||||
:y (.getFloat32 dview (+ offset 24))}
|
||||
2 {:x (.getFloat32 dview (+ offset 20))
|
||||
:y (.getFloat32 dview (+ offset 24))}
|
||||
3 {:c1x (.getFloat32 dview (+ offset 4))
|
||||
:c1y (.getFloat32 dview (+ offset 8))
|
||||
:c2x (.getFloat32 dview (+ offset 12))
|
||||
:c2y (.getFloat32 dview (+ offset 16))
|
||||
:x (.getFloat32 dview (+ offset 20))
|
||||
:y (.getFloat32 dview (+ offset 24))}
|
||||
4 {})]
|
||||
(recur (inc index)
|
||||
(conj result {:command command
|
||||
:params params})))
|
||||
result))))
|
|
@ -10,6 +10,7 @@
|
|||
[app.common.types.shape :as shape]
|
||||
;; [app.common.svg.path :as path]
|
||||
[app.render-wasm.api :as api]
|
||||
[app.render-wasm.path :as path]
|
||||
[clojure.core :as c]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
|
@ -120,6 +121,7 @@
|
|||
:opacity (api/set-shape-opacity v)
|
||||
:hidden (api/set-shape-hidden v)
|
||||
:shapes (api/set-shape-children v)
|
||||
:content (api/set-shape-path-content v)
|
||||
nil)
|
||||
;; when something synced with wasm
|
||||
;; is modified, we need to request
|
||||
|
|
|
@ -103,16 +103,15 @@ pub extern "C" fn use_shape(a: u32, b: u32, c: u32, d: u32) {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn set_shape_selrect(left: f32, top: f32, right: f32, bottom: f32) {
|
||||
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");
|
||||
|
||||
if let Some(shape) = state.current_shape() {
|
||||
shape.selrect.set_ltrb(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn set_shape_rotation(rotation: f32) {
|
||||
pub extern "C" fn set_shape_rotation(rotation: f32) {
|
||||
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
|
||||
if let Some(shape) = state.current_shape() {
|
||||
shape.rotation = rotation;
|
||||
|
@ -120,7 +119,7 @@ pub unsafe extern "C" fn set_shape_rotation(rotation: f32) {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn set_shape_transform(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32) {
|
||||
pub extern "C" fn set_shape_transform(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32) {
|
||||
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
|
||||
if let Some(shape) = state.current_shape() {
|
||||
shape.transform.a = a;
|
||||
|
@ -271,6 +270,24 @@ pub extern "C" fn set_shape_hidden(hidden: bool) {
|
|||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn set_shape_path_content(n_segments: u32) {
|
||||
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
|
||||
|
||||
if let Some(shape) = state.current_shape() {
|
||||
let len = n_segments as usize;
|
||||
|
||||
unsafe {
|
||||
let buffer = Vec::<shapes::RawPathData>::from_raw_parts(
|
||||
mem::buffer_ptr() as *mut shapes::RawPathData,
|
||||
len,
|
||||
len,
|
||||
);
|
||||
mem::free_bytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
init_gl();
|
||||
}
|
||||
|
|
|
@ -5,9 +5,11 @@ use uuid::Uuid;
|
|||
mod blend;
|
||||
mod fills;
|
||||
mod images;
|
||||
mod paths;
|
||||
pub use blend::*;
|
||||
pub use fills::*;
|
||||
pub use images::*;
|
||||
pub use paths::*;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Kind {
|
||||
|
|
4
render-wasm/src/shapes/paths.rs
Normal file
4
render-wasm/src/shapes/paths.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
#[derive(Debug)]
|
||||
pub struct RawPathData {
|
||||
data: [u8; 28],
|
||||
}
|
Loading…
Add table
Reference in a new issue