mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 22:10:34 +00:00
images
This commit is contained in:
parent
ceadaea98b
commit
10a2c9bc5c
@ -21,8 +21,8 @@
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
||||
;; v2: JVM UUID layout fixed to LE u32 quartet (matches CLJS/WASM).
|
||||
(def ^:const PROTOCOL-VERSION "wasm-shapes-batch/v2")
|
||||
;; v3: fill/stroke image UUIDs use LE u32 quartet on the JVM (v2 only fixed shape ids).
|
||||
(def ^:const PROTOCOL-VERSION "wasm-shapes-batch/v3")
|
||||
|
||||
(def ^:const BASE-PROPS-SIZE 104)
|
||||
(def ^:const FLAG-CLIP-CONTENT 0x01)
|
||||
@ -262,12 +262,28 @@
|
||||
[fills]
|
||||
(+ 4 (* (count fills) types.fills.impl/FILL-U8-SIZE)))
|
||||
|
||||
(defn- write-image-fill-wasm!
|
||||
"Like `types.fills.impl/write-image-fill`, then rewrite the image id with
|
||||
`write-uuid!` (JVM `buf/write-uuid` is BE; WASM expects LE u32 quartet)."
|
||||
[offset dview opacity image]
|
||||
(let [end (types.fills.impl/write-image-fill offset dview opacity image)]
|
||||
(write-uuid! dview (+ offset 4) (get image :id))
|
||||
end))
|
||||
|
||||
(defn- write-fills-section!
|
||||
[dview offset fills]
|
||||
(let [fills (types.fills/coerce (or fills []))
|
||||
(let [fills* (into [] (take types.fills.impl/MAX-FILLS) (or fills []))
|
||||
fills (types.fills/coerce fills*)
|
||||
nbytes (fills-data-byte-size fills)
|
||||
src (.-dbuffer fills)]
|
||||
(copy-u8! dview offset src 0 nbytes)
|
||||
;; Coerce encodes image ids with `buf/write-uuid` (BE on JVM). Patch to LE.
|
||||
(doseq [[i fill] (map-indexed vector fills*)
|
||||
:let [image (:fill-image fill)]
|
||||
:when image]
|
||||
(write-uuid! dview
|
||||
(+ offset 4 (* i types.fills.impl/FILL-U8-SIZE) 4)
|
||||
(get image :id)))
|
||||
(+ offset nbytes)))
|
||||
|
||||
(defn- write-stroke-fill!
|
||||
@ -281,7 +297,7 @@
|
||||
(types.fills.impl/write-gradient-fill offset dview opacity gradient)
|
||||
|
||||
(some? image)
|
||||
(types.fills.impl/write-image-fill offset dview opacity image)
|
||||
(write-image-fill-wasm! offset dview opacity image)
|
||||
|
||||
(some? color)
|
||||
(types.fills.impl/write-solid-fill offset dview opacity color)
|
||||
|
||||
@ -132,6 +132,35 @@
|
||||
(t/is (= (nth expected i) (u8-at rec (+ 4 i)))
|
||||
(str "uuid byte " i)))))
|
||||
|
||||
(t/deftest encode-fill-image-uuid-matches-wasm-le-u32-quartet
|
||||
;; Image fill id must use the same LE layout as shape ids; otherwise WASM
|
||||
;; looks up a swapped id and never binds the host-fetched texture.
|
||||
(let [shape-id #uuid "11111111-1111-1111-1111-111111111111"
|
||||
image-id #uuid "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
|
||||
shape (-> (sample-rect shape-id uuid/zero)
|
||||
(assoc :parent-id uuid/zero
|
||||
:fills [{:fill-image {:id image-id
|
||||
:width 10
|
||||
:height 10
|
||||
:keep-aspect-ratio false}
|
||||
:fill-opacity 1}]
|
||||
:strokes []))
|
||||
rec (encode/encode-shape-record
|
||||
shape
|
||||
{:include-layout? false
|
||||
:include-fills-strokes? true})
|
||||
;; [len][base 104][mask][children count=0][fills count][fill…]
|
||||
;; image uuid is at fill_payload + 4.
|
||||
fill0 (+ 4 104 4 4 4)
|
||||
expected [0xa4 0xa3 0xa2 0xa1
|
||||
0xc2 0xc1 0xb2 0xb1
|
||||
0xd4 0xd3 0xd2 0xd1
|
||||
0xd8 0xd7 0xd6 0xd5]]
|
||||
(t/is (= 0x03 (u8-at rec fill0)) "image fill type tag")
|
||||
(doseq [i (range 16)]
|
||||
(t/is (= (nth expected i) (u8-at rec (+ fill0 4 i)))
|
||||
(str "fill-image uuid byte " i)))))
|
||||
|
||||
(t/deftest encode-text-shape-type-and-grow
|
||||
(let [id (uuid/next)
|
||||
shape {:id id
|
||||
|
||||
@ -622,9 +622,7 @@
|
||||
"Paint geometry/fills as soon as the structural batch is in WASM, before
|
||||
the slower host-attrs pass (text/path/grid/images).
|
||||
|
||||
Leaves `_begin_loading` active afterward so host-attr mutations do not
|
||||
invalidate tiles until the final `_end_loading` in finalize. Optionally
|
||||
invokes `on-shapes-ready` so page-transition blur can lift on this frame."
|
||||
Leaves loading mode OFF so later image stores can invalidate tiles."
|
||||
[on-shapes-ready]
|
||||
(when (wasm/live?)
|
||||
(h/call wasm/internal-module "_end_loading")
|
||||
@ -632,8 +630,7 @@
|
||||
;; Sync render: do not wait for rAF — host-attrs chunks would delay it.
|
||||
(h/call wasm/internal-module "_render_sync")
|
||||
(set! wasm/internal-frame-id nil)
|
||||
(js/console.info "[wasm-batch] structural paint")
|
||||
(h/call wasm/internal-module "_begin_loading")))
|
||||
(js/console.info "[wasm-batch] structural paint")))
|
||||
|
||||
(defonce pending-render (atom false))
|
||||
(defonce shapes-loading? (atom false))
|
||||
@ -796,6 +793,16 @@
|
||||
(when was-loading
|
||||
(request-render "set-objects:flush"))))
|
||||
|
||||
(defn- paint-after-images!
|
||||
"Sync paint after image bytes are stored. Progressive `request-render` can
|
||||
keep early-paint tiles that lack textures; `render_sync` rebuilds them."
|
||||
[]
|
||||
(when (wasm/live?)
|
||||
(stop-progressive-render!)
|
||||
(h/call wasm/internal-module "_render_sync")
|
||||
(set! wasm/internal-frame-id nil)
|
||||
(ug/dispatch! (ug/event "penpot:wasm:render"))))
|
||||
|
||||
(declare get-text-dimensions)
|
||||
|
||||
(defn has-shape
|
||||
@ -1813,7 +1820,7 @@
|
||||
noop-fn
|
||||
(fn []
|
||||
(relayout-after-fonts! shapes text-font-state)
|
||||
(request-render "images-loaded")
|
||||
(paint-after-images!)
|
||||
(when (fn? on-complete) (on-complete)))))
|
||||
;; No pending images — complete immediately.
|
||||
(when on-complete (on-complete)))))
|
||||
@ -2043,7 +2050,7 @@
|
||||
noop-fn
|
||||
(fn []
|
||||
(relayout-after-fonts! prepared-shapes text-font-state-acc)
|
||||
(request-render "images-loaded")))))))))
|
||||
(paint-after-images!)))))))))
|
||||
|
||||
(process-next-client-chunk [index thumbnails-acc full-acc text-font-state-acc]
|
||||
(if (< index total-shapes)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user