mirror of
https://github.com/penpot/penpot.git
synced 2025-05-31 15:26:11 +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
|
||||
(:require
|
||||
[app.common.schema :as sm])
|
||||
#?(:clj [app.common.fressian :as fres])
|
||||
[app.common.schema :as sm]
|
||||
[app.common.transit :as t])
|
||||
(:import
|
||||
#?(:cljs [goog.string StringBuffer]
|
||||
:clj [java.nio ByteBuffer])))
|
||||
|
@ -74,7 +76,8 @@
|
|||
(def ^:const SEGMENT-BYTE-SIZE 28)
|
||||
|
||||
(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])
|
||||
|
||||
|
@ -225,7 +228,15 @@
|
|||
default))
|
||||
|
||||
clojure.lang.Counted
|
||||
(count [_] size))
|
||||
(count [_] size)
|
||||
|
||||
|
||||
IPathData
|
||||
(-write-to [_ _ _]
|
||||
(throw (RuntimeException. "not implemented")))
|
||||
|
||||
(-bytes [_]
|
||||
(.array ^ByteBuffer buffer)))
|
||||
|
||||
:cljs
|
||||
(deftype PathData [size buffer dview]
|
||||
|
@ -240,18 +251,21 @@
|
|||
mem (js/Uint32Array. into-buffer offset size)]
|
||||
(.set mem (js/Uint32Array. buffer))))
|
||||
|
||||
(-bytes [_]
|
||||
(js/Uint8Array. buffer))
|
||||
|
||||
cljs.core/ISequential
|
||||
cljs.core/IEquiv
|
||||
(-equiv [_ other]
|
||||
(if (instance? PathData other)
|
||||
(let [obuffer (.-buffer other)
|
||||
osize (.-byteLength obuffer)
|
||||
csize (.-byteLength buffer)]
|
||||
(if (= osize csize)
|
||||
(let [obuffer (.-buffer other)]
|
||||
(if (= (.-byteLength obuffer)
|
||||
(.-byteLength buffer))
|
||||
(let [cb (js/Uint32Array. buffer)
|
||||
ob (js/Uint32Array. obuffer)]
|
||||
ob (js/Uint32Array. obuffer)
|
||||
sz (alength cb)]
|
||||
(loop [i 0]
|
||||
(if (< i osize)
|
||||
(if (< i sz)
|
||||
(if (= (aget ob i)
|
||||
(aget cb i))
|
||||
(recur (inc i))
|
||||
|
@ -341,6 +355,9 @@
|
|||
count (long (/ size SEGMENT-BYTE-SIZE))]
|
||||
(PathData. count buffer dview))
|
||||
|
||||
(instance? js/Uint8Array buffer)
|
||||
(from-bytes (.-buffer buffer))
|
||||
|
||||
:else
|
||||
(throw (js/Error. "invalid data provided")))))
|
||||
|
||||
|
@ -429,3 +446,23 @@
|
|||
|
||||
:else
|
||||
(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
|
||||
(:require
|
||||
#?(:clj [app.common.fressian :as fres])
|
||||
[app.common.data :as d]
|
||||
[app.common.math :as mth]
|
||||
[app.common.pprint :as pp]
|
||||
[app.common.transit :as trans]
|
||||
[app.common.types.shape.path :as path]
|
||||
[clojure.test :as t]))
|
||||
|
||||
|
@ -57,3 +59,19 @@
|
|||
(mapv path/map->PathSegment))
|
||||
(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