mirror of
https://github.com/penpot/penpot.git
synced 2025-06-02 06:21:37 +02:00
✨ Add serialization support for PathData
For transit and fressian
This commit is contained in:
parent
e62231cfed
commit
fac93e4ff8
2 changed files with 64 additions and 9 deletions
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
(ns app.common.types.shape.path
|
(ns app.common.types.shape.path
|
||||||
(:require
|
(:require
|
||||||
[app.common.schema :as sm])
|
#?(:clj [app.common.fressian :as fres])
|
||||||
|
[app.common.schema :as sm]
|
||||||
|
[app.common.transit :as t])
|
||||||
(:import
|
(:import
|
||||||
#?(:cljs [goog.string StringBuffer]
|
#?(:cljs [goog.string StringBuffer]
|
||||||
:clj [java.nio ByteBuffer])))
|
:clj [java.nio ByteBuffer])))
|
||||||
|
@ -74,7 +76,8 @@
|
||||||
(def ^:const SEGMENT-BYTE-SIZE 28)
|
(def ^:const SEGMENT-BYTE-SIZE 28)
|
||||||
|
|
||||||
(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")
|
||||||
|
(-bytes [_] "get path data as byte array"))
|
||||||
|
|
||||||
(defrecord PathSegment [command params])
|
(defrecord PathSegment [command params])
|
||||||
|
|
||||||
|
@ -225,7 +228,15 @@
|
||||||
default))
|
default))
|
||||||
|
|
||||||
clojure.lang.Counted
|
clojure.lang.Counted
|
||||||
(count [_] size))
|
(count [_] size)
|
||||||
|
|
||||||
|
|
||||||
|
IPathData
|
||||||
|
(-write-to [_ _ _]
|
||||||
|
(throw (RuntimeException. "not implemented")))
|
||||||
|
|
||||||
|
(-bytes [_]
|
||||||
|
(.array ^ByteBuffer buffer)))
|
||||||
|
|
||||||
:cljs
|
:cljs
|
||||||
(deftype PathData [size buffer dview]
|
(deftype PathData [size buffer dview]
|
||||||
|
@ -240,18 +251,21 @@
|
||||||
mem (js/Uint32Array. into-buffer offset size)]
|
mem (js/Uint32Array. into-buffer offset size)]
|
||||||
(.set mem (js/Uint32Array. buffer))))
|
(.set mem (js/Uint32Array. buffer))))
|
||||||
|
|
||||||
|
(-bytes [_]
|
||||||
|
(js/Uint8Array. buffer))
|
||||||
|
|
||||||
cljs.core/ISequential
|
cljs.core/ISequential
|
||||||
cljs.core/IEquiv
|
cljs.core/IEquiv
|
||||||
(-equiv [_ other]
|
(-equiv [_ other]
|
||||||
(if (instance? PathData other)
|
(if (instance? PathData other)
|
||||||
(let [obuffer (.-buffer other)
|
(let [obuffer (.-buffer other)]
|
||||||
osize (.-byteLength obuffer)
|
(if (= (.-byteLength obuffer)
|
||||||
csize (.-byteLength buffer)]
|
(.-byteLength buffer))
|
||||||
(if (= osize csize)
|
|
||||||
(let [cb (js/Uint32Array. buffer)
|
(let [cb (js/Uint32Array. buffer)
|
||||||
ob (js/Uint32Array. obuffer)]
|
ob (js/Uint32Array. obuffer)
|
||||||
|
sz (alength cb)]
|
||||||
(loop [i 0]
|
(loop [i 0]
|
||||||
(if (< i osize)
|
(if (< i sz)
|
||||||
(if (= (aget ob i)
|
(if (= (aget ob i)
|
||||||
(aget cb i))
|
(aget cb i))
|
||||||
(recur (inc i))
|
(recur (inc i))
|
||||||
|
@ -341,6 +355,9 @@
|
||||||
count (long (/ size SEGMENT-BYTE-SIZE))]
|
count (long (/ size SEGMENT-BYTE-SIZE))]
|
||||||
(PathData. count buffer dview))
|
(PathData. count buffer dview))
|
||||||
|
|
||||||
|
(instance? js/Uint8Array buffer)
|
||||||
|
(from-bytes (.-buffer buffer))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(throw (js/Error. "invalid data provided")))))
|
(throw (js/Error. "invalid data provided")))))
|
||||||
|
|
||||||
|
@ -429,3 +446,23 @@
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(from-bytes data)))
|
(from-bytes data)))
|
||||||
|
|
||||||
|
(t/add-handlers!
|
||||||
|
{:id "penpot/path-data"
|
||||||
|
:class PathData
|
||||||
|
:wfn (fn [^PathData pdata]
|
||||||
|
(-bytes pdata))
|
||||||
|
:rfn path-data})
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(fres/add-handlers!
|
||||||
|
{:name "penpot/path-data"
|
||||||
|
:class PathData
|
||||||
|
:wfn (fn [n w o]
|
||||||
|
(fres/write-tag! w n 1)
|
||||||
|
(let [buffer (.-buffer ^PathData o)
|
||||||
|
bytes (.array ^ByteBuffer buffer)]
|
||||||
|
(fres/write-bytes! w bytes)))
|
||||||
|
:rfn (fn [r]
|
||||||
|
(let [^bytes bytes (fres/read-object! r)]
|
||||||
|
(path-data (ByteBuffer/wrap bytes))))}))
|
||||||
|
|
|
@ -6,9 +6,11 @@
|
||||||
|
|
||||||
(ns common-tests.types.shape-path-data-test
|
(ns common-tests.types.shape-path-data-test
|
||||||
(:require
|
(:require
|
||||||
|
#?(:clj [app.common.fressian :as fres])
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.common.pprint :as pp]
|
[app.common.pprint :as pp]
|
||||||
|
[app.common.transit :as trans]
|
||||||
[app.common.types.shape.path :as path]
|
[app.common.types.shape.path :as path]
|
||||||
[clojure.test :as t]))
|
[clojure.test :as t]))
|
||||||
|
|
||||||
|
@ -57,3 +59,19 @@
|
||||||
(mapv path/map->PathSegment))
|
(mapv path/map->PathSegment))
|
||||||
(vec pdata)))))
|
(vec pdata)))))
|
||||||
|
|
||||||
|
(t/deftest path-data-transit-roundtrip
|
||||||
|
(let [pdata (path/path-data sample-content)
|
||||||
|
result1 (trans/encode-str pdata)
|
||||||
|
expected "[\"~#penpot/path-data\",\"~bAAEAAAAAAAAAAAAAAAAAAAAAAABD8AAARFHAAAACAAAAAAAAAAAAAAAAAAAAAAAAQ9uAAERIgAAAAwAAQ7gAAEQ4QABDmwAARCpAAEOEAABEHoAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\"]"
|
||||||
|
result2 (trans/decode-str result1)]
|
||||||
|
|
||||||
|
(t/is (= expected result1))
|
||||||
|
(t/is (= pdata result2))))
|
||||||
|
|
||||||
|
#?(:clj
|
||||||
|
(t/deftest path-data-fresian
|
||||||
|
(let [pdata (path/path-data sample-content)
|
||||||
|
result1 (fres/encode pdata)
|
||||||
|
result2 (fres/decode result1)]
|
||||||
|
(t/is (= pdata result2)))))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue