Merge pull request #5388 from penpot/azazeln28-feat-start-drawing-paths

🎉 Start drawing paths
This commit is contained in:
Alejandro 2024-12-09 16:27:28 +01:00 committed by GitHub
commit 0eedc036be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 307 additions and 34 deletions

View file

@ -43,7 +43,7 @@
[:div {:class (stl/css :debug-panel-inner)}
(for [option (sort-by d/name dbg/options)]
[:div {:class (stl/css :checkbox-wrapper)}
[:div {:key (d/name option) :class (stl/css :checkbox-wrapper)}
[:span {:class (stl/css-case :checkbox-icon true :global/checked (dbg/enabled? option))
:on-click #(on-toggle-enabled % option)}
(when (dbg/enabled? option) i/status-tick)]

View file

@ -9,9 +9,11 @@
(:require
[app.common.data.macros :as dm]
[app.common.math :as mth]
[app.common.svg.path :as path]
[app.common.uuid :as uuid]
[app.config :as cf]
[app.render-wasm.helpers :as h]
[app.util.debug :as dbg]
[app.util.functions :as fns]
[app.util.http :as http]
[app.util.webapi :as wapi]
@ -185,6 +187,16 @@
(store-image id))))))
fills))
(defn set-shape-path-content
[content]
(let [buffer (path/content->buffer content)
size (.-byteLength buffer)
ptr (h/call internal-module "_alloc_bytes" size)
heap (gobj/get ^js internal-module "HEAPU8")
mem (js/Uint8Array. (.-buffer heap) ptr size)]
(.set mem (js/Uint8Array. buffer))
(h/call internal-module "_set_shape_path_content")))
(defn- translate-blend-mode
[blend-mode]
(case blend-mode
@ -236,15 +248,18 @@
(loop [index 0 pending []]
(if (< index total-shapes)
(let [shape (nth shapes index)
type (dm/get-prop shape :type)
id (dm/get-prop shape :id)
selrect (dm/get-prop shape :selrect)
rotation (dm/get-prop shape :rotation)
transform (dm/get-prop shape :transform)
fills (dm/get-prop shape :fills)
fills (if (= type :group)
[] (dm/get-prop shape :fills))
children (dm/get-prop shape :shapes)
blend-mode (dm/get-prop shape :blend-mode)
opacity (dm/get-prop shape :opacity)
hidden (dm/get-prop shape :hidden)]
hidden (dm/get-prop shape :hidden)
content (dm/get-prop shape :content)]
(use-shape id)
(set-shape-selrect selrect)
@ -254,6 +269,7 @@
(set-shape-children children)
(set-shape-opacity opacity)
(set-shape-hidden hidden)
(when (and (some? content) (= type :path)) (set-shape-path-content content))
(let [pending-fills (doall (set-shape-fills fills))]
(recur (inc index) (into pending pending-fills))))
pending))]
@ -279,9 +295,16 @@
[width height]
(h/call internal-module "_resize_viewbox" width height))
(defn- debug-flags
[]
(cond-> 0
(dbg/enabled? :wasm-viewbox)
(bit-or 2r00000000000000000000000000000001)))
(defn assign-canvas
[canvas]
(let [gl (unchecked-get internal-module "GL")
flags (debug-flags)
context (.getContext ^js canvas "webgl2" canvas-options)
;; Register the context with emscripten
@ -290,7 +313,7 @@
;; Initialize Wasm Render Engine
(h/call internal-module "_init" (/ (.-width ^js canvas) dpr) (/ (.-height ^js canvas) dpr))
(h/call internal-module "_set_render_options" 0x01 dpr))
(h/call internal-module "_set_render_options" flags dpr))
(set! (.-width canvas) (* dpr (.-clientWidth ^js canvas)))
(set! (.-height canvas) (* dpr (.-clientHeight ^js canvas))))

View file

@ -0,0 +1,72 @@
(ns app.render-wasm.path)
(def command-size 28)
#_(defn content->buffer
"Converts the path content into binary format."
[content]
(let [total (count content)
buffer (new js/ArrayBuffer (* total command-size))
dview (new js/DataView buffer)]
(loop [index 0]
(when (< index total)
(let [segment (nth content index)
offset (* index command-size)]
(case (:command segment)
:move-to
(let [{:keys [x y]} (:params segment)]
(.setUint16 dview (+ offset 0) 1)
(.setFloat32 dview (+ offset 20) x)
(.setFloat32 dview (+ offset 24) y))
:line-to
(let [{:keys [x y]} (:params segment)]
(.setUint16 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)]
(.setUint16 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
(.setUint16 dview (+ offset 0) 4))
(recur (inc index)))))
buffer))
#_(defn buffer->content
"Converts the a buffer to a path content vector"
[buffer]
(assert (instance? js/ArrayBuffer buffer) "expected ArrayBuffer instance")
(let [total (/ (.-byteLength buffer) command-size)
dview (new js/DataView buffer)]
(loop [index 0
result []]
(if (< index total)
(let [offset (* index command-size)
type (.getUint16 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))))

View file

@ -8,7 +8,6 @@
(: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]))
@ -120,6 +119,7 @@
:opacity (api/set-shape-opacity v)
:hidden (api/set-shape-hidden v)
:shapes (api/set-shape-children v)
:content (api/set-shape-path-content v)
nil)
;; when something synced with wasm
;; is modified, we need to request

View file

@ -92,7 +92,10 @@
:bool-shapes
;; Show some information about the WebGL context.
:gl-context})
:gl-context
;; Show viewbox
:wasm-viewbox})
(defn enable!
[option]