mirror of
https://github.com/penpot/penpot.git
synced 2026-09-14 07:59:36 +00:00
Merge pull request #7103 from penpot/niwinz-develop-modifiers-enhacements
♻️ Sanitize heap write and read operations
This commit is contained in:
commit
029a9674ca
@ -127,6 +127,12 @@
|
|||||||
(finally
|
(finally
|
||||||
(.order ~target ByteOrder/LITTLE_ENDIAN))))))
|
(.order ~target ByteOrder/LITTLE_ENDIAN))))))
|
||||||
|
|
||||||
|
(defn wrap
|
||||||
|
[data]
|
||||||
|
#?(:clj (let [buffer (ByteBuffer/wrap ^bytes data)]
|
||||||
|
(.order buffer ByteOrder/LITTLE_ENDIAN))
|
||||||
|
:cljs (new js/DataView (.-buffer ^js data))))
|
||||||
|
|
||||||
(defn allocate
|
(defn allocate
|
||||||
[size]
|
[size]
|
||||||
#?(:clj (let [buffer (ByteBuffer/allocate (int size))]
|
#?(:clj (let [buffer (ByteBuffer/allocate (int size))]
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
#?(:clj (set! *warn-on-reflection* true))
|
#?(:clj (set! *warn-on-reflection* true))
|
||||||
|
|
||||||
(def ^:const SEGMENT-U8-SIZE 28)
|
(def ^:const SEGMENT-U8-SIZE 28)
|
||||||
|
(def ^:const SEGMENT-U32-SIZE (/ SEGMENT-U8-SIZE 4))
|
||||||
|
|
||||||
(defprotocol IPathData
|
(defprotocol IPathData
|
||||||
(-write-to [_ buffer offset] "write the content to the specified buffer")
|
(-write-to [_ buffer offset] "write the content to the specified buffer")
|
||||||
|
|||||||
@ -530,25 +530,24 @@
|
|||||||
nil)))))))
|
nil)))))))
|
||||||
modif-tree))
|
modif-tree))
|
||||||
|
|
||||||
|
|
||||||
|
(def ^:private xf:parse-geometry-modifier
|
||||||
|
(let [default-transform (gmt/matrix)]
|
||||||
|
(keep (fn [[id data]]
|
||||||
|
(cond
|
||||||
|
(= id uuid/zero)
|
||||||
|
nil
|
||||||
|
|
||||||
|
(ctm/has-geometry? (:modifiers data))
|
||||||
|
(d/vec2 id (ctm/modifiers->transform (:modifiers data)))
|
||||||
|
|
||||||
|
;; Unit matrix is used for reflowing
|
||||||
|
:else
|
||||||
|
(d/vec2 id default-transform))))))
|
||||||
|
|
||||||
(defn- parse-geometry-modifiers
|
(defn- parse-geometry-modifiers
|
||||||
[modif-tree]
|
[modif-tree]
|
||||||
(into
|
(into [] xf:parse-geometry-modifier modif-tree))
|
||||||
[]
|
|
||||||
(keep
|
|
||||||
(fn [[id data]]
|
|
||||||
(cond
|
|
||||||
(= id uuid/zero)
|
|
||||||
nil
|
|
||||||
|
|
||||||
(ctm/has-geometry? (:modifiers data))
|
|
||||||
{:id id
|
|
||||||
:transform (ctm/modifiers->transform (:modifiers data))}
|
|
||||||
|
|
||||||
;; Unit matrix is used for reflowing
|
|
||||||
:else
|
|
||||||
{:id id
|
|
||||||
:transform (gmt/matrix)})))
|
|
||||||
modif-tree))
|
|
||||||
|
|
||||||
(defn- extract-property-changes
|
(defn- extract-property-changes
|
||||||
[modif-tree]
|
[modif-tree]
|
||||||
@ -573,6 +572,8 @@
|
|||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc state :workspace-wasm-modifiers modifiers))))
|
(assoc state :workspace-wasm-modifiers modifiers))))
|
||||||
|
|
||||||
|
(def ^:private xf:map-key (map key))
|
||||||
|
|
||||||
#_:clj-kondo/ignore
|
#_:clj-kondo/ignore
|
||||||
(defn set-wasm-modifiers
|
(defn set-wasm-modifiers
|
||||||
[modif-tree & {:keys [ignore-constraints ignore-snap-pixel]
|
[modif-tree & {:keys [ignore-constraints ignore-snap-pixel]
|
||||||
@ -591,16 +592,17 @@
|
|||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(wasm.api/clean-modifiers)
|
(wasm.api/clean-modifiers)
|
||||||
(let [prev-wasm-props (:prev-wasm-props state)
|
(let [prev-wasm-props (:prev-wasm-props state)
|
||||||
wasm-props (:wasm-props state)
|
wasm-props (:wasm-props state)
|
||||||
objects (dsh/lookup-page-objects state)
|
objects (dsh/lookup-page-objects state)
|
||||||
pixel-precision false]
|
pixel-precision false]
|
||||||
(set-wasm-props! objects prev-wasm-props wasm-props)
|
(set-wasm-props! objects prev-wasm-props wasm-props)
|
||||||
(let [structure-entries (parse-structure-modifiers modif-tree)]
|
(let [structure-entries (parse-structure-modifiers modif-tree)]
|
||||||
(wasm.api/set-structure-modifiers structure-entries)
|
(wasm.api/set-structure-modifiers structure-entries)
|
||||||
(let [geometry-entries (parse-geometry-modifiers modif-tree)
|
(let [geometry-entries (parse-geometry-modifiers modif-tree)
|
||||||
modifiers (wasm.api/propagate-modifiers geometry-entries pixel-precision)]
|
modifiers (wasm.api/propagate-modifiers geometry-entries pixel-precision)]
|
||||||
(wasm.api/set-modifiers modifiers)
|
(wasm.api/set-modifiers modifiers)
|
||||||
(let [selrect (wasm.api/get-selection-rect (->> geometry-entries (map :id)))]
|
(let [ids (into [] xf:map-key geometry-entries)
|
||||||
|
selrect (wasm.api/get-selection-rect ids)]
|
||||||
(rx/of (set-temporary-selrect selrect)
|
(rx/of (set-temporary-selrect selrect)
|
||||||
(set-temporary-modifiers modifiers)))))))))
|
(set-temporary-modifiers modifiers)))))))))
|
||||||
|
|
||||||
@ -649,16 +651,14 @@
|
|||||||
;; way we don't have to check all the attributes
|
;; way we don't have to check all the attributes
|
||||||
(assoc :attrs transform-attrs))
|
(assoc :attrs transform-attrs))
|
||||||
|
|
||||||
geometry-entries (parse-geometry-modifiers modif-tree)
|
geometry-entries
|
||||||
|
(parse-geometry-modifiers modif-tree)
|
||||||
|
|
||||||
snap-pixel?
|
snap-pixel?
|
||||||
(and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))
|
(and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))
|
||||||
|
|
||||||
transforms
|
transforms
|
||||||
(into
|
(into {} (wasm.api/propagate-modifiers geometry-entries snap-pixel?))
|
||||||
{}
|
|
||||||
(map (fn [{:keys [id transform]}] [id transform]))
|
|
||||||
(wasm.api/propagate-modifiers geometry-entries snap-pixel?))
|
|
||||||
|
|
||||||
modif-tree
|
modif-tree
|
||||||
(propagate-structure-modifiers modif-tree (dsh/lookup-page-objects state))
|
(propagate-structure-modifiers modif-tree (dsh/lookup-page-objects state))
|
||||||
@ -709,10 +709,9 @@
|
|||||||
(gm/set-objects-modifiers objects))
|
(gm/set-objects-modifiers objects))
|
||||||
|
|
||||||
modifiers
|
modifiers
|
||||||
(->> modif-tree
|
(mapv (fn [[id {:keys [modifiers]}]]
|
||||||
(map (fn [[id {:keys [modifiers]}]]
|
(d/vec2 id (ctm/modifiers->transform modifiers)))
|
||||||
{:id id
|
modif-tree)]
|
||||||
:transform (ctm/modifiers->transform modifiers)})))]
|
|
||||||
|
|
||||||
(wasm.api/set-modifiers modifiers))))))
|
(wasm.api/set-modifiers modifiers))))))
|
||||||
|
|
||||||
|
|||||||
@ -10,8 +10,6 @@
|
|||||||
["react-dom/server" :as rds]
|
["react-dom/server" :as rds]
|
||||||
[app.common.data :as d :refer [not-empty?]]
|
[app.common.data :as d :refer [not-empty?]]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.matrix :as gmt]
|
|
||||||
[app.common.geom.point :as gpt]
|
|
||||||
[app.common.types.fills :as types.fills]
|
[app.common.types.fills :as types.fills]
|
||||||
[app.common.types.fills.impl :as types.fills.impl]
|
[app.common.types.fills.impl :as types.fills.impl]
|
||||||
[app.common.types.path :as path]
|
[app.common.types.path :as path]
|
||||||
@ -27,6 +25,7 @@
|
|||||||
[app.render-wasm.deserializers :as dr]
|
[app.render-wasm.deserializers :as dr]
|
||||||
[app.render-wasm.helpers :as h]
|
[app.render-wasm.helpers :as h]
|
||||||
[app.render-wasm.mem :as mem]
|
[app.render-wasm.mem :as mem]
|
||||||
|
[app.render-wasm.mem.heap32 :as mem.h32]
|
||||||
[app.render-wasm.performance :as perf]
|
[app.render-wasm.performance :as perf]
|
||||||
[app.render-wasm.serializers :as sr]
|
[app.render-wasm.serializers :as sr]
|
||||||
[app.render-wasm.serializers.color :as sr-clr]
|
[app.render-wasm.serializers.color :as sr-clr]
|
||||||
@ -41,39 +40,17 @@
|
|||||||
|
|
||||||
(def use-dpr? (contains? cf/flags :render-wasm-dpr))
|
(def use-dpr? (contains? cf/flags :render-wasm-dpr))
|
||||||
|
|
||||||
;;
|
|
||||||
;; List of common entry sizes.
|
|
||||||
;;
|
|
||||||
;; All of these entries are in bytes so we need to adjust
|
|
||||||
;; these values to work with TypedArrays of 32 bits.
|
|
||||||
;;
|
|
||||||
(def ^:const UUID-U8-SIZE 16)
|
(def ^:const UUID-U8-SIZE 16)
|
||||||
(def ^:const UUID-U32-SIZE (/ UUID-U8-SIZE 4))
|
(def ^:const UUID-U32-SIZE (/ UUID-U8-SIZE 4))
|
||||||
|
|
||||||
(def ^:const MODIFIER-U8-SIZE 40)
|
(def ^:const MODIFIER-U8-SIZE 40)
|
||||||
|
(def ^:const MODIFIER-U32-SIZE (/ MODIFIER-U8-SIZE 4))
|
||||||
(def ^:const MODIFIER-TRANSFORM-U8-OFFSET-SIZE 16)
|
(def ^:const MODIFIER-TRANSFORM-U8-OFFSET-SIZE 16)
|
||||||
|
|
||||||
(def ^:const GRID-LAYOUT-ROW-U8-SIZE 5)
|
(def ^:const GRID-LAYOUT-ROW-U8-SIZE 5)
|
||||||
(def ^:const GRID-LAYOUT-COLUMN-U8-SIZE 5)
|
(def ^:const GRID-LAYOUT-COLUMN-U8-SIZE 5)
|
||||||
(def ^:const GRID-LAYOUT-CELL-U8-SIZE 37)
|
(def ^:const GRID-LAYOUT-CELL-U8-SIZE 37)
|
||||||
|
|
||||||
(defn modifier-get-entries-size
|
|
||||||
"Returns the list of a modifier list in bytes"
|
|
||||||
[modifiers]
|
|
||||||
(mem/get-list-size modifiers MODIFIER-U8-SIZE))
|
|
||||||
|
|
||||||
(defn grid-layout-get-row-entries-size
|
|
||||||
[rows]
|
|
||||||
(mem/get-list-size rows GRID-LAYOUT-ROW-U8-SIZE))
|
|
||||||
|
|
||||||
(defn grid-layout-get-column-entries-size
|
|
||||||
[columns]
|
|
||||||
(mem/get-list-size columns GRID-LAYOUT-COLUMN-U8-SIZE))
|
|
||||||
|
|
||||||
(defn grid-layout-get-cell-entries-size
|
|
||||||
[cells]
|
|
||||||
(mem/get-list-size cells GRID-LAYOUT-CELL-U8-SIZE))
|
|
||||||
|
|
||||||
(def dpr
|
(def dpr
|
||||||
(if use-dpr? (if (exists? js/window) js/window.devicePixelRatio 1.0) 1.0))
|
(if use-dpr? (if (exists? js/window) js/window.devicePixelRatio 1.0) 1.0))
|
||||||
|
|
||||||
@ -175,20 +152,20 @@
|
|||||||
|
|
||||||
(defn set-shape-children
|
(defn set-shape-children
|
||||||
[children]
|
[children]
|
||||||
(let [heap (mem/get-heap-u32)
|
|
||||||
length (count children)]
|
|
||||||
(perf/begin-measure "set-shape-children")
|
|
||||||
(when (pos? length)
|
|
||||||
(let [offset (mem/alloc->offset-32 (* UUID-U8-SIZE length))]
|
|
||||||
(reduce (fn [offset id]
|
|
||||||
(sr/heapu32-set-uuid id heap offset)
|
|
||||||
(+ offset UUID-U32-SIZE))
|
|
||||||
offset
|
|
||||||
children)))
|
|
||||||
|
|
||||||
(let [result (h/call wasm/internal-module "_set_children")]
|
(when-not ^boolean (empty? children)
|
||||||
(perf/end-measure "set-shape-children")
|
(perf/begin-measure "set-shape-children")
|
||||||
result)))
|
(let [heap (mem/get-heap-u32)
|
||||||
|
size (mem/get-alloc-size children UUID-U8-SIZE)
|
||||||
|
offset (mem/alloc->offset-32 size)]
|
||||||
|
(reduce (fn [offset id]
|
||||||
|
(mem.h32/write-uuid offset heap id))
|
||||||
|
offset
|
||||||
|
children)
|
||||||
|
|
||||||
|
(let [result (h/call wasm/internal-module "_set_children")]
|
||||||
|
(perf/end-measure "set-shape-children")
|
||||||
|
result))))
|
||||||
|
|
||||||
(defn- get-string-length
|
(defn- get-string-length
|
||||||
[string]
|
[string]
|
||||||
@ -396,31 +373,38 @@
|
|||||||
(h/call wasm/internal-module "_set_shape_blur" type hidden value)))
|
(h/call wasm/internal-module "_set_shape_blur" type hidden value)))
|
||||||
|
|
||||||
(defn set-shape-corners
|
(defn set-shape-corners
|
||||||
[corners]
|
[shape]
|
||||||
(let [r1 (or (get corners 0) 0)
|
(let [r1 (dm/get-prop shape :r1)]
|
||||||
r2 (or (get corners 1) 0)
|
(when (some? r1)
|
||||||
r3 (or (get corners 2) 0)
|
(let [r2 (dm/get-prop shape :r2)
|
||||||
r4 (or (get corners 3) 0)]
|
r3 (dm/get-prop shape :r3)
|
||||||
(h/call wasm/internal-module "_set_shape_corners" r1 r2 r3 r4)))
|
r4 (dm/get-prop shape :r4)]
|
||||||
|
(h/call wasm/internal-module "_set_shape_corners"
|
||||||
|
(d/nilv r1 0)
|
||||||
|
(d/nilv r2 0)
|
||||||
|
(d/nilv r3 0)
|
||||||
|
(d/nilv r4 0))))))
|
||||||
|
|
||||||
(defn set-flex-layout
|
(defn set-flex-layout
|
||||||
[shape]
|
[shape]
|
||||||
(let [dir (-> (or (dm/get-prop shape :layout-flex-dir) :row) sr/translate-layout-flex-dir)
|
(let [dir (-> (get shape :layout-flex-dir :row)
|
||||||
gap (dm/get-prop shape :layout-gap)
|
(sr/translate-layout-flex-dir))
|
||||||
row-gap (or (dm/get-prop gap :row-gap) 0)
|
gap (get shape :layout-gap)
|
||||||
column-gap (or (dm/get-prop gap :column-gap) 0)
|
row-gap (get gap :row-gap 0)
|
||||||
|
column-gap (get gap :column-gap 0)
|
||||||
|
|
||||||
align-items (-> (or (dm/get-prop shape :layout-align-items) :start) sr/translate-layout-align-items)
|
align-items (-> (get shape :layout-align-items) sr/translate-layout-align-items)
|
||||||
align-content (-> (or (dm/get-prop shape :layout-align-content) :stretch) sr/translate-layout-align-content)
|
align-content (-> (get shape :layout-align-content) sr/translate-layout-align-content)
|
||||||
justify-items (-> (or (dm/get-prop shape :layout-justify-items) :start) sr/translate-layout-justify-items)
|
justify-items (-> (get shape :layout-justify-items) sr/translate-layout-justify-items)
|
||||||
justify-content (-> (or (dm/get-prop shape :layout-justify-content) :stretch) sr/translate-layout-justify-content)
|
justify-content (-> (get shape :layout-justify-content) sr/translate-layout-justify-content)
|
||||||
wrap-type (-> (or (dm/get-prop shape :layout-wrap-type) :nowrap) sr/translate-layout-wrap-type)
|
wrap-type (-> (get shape :layout-wrap-type) sr/translate-layout-wrap-type)
|
||||||
|
|
||||||
|
padding (get shape :layout-padding)
|
||||||
|
padding-top (get padding :p1 0)
|
||||||
|
padding-right (get padding :p2 0)
|
||||||
|
padding-bottom (get padding :p3 0)
|
||||||
|
padding-left (get padding :p4 0)]
|
||||||
|
|
||||||
padding (dm/get-prop shape :layout-padding)
|
|
||||||
padding-top (or (dm/get-prop padding :p1) 0)
|
|
||||||
padding-right (or (dm/get-prop padding :p2) 0)
|
|
||||||
padding-bottom (or (dm/get-prop padding :p3) 0)
|
|
||||||
padding-left (or (dm/get-prop padding :p4) 0)]
|
|
||||||
(h/call wasm/internal-module
|
(h/call wasm/internal-module
|
||||||
"_set_flex_layout_data"
|
"_set_flex_layout_data"
|
||||||
dir
|
dir
|
||||||
@ -438,21 +422,22 @@
|
|||||||
|
|
||||||
(defn set-grid-layout-data
|
(defn set-grid-layout-data
|
||||||
[shape]
|
[shape]
|
||||||
(let [dir (-> (or (dm/get-prop shape :layout-grid-dir) :row) sr/translate-layout-grid-dir)
|
(let [dir (-> (get shape :layout-grid-dir :row)
|
||||||
gap (dm/get-prop shape :layout-gap)
|
(sr/translate-layout-grid-dir))
|
||||||
row-gap (or (dm/get-prop gap :row-gap) 0)
|
gap (get shape :layout-gap)
|
||||||
column-gap (or (dm/get-prop gap :column-gap) 0)
|
row-gap (get gap :row-gap 0)
|
||||||
|
column-gap (get gap :column-gap 0)
|
||||||
|
|
||||||
align-items (-> (or (dm/get-prop shape :layout-align-items) :start) sr/translate-layout-align-items)
|
align-items (-> (get shape :layout-align-items) sr/translate-layout-align-items)
|
||||||
align-content (-> (or (dm/get-prop shape :layout-align-content) :stretch) sr/translate-layout-align-content)
|
align-content (-> (get shape :layout-align-content) sr/translate-layout-align-content)
|
||||||
justify-items (-> (or (dm/get-prop shape :layout-justify-items) :start) sr/translate-layout-justify-items)
|
justify-items (-> (get shape :layout-justify-items) sr/translate-layout-justify-items)
|
||||||
justify-content (-> (or (dm/get-prop shape :layout-justify-content) :stretch) sr/translate-layout-justify-content)
|
justify-content (-> (get shape :layout-justify-content) sr/translate-layout-justify-content)
|
||||||
|
|
||||||
padding (dm/get-prop shape :layout-padding)
|
padding (get shape :layout-padding)
|
||||||
padding-top (or (dm/get-prop padding :p1) 0)
|
padding-top (get padding :p1 0)
|
||||||
padding-right (or (dm/get-prop padding :p2) 0)
|
padding-right (get padding :p2 0)
|
||||||
padding-bottom (or (dm/get-prop padding :p3) 0)
|
padding-bottom (get padding :p3 0)
|
||||||
padding-left (or (dm/get-prop padding :p4) 0)]
|
padding-left (get padding :p4 0)]
|
||||||
|
|
||||||
(h/call wasm/internal-module
|
(h/call wasm/internal-module
|
||||||
"_set_grid_layout_data"
|
"_set_grid_layout_data"
|
||||||
@ -470,53 +455,51 @@
|
|||||||
|
|
||||||
(defn set-grid-layout-rows
|
(defn set-grid-layout-rows
|
||||||
[entries]
|
[entries]
|
||||||
(let [size (grid-layout-get-row-entries-size entries)
|
(let [size (mem/get-alloc-size entries GRID-LAYOUT-ROW-U8-SIZE)
|
||||||
offset (mem/alloc size)
|
offset (mem/alloc size)
|
||||||
|
dview (mem/get-data-view)]
|
||||||
|
|
||||||
|
(reduce (fn [offset {:keys [type value]}]
|
||||||
|
;; NOTE: because of the nature of the grid row data
|
||||||
|
;; structure memory layout we can't use fully 32 bits
|
||||||
|
;; alligned writes, so for heteregeneus writes we use
|
||||||
|
;; the buffer abstraction (DataView) for perform
|
||||||
|
;; surgical writes.
|
||||||
|
(mem/write-u8 dview (+ offset 0) (sr/translate-grid-track-type type))
|
||||||
|
(mem/write-f32 dview (+ offset 1) value)
|
||||||
|
(+ offset GRID-LAYOUT-ROW-U8-SIZE))
|
||||||
|
offset
|
||||||
|
entries)
|
||||||
|
|
||||||
heap
|
|
||||||
(js/Uint8Array.
|
|
||||||
(.-buffer (mem/get-heap-u8))
|
|
||||||
offset
|
|
||||||
size)]
|
|
||||||
(loop [entries (seq entries)
|
|
||||||
current-offset 0]
|
|
||||||
(when-not (empty? entries)
|
|
||||||
(let [{:keys [type value]} (first entries)]
|
|
||||||
(.set heap (sr/u8 (sr/translate-grid-track-type type)) (+ current-offset 0))
|
|
||||||
(.set heap (sr/f32->u8 value) (+ current-offset 1))
|
|
||||||
(recur (rest entries) (+ current-offset GRID-LAYOUT-ROW-U8-SIZE)))))
|
|
||||||
(h/call wasm/internal-module "_set_grid_rows")))
|
(h/call wasm/internal-module "_set_grid_rows")))
|
||||||
|
|
||||||
(defn set-grid-layout-columns
|
(defn set-grid-layout-columns
|
||||||
[entries]
|
[entries]
|
||||||
(let [size (grid-layout-get-column-entries-size entries)
|
(let [size (mem/get-alloc-size entries GRID-LAYOUT-COLUMN-U8-SIZE)
|
||||||
offset (mem/alloc size)
|
offset (mem/alloc size)
|
||||||
|
dview (mem/get-data-view)]
|
||||||
|
|
||||||
|
(reduce (fn [offset {:keys [type value]}]
|
||||||
|
;; NOTE: because of the nature of the grid column data
|
||||||
|
;; structure memory layout we can't use fully 32 bits
|
||||||
|
;; alligned writes, so for heteregeneus writes we use
|
||||||
|
;; the buffer abstraction (DataView) for perform
|
||||||
|
;; surgical writes.
|
||||||
|
(mem/write-u8 dview (+ offset 0) (sr/translate-grid-track-type type))
|
||||||
|
(mem/write-f32 dview (+ offset 1) value)
|
||||||
|
(+ offset GRID-LAYOUT-COLUMN-U8-SIZE))
|
||||||
|
offset
|
||||||
|
entries)
|
||||||
|
|
||||||
heap
|
|
||||||
(js/Uint8Array.
|
|
||||||
(.-buffer (mem/get-heap-u8))
|
|
||||||
offset
|
|
||||||
size)]
|
|
||||||
(loop [entries (seq entries)
|
|
||||||
current-offset 0]
|
|
||||||
(when-not (empty? entries)
|
|
||||||
(let [{:keys [type value]} (first entries)]
|
|
||||||
(.set heap (sr/u8 (sr/translate-grid-track-type type)) (+ current-offset 0))
|
|
||||||
(.set heap (sr/f32->u8 value) (+ current-offset 1))
|
|
||||||
(recur (rest entries) (+ current-offset GRID-LAYOUT-COLUMN-U8-SIZE)))))
|
|
||||||
(h/call wasm/internal-module "_set_grid_columns")))
|
(h/call wasm/internal-module "_set_grid_columns")))
|
||||||
|
|
||||||
(defn set-grid-layout-cells
|
(defn set-grid-layout-cells
|
||||||
[cells]
|
[cells]
|
||||||
(let [entries (vals cells)
|
(let [entries (vals cells)
|
||||||
size (grid-layout-get-cell-entries-size entries)
|
size (mem/get-alloc-size cells GRID-LAYOUT-CELL-U8-SIZE)
|
||||||
offset (mem/alloc size)
|
offset (mem/alloc size)
|
||||||
|
heap (-> (mem/get-heap-u8)
|
||||||
heap
|
(mem/view offset size))]
|
||||||
(js/Uint8Array.
|
|
||||||
(.-buffer (mem/get-heap-u8))
|
|
||||||
offset
|
|
||||||
size)]
|
|
||||||
|
|
||||||
(loop [entries (seq entries)
|
(loop [entries (seq entries)
|
||||||
current-offset 0]
|
current-offset 0]
|
||||||
@ -628,7 +611,7 @@
|
|||||||
(h/call wasm/internal-module "_add_shape_shadow" rgba blur spread x y (sr/translate-shadow-style style) hidden)
|
(h/call wasm/internal-module "_add_shape_shadow" rgba blur spread x y (sr/translate-shadow-style style) hidden)
|
||||||
(recur (inc index)))))))
|
(recur (inc index)))))))
|
||||||
|
|
||||||
(declare propagate-apply)
|
;; (declare propagate-apply)
|
||||||
|
|
||||||
(defn set-shape-text-content
|
(defn set-shape-text-content
|
||||||
[shape-id content]
|
[shape-id content]
|
||||||
@ -722,11 +705,6 @@
|
|||||||
bool-type (dm/get-prop shape :bool-type)
|
bool-type (dm/get-prop shape :bool-type)
|
||||||
grow-type (dm/get-prop shape :grow-type)
|
grow-type (dm/get-prop shape :grow-type)
|
||||||
blur (dm/get-prop shape :blur)
|
blur (dm/get-prop shape :blur)
|
||||||
corners (when (some? (dm/get-prop shape :r1))
|
|
||||||
[(dm/get-prop shape :r1)
|
|
||||||
(dm/get-prop shape :r2)
|
|
||||||
(dm/get-prop shape :r3)
|
|
||||||
(dm/get-prop shape :r4)])
|
|
||||||
svg-attrs (dm/get-prop shape :svg-attrs)
|
svg-attrs (dm/get-prop shape :svg-attrs)
|
||||||
shadows (dm/get-prop shape :shadow)]
|
shadows (dm/get-prop shape :shadow)]
|
||||||
|
|
||||||
@ -742,6 +720,7 @@
|
|||||||
(set-shape-opacity opacity)
|
(set-shape-opacity opacity)
|
||||||
(set-shape-hidden hidden)
|
(set-shape-hidden hidden)
|
||||||
(set-shape-children children)
|
(set-shape-children children)
|
||||||
|
(set-shape-corners shape)
|
||||||
(when (and (= type :group) masked)
|
(when (and (= type :group) masked)
|
||||||
(set-masked masked))
|
(set-masked masked))
|
||||||
(when (some? blur)
|
(when (some? blur)
|
||||||
@ -756,7 +735,6 @@
|
|||||||
(set-shape-path-content content))
|
(set-shape-path-content content))
|
||||||
(when (and (some? content) (= type :svg-raw))
|
(when (and (some? content) (= type :svg-raw))
|
||||||
(set-shape-svg-raw-content (get-static-markup shape)))
|
(set-shape-svg-raw-content (get-static-markup shape)))
|
||||||
(when (some? corners) (set-shape-corners corners))
|
|
||||||
(when (some? shadows) (set-shape-shadows shadows))
|
(when (some? shadows) (set-shape-shadows shadows))
|
||||||
(when (= type :text)
|
(when (= type :text)
|
||||||
(set-shape-grow-type grow-type))
|
(set-shape-grow-type grow-type))
|
||||||
@ -827,134 +805,90 @@
|
|||||||
|
|
||||||
(defn set-focus-mode
|
(defn set-focus-mode
|
||||||
[entries]
|
[entries]
|
||||||
(let [offset (mem/alloc->offset-32 (* (count entries) 16))
|
(when-not ^boolean (empty? entries)
|
||||||
heapu32 (mem/get-heap-u32)]
|
(let [size (mem/get-alloc-size entries UUID-U8-SIZE)
|
||||||
|
heap (mem/get-heap-u32)
|
||||||
|
offset (mem/alloc->offset-32 size)]
|
||||||
|
|
||||||
(loop [entries (seq entries)
|
(reduce (fn [offset id]
|
||||||
current-offset offset]
|
(mem.h32/write-uuid offset heap id))
|
||||||
(when-not (empty? entries)
|
offset
|
||||||
(let [id (first entries)]
|
entries)
|
||||||
(sr/heapu32-set-uuid id heapu32 current-offset)
|
|
||||||
(recur (rest entries) (+ current-offset (mem/->offset-32 16))))))
|
|
||||||
|
|
||||||
(h/call wasm/internal-module "_set_focus_mode")
|
(h/call wasm/internal-module "_set_focus_mode")
|
||||||
(clear-drawing-cache)
|
(clear-drawing-cache)
|
||||||
(request-render "set-focus-mode")))
|
(request-render "set-focus-mode"))))
|
||||||
|
|
||||||
(defn set-structure-modifiers
|
(defn set-structure-modifiers
|
||||||
[entries]
|
[entries]
|
||||||
(when-not (empty? entries)
|
(when-not ^boolean (empty? entries)
|
||||||
(let [offset (mem/alloc->offset-32 (mem/get-list-size entries 44))
|
(let [size (mem/get-alloc-size entries 44)
|
||||||
|
offset (mem/alloc->offset-32 size)
|
||||||
heapu32 (mem/get-heap-u32)
|
heapu32 (mem/get-heap-u32)
|
||||||
heapf32 (mem/get-heap-f32)]
|
heapf32 (mem/get-heap-f32)]
|
||||||
(loop [entries (seq entries)
|
|
||||||
current-offset offset]
|
|
||||||
(when-not (empty? entries)
|
(reduce (fn [offset {:keys [type parent id index value]}]
|
||||||
(let [{:keys [type parent id index value] :as entry} (first entries)]
|
(-> offset
|
||||||
(sr/heapu32-set-u32 (sr/translate-structure-modifier-type type) heapu32 (+ current-offset 0))
|
(mem.h32/write-u32 heapu32 (sr/translate-structure-modifier-type type))
|
||||||
(sr/heapu32-set-u32 (or index 0) heapu32 (+ current-offset 1))
|
(mem.h32/write-u32 heapu32 (d/nilv index 0))
|
||||||
(sr/heapu32-set-uuid parent heapu32 (+ current-offset 2))
|
(mem.h32/write-uuid heapu32 parent)
|
||||||
(sr/heapu32-set-uuid id heapu32 (+ current-offset 6))
|
(mem.h32/write-uuid heapu32 id)
|
||||||
(aset heapf32 (+ current-offset 10) value)
|
(mem.h32/write-f32 heapf32 value)))
|
||||||
(recur (rest entries) (+ current-offset 11)))))
|
offset
|
||||||
|
entries)
|
||||||
|
|
||||||
(h/call wasm/internal-module "_set_structure_modifiers"))))
|
(h/call wasm/internal-module "_set_structure_modifiers"))))
|
||||||
|
|
||||||
(defn propagate-modifiers
|
(defn propagate-modifiers
|
||||||
[entries pixel-precision]
|
[entries pixel-precision]
|
||||||
(when (d/not-empty? entries)
|
(when-not ^boolean (empty? entries)
|
||||||
(let [offset (mem/alloc->offset-32 (modifier-get-entries-size entries))
|
(let [heapf32 (mem/get-heap-f32)
|
||||||
heapf32 (mem/get-heap-f32)
|
heapu32 (mem/get-heap-u32)
|
||||||
heapu32 (mem/get-heap-u32)]
|
size (mem/get-alloc-size entries MODIFIER-U8-SIZE)
|
||||||
|
offset (mem/alloc->offset-32 size)]
|
||||||
|
|
||||||
(loop [entries (seq entries)
|
(reduce (fn [offset [id transform]]
|
||||||
current-offset offset]
|
(-> offset
|
||||||
(when-not (empty? entries)
|
(mem.h32/write-uuid heapu32 id)
|
||||||
(let [{:keys [id transform]} (first entries)]
|
(mem.h32/write-matrix heapf32 transform)))
|
||||||
(sr/heapu32-set-uuid id heapu32 current-offset)
|
offset
|
||||||
(sr/heapf32-set-matrix transform heapf32 (+ current-offset (mem/->offset-32 MODIFIER-TRANSFORM-U8-OFFSET-SIZE)))
|
entries)
|
||||||
(recur (rest entries) (+ current-offset (mem/->offset-32 MODIFIER-U8-SIZE))))))
|
|
||||||
|
(let [offset (-> (h/call wasm/internal-module "_propagate_modifiers" pixel-precision)
|
||||||
|
(mem/->offset-32))
|
||||||
|
length (aget heapu32 offset)
|
||||||
|
max-offset (+ offset 1 (* length MODIFIER-U32-SIZE))
|
||||||
|
result (loop [result (transient [])
|
||||||
|
offset (inc offset)]
|
||||||
|
(if (< offset max-offset)
|
||||||
|
(let [entry (dr/read-modifier-entry heapu32 heapf32 offset)]
|
||||||
|
(recur (conj! result entry)
|
||||||
|
(+ offset MODIFIER-U32-SIZE)))
|
||||||
|
(persistent! result)))]
|
||||||
|
|
||||||
(let [result-offset (h/call wasm/internal-module "_propagate_modifiers" pixel-precision)
|
|
||||||
heapf32 (mem/get-heap-f32)
|
|
||||||
heapu32 (mem/get-heap-u32)
|
|
||||||
len (aget heapu32 (mem/->offset-32 result-offset))
|
|
||||||
result
|
|
||||||
(->> (range 0 len)
|
|
||||||
(mapv #(dr/heap32->entry heapu32 heapf32 (mem/->offset-32 (+ result-offset 4 (* % MODIFIER-U8-SIZE))))))]
|
|
||||||
(mem/free)
|
(mem/free)
|
||||||
|
|
||||||
result))))
|
result))))
|
||||||
|
|
||||||
(defn propagate-apply
|
|
||||||
[entries pixel-precision]
|
|
||||||
(when (d/not-empty? entries)
|
|
||||||
(let [offset (mem/alloc->offset-32 (modifier-get-entries-size entries))
|
|
||||||
heapf32 (mem/get-heap-f32)
|
|
||||||
heapu32 (mem/get-heap-u32)]
|
|
||||||
|
|
||||||
(loop [entries (seq entries)
|
|
||||||
current-offset offset]
|
|
||||||
(when-not (empty? entries)
|
|
||||||
(let [{:keys [id transform]} (first entries)]
|
|
||||||
(sr/heapu32-set-uuid id heapu32 current-offset)
|
|
||||||
(sr/heapf32-set-matrix transform heapf32 (+ current-offset (mem/->offset-32 MODIFIER-TRANSFORM-U8-OFFSET-SIZE)))
|
|
||||||
(recur (rest entries) (+ current-offset (mem/->offset-32 MODIFIER-U8-SIZE))))))
|
|
||||||
|
|
||||||
(let [offset (h/call wasm/internal-module "_propagate_apply" pixel-precision)
|
|
||||||
heapf32 (mem/get-heap-f32)
|
|
||||||
width (aget heapf32 (mem/->offset-32 (+ offset 0)))
|
|
||||||
height (aget heapf32 (mem/->offset-32 (+ offset 4)))
|
|
||||||
cx (aget heapf32 (mem/->offset-32 (+ offset 8)))
|
|
||||||
cy (aget heapf32 (mem/->offset-32 (+ offset 12)))
|
|
||||||
|
|
||||||
a (aget heapf32 (mem/->offset-32 (+ offset 16)))
|
|
||||||
b (aget heapf32 (mem/->offset-32 (+ offset 20)))
|
|
||||||
c (aget heapf32 (mem/->offset-32 (+ offset 24)))
|
|
||||||
d (aget heapf32 (mem/->offset-32 (+ offset 28)))
|
|
||||||
e (aget heapf32 (mem/->offset-32 (+ offset 32)))
|
|
||||||
f (aget heapf32 (mem/->offset-32 (+ offset 36)))
|
|
||||||
transform (gmt/matrix a b c d e f)]
|
|
||||||
|
|
||||||
(mem/free)
|
|
||||||
(request-render "set-modifiers")
|
|
||||||
|
|
||||||
{:width width
|
|
||||||
:height height
|
|
||||||
:center (gpt/point cx cy)
|
|
||||||
:transform transform}))))
|
|
||||||
|
|
||||||
(defn get-selection-rect
|
(defn get-selection-rect
|
||||||
[entries]
|
[entries]
|
||||||
(when (d/not-empty? entries)
|
|
||||||
(let [offset (mem/alloc->offset-32 (* (count entries) 16))
|
|
||||||
heapu32 (mem/get-heap-u32)]
|
|
||||||
|
|
||||||
(loop [entries (seq entries)
|
(when-not ^boolean (empty? entries)
|
||||||
current-offset offset]
|
(let [size (mem/get-alloc-size entries UUID-U8-SIZE)
|
||||||
(when-not (empty? entries)
|
offset (mem/alloc->offset-32 size)
|
||||||
(let [id (first entries)]
|
heapu32 (mem/get-heap-u32)
|
||||||
(sr/heapu32-set-uuid id heapu32 current-offset)
|
heapf32 (mem/get-heap-f32)]
|
||||||
(recur (rest entries) (+ current-offset (mem/->offset-32 16))))))
|
|
||||||
|
|
||||||
(let [offset (h/call wasm/internal-module "_get_selection_rect")
|
(reduce (fn [offset id]
|
||||||
heap (mem/get-heap-f32)
|
(mem.h32/write-uuid offset heapu32 id))
|
||||||
width (aget heap (mem/->offset-32 (+ offset 0)))
|
offset
|
||||||
height (aget heap (mem/->offset-32 (+ offset 4)))
|
entries)
|
||||||
cx (aget heap (mem/->offset-32 (+ offset 8)))
|
|
||||||
cy (aget heap (mem/->offset-32 (+ offset 12)))
|
|
||||||
a (aget heap (mem/->offset-32 (+ offset 16)))
|
|
||||||
b (aget heap (mem/->offset-32 (+ offset 20)))
|
|
||||||
c (aget heap (mem/->offset-32 (+ offset 24)))
|
|
||||||
d (aget heap (mem/->offset-32 (+ offset 28)))
|
|
||||||
e (aget heap (mem/->offset-32 (+ offset 32)))
|
|
||||||
f (aget heap (mem/->offset-32 (+ offset 36)))]
|
|
||||||
|
|
||||||
|
(let [offset (-> (h/call wasm/internal-module "_get_selection_rect")
|
||||||
|
(mem/->offset-32))
|
||||||
|
result (dr/read-selection-rect heapf32 offset)]
|
||||||
(mem/free)
|
(mem/free)
|
||||||
{:width width
|
result))))
|
||||||
:height height
|
|
||||||
:center (gpt/point cx cy)
|
|
||||||
:transform (gmt/matrix a b c d e f)}))))
|
|
||||||
|
|
||||||
|
|
||||||
(defn set-canvas-background
|
(defn set-canvas-background
|
||||||
[background]
|
[background]
|
||||||
@ -968,22 +902,26 @@
|
|||||||
|
|
||||||
(defn set-modifiers
|
(defn set-modifiers
|
||||||
[modifiers]
|
[modifiers]
|
||||||
(when-not (empty? modifiers)
|
|
||||||
(let [offset (mem/alloc->offset-32 (* MODIFIER-U8-SIZE (count modifiers)))
|
|
||||||
heapu32 (mem/get-heap-u32)
|
|
||||||
heapf32 (mem/get-heap-f32)]
|
|
||||||
|
|
||||||
(loop [entries (seq modifiers)
|
;; We need to ensure efficient operations
|
||||||
current-offset offset]
|
(assert (vector? modifiers) "expected a vector for `set-modifiers`")
|
||||||
(when-not (empty? entries)
|
|
||||||
(let [{:keys [id transform]} (first entries)]
|
|
||||||
(sr/heapu32-set-uuid id heapu32 current-offset)
|
|
||||||
(sr/heapf32-set-matrix transform heapf32 (+ current-offset (mem/->offset-32 MODIFIER-TRANSFORM-U8-OFFSET-SIZE)))
|
|
||||||
(recur (rest entries) (+ current-offset (mem/->offset-32 MODIFIER-U8-SIZE))))))
|
|
||||||
|
|
||||||
(h/call wasm/internal-module "_set_modifiers")
|
(let [length (count modifiers)]
|
||||||
|
(when (pos? length)
|
||||||
|
(let [offset (mem/alloc->offset-32 (* MODIFIER-U8-SIZE length))
|
||||||
|
heapu32 (mem/get-heap-u32)
|
||||||
|
heapf32 (mem/get-heap-f32)]
|
||||||
|
|
||||||
(request-render "set-modifiers"))))
|
(reduce (fn [offset [id transform]]
|
||||||
|
(-> offset
|
||||||
|
(mem.h32/write-uuid heapu32 id)
|
||||||
|
(mem.h32/write-matrix heapf32 transform)))
|
||||||
|
offset
|
||||||
|
modifiers)
|
||||||
|
|
||||||
|
(h/call wasm/internal-module "_set_modifiers")
|
||||||
|
|
||||||
|
(request-render "set-modifiers")))))
|
||||||
|
|
||||||
(defn initialize
|
(defn initialize
|
||||||
[base-objects zoom vbox background]
|
[base-objects zoom vbox background]
|
||||||
@ -1065,41 +1003,42 @@
|
|||||||
(defn shape-to-path
|
(defn shape-to-path
|
||||||
[id]
|
[id]
|
||||||
(use-shape id)
|
(use-shape id)
|
||||||
(let [offset (h/call wasm/internal-module "_current_to_path")
|
(let [offset (-> (h/call wasm/internal-module "_current_to_path")
|
||||||
offset (mem/->offset-32 offset)
|
(mem/->offset-32))
|
||||||
heapu32 (mem/get-heap-u32)
|
heap (mem/get-heap-u32)
|
||||||
|
length (aget heap offset)
|
||||||
length (aget heapu32 offset)
|
data (mem/slice heap
|
||||||
data (mem/slice heapu32
|
(+ offset 1)
|
||||||
(+ offset 1)
|
(* length path.impl/SEGMENT-U32-SIZE))
|
||||||
(+ offset 1 (* length (/ path.impl/SEGMENT-U8-SIZE 4))))
|
|
||||||
content (path/from-bytes data)]
|
content (path/from-bytes data)]
|
||||||
(mem/free)
|
(mem/free)
|
||||||
content))
|
content))
|
||||||
|
|
||||||
|
(defn- calculate-bool*
|
||||||
|
[bool-type]
|
||||||
|
(-> (h/call wasm/internal-module "_calculate_bool" (sr/translate-bool-type bool-type))
|
||||||
|
(mem/->offset-32)))
|
||||||
|
|
||||||
(defn calculate-bool
|
(defn calculate-bool
|
||||||
[bool-type ids]
|
[bool-type ids]
|
||||||
(let [num-ids (count ids)
|
|
||||||
offset (mem/alloc->offset-32 (* UUID-U8-SIZE num-ids))
|
(let [size (mem/get-alloc-size ids UUID-U8-SIZE)
|
||||||
heap (mem/get-heap-u32)]
|
heap (mem/get-heap-u32)
|
||||||
|
offset (mem/alloc->offset-32 size)]
|
||||||
|
|
||||||
(reduce (fn [offset id]
|
(reduce (fn [offset id]
|
||||||
(sr/heapu32-set-uuid id heap offset)
|
(mem.h32/write-uuid offset heap id))
|
||||||
(+ offset UUID-U32-SIZE))
|
|
||||||
offset
|
offset
|
||||||
(rseq ids)))
|
(rseq ids))
|
||||||
|
|
||||||
(let [offset (h/call wasm/internal-module "_calculate_bool" (sr/translate-bool-type bool-type))
|
(let [offset (calculate-bool* bool-type)
|
||||||
offset (mem/->offset-32 offset)
|
length (aget heap offset)
|
||||||
heapu32 (mem/get-heap-u32)
|
data (mem/slice heap
|
||||||
|
(+ offset 1)
|
||||||
length (aget heapu32 offset)
|
(* length path.impl/SEGMENT-U32-SIZE))
|
||||||
data (mem/slice heapu32
|
content (path/from-bytes data)]
|
||||||
(+ offset 1)
|
(mem/free)
|
||||||
(+ offset 1 (* length (/ path.impl/SEGMENT-U8-SIZE 4))))
|
content)))
|
||||||
content (path/from-bytes data)]
|
|
||||||
(mem/free)
|
|
||||||
content))
|
|
||||||
|
|
||||||
(defonce module
|
(defonce module
|
||||||
(delay
|
(delay
|
||||||
|
|||||||
@ -5,25 +5,44 @@
|
|||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
(ns app.render-wasm.deserializers
|
(ns app.render-wasm.deserializers
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
(defn heap32->entry
|
(defn read-modifier-entry
|
||||||
[heapu32 heapf32 offset]
|
[heapu32 heapf32 offset]
|
||||||
(let [id1 (aget heapu32 (+ offset 0))
|
(let [id1 (aget heapu32 (+ offset 0))
|
||||||
id2 (aget heapu32 (+ offset 1))
|
id2 (aget heapu32 (+ offset 1))
|
||||||
id3 (aget heapu32 (+ offset 2))
|
id3 (aget heapu32 (+ offset 2))
|
||||||
id4 (aget heapu32 (+ offset 3))
|
id4 (aget heapu32 (+ offset 3))
|
||||||
|
|
||||||
a (aget heapf32 (+ offset 4))
|
a (aget heapf32 (+ offset 4))
|
||||||
b (aget heapf32 (+ offset 5))
|
b (aget heapf32 (+ offset 5))
|
||||||
c (aget heapf32 (+ offset 6))
|
c (aget heapf32 (+ offset 6))
|
||||||
d (aget heapf32 (+ offset 7))
|
d (aget heapf32 (+ offset 7))
|
||||||
e (aget heapf32 (+ offset 8))
|
e (aget heapf32 (+ offset 8))
|
||||||
f (aget heapf32 (+ offset 9))
|
f (aget heapf32 (+ offset 9))]
|
||||||
|
|
||||||
id (uuid/from-unsigned-parts id1 id2 id3 id4)]
|
(d/vec2 (uuid/from-unsigned-parts id1 id2 id3 id4)
|
||||||
|
(gmt/matrix a b c d e f))))
|
||||||
|
|
||||||
{:id id
|
|
||||||
|
(defn read-selection-rect
|
||||||
|
[heapf32 offset]
|
||||||
|
(let [width (aget heapf32 (+ offset 0))
|
||||||
|
height (aget heapf32 (+ offset 1))
|
||||||
|
cx (aget heapf32 (+ offset 2))
|
||||||
|
cy (aget heapf32 (+ offset 3))
|
||||||
|
a (aget heapf32 (+ offset 4))
|
||||||
|
b (aget heapf32 (+ offset 5))
|
||||||
|
c (aget heapf32 (+ offset 6))
|
||||||
|
d (aget heapf32 (+ offset 7))
|
||||||
|
e (aget heapf32 (+ offset 8))
|
||||||
|
f (aget heapf32 (+ offset 9))]
|
||||||
|
{:width width
|
||||||
|
:height height
|
||||||
|
:center (gpt/point cx cy)
|
||||||
:transform (gmt/matrix a b c d e f)}))
|
:transform (gmt/matrix a b c d e f)}))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
(ns app.render-wasm.mem
|
(ns app.render-wasm.mem
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.buffer :as buf]
|
||||||
[app.render-wasm.helpers :as h]
|
[app.render-wasm.helpers :as h]
|
||||||
[app.render-wasm.wasm :as wasm]))
|
[app.render-wasm.wasm :as wasm]))
|
||||||
|
|
||||||
@ -15,10 +16,12 @@
|
|||||||
;; Divides the value by 4
|
;; Divides the value by 4
|
||||||
(bit-shift-right value 2))
|
(bit-shift-right value 2))
|
||||||
|
|
||||||
(defn get-list-size
|
(defn get-alloc-size
|
||||||
"Returns the size of a list in bytes"
|
"Calculate allocation size for a sequential collection of identical
|
||||||
[list list-item-size]
|
objects of the specified size."
|
||||||
(* list-item-size (count list)))
|
[coll item-size]
|
||||||
|
(assert (counted? coll) "`coll` should be constant time countable")
|
||||||
|
(* item-size (count coll)))
|
||||||
|
|
||||||
(defn alloc
|
(defn alloc
|
||||||
"Allocates an arbitrary amount of bytes (aligned to 4 bytes).
|
"Allocates an arbitrary amount of bytes (aligned to 4 bytes).
|
||||||
@ -61,5 +64,26 @@
|
|||||||
(defn slice
|
(defn slice
|
||||||
"Returns a copy of a portion of a typed array into a new typed array
|
"Returns a copy of a portion of a typed array into a new typed array
|
||||||
object selected from start to end."
|
object selected from start to end."
|
||||||
[heap start end]
|
[heap offset size]
|
||||||
(.slice ^js heap start end))
|
(.slice ^js heap offset (+ offset size)))
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
"Returns a new typed array on the same ArrayBuffer store and with the
|
||||||
|
same element types as for this typed array."
|
||||||
|
[heap offset size]
|
||||||
|
(.subarray ^js heap offset (+ offset size)))
|
||||||
|
|
||||||
|
(defn get-data-view
|
||||||
|
"Returns a heap wrapped in a DataView for surgical write operations"
|
||||||
|
[]
|
||||||
|
(buf/wrap (get-heap-u8)))
|
||||||
|
|
||||||
|
(defn write-u8
|
||||||
|
"Write unsigned int8. Expects a DataView instance"
|
||||||
|
[target offset value]
|
||||||
|
(buf/write-byte target offset value))
|
||||||
|
|
||||||
|
(defn write-f32
|
||||||
|
"Write float32. Expects a DataView instance"
|
||||||
|
[target offset value]
|
||||||
|
(buf/write-float target offset value))
|
||||||
|
|||||||
51
frontend/src/app/render_wasm/mem/heap32.cljs
Normal file
51
frontend/src/app/render_wasm/mem/heap32.cljs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.render-wasm.mem.heap32
|
||||||
|
"A memory write helpers that uses 32 bits addressed offsets."
|
||||||
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
|
(defn write-u32
|
||||||
|
[offset heap value]
|
||||||
|
(assert (instance? js/Uint32Array heap) "expected Uint32Array instance for `heap`")
|
||||||
|
(aset heap offset value)
|
||||||
|
(inc offset))
|
||||||
|
|
||||||
|
(defn write-f32
|
||||||
|
[offset heap value]
|
||||||
|
(assert (instance? js/Float32Array heap) "expected Float32Array instance for `heap`")
|
||||||
|
(aset heap offset value)
|
||||||
|
(inc offset))
|
||||||
|
|
||||||
|
(defn write-uuid
|
||||||
|
"Write a uuid to 32 bits addressed heap and return the offset
|
||||||
|
after write."
|
||||||
|
[offset heap id]
|
||||||
|
(assert (instance? js/Uint32Array heap) "expected Uint32Array instance for `heap`")
|
||||||
|
(let [buffer (uuid/get-u32 id)]
|
||||||
|
(.set heap buffer offset)
|
||||||
|
(+ offset 4)))
|
||||||
|
|
||||||
|
(defn write-matrix
|
||||||
|
"Write a matrix to 32 bits addressed heap and return the offset
|
||||||
|
after write."
|
||||||
|
[offset heap matrix]
|
||||||
|
(assert (instance? js/Float32Array heap) "expected Float32Array instance for `heap`")
|
||||||
|
(let [a (dm/get-prop matrix :a)
|
||||||
|
b (dm/get-prop matrix :b)
|
||||||
|
c (dm/get-prop matrix :c)
|
||||||
|
d (dm/get-prop matrix :d)
|
||||||
|
e (dm/get-prop matrix :e)
|
||||||
|
f (dm/get-prop matrix :f)]
|
||||||
|
(aset heap (+ offset 0) a)
|
||||||
|
(aset heap (+ offset 1) b)
|
||||||
|
(aset heap (+ offset 2) c)
|
||||||
|
(aset heap (+ offset 3) d)
|
||||||
|
(aset heap (+ offset 4) e)
|
||||||
|
(aset heap (+ offset 5) f)
|
||||||
|
(+ offset 6)))
|
||||||
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
(ns app.render-wasm.serializers
|
(ns app.render-wasm.serializers
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[cuerdas.core :as str]))
|
[cuerdas.core :as str]))
|
||||||
|
|
||||||
@ -55,31 +54,6 @@
|
|||||||
(catch :default _e
|
(catch :default _e
|
||||||
[uuid/zero])))
|
[uuid/zero])))
|
||||||
|
|
||||||
(defn heapu32-set-u32
|
|
||||||
[value heap offset]
|
|
||||||
(aset heap offset value))
|
|
||||||
|
|
||||||
(defn heapu32-set-uuid
|
|
||||||
[id heap offset]
|
|
||||||
(let [buffer (uuid/get-u32 id)]
|
|
||||||
(.set heap buffer offset)
|
|
||||||
buffer))
|
|
||||||
|
|
||||||
(defn heapf32-set-matrix
|
|
||||||
[matrix heap offset]
|
|
||||||
(let [a (dm/get-prop matrix :a)
|
|
||||||
b (dm/get-prop matrix :b)
|
|
||||||
c (dm/get-prop matrix :c)
|
|
||||||
d (dm/get-prop matrix :d)
|
|
||||||
e (dm/get-prop matrix :e)
|
|
||||||
f (dm/get-prop matrix :f)]
|
|
||||||
(aset heap (+ offset 0) a)
|
|
||||||
(aset heap (+ offset 1) b)
|
|
||||||
(aset heap (+ offset 2) c)
|
|
||||||
(aset heap (+ offset 3) d)
|
|
||||||
(aset heap (+ offset 4) e)
|
|
||||||
(aset heap (+ offset 5) f)))
|
|
||||||
|
|
||||||
(defn translate-shape-type
|
(defn translate-shape-type
|
||||||
[type]
|
[type]
|
||||||
(case type
|
(case type
|
||||||
@ -197,7 +171,8 @@
|
|||||||
:start 0
|
:start 0
|
||||||
:end 1
|
:end 1
|
||||||
:center 2
|
:center 2
|
||||||
:stretch 3))
|
:stretch 3
|
||||||
|
0))
|
||||||
|
|
||||||
(defn translate-layout-align-content
|
(defn translate-layout-align-content
|
||||||
[align-content]
|
[align-content]
|
||||||
@ -208,7 +183,8 @@
|
|||||||
:space-between 3
|
:space-between 3
|
||||||
:space-around 4
|
:space-around 4
|
||||||
:space-evenly 5
|
:space-evenly 5
|
||||||
:stretch 6))
|
:stretch 6
|
||||||
|
6))
|
||||||
|
|
||||||
(defn translate-layout-justify-items
|
(defn translate-layout-justify-items
|
||||||
[justify-items]
|
[justify-items]
|
||||||
@ -216,7 +192,8 @@
|
|||||||
:start 0
|
:start 0
|
||||||
:end 1
|
:end 1
|
||||||
:center 2
|
:center 2
|
||||||
:stretch 3))
|
:stretch 3
|
||||||
|
0))
|
||||||
|
|
||||||
(defn translate-layout-justify-content
|
(defn translate-layout-justify-content
|
||||||
[justify-content]
|
[justify-content]
|
||||||
@ -227,13 +204,15 @@
|
|||||||
:space-between 3
|
:space-between 3
|
||||||
:space-around 4
|
:space-around 4
|
||||||
:space-evenly 5
|
:space-evenly 5
|
||||||
:stretch 6))
|
:stretch 6
|
||||||
|
6))
|
||||||
|
|
||||||
(defn translate-layout-wrap-type
|
(defn translate-layout-wrap-type
|
||||||
[wrap-type]
|
[wrap-type]
|
||||||
(case wrap-type
|
(case wrap-type
|
||||||
:wrap 0
|
:wrap 0
|
||||||
:nowrap 1))
|
:nowrap 1
|
||||||
|
1))
|
||||||
|
|
||||||
(defn translate-grid-track-type
|
(defn translate-grid-track-type
|
||||||
[type]
|
[type]
|
||||||
|
|||||||
@ -385,6 +385,7 @@ impl GridData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: use transmute
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct RawGridTrack {
|
pub struct RawGridTrack {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user