diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 5d0dacd1d..ce7503a09 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -23,6 +23,8 @@ [app.render-wasm.mem :as mem] [app.render-wasm.performance :as perf] [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.util.debug :as dbg] [app.util.http :as http] @@ -224,7 +226,7 @@ image (:fill-image fill)] (cond (some? color) - (let [rgba (sr/hex->u32argb color opacity)] + (let [rgba (sr-clr/hex->u32argb color opacity)] (h/call wasm/internal-module "_add_shape_solid_fill" rgba)) (some? gradient) @@ -234,7 +236,7 @@ size (+ LINEAR-FILL-BASE-SIZE (* (count stops) GRADIENT-STOP-SIZE)) offset (mem/alloc-bytes size) heap (mem/get-heap-u8)] - (sr/serialize-linear-fill gradient opacity heap offset) + (sr-fills/serialize-linear-fill gradient opacity heap offset) (h/call wasm/internal-module "_add_shape_linear_fill")) :radial (let [stops (:stops gradient) @@ -250,7 +252,7 @@ opacity (:width gradient)) (.set mem (js/Uint8Array. (clj->js (flatten (map (fn [stop] - (let [[r g b a] (sr/rgba-bytes-from-hex (:color stop) (:opacity stop)) + (let [[r g b a] (sr-clr/rgba-bytes-from-hex (:color stop) (:opacity stop)) offset (:offset stop)] [r g b a (* 100 offset)])) stops))))) @@ -312,7 +314,7 @@ opacity (:width gradient))) (.set mem (js/Uint8Array. (clj->js (flatten (map (fn [stop] - (let [[r g b a] (sr/rgba-bytes-from-hex (:color stop) (:opacity stop)) + (let [[r g b a] (sr-clr/rgba-bytes-from-hex (:color stop) (:opacity stop)) offset (:offset stop)] [r g b a (* 100 offset)])) stops))))) @@ -334,7 +336,7 @@ (store-image id))) (some? color) - (let [rgba (sr/hex->u32argb color opacity)] + (let [rgba (sr-clr/hex->u32argb color opacity)] (h/call wasm/internal-module "_add_shape_stroke_solid_fill" rgba))))) strokes)) @@ -626,7 +628,7 @@ (let [shadow (nth shadows index) color (dm/get-prop shadow :color) blur (dm/get-prop shadow :blur) - rgba (sr/hex->u32argb (dm/get-prop color :color) (dm/get-prop color :opacity)) + rgba (sr-clr/hex->u32argb (dm/get-prop color :color) (dm/get-prop color :opacity)) hidden (dm/get-prop shadow :hidden) x (dm/get-prop shadow :offset-x) y (dm/get-prop shadow :offset-y) @@ -849,7 +851,7 @@ (defn set-canvas-background [background] - (let [rgba (sr/hex->u32argb background 1)] + (let [rgba (sr-clr/hex->u32argb background 1)] (h/call wasm/internal-module "_set_canvas_background" rgba) (request-render "set-canvas-background"))) @@ -878,7 +880,7 @@ (defn initialize [base-objects zoom vbox background] - (let [rgba (sr/hex->u32argb background 1)] + (let [rgba (sr-clr/hex->u32argb background 1)] (h/call wasm/internal-module "_set_canvas_background" rgba) (h/call wasm/internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox))) (set-objects base-objects))) diff --git a/frontend/src/app/render_wasm/serializers.cljs b/frontend/src/app/render_wasm/serializers.cljs index a977a69b5..0574b850a 100644 --- a/frontend/src/app/render_wasm/serializers.cljs +++ b/frontend/src/app/render_wasm/serializers.cljs @@ -7,28 +7,10 @@ (ns app.render-wasm.serializers (:require [app.common.data.macros :as dm] - [app.common.math :as mth] [app.common.uuid :as uuid] [cuerdas.core :as str])) -(defn hex->u32argb - "Takes a hex color in #rrggbb format, and an opacity value from 0 to 1 and returns its 32-bit argb representation" - [hex opacity] - (let [rgb (js/parseInt (subs hex 1) 16) - a (mth/floor (* (or opacity 1) 0xff))] - ;; rgba >>> 0 so we have an unsigned representation - (unsigned-bit-shift-right (bit-or (bit-shift-left a 24) rgb) 0))) -(defn rgba-bytes-from-hex - "Takes a hex color in #rrggbb format, and an opacity value from 0 to 1 and returns an array with its r g b a values" - [hex opacity] - (let [rgb (js/parseInt (subs hex 1) 16) - a (mth/floor (* (or opacity 1) 0xff)) - ;; rgba >>> 0 so we have an unsigned representation - r (bit-shift-right rgb 16) - g (bit-and (bit-shift-right rgb 8) 255) - b (bit-and rgb 255)] - [r g b a])) (defn u8 [value] diff --git a/frontend/src/app/render_wasm/serializers/color.cljs b/frontend/src/app/render_wasm/serializers/color.cljs new file mode 100644 index 000000000..af7fe36f4 --- /dev/null +++ b/frontend/src/app/render_wasm/serializers/color.cljs @@ -0,0 +1,22 @@ +(ns app.render-wasm.serializers.color + (:require + [app.common.math :as mth])) + +(defn hex->u32argb + "Takes a hex color in #rrggbb format, and an opacity value from 0 to 1 and returns its 32-bit argb representation" + [hex opacity] + (let [rgb (js/parseInt (subs hex 1) 16) + a (mth/floor (* (or opacity 1) 0xff))] + ;; rgba >>> 0 so we have an unsigned representation + (unsigned-bit-shift-right (bit-or (bit-shift-left a 24) rgb) 0))) + +(defn rgba-bytes-from-hex + "Takes a hex color in #rrggbb format, and an opacity value from 0 to 1 and returns an array with its r g b a values" + [hex opacity] + (let [rgb (js/parseInt (subs hex 1) 16) + a (mth/floor (* (or opacity 1) 0xff)) + ;; rgba >>> 0 so we have an unsigned representation + r (bit-shift-right rgb 16) + g (bit-and (bit-shift-right rgb 8) 255) + b (bit-and rgb 255)] + [r g b a])) \ No newline at end of file diff --git a/frontend/src/app/render_wasm/serializers/fills.cljs b/frontend/src/app/render_wasm/serializers/fills.cljs new file mode 100644 index 000000000..3864cb642 --- /dev/null +++ b/frontend/src/app/render_wasm/serializers/fills.cljs @@ -0,0 +1,30 @@ +(ns app.render-wasm.serializers.fills + (:require + [app.common.data.macros :as dm] + [app.render-wasm.serializers.color :as clr])) + +(defn serialize-linear-fill + [gradient opacity heap-u8 offset] + (let [dview (js/DataView. (.-buffer heap-u8)) + start-x (dm/get-prop gradient :start-x) + 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)] + (.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)) + (loop [stops (seq stops) idx 0] + (when-not (empty? stops) + (let [stop (first stops) + hex-color (dm/get-prop stop :color) + 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)] + (.setUint32 dview dview-offset rgba true) + (.setUint8 dview (+ dview-offset 4) stop-offset) + (recur (rest stops) (+ idx 1))))))) \ No newline at end of file