mirror of
https://github.com/penpot/penpot.git
synced 2026-09-11 22:49:30 +00:00
✨ Use binary fills to write data to wasm memory
This commit is contained in:
parent
8a58b9d459
commit
af99bd620c
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
(ns app.common.types.fills
|
(ns app.common.types.fills
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.exceptions :as ex]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.types.color :as types.color]
|
[app.common.types.color :as types.color]
|
||||||
[app.common.types.fills.impl :as impl]
|
[app.common.types.fills.impl :as impl]
|
||||||
@ -50,10 +51,6 @@
|
|||||||
(def check-fill
|
(def check-fill
|
||||||
(sm/check-fn schema:fill))
|
(sm/check-fn schema:fill))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; HELPERS
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; CONSTRUCTORS
|
;; CONSTRUCTORS
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@ -66,3 +63,48 @@
|
|||||||
(defn fills?
|
(defn fills?
|
||||||
[o]
|
[o]
|
||||||
(impl/fills? o))
|
(impl/fills? o))
|
||||||
|
|
||||||
|
(defn coerce
|
||||||
|
[o]
|
||||||
|
(cond
|
||||||
|
(nil? o)
|
||||||
|
(impl/from-plain [])
|
||||||
|
|
||||||
|
(impl/fills? o)
|
||||||
|
o
|
||||||
|
|
||||||
|
(vector? o)
|
||||||
|
(impl/from-plain o)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(ex/raise :type :internal
|
||||||
|
:code :invalid-type
|
||||||
|
:hint (str "cannot coerce " (pr-str o) "to fills"))))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; HELPERS
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn assoc-fill
|
||||||
|
[fills position fill]
|
||||||
|
(if (nil? fills)
|
||||||
|
(impl/from-plain [fill])
|
||||||
|
(-> (coerce fills)
|
||||||
|
(assoc position fill))))
|
||||||
|
|
||||||
|
(defn get-image-ids
|
||||||
|
[fills]
|
||||||
|
(if (vector? fills)
|
||||||
|
(into #{}
|
||||||
|
(comp (keep :fill-image)
|
||||||
|
(map :id))
|
||||||
|
fills)
|
||||||
|
(impl/-get-image-ids fills)))
|
||||||
|
|
||||||
|
(defn get-byte-size
|
||||||
|
[fills]
|
||||||
|
(impl/-get-byte-size fills))
|
||||||
|
|
||||||
|
(defn write-to
|
||||||
|
[fills buffer offset]
|
||||||
|
(impl/-write-to fills buffer offset))
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
[app.common.buffer :as buf]
|
[app.common.buffer :as buf]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.exceptions :as ex]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.common.transit :as t]))
|
[app.common.transit :as t]))
|
||||||
|
|
||||||
@ -35,6 +36,13 @@
|
|||||||
(def ^:private xf:take-fills
|
(def ^:private xf:take-fills
|
||||||
(take MAX-FILLS))
|
(take MAX-FILLS))
|
||||||
|
|
||||||
|
(defprotocol IHeapWritable
|
||||||
|
(-write-to [_ buffer offset] "write the content to the specified buffer")
|
||||||
|
(-get-byte-size [_] "get byte size"))
|
||||||
|
|
||||||
|
(defprotocol IBinaryFills
|
||||||
|
(-get-image-ids [_] "get referenced image ids"))
|
||||||
|
|
||||||
(defn- hex->rgb
|
(defn- hex->rgb
|
||||||
"Encode an hex string as rgb (int32)"
|
"Encode an hex string as rgb (int32)"
|
||||||
[hex]
|
[hex]
|
||||||
@ -64,16 +72,16 @@
|
|||||||
n (unsigned-bit-shift-right n 24)]
|
n (unsigned-bit-shift-right n 24)]
|
||||||
(mth/precision (/ (float n) 0xff) 2)))
|
(mth/precision (/ (float n) 0xff) 2)))
|
||||||
|
|
||||||
(defn- write-solid-fill
|
(defn write-solid-fill
|
||||||
[offset buffer color alpha]
|
[offset buffer opacity color]
|
||||||
(buf/write-byte buffer (+ offset 0) 0x00)
|
(buf/write-byte buffer (+ offset 0) 0x00)
|
||||||
(buf/write-int buffer (+ offset 4)
|
(buf/write-int buffer (+ offset 4)
|
||||||
(-> (hex->rgb color)
|
(-> (hex->rgb color)
|
||||||
(rgb->rgba alpha)))
|
(rgb->rgba opacity)))
|
||||||
(+ offset FILL-BYTE-SIZE))
|
(+ offset FILL-BYTE-SIZE))
|
||||||
|
|
||||||
(defn- write-gradient-fill
|
(defn write-gradient-fill
|
||||||
[offset buffer gradient opacity]
|
[offset buffer opacity gradient]
|
||||||
(let [start-x (:start-x gradient)
|
(let [start-x (:start-x gradient)
|
||||||
start-y (:start-y gradient)
|
start-y (:start-y gradient)
|
||||||
end-x (:end-x gradient)
|
end-x (:end-x gradient)
|
||||||
@ -108,10 +116,10 @@
|
|||||||
(+ offset' GRADIENT-STOP-SIZE)))
|
(+ offset' GRADIENT-STOP-SIZE)))
|
||||||
(+ offset FILL-BYTE-SIZE)))))
|
(+ offset FILL-BYTE-SIZE)))))
|
||||||
|
|
||||||
(defn- write-image-fill
|
(defn write-image-fill
|
||||||
[offset buffer opacity image]
|
[offset buffer opacity image]
|
||||||
(let [image-id (get image :id)
|
(let [image-id (get image :id)
|
||||||
image-width (get image :width)
|
image-width (get image :width)
|
||||||
image-height (get image :height)
|
image-height (get image :height)
|
||||||
keep-ratio (get image :keep-aspect-ratio false)]
|
keep-ratio (get image :keep-aspect-ratio false)]
|
||||||
(buf/write-byte buffer (+ offset 0) 0x03)
|
(buf/write-byte buffer (+ offset 0) 0x03)
|
||||||
@ -282,7 +290,20 @@
|
|||||||
|
|
||||||
:cljs
|
:cljs
|
||||||
#_:clj-kondo/ignore
|
#_:clj-kondo/ignore
|
||||||
(deftype Fills [size dbuffer mbuffer cache ^:mutable __hash]
|
(deftype Fills [size dbuffer mbuffer image-ids cache ^:mutable __hash]
|
||||||
|
|
||||||
|
IHeapWritable
|
||||||
|
(-get-byte-size [_]
|
||||||
|
(- (.-byteLength dbuffer) 4))
|
||||||
|
|
||||||
|
(-write-to [_ heap offset]
|
||||||
|
(let [buffer' (.-buffer ^js/DataView dbuffer)]
|
||||||
|
(.set heap (js/Uint32Array. buffer' 4) offset)))
|
||||||
|
|
||||||
|
IBinaryFills
|
||||||
|
(-get-image-ids [_]
|
||||||
|
image-ids)
|
||||||
|
|
||||||
cljs.core/ISequential
|
cljs.core/ISequential
|
||||||
cljs.core/IEquiv
|
cljs.core/IEquiv
|
||||||
(-equiv [this other]
|
(-equiv [this other]
|
||||||
@ -368,8 +389,9 @@
|
|||||||
|
|
||||||
(buf/write-byte dbuffer 0 total)
|
(buf/write-byte dbuffer 0 total)
|
||||||
|
|
||||||
(loop [index 0]
|
(loop [index 0
|
||||||
(when (< index total)
|
image-ids #{}]
|
||||||
|
(if (< index total)
|
||||||
(let [fill (nth fills index)
|
(let [fill (nth fills index)
|
||||||
doffset (+ 4 (* index FILL-BYTE-SIZE))
|
doffset (+ 4 (* index FILL-BYTE-SIZE))
|
||||||
moffset (* index METADATA-BYTE-SIZE)
|
moffset (* index METADATA-BYTE-SIZE)
|
||||||
@ -377,23 +399,26 @@
|
|||||||
|
|
||||||
(if-let [color (get fill :fill-color)]
|
(if-let [color (get fill :fill-color)]
|
||||||
(do
|
(do
|
||||||
(write-solid-fill doffset dbuffer color opacity)
|
(write-solid-fill doffset dbuffer opacity color)
|
||||||
(write-metadata moffset mbuffer fill)
|
(write-metadata moffset mbuffer fill)
|
||||||
(recur (inc index)))
|
(recur (inc index) image-ids))
|
||||||
(if-let [gradient (get fill :fill-color-gradient)]
|
(if-let [gradient (get fill :fill-color-gradient)]
|
||||||
(do
|
(do
|
||||||
(write-gradient-fill doffset dbuffer gradient opacity)
|
(write-gradient-fill doffset dbuffer opacity gradient)
|
||||||
(write-metadata moffset mbuffer fill)
|
(write-metadata moffset mbuffer fill)
|
||||||
(recur (inc index)))
|
(recur (inc index) image-ids))
|
||||||
(if-let [image (get fill :fill-image)]
|
(if-let [image (get fill :fill-image)]
|
||||||
(do
|
(do
|
||||||
(write-image-fill doffset dbuffer opacity image)
|
(write-image-fill doffset dbuffer opacity image)
|
||||||
(write-metadata moffset mbuffer fill)
|
(write-metadata moffset mbuffer fill)
|
||||||
(recur (inc index)))
|
(recur (inc index)
|
||||||
(recur (inc index))))))))
|
(conj image-ids (get image :id))))
|
||||||
|
(ex/raise :type :internal
|
||||||
|
:code :invalid-fill
|
||||||
|
:hint "found invalid fill on encoding fills to binary format")))))
|
||||||
|
|
||||||
#?(:cljs (Fills. total dbuffer mbuffer (weak-map/create) nil)
|
#?(:cljs (Fills. total dbuffer mbuffer image-ids (weak-map/create) nil)
|
||||||
:clj (Fills. total dbuffer mbuffer nil))))
|
:clj (Fills. total dbuffer mbuffer nil))))))
|
||||||
|
|
||||||
(defn fills?
|
(defn fills?
|
||||||
[o]
|
[o]
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.point :as gpt]
|
[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.path :as path]
|
[app.common.types.path :as path]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
@ -28,7 +29,6 @@
|
|||||||
[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]
|
||||||
[app.render-wasm.serializers.fills :as sr-fills]
|
|
||||||
[app.render-wasm.wasm :as wasm]
|
[app.render-wasm.wasm :as wasm]
|
||||||
[app.util.debug :as dbg]
|
[app.util.debug :as dbg]
|
||||||
[app.util.functions :as fns]
|
[app.util.functions :as fns]
|
||||||
@ -201,6 +201,9 @@
|
|||||||
(rx/map :body)
|
(rx/map :body)
|
||||||
(rx/mapcat wapi/read-file-as-array-buffer)
|
(rx/mapcat wapi/read-file-as-array-buffer)
|
||||||
(rx/map (fn [image]
|
(rx/map (fn [image]
|
||||||
|
;; FIXME use bigger heap ptr size if it
|
||||||
|
;; is possible (if image size modulo
|
||||||
|
;; permits it)
|
||||||
(let [size (.-byteLength image)
|
(let [size (.-byteLength image)
|
||||||
offset (mem/alloc-bytes size)
|
offset (mem/alloc-bytes size)
|
||||||
heap (mem/get-heap-u8)
|
heap (mem/get-heap-u8)
|
||||||
@ -248,28 +251,19 @@
|
|||||||
[shape-id fills]
|
[shape-id fills]
|
||||||
(if (empty? fills)
|
(if (empty? fills)
|
||||||
(h/call wasm/internal-module "_clear_shape_fills")
|
(h/call wasm/internal-module "_clear_shape_fills")
|
||||||
(let [fills (take types.fills/MAX-FILLS fills)
|
(let [fills (types.fills/coerce fills)
|
||||||
image-fills (filter :fill-image fills)
|
offset (mem/alloc-bytes-32 (types.fills/get-byte-size fills))
|
||||||
offset (mem/alloc-bytes (* (count fills) sr-fills/FILL-BYTE-SIZE))
|
heap (mem/get-heap-u32)]
|
||||||
heap (mem/get-heap-u8)
|
|
||||||
dview (js/DataView. (.-buffer heap))]
|
|
||||||
|
|
||||||
;; write fill data to heap
|
;; write fills to the heap
|
||||||
(loop [fills (seq fills)
|
(types.fills/write-to fills heap offset)
|
||||||
current-offset offset]
|
|
||||||
(when-not (empty? fills)
|
|
||||||
(let [fill (first fills)
|
|
||||||
new-offset (sr-fills/write-fill! current-offset dview fill)]
|
|
||||||
(recur (rest fills) new-offset))))
|
|
||||||
|
|
||||||
;; send fills to wasm
|
;; send fills to wasm
|
||||||
(h/call wasm/internal-module "_set_shape_fills")
|
(h/call wasm/internal-module "_set_shape_fills")
|
||||||
|
|
||||||
;; load images for image fills if not cached
|
;; load images for image fills if not cached
|
||||||
(keep (fn [fill]
|
(keep (fn [id]
|
||||||
(let [image (:fill-image fill)
|
(let [buffer (uuid/get-u32 id)
|
||||||
id (dm/get-prop image :id)
|
|
||||||
buffer (uuid/get-u32 id)
|
|
||||||
cached-image? (h/call wasm/internal-module "_is_image_cached"
|
cached-image? (h/call wasm/internal-module "_is_image_cached"
|
||||||
(aget buffer 0)
|
(aget buffer 0)
|
||||||
(aget buffer 1)
|
(aget buffer 1)
|
||||||
@ -277,7 +271,8 @@
|
|||||||
(aget buffer 3))]
|
(aget buffer 3))]
|
||||||
(when (zero? cached-image?)
|
(when (zero? cached-image?)
|
||||||
(fetch-image shape-id id))))
|
(fetch-image shape-id id))))
|
||||||
image-fills))))
|
|
||||||
|
(types.fills/get-image-ids fills)))))
|
||||||
|
|
||||||
(defn set-shape-strokes
|
(defn set-shape-strokes
|
||||||
[shape-id strokes]
|
[shape-id strokes]
|
||||||
@ -292,7 +287,7 @@
|
|||||||
style (-> stroke :stroke-style sr/translate-stroke-style)
|
style (-> stroke :stroke-style sr/translate-stroke-style)
|
||||||
cap-start (-> stroke :stroke-cap-start sr/translate-stroke-cap)
|
cap-start (-> stroke :stroke-cap-start sr/translate-stroke-cap)
|
||||||
cap-end (-> stroke :stroke-cap-end sr/translate-stroke-cap)
|
cap-end (-> stroke :stroke-cap-end sr/translate-stroke-cap)
|
||||||
offset (mem/alloc-bytes sr-fills/FILL-BYTE-SIZE)
|
offset (mem/alloc-bytes types.fills.impl/FILL-BYTE-SIZE)
|
||||||
heap (mem/get-heap-u8)
|
heap (mem/get-heap-u8)
|
||||||
dview (js/DataView. (.-buffer heap))]
|
dview (js/DataView. (.-buffer heap))]
|
||||||
(case align
|
(case align
|
||||||
@ -303,23 +298,21 @@
|
|||||||
(cond
|
(cond
|
||||||
(some? gradient)
|
(some? gradient)
|
||||||
(do
|
(do
|
||||||
(sr-fills/write-gradient-fill! offset dview gradient opacity)
|
(types.fills.impl/write-gradient-fill offset dview opacity gradient)
|
||||||
(h/call wasm/internal-module "_add_shape_stroke_fill"))
|
(h/call wasm/internal-module "_add_shape_stroke_fill"))
|
||||||
|
|
||||||
(some? image)
|
(some? image)
|
||||||
(let [image-id (dm/get-prop image :id)
|
(let [image-id (dm/get-prop image :id)
|
||||||
buffer (uuid/get-u32 image-id)
|
buffer (uuid/get-u32 image-id)
|
||||||
cached-image? (h/call wasm/internal-module "_is_image_cached" (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))]
|
cached-image? (h/call wasm/internal-module "_is_image_cached" (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))]
|
||||||
(sr-fills/write-image-fill! offset dview image-id opacity
|
(types.fills.impl/write-image-fill offset dview opacity image)
|
||||||
(dm/get-prop image :width)
|
|
||||||
(dm/get-prop image :height))
|
|
||||||
(h/call wasm/internal-module "_add_shape_stroke_fill")
|
(h/call wasm/internal-module "_add_shape_stroke_fill")
|
||||||
(when (== cached-image? 0)
|
(when (== cached-image? 0)
|
||||||
(fetch-image shape-id image-id)))
|
(fetch-image shape-id image-id)))
|
||||||
|
|
||||||
(some? color)
|
(some? color)
|
||||||
(do
|
(do
|
||||||
(sr-fills/write-solid-fill! offset dview (sr-clr/hex->u32argb color opacity))
|
(types.fills.impl/write-solid-fill offset dview opacity color)
|
||||||
(h/call wasm/internal-module "_add_shape_stroke_fill")))))
|
(h/call wasm/internal-module "_add_shape_stroke_fill")))))
|
||||||
strokes))
|
strokes))
|
||||||
|
|
||||||
|
|||||||
@ -7,12 +7,11 @@
|
|||||||
(ns app.render-wasm.api.texts
|
(ns app.render-wasm.api.texts
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.types.fills.impl :as types.fills.impl]
|
||||||
[app.render-wasm.api.fonts :as f]
|
[app.render-wasm.api.fonts :as f]
|
||||||
[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.serializers :as sr]
|
[app.render-wasm.serializers :as sr]
|
||||||
[app.render-wasm.serializers.color :as sr-clr]
|
|
||||||
[app.render-wasm.serializers.fills :as sr-fills]
|
|
||||||
[app.render-wasm.wasm :as wasm]))
|
[app.render-wasm.wasm :as wasm]))
|
||||||
|
|
||||||
(defn utf8->buffer [text]
|
(defn utf8->buffer [text]
|
||||||
@ -26,21 +25,18 @@
|
|||||||
color (:fill-color fill)
|
color (:fill-color fill)
|
||||||
gradient (:fill-color-gradient fill)
|
gradient (:fill-color-gradient fill)
|
||||||
image (:fill-image fill)]
|
image (:fill-image fill)]
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(some? color)
|
(some? color)
|
||||||
(sr-fills/write-solid-fill! offset dview (sr-clr/hex->u32argb color opacity))
|
(types.fills.impl/write-solid-fill offset dview opacity color)
|
||||||
|
|
||||||
(some? gradient)
|
(some? gradient)
|
||||||
(sr-fills/write-gradient-fill! offset dview gradient opacity)
|
(types.fills.impl/write-gradient-fill offset dview opacity gradient)
|
||||||
|
|
||||||
(some? image)
|
(some? image)
|
||||||
(sr-fills/write-image-fill! offset dview
|
(types.fills.impl/write-image-fill offset dview opacity image))
|
||||||
(dm/get-prop image :id)
|
|
||||||
opacity
|
|
||||||
(dm/get-prop image :width)
|
|
||||||
(dm/get-prop image :height)))
|
|
||||||
|
|
||||||
(+ offset sr-fills/FILL-BYTE-SIZE)))
|
(+ offset types.fills.impl/FILL-BYTE-SIZE)))
|
||||||
current-offset
|
current-offset
|
||||||
fills))
|
fills))
|
||||||
|
|
||||||
@ -56,7 +52,7 @@
|
|||||||
num-leaves (count leaves)
|
num-leaves (count leaves)
|
||||||
paragraph-attr-size 48
|
paragraph-attr-size 48
|
||||||
total-fills (total-fills-count leaves)
|
total-fills (total-fills-count leaves)
|
||||||
total-fills-size (* sr-fills/FILL-BYTE-SIZE total-fills)
|
total-fills-size (* types.fills.impl/FILL-BYTE-SIZE total-fills)
|
||||||
leaf-attr-size 56
|
leaf-attr-size 56
|
||||||
metadata-size (+ paragraph-attr-size (* num-leaves leaf-attr-size) total-fills-size)
|
metadata-size (+ paragraph-attr-size (* num-leaves leaf-attr-size) total-fills-size)
|
||||||
text-buffer (utf8->buffer text)
|
text-buffer (utf8->buffer text)
|
||||||
|
|||||||
@ -1,81 +0,0 @@
|
|||||||
(ns app.render-wasm.serializers.fills
|
|
||||||
(:require
|
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.common.types.fills :as types.fills]
|
|
||||||
[app.common.uuid :as uuid]
|
|
||||||
[app.render-wasm.serializers.color :as clr]))
|
|
||||||
|
|
||||||
(def ^:private GRADIENT-STOP-SIZE 8)
|
|
||||||
|
|
||||||
(def GRADIENT-BYTE-SIZE 156)
|
|
||||||
(def SOLID-BYTE-SIZE 4)
|
|
||||||
(def IMAGE-BYTE-SIZE 28)
|
|
||||||
|
|
||||||
;; FIXME: get it from the wasm module
|
|
||||||
(def FILL-BYTE-SIZE (+ 4 (max GRADIENT-BYTE-SIZE IMAGE-BYTE-SIZE SOLID-BYTE-SIZE)))
|
|
||||||
|
|
||||||
|
|
||||||
(defn write-solid-fill!
|
|
||||||
[offset dview argb]
|
|
||||||
(.setUint8 dview offset 0x00 true)
|
|
||||||
(.setUint32 dview (+ offset 4) argb true)
|
|
||||||
(+ offset FILL-BYTE-SIZE))
|
|
||||||
|
|
||||||
(defn write-image-fill!
|
|
||||||
[offset dview id opacity width height]
|
|
||||||
(let [uuid-buffer (uuid/get-u32 id)]
|
|
||||||
(.setUint8 dview offset 0x03 true)
|
|
||||||
(.setUint32 dview (+ offset 4) (aget uuid-buffer 0) true)
|
|
||||||
(.setUint32 dview (+ offset 8) (aget uuid-buffer 1) true)
|
|
||||||
(.setUint32 dview (+ offset 12) (aget uuid-buffer 2) true)
|
|
||||||
(.setUint32 dview (+ offset 16) (aget uuid-buffer 3) true)
|
|
||||||
(.setFloat32 dview (+ offset 20) opacity true)
|
|
||||||
(.setInt32 dview (+ offset 24) width true)
|
|
||||||
(.setInt32 dview (+ offset 28) height true)
|
|
||||||
(+ offset FILL-BYTE-SIZE)))
|
|
||||||
|
|
||||||
(defn write-gradient-fill!
|
|
||||||
[offset dview gradient opacity]
|
|
||||||
(let [start-x (:start-x gradient)
|
|
||||||
start-y (:start-y gradient)
|
|
||||||
end-x (:end-x gradient)
|
|
||||||
end-y (:end-y gradient)
|
|
||||||
width (or (:width gradient) 0)
|
|
||||||
stops (take types.fills/MAX-GRADIENT-STOPS (:stops gradient))
|
|
||||||
type (if (= (:type gradient) :linear) 0x01 0x02)]
|
|
||||||
(.setUint8 dview offset type true)
|
|
||||||
(.setFloat32 dview (+ offset 4) start-x true)
|
|
||||||
(.setFloat32 dview (+ offset 8) start-y true)
|
|
||||||
(.setFloat32 dview (+ offset 12) end-x true)
|
|
||||||
(.setFloat32 dview (+ offset 16) end-y true)
|
|
||||||
(.setFloat32 dview (+ offset 20) opacity true)
|
|
||||||
(.setFloat32 dview (+ offset 24) width true)
|
|
||||||
(.setUint8 dview (+ offset 28) (count stops) true)
|
|
||||||
(loop [stops (seq stops) loop-offset (+ offset 32)]
|
|
||||||
(if (empty? stops)
|
|
||||||
(+ offset FILL-BYTE-SIZE)
|
|
||||||
(let [stop (first stops)
|
|
||||||
hex-color (:color stop)
|
|
||||||
stop-opacity (:opacity stop)
|
|
||||||
argb (clr/hex->u32argb hex-color stop-opacity)
|
|
||||||
stop-offset (:offset stop)]
|
|
||||||
(.setUint32 dview loop-offset argb true)
|
|
||||||
(.setFloat32 dview (+ loop-offset 4) stop-offset true)
|
|
||||||
(recur (rest stops) (+ loop-offset GRADIENT-STOP-SIZE)))))))
|
|
||||||
|
|
||||||
(defn write-fill!
|
|
||||||
[offset dview fill]
|
|
||||||
(let [opacity (or (:fill-opacity fill) 1.0)
|
|
||||||
color (:fill-color fill)
|
|
||||||
gradient (:fill-color-gradient fill)
|
|
||||||
image (:fill-image fill)]
|
|
||||||
(cond
|
|
||||||
(some? color)
|
|
||||||
(write-solid-fill! offset dview (clr/hex->u32argb color opacity))
|
|
||||||
|
|
||||||
(some? gradient)
|
|
||||||
(write-gradient-fill! offset dview gradient opacity)
|
|
||||||
|
|
||||||
(some? image)
|
|
||||||
(let [id (dm/get-prop image :id)]
|
|
||||||
(write-image-fill! offset dview id opacity (dm/get-prop image :width) (dm/get-prop image :height))))))
|
|
||||||
Loading…
x
Reference in New Issue
Block a user