Skip to content

Commit

Permalink
Merge pull request penpot#5336 from penpot/niwinz-render-wasm-improve…
Browse files Browse the repository at this point in the history
…ments-2

✨ Minor improvements to wasm shape and intial draft for path encoding
  • Loading branch information
AzazelN28 authored Nov 26, 2024
2 parents 82104dd + 6d419a4 commit 5b52e2a
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 18 deletions.
73 changes: 73 additions & 0 deletions common/src/app/common/svg/path.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,76 @@
(map (fn [segment]
(.toPersistentMap ^js segment)))
(parser/parse path-str)))))

#?(:cljs
(defn content->buffer
"Converts the path content into binary format."
[content]
(let [total (count content)
ssize 28
buffer (new js/ArrayBuffer (* total ssize))
dview (new js/DataView buffer)]
(loop [index 0]
(when (< index total)
(let [segment (nth content index)
offset (* index ssize)]
(case (:command segment)
:move-to
(let [{:keys [x y]} (:params segment)]
(.setInt16 dview (+ offset 0) 1)
(.setFloat32 dview (+ offset 20) x)
(.setFloat32 dview (+ offset 24) y))
:line-to
(let [{:keys [x y]} (:params segment)]
(.setInt16 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)]
(.setInt16 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
(.setInt16 dview (+ offset 0) 4))
(recur (inc index)))))
buffer)))

#?(:cljs
(defn buffer->content
"Converts the a buffer to a path content vector"
[buffer]
(assert (instance? js/ArrayBuffer buffer) "expected ArrayBuffer instance")
(let [ssize 28
total (/ (.-byteLength buffer) ssize)
dview (new js/DataView buffer)]
(loop [index 0
result []]
(if (< index total)
(let [offset (* index ssize)
type (.getInt16 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)))))
80 changes: 62 additions & 18 deletions frontend/src/app/render_wasm/shape.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
(:require
[app.common.transit :as t]
[app.common.types.shape :as shape]
;; [app.common.svg.path :as path]
[app.render-wasm.api :as api]
[clojure.core :as c]
[cuerdas.core :as str]))
Expand All @@ -16,7 +17,11 @@
(declare ^:private impl-conj)
(declare ^:private impl-dissoc)

(deftype ShapeProxy [delegate]
(defn map-entry
[k v]
(cljs.core/MapEntry. k v nil))

(deftype ShapeProxy [id type delegate]
Object
(toString [coll]
(str "{" (str/join ", " (for [[k v] coll] (str k " " v))) "}"))
Expand All @@ -29,7 +34,7 @@

IWithMeta
(-with-meta [_ meta]
(ShapeProxy. (with-meta delegate meta)))
(ShapeProxy. id type (with-meta delegate meta)))

IMeta
(-meta [_] (meta delegate))
Expand All @@ -49,7 +54,9 @@

ISeqable
(-seq [_]
(c/-seq delegate))
(cons (map-entry :id id)
(cons (map-entry :type type)
(c/-seq delegate))))

ICounted
(-count [_]
Expand All @@ -60,26 +67,36 @@
(-lookup coll k nil))

(-lookup [_ k not-found]
(c/-lookup delegate k not-found))
(case k
:id id
:type type
(c/-lookup delegate k not-found)))

IFind
(-find [_ k]
(c/-find delegate k))
(case k
:id
(map-entry :id id)
:type
(map-entry :type type)
(c/-find delegate k)))

IAssociative
(-assoc [coll k v]
(impl-assoc coll k v))

(-contains-key? [_ k]
(contains? delegate k))
(or (= k :id)
(= k :type)
(contains? delegate k)))

IMap
(-dissoc [coll k]
(impl-dissoc coll k))

IFn
(-invoke [coll k]
(-lookup coll k))
(-lookup coll k nil))

(-invoke [coll k not-found]
(-lookup coll k not-found))
Expand Down Expand Up @@ -107,19 +124,44 @@
;; is modified, we need to request
;; a new render.
(api/request-render))
(let [delegate (.-delegate ^ShapeProxy self)
delegate' (assoc delegate k v)]
(if (identical? delegate' delegate)
self
(ShapeProxy. delegate'))))
(case k
:id
(ShapeProxy. v
(.-type ^ShapeProxy self)
(.-delegate ^ShapeProxy self))
:type
(ShapeProxy. (.-id ^ShapeProxy self)
v
(.-delegate ^ShapeProxy self))

(let [delegate (.-delegate ^ShapeProxy self)
delegate' (assoc delegate k v)]
(if (identical? delegate' delegate)
self
(ShapeProxy. (.-id ^ShapeProxy self)
(.-type ^ShapeProxy self)
delegate')))))

(defn- impl-dissoc
[self k]
(let [delegate (.-delegate ^ShapeProxy self)
delegate' (dissoc delegate k)]
(if (identical? delegate delegate')
self
(ShapeProxy. delegate'))))
(case k
:id
(ShapeProxy. nil
(.-type ^ShapeProxy self)
(.-delegate ^ShapeProxy self))
:type
(ShapeProxy. (.-id ^ShapeProxy self)
nil
(.-delegate ^ShapeProxy self))

:else
(let [delegate (.-delegate ^ShapeProxy self)
delegate' (dissoc delegate k)]
(if (identical? delegate delegate')
self
(ShapeProxy. (.-id ^ShapeProxy self)
(.-type ^ShapeProxy self)
delegate')))))

(defn- impl-conj
[self entry]
Expand All @@ -137,7 +179,9 @@
(defn create-shape
"Instanciate a shape from a map"
[attrs]
(ShapeProxy. attrs))
(ShapeProxy. (:id attrs)
(:type attrs)
(dissoc attrs :id :type)))

(t/add-handlers!
;; We only add a write handler, read handler uses the dynamic dispatch
Expand Down

0 comments on commit 5b52e2a

Please sign in to comment.