mirror of
https://github.com/penpot/penpot.git
synced 2025-12-12 06:24:17 +01:00
Merge pull request #7106 from penpot/niwinz-develop-modifiers-enhacements
⚡ Several enhancements on how shape data is written on memory
This commit is contained in:
@@ -5,7 +5,8 @@
|
|||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.common.buffer
|
(ns app.common.buffer
|
||||||
"A collection of helpers and macros for work with byte buffers"
|
"A collection of helpers and macros for work with byte
|
||||||
|
buffer (ByteBuffer on JVM and DataView on JS)."
|
||||||
(:refer-clojure :exclude [clone])
|
(:refer-clojure :exclude [clone])
|
||||||
(:require
|
(:require
|
||||||
[app.common.uuid :as uuid])
|
[app.common.uuid :as uuid])
|
||||||
@@ -81,6 +82,13 @@
|
|||||||
(let [target (with-meta target {:tag 'java.nio.ByteBuffer})]
|
(let [target (with-meta target {:tag 'java.nio.ByteBuffer})]
|
||||||
`(.put ~target ~offset (unchecked-byte ~value)))))
|
`(.put ~target ~offset (unchecked-byte ~value)))))
|
||||||
|
|
||||||
|
(defmacro write-u8
|
||||||
|
[target offset value]
|
||||||
|
(if (:ns &env)
|
||||||
|
`(.setUint8 ~target ~offset ~value true)
|
||||||
|
(let [target (with-meta target {:tag 'java.nio.ByteBuffer})]
|
||||||
|
`(.put ~target ~offset (unchecked-byte ~value)))))
|
||||||
|
|
||||||
(defmacro write-bool
|
(defmacro write-bool
|
||||||
[target offset value]
|
[target offset value]
|
||||||
(if (:ns &env)
|
(if (:ns &env)
|
||||||
@@ -102,6 +110,18 @@
|
|||||||
(let [target (with-meta target {:tag 'java.nio.ByteBuffer})]
|
(let [target (with-meta target {:tag 'java.nio.ByteBuffer})]
|
||||||
`(.putInt ~target ~offset (unchecked-int ~value)))))
|
`(.putInt ~target ~offset (unchecked-int ~value)))))
|
||||||
|
|
||||||
|
(defmacro write-u32
|
||||||
|
[target offset value]
|
||||||
|
(if (:ns &env)
|
||||||
|
`(.setUint32 ~target ~offset ~value true)
|
||||||
|
(let [target (with-meta target {:tag 'java.nio.ByteBuffer})]
|
||||||
|
`(.putInt ~target ~offset (unchecked-int ~value)))))
|
||||||
|
|
||||||
|
(defmacro write-i32
|
||||||
|
"Idiomatic alias for `write-int`"
|
||||||
|
[target offset value]
|
||||||
|
`(write-int ~target ~offset ~value))
|
||||||
|
|
||||||
(defmacro write-float
|
(defmacro write-float
|
||||||
[target offset value]
|
[target offset value]
|
||||||
(if (:ns &env)
|
(if (:ns &env)
|
||||||
@@ -109,6 +129,11 @@
|
|||||||
(let [target (with-meta target {:tag 'java.nio.ByteBuffer})]
|
(let [target (with-meta target {:tag 'java.nio.ByteBuffer})]
|
||||||
`(.putFloat ~target ~offset (unchecked-float ~value)))))
|
`(.putFloat ~target ~offset (unchecked-float ~value)))))
|
||||||
|
|
||||||
|
(defmacro write-f32
|
||||||
|
"Idiomatic alias for `write-float`."
|
||||||
|
[target offset value]
|
||||||
|
`(write-float ~target ~offset ~value))
|
||||||
|
|
||||||
(defmacro write-uuid
|
(defmacro write-uuid
|
||||||
[target offset value]
|
[target offset value]
|
||||||
(if (:ns &env)
|
(if (:ns &env)
|
||||||
|
|||||||
@@ -58,13 +58,13 @@
|
|||||||
([{:keys [id points selrect] :as shape} content]
|
([{:keys [id points selrect] :as shape} content]
|
||||||
(wasm.api/use-shape id)
|
(wasm.api/use-shape id)
|
||||||
(wasm.api/set-shape-text id content)
|
(wasm.api/set-shape-text id content)
|
||||||
(let [dimension (wasm.api/text-dimensions)
|
(let [dimension (wasm.api/get-text-dimensions)
|
||||||
resize-v
|
resize-v (gpt/point
|
||||||
(gpt/point
|
(/ (:width dimension) (-> selrect :width))
|
||||||
(/ (:width dimension) (-> selrect :width))
|
(/ (:height dimension) (-> selrect :height)))
|
||||||
(/ (:height dimension) (-> selrect :height)))
|
|
||||||
|
origin (first points)]
|
||||||
|
|
||||||
origin (first points)]
|
|
||||||
{id
|
{id
|
||||||
{:modifiers
|
{:modifiers
|
||||||
(ctm/resize-modifiers
|
(ctm/resize-modifiers
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
(if (features/active-feature? @st/state "render-wasm/v1")
|
(if (features/active-feature? @st/state "render-wasm/v1")
|
||||||
(let [transform (gsh/transform-str shape)
|
(let [transform (gsh/transform-str shape)
|
||||||
{:keys [id x y grow-type]} shape
|
{:keys [id x y grow-type]} shape
|
||||||
{:keys [width height]} (if (= :fixed grow-type) shape (wasm.api/text-dimensions id))]
|
{:keys [width height]} (if (= :fixed grow-type) shape (wasm.api/get-text-dimensions id))]
|
||||||
[:rect.main.viewport-selrect
|
[:rect.main.viewport-selrect
|
||||||
{:x x
|
{:x x
|
||||||
:y y
|
:y y
|
||||||
|
|||||||
@@ -310,7 +310,7 @@
|
|||||||
|
|
||||||
[x y width height]
|
[x y width height]
|
||||||
(if (features/active-feature? @st/state "render-wasm/v1")
|
(if (features/active-feature? @st/state "render-wasm/v1")
|
||||||
(let [{:keys [max-width height]} (wasm.api/text-dimensions shape-id)
|
(let [{:keys [max-width height]} (wasm.api/get-text-dimensions shape-id)
|
||||||
{:keys [x y]} (:selrect shape)]
|
{:keys [x y]} (:selrect shape)]
|
||||||
|
|
||||||
[x y max-width height])
|
[x y max-width height])
|
||||||
|
|||||||
@@ -309,7 +309,7 @@
|
|||||||
(ted/export-content))]
|
(ted/export-content))]
|
||||||
(wasm.api/use-shape edition)
|
(wasm.api/use-shape edition)
|
||||||
(wasm.api/set-shape-text-content edition content)
|
(wasm.api/set-shape-text-content edition content)
|
||||||
(let [dimension (wasm.api/text-dimensions)]
|
(let [dimension (wasm.api/get-text-dimensions)]
|
||||||
(st/emit! (dwt/resize-text-editor edition dimension))
|
(st/emit! (dwt/resize-text-editor edition dimension))
|
||||||
(wasm.api/clear-drawing-cache)
|
(wasm.api/clear-drawing-cache)
|
||||||
(wasm.api/request-render "content"))))))
|
(wasm.api/request-render "content"))))))
|
||||||
|
|||||||
@@ -208,7 +208,7 @@
|
|||||||
(defn- process-fill-image
|
(defn- process-fill-image
|
||||||
[shape-id fill]
|
[shape-id fill]
|
||||||
(when-let [image (:fill-image fill)]
|
(when-let [image (:fill-image fill)]
|
||||||
(let [id (dm/get-prop image :id)
|
(let [id (get image :id)
|
||||||
buffer (uuid/get-u32 id)
|
buffer (uuid/get-u32 id)
|
||||||
cached-image? (h/call wasm/internal-module "_is_image_cached"
|
cached-image? (h/call wasm/internal-module "_is_image_cached"
|
||||||
(aget buffer 0)
|
(aget buffer 0)
|
||||||
@@ -283,7 +283,7 @@
|
|||||||
(h/call wasm/internal-module "_add_shape_stroke_fill"))
|
(h/call wasm/internal-module "_add_shape_stroke_fill"))
|
||||||
|
|
||||||
(some? image)
|
(some? image)
|
||||||
(let [image-id (dm/get-prop image :id)
|
(let [image-id (get image :id)
|
||||||
buffer (uuid/get-u32 image-id)
|
buffer (uuid/get-u32 image-id)
|
||||||
cached-image? (h/call wasm/internal-module "_is_image_cached" (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))]
|
cached-image? (h/call wasm/internal-module "_is_image_cached" (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))]
|
||||||
(types.fills.impl/write-image-fill offset dview opacity image)
|
(types.fills.impl/write-image-fill offset dview opacity image)
|
||||||
@@ -334,7 +334,7 @@
|
|||||||
|
|
||||||
(defn set-shape-vertical-align
|
(defn set-shape-vertical-align
|
||||||
[vertical-align]
|
[vertical-align]
|
||||||
(h/call wasm/internal-module "_set_shape_vertical_align" (sr/serialize-vertical-align vertical-align)))
|
(h/call wasm/internal-module "_set_shape_vertical_align" (sr/translate-vertical-align vertical-align)))
|
||||||
|
|
||||||
(defn set-shape-opacity
|
(defn set-shape-opacity
|
||||||
[opacity]
|
[opacity]
|
||||||
@@ -378,8 +378,11 @@
|
|||||||
(h/call wasm/internal-module "_set_shape_blur" type hidden value)))
|
(h/call wasm/internal-module "_set_shape_blur" type hidden value)))
|
||||||
|
|
||||||
(defn set-shape-corners
|
(defn set-shape-corners
|
||||||
[corners]
|
[shape]
|
||||||
(let [[r1 r2 r3 r4] corners]
|
(let [r1 (get shape :r1)
|
||||||
|
r2 (get shape :r2)
|
||||||
|
r3 (get shape :r3)
|
||||||
|
r4 (get shape :r4)]
|
||||||
(h/call wasm/internal-module "_set_shape_corners"
|
(h/call wasm/internal-module "_set_shape_corners"
|
||||||
(d/nilv r1 0)
|
(d/nilv r1 0)
|
||||||
(d/nilv r2 0)
|
(d/nilv r2 0)
|
||||||
@@ -466,9 +469,11 @@
|
|||||||
;; alligned writes, so for heteregeneus writes we use
|
;; alligned writes, so for heteregeneus writes we use
|
||||||
;; the buffer abstraction (DataView) for perform
|
;; the buffer abstraction (DataView) for perform
|
||||||
;; surgical writes.
|
;; surgical writes.
|
||||||
(mem/write-u8 dview (+ offset 0) (sr/translate-grid-track-type type))
|
(-> offset
|
||||||
(mem/write-f32 dview (+ offset 1) value)
|
(mem/write-u8 dview (sr/translate-grid-track-type type))
|
||||||
(+ offset GRID-LAYOUT-ROW-U8-SIZE))
|
(mem/write-f32 dview value)
|
||||||
|
(mem/assert-written offset GRID-LAYOUT-ROW-U8-SIZE)))
|
||||||
|
|
||||||
offset
|
offset
|
||||||
entries)
|
entries)
|
||||||
|
|
||||||
@@ -486,9 +491,12 @@
|
|||||||
;; alligned writes, so for heteregeneus writes we use
|
;; alligned writes, so for heteregeneus writes we use
|
||||||
;; the buffer abstraction (DataView) for perform
|
;; the buffer abstraction (DataView) for perform
|
||||||
;; surgical writes.
|
;; surgical writes.
|
||||||
(mem/write-u8 dview (+ offset 0) (sr/translate-grid-track-type type))
|
(-> offset
|
||||||
(mem/write-f32 dview (+ offset 1) value)
|
(mem/write-u8 dview (sr/translate-grid-track-type type))
|
||||||
(+ offset GRID-LAYOUT-COLUMN-U8-SIZE))
|
(mem/write-f32 dview value)
|
||||||
|
(mem/assert-written offset GRID-LAYOUT-COLUMN-U8-SIZE)))
|
||||||
|
|
||||||
|
|
||||||
offset
|
offset
|
||||||
entries)
|
entries)
|
||||||
|
|
||||||
@@ -496,83 +504,82 @@
|
|||||||
|
|
||||||
(defn set-grid-layout-cells
|
(defn set-grid-layout-cells
|
||||||
[cells]
|
[cells]
|
||||||
(let [entries (vals cells)
|
(let [size (mem/get-alloc-size cells GRID-LAYOUT-CELL-U8-SIZE)
|
||||||
size (mem/get-alloc-size cells GRID-LAYOUT-CELL-U8-SIZE)
|
|
||||||
offset (mem/alloc size)
|
offset (mem/alloc size)
|
||||||
heap (-> (mem/get-heap-u8)
|
dview (mem/get-data-view)]
|
||||||
(mem/view offset size))]
|
|
||||||
|
|
||||||
(loop [entries (seq entries)
|
(reduce-kv (fn [offset _ cell]
|
||||||
current-offset 0]
|
(let [shape-id (-> (get cell :shapes) first)]
|
||||||
(when-not (empty? entries)
|
(-> offset
|
||||||
(let [cell (first entries)]
|
;; row: [u8; 4],
|
||||||
|
(mem/write-i32 dview (get cell :row))
|
||||||
|
|
||||||
;; row: [u8; 4],
|
;; row_span: [u8; 4],
|
||||||
(.set heap (sr/i32->u8 (:row cell)) (+ current-offset 0))
|
(mem/write-i32 dview (get cell :row-span))
|
||||||
|
|
||||||
;; row_span: [u8; 4],
|
;; column: [u8; 4],
|
||||||
(.set heap (sr/i32->u8 (:row-span cell)) (+ current-offset 4))
|
(mem/write-i32 dview (get cell :column))
|
||||||
|
|
||||||
;; column: [u8; 4],
|
;; column_span: [u8; 4],
|
||||||
(.set heap (sr/i32->u8 (:column cell)) (+ current-offset 8))
|
(mem/write-i32 dview (get cell :column-span))
|
||||||
|
|
||||||
;; column_span: [u8; 4],
|
;; has_align_self: u8,
|
||||||
(.set heap (sr/i32->u8 (:column-span cell)) (+ current-offset 12))
|
(mem/write-bool dview (some? (get cell :align-self)))
|
||||||
|
|
||||||
;; has_align_self: u8,
|
;; align_self: u8,
|
||||||
(.set heap (sr/bool->u8 (some? (:align-self cell))) (+ current-offset 16))
|
(mem/write-u8 dview (get cell :align-self))
|
||||||
|
|
||||||
;; align_self: u8,
|
;; has_justify_self: u8,
|
||||||
(.set heap (sr/u8 (sr/translate-align-self (:align-self cell))) (+ current-offset 17))
|
(mem/write-bool dview (get cell :justify-self))
|
||||||
|
|
||||||
;; has_justify_self: u8,
|
;; justify_self: u8,
|
||||||
(.set heap (sr/bool->u8 (some? (:justify-self cell))) (+ current-offset 18))
|
(mem/write-u8 dview (sr/translate-justify-self (get cell :justify-self)))
|
||||||
|
|
||||||
;; justify_self: u8,
|
;; has_shape_id: u8,
|
||||||
(.set heap (sr/u8 (sr/translate-justify-self (:justify-self cell))) (+ current-offset 19))
|
;; (.set heap (sr/bool->u8 (d/not-empty? (:shapes cell))) (+ current-offset 20))
|
||||||
|
(mem/write-u8 dview (some? shape-id))
|
||||||
|
|
||||||
;; has_shape_id: u8,
|
;; shape_id_a: [u8; 4],
|
||||||
(.set heap (sr/bool->u8 (d/not-empty? (:shapes cell))) (+ current-offset 20))
|
;; shape_id_b: [u8; 4],
|
||||||
|
;; shape_id_c: [u8; 4],
|
||||||
|
;; shape_id_d: [u8; 4],
|
||||||
|
(mem/write-uuid dview (d/nilv shape-id uuid/zero))
|
||||||
|
(mem/assert-written offset GRID-LAYOUT-CELL-U8-SIZE))))
|
||||||
|
|
||||||
;; shape_id_a: [u8; 4],
|
offset
|
||||||
;; shape_id_b: [u8; 4],
|
cells)
|
||||||
;; shape_id_c: [u8; 4],
|
|
||||||
;; shape_id_d: [u8; 4],
|
|
||||||
(.set heap (sr/uuid->u8 (or (-> cell :shapes first) uuid/zero)) (+ current-offset 21))
|
|
||||||
|
|
||||||
(recur (rest entries) (+ current-offset GRID-LAYOUT-CELL-U8-SIZE)))))
|
|
||||||
|
|
||||||
(h/call wasm/internal-module "_set_grid_cells")))
|
(h/call wasm/internal-module "_set_grid_cells")))
|
||||||
|
|
||||||
(defn set-grid-layout
|
(defn set-grid-layout
|
||||||
[shape]
|
[shape]
|
||||||
(set-grid-layout-data shape)
|
(set-grid-layout-data shape)
|
||||||
(set-grid-layout-rows (:layout-grid-rows shape))
|
(set-grid-layout-rows (get shape :layout-grid-rows))
|
||||||
(set-grid-layout-columns (:layout-grid-columns shape))
|
(set-grid-layout-columns (get shape :layout-grid-columns))
|
||||||
(set-grid-layout-cells (:layout-grid-cells shape)))
|
(set-grid-layout-cells (get shape :layout-grid-cells)))
|
||||||
|
|
||||||
(defn set-layout-child
|
(defn set-layout-child
|
||||||
[shape]
|
[shape]
|
||||||
(let [margins (dm/get-prop shape :layout-item-margin)
|
(let [margins (get shape :layout-item-margin)
|
||||||
margin-top (or (dm/get-prop margins :m1) 0)
|
margin-top (get margins :m1 0)
|
||||||
margin-right (or (dm/get-prop margins :m2) 0)
|
margin-right (get margins :m2 0)
|
||||||
margin-bottom (or (dm/get-prop margins :m3) 0)
|
margin-bottom (get margins :m3 0)
|
||||||
margin-left (or (dm/get-prop margins :m4) 0)
|
margin-left (get margins :m4 0)
|
||||||
|
|
||||||
h-sizing (-> (dm/get-prop shape :layout-item-h-sizing) (or :fix) sr/translate-layout-sizing)
|
h-sizing (-> (get shape :layout-item-h-sizing) sr/translate-layout-sizing)
|
||||||
v-sizing (-> (dm/get-prop shape :layout-item-v-sizing) (or :fix) sr/translate-layout-sizing)
|
v-sizing (-> (get shape :layout-item-v-sizing) sr/translate-layout-sizing)
|
||||||
align-self (-> (dm/get-prop shape :layout-item-align-self) sr/translate-align-self)
|
align-self (-> (get shape :layout-item-align-self) sr/translate-align-self)
|
||||||
|
|
||||||
max-h (dm/get-prop shape :layout-item-max-h)
|
max-h (get shape :layout-item-max-h)
|
||||||
has-max-h (some? max-h)
|
has-max-h (some? max-h)
|
||||||
min-h (dm/get-prop shape :layout-item-min-h)
|
min-h (get shape :layout-item-min-h)
|
||||||
has-min-h (some? min-h)
|
has-min-h (some? min-h)
|
||||||
max-w (dm/get-prop shape :layout-item-max-w)
|
max-w (get shape :layout-item-max-w)
|
||||||
has-max-w (some? max-w)
|
has-max-w (some? max-w)
|
||||||
min-w (dm/get-prop shape :layout-item-min-w)
|
min-w (get shape :layout-item-min-w)
|
||||||
has-min-w (some? min-w)
|
has-min-w (some? min-w)
|
||||||
is-absolute (boolean (dm/get-prop shape :layout-item-absolute))
|
is-absolute (boolean (get shape :layout-item-absolute))
|
||||||
z-index (-> (dm/get-prop shape :layout-item-z-index) (or 0))]
|
z-index (get shape :layout-item-z-index)]
|
||||||
(h/call wasm/internal-module
|
(h/call wasm/internal-module
|
||||||
"_set_layout_child_data"
|
"_set_layout_child_data"
|
||||||
margin-top
|
margin-top
|
||||||
@@ -582,17 +589,17 @@
|
|||||||
h-sizing
|
h-sizing
|
||||||
v-sizing
|
v-sizing
|
||||||
has-max-h
|
has-max-h
|
||||||
(or max-h 0)
|
(d/nilv max-h 0)
|
||||||
has-min-h
|
has-min-h
|
||||||
(or min-h 0)
|
(d/nilv min-h 0)
|
||||||
has-max-w
|
has-max-w
|
||||||
(or max-w 0)
|
(d/nilv max-w 0)
|
||||||
has-min-w
|
has-min-w
|
||||||
(or min-w 0)
|
(d/nilv min-w 0)
|
||||||
(some? align-self)
|
(some? align-self)
|
||||||
(or align-self 0)
|
(d/nilv align-self 0)
|
||||||
is-absolute
|
is-absolute
|
||||||
z-index)))
|
(d/nilv z-index))))
|
||||||
|
|
||||||
(defn clear-layout
|
(defn clear-layout
|
||||||
[]
|
[]
|
||||||
@@ -615,50 +622,63 @@
|
|||||||
(defn set-shape-shadows
|
(defn set-shape-shadows
|
||||||
[shadows]
|
[shadows]
|
||||||
(h/call wasm/internal-module "_clear_shape_shadows")
|
(h/call wasm/internal-module "_clear_shape_shadows")
|
||||||
(let [total-shadows (count shadows)]
|
|
||||||
(loop [index 0]
|
|
||||||
(when (< index total-shadows)
|
|
||||||
(let [shadow (nth shadows index)
|
|
||||||
color (dm/get-prop shadow :color)
|
|
||||||
blur (dm/get-prop shadow :blur)
|
|
||||||
rgba (sr-clr/hex->u32argb (dm/get-prop color :color) (dm/get-prop color :opacity))
|
|
||||||
hidden (dm/get-prop shadow :hidden)
|
|
||||||
x (dm/get-prop shadow :offset-x)
|
|
||||||
y (dm/get-prop shadow :offset-y)
|
|
||||||
spread (dm/get-prop shadow :spread)
|
|
||||||
style (dm/get-prop shadow :style)]
|
|
||||||
(h/call wasm/internal-module "_add_shape_shadow" rgba blur spread x y (sr/translate-shadow-style style) hidden)
|
|
||||||
(recur (inc index)))))))
|
|
||||||
|
|
||||||
;; (declare propagate-apply)
|
(run! (fn [shadow]
|
||||||
|
(let [color (get shadow :color)
|
||||||
|
blur (get shadow :blur)
|
||||||
|
rgba (sr-clr/hex->u32argb (get color :color)
|
||||||
|
(get color :opacity))
|
||||||
|
hidden (get shadow :hidden)
|
||||||
|
x (get shadow :offset-x)
|
||||||
|
y (get shadow :offset-y)
|
||||||
|
spread (get shadow :spread)
|
||||||
|
style (get shadow :style)]
|
||||||
|
(h/call wasm/internal-module "_add_shape_shadow"
|
||||||
|
rgba
|
||||||
|
blur
|
||||||
|
spread
|
||||||
|
x
|
||||||
|
y
|
||||||
|
(sr/translate-shadow-style style)
|
||||||
|
hidden)))
|
||||||
|
shadows))
|
||||||
|
|
||||||
(defn set-shape-text-content
|
(defn set-shape-text-content
|
||||||
[shape-id content]
|
[shape-id content]
|
||||||
(h/call wasm/internal-module "_clear_shape_text")
|
(h/call wasm/internal-module "_clear_shape_text")
|
||||||
(set-shape-vertical-align (dm/get-prop content :vertical-align))
|
(set-shape-vertical-align (get content :vertical-align))
|
||||||
|
|
||||||
(let [paragraph-set (first (dm/get-prop content :children))
|
(let [paragraph-set (first (get content :children))
|
||||||
paragraphs (dm/get-prop paragraph-set :children)
|
paragraphs (get paragraph-set :children)
|
||||||
fonts (fonts/get-content-fonts content)
|
fonts (fonts/get-content-fonts content)
|
||||||
emoji? (atom false)
|
total (count paragraphs)]
|
||||||
languages (atom #{})]
|
|
||||||
(loop [index 0]
|
(loop [index 0
|
||||||
(when (< index (count paragraphs))
|
emoji? false
|
||||||
|
langs #{}]
|
||||||
|
|
||||||
|
(if (< index total)
|
||||||
(let [paragraph (nth paragraphs index)
|
(let [paragraph (nth paragraphs index)
|
||||||
leaves (dm/get-prop paragraph :children)]
|
leaves (get paragraph :children)]
|
||||||
(when (seq leaves)
|
(if (empty? (seq leaves))
|
||||||
(let [text (apply str (map :text leaves))]
|
(recur (inc index)
|
||||||
(when (and (not @emoji?) (t/contains-emoji? text))
|
emoji?
|
||||||
(reset! emoji? true))
|
langs)
|
||||||
(swap! languages into (t/get-languages text))
|
|
||||||
(t/write-shape-text leaves paragraph text))
|
|
||||||
(recur (inc index))))))
|
|
||||||
|
|
||||||
(let [updated-fonts
|
(let [text (apply str (map :text leaves))
|
||||||
(-> fonts
|
emoji? (if emoji? emoji? (t/contains-emoji? text))
|
||||||
(cond-> @emoji? (f/add-emoji-font))
|
langs (t/collect-used-languages langs text)]
|
||||||
(f/add-noto-fonts @languages))]
|
|
||||||
(f/store-fonts shape-id updated-fonts))))
|
(t/write-shape-text leaves paragraph text)
|
||||||
|
(recur (inc index)
|
||||||
|
emoji?
|
||||||
|
langs))))
|
||||||
|
|
||||||
|
(let [updated-fonts
|
||||||
|
(-> fonts
|
||||||
|
(cond-> ^boolean emoji? (f/add-emoji-font))
|
||||||
|
(f/add-noto-fonts langs))]
|
||||||
|
(f/store-fonts shape-id updated-fonts))))))
|
||||||
|
|
||||||
(defn set-shape-text
|
(defn set-shape-text
|
||||||
[shape-id content]
|
[shape-id content]
|
||||||
@@ -670,16 +690,17 @@
|
|||||||
[grow-type]
|
[grow-type]
|
||||||
(h/call wasm/internal-module "_set_shape_grow_type" (sr/translate-grow-type grow-type)))
|
(h/call wasm/internal-module "_set_shape_grow_type" (sr/translate-grow-type grow-type)))
|
||||||
|
|
||||||
(defn text-dimensions
|
(defn get-text-dimensions
|
||||||
([id]
|
([id]
|
||||||
(use-shape id)
|
(use-shape id)
|
||||||
(text-dimensions))
|
(get-text-dimensions))
|
||||||
([]
|
([]
|
||||||
(let [offset (h/call wasm/internal-module "_get_text_dimensions")
|
(let [offset (-> (h/call wasm/internal-module "_get_text_dimensions")
|
||||||
heapf32 (mem/get-heap-f32)
|
(mem/->offset-32))
|
||||||
width (aget heapf32 (mem/->offset-32 offset))
|
heapf32 (mem/get-heap-f32)
|
||||||
height (aget heapf32 (mem/->offset-32 (+ offset 4)))
|
width (aget heapf32 (+ offset 0))
|
||||||
max-width (aget heapf32 (mem/->offset-32 (+ offset 8)))]
|
height (aget heapf32 (+ offset 1))
|
||||||
|
max-width (aget heapf32 (+ offset 2))]
|
||||||
(mem/free)
|
(mem/free)
|
||||||
{:width width :height height :max-width max-width})))
|
{:width width :height height :max-width max-width})))
|
||||||
|
|
||||||
@@ -699,37 +720,34 @@
|
|||||||
[objects shape]
|
[objects shape]
|
||||||
(perf/begin-measure "set-object")
|
(perf/begin-measure "set-object")
|
||||||
(let [id (dm/get-prop shape :id)
|
(let [id (dm/get-prop shape :id)
|
||||||
parent-id (dm/get-prop shape :parent-id)
|
|
||||||
type (dm/get-prop shape :type)
|
type (dm/get-prop shape :type)
|
||||||
masked (dm/get-prop shape :masked-group)
|
|
||||||
selrect (dm/get-prop shape :selrect)
|
parent-id (get shape :parent-id)
|
||||||
constraint-h (dm/get-prop shape :constraints-h)
|
masked (get shape :masked-group)
|
||||||
constraint-v (dm/get-prop shape :constraints-v)
|
selrect (get shape :selrect)
|
||||||
|
constraint-h (get shape :constraints-h)
|
||||||
|
constraint-v (get shape :constraints-v)
|
||||||
clip-content (if (= type :frame)
|
clip-content (if (= type :frame)
|
||||||
(not (dm/get-prop shape :show-content))
|
(not (get shape :show-content))
|
||||||
false)
|
false)
|
||||||
rotation (dm/get-prop shape :rotation)
|
rotation (get shape :rotation)
|
||||||
transform (dm/get-prop shape :transform)
|
transform (get shape :transform)
|
||||||
|
|
||||||
;; Groups from imported SVG's can have their own fills
|
;; Groups from imported SVG's can have their own fills
|
||||||
fills (dm/get-prop shape :fills)
|
fills (get shape :fills)
|
||||||
|
|
||||||
strokes (if (= type :group)
|
strokes (if (= type :group)
|
||||||
[] (dm/get-prop shape :strokes))
|
[] (get shape :strokes))
|
||||||
children (dm/get-prop shape :shapes)
|
children (get shape :shapes)
|
||||||
blend-mode (dm/get-prop shape :blend-mode)
|
blend-mode (get shape :blend-mode)
|
||||||
opacity (dm/get-prop shape :opacity)
|
opacity (get shape :opacity)
|
||||||
hidden (dm/get-prop shape :hidden)
|
hidden (get shape :hidden)
|
||||||
content (dm/get-prop shape :content)
|
content (get shape :content)
|
||||||
bool-type (dm/get-prop shape :bool-type)
|
bool-type (get shape :bool-type)
|
||||||
grow-type (dm/get-prop shape :grow-type)
|
grow-type (get shape :grow-type)
|
||||||
blur (dm/get-prop shape :blur)
|
blur (get shape :blur)
|
||||||
svg-attrs (dm/get-prop shape :svg-attrs)
|
svg-attrs (get shape :svg-attrs)
|
||||||
shadows (dm/get-prop shape :shadow)
|
shadows (get shape :shadow)]
|
||||||
r1 (dm/get-prop shape :r1)
|
|
||||||
r2 (dm/get-prop shape :r2)
|
|
||||||
r3 (dm/get-prop shape :r3)
|
|
||||||
r4 (dm/get-prop shape :r4)]
|
|
||||||
|
|
||||||
(use-shape id)
|
(use-shape id)
|
||||||
(set-parent-id parent-id)
|
(set-parent-id parent-id)
|
||||||
@@ -743,7 +761,7 @@
|
|||||||
(set-shape-opacity opacity)
|
(set-shape-opacity opacity)
|
||||||
(set-shape-hidden hidden)
|
(set-shape-hidden hidden)
|
||||||
(set-shape-children children)
|
(set-shape-children children)
|
||||||
(set-shape-corners [r1 r2 r3 r4])
|
(set-shape-corners shape)
|
||||||
(when (and (= type :group) masked)
|
(when (and (= type :group) masked)
|
||||||
(set-masked masked))
|
(set-masked masked))
|
||||||
(when (some? blur)
|
(when (some? blur)
|
||||||
@@ -773,7 +791,6 @@
|
|||||||
(perf/end-measure "set-object")
|
(perf/end-measure "set-object")
|
||||||
pending)))
|
pending)))
|
||||||
|
|
||||||
|
|
||||||
(defn process-pending
|
(defn process-pending
|
||||||
[pending]
|
[pending]
|
||||||
(let [event (js/CustomEvent. "wasm:set-objects-finished")
|
(let [event (js/CustomEvent. "wasm:set-objects-finished")
|
||||||
|
|||||||
@@ -151,21 +151,17 @@
|
|||||||
"italic" 1
|
"italic" 1
|
||||||
0))
|
0))
|
||||||
|
|
||||||
(defn serialize-font-id
|
(defn normalize-font-id
|
||||||
[font-id]
|
[font-id]
|
||||||
(try
|
(try
|
||||||
(if (nil? font-id)
|
(if ^boolean (str/starts-with? font-id "gfont-")
|
||||||
(do
|
(google-font-id->uuid font-id)
|
||||||
[uuid/zero])
|
(let [no-prefix (subs font-id (inc (str/index-of font-id "-")))]
|
||||||
(let [google-font? (str/starts-with? font-id "gfont-")]
|
(if (or (nil? no-prefix) (not (string? no-prefix)) (str/blank? no-prefix))
|
||||||
(if google-font?
|
uuid/zero
|
||||||
(uuid/get-u32 (google-font-id->uuid font-id))
|
(uuid/parse no-prefix))))
|
||||||
(let [no-prefix (subs font-id (inc (str/index-of font-id "-")))]
|
|
||||||
(if (or (nil? no-prefix) (not (string? no-prefix)) (str/blank? no-prefix))
|
|
||||||
[uuid/zero]
|
|
||||||
(uuid/get-u32 (uuid/uuid no-prefix)))))))
|
|
||||||
(catch :default _e
|
(catch :default _e
|
||||||
[uuid/zero])))
|
uuid/zero)))
|
||||||
|
|
||||||
(defn serialize-font-weight
|
(defn serialize-font-weight
|
||||||
[font-weight]
|
[font-weight]
|
||||||
|
|||||||
@@ -6,24 +6,31 @@
|
|||||||
|
|
||||||
(ns app.render-wasm.api.texts
|
(ns app.render-wasm.api.texts
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.types.fills.impl :as types.fills.impl]
|
[app.common.types.fills.impl :as types.fills.impl]
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
[app.render-wasm.api.fonts :as f]
|
[app.render-wasm.api.fonts :as f]
|
||||||
[app.render-wasm.helpers :as h]
|
[app.render-wasm.helpers :as h]
|
||||||
[app.render-wasm.mem :as mem]
|
[app.render-wasm.mem :as mem]
|
||||||
[app.render-wasm.serializers :as sr]
|
[app.render-wasm.serializers :as sr]
|
||||||
[app.render-wasm.wasm :as wasm]))
|
[app.render-wasm.wasm :as wasm]))
|
||||||
|
|
||||||
(defn utf8->buffer [text]
|
(def ^:const PARAGRAPH-ATTR-U8-SIZE 44)
|
||||||
|
(def ^:const LEAF-ATTR-U8-SIZE 56)
|
||||||
|
|
||||||
|
(defn- encode-text
|
||||||
|
"Into an UTF8 buffer. Returns an ArrayBuffer instance"
|
||||||
|
[text]
|
||||||
(let [encoder (js/TextEncoder.)]
|
(let [encoder (js/TextEncoder.)]
|
||||||
(.encode encoder text)))
|
(.encode encoder text)))
|
||||||
|
|
||||||
(defn set-text-leaf-fills
|
(defn- write-leaf-fills
|
||||||
[fills current-offset dview]
|
[offset dview fills]
|
||||||
(reduce (fn [offset fill]
|
(reduce (fn [offset fill]
|
||||||
(let [opacity (or (:fill-opacity fill) 1.0)
|
(let [opacity (get fill :fill-opacity 1.0)
|
||||||
color (:fill-color fill)
|
color (get fill :fill-color)
|
||||||
gradient (:fill-color-gradient fill)
|
gradient (get fill :fill-color-gradient)
|
||||||
image (:fill-image fill)]
|
image (get fill :fill-image)]
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(some? color)
|
(some? color)
|
||||||
@@ -33,115 +40,119 @@
|
|||||||
(types.fills.impl/write-gradient-fill offset dview opacity gradient)
|
(types.fills.impl/write-gradient-fill offset dview opacity gradient)
|
||||||
|
|
||||||
(some? image)
|
(some? image)
|
||||||
(types.fills.impl/write-image-fill offset dview opacity image))
|
(types.fills.impl/write-image-fill offset dview opacity image))))
|
||||||
|
|
||||||
(+ offset types.fills.impl/FILL-U8-SIZE)))
|
offset
|
||||||
current-offset
|
|
||||||
fills))
|
fills))
|
||||||
|
|
||||||
(defn total-fills-count
|
(defn- get-total-fills
|
||||||
[leaves]
|
[leaves]
|
||||||
(reduce #(+ %1 (count (:fills %2))) 0 leaves))
|
(reduce #(+ %1 (count (:fills %2))) 0 leaves))
|
||||||
|
|
||||||
|
(defn- write-paragraph
|
||||||
|
[offset dview paragraph]
|
||||||
|
(let [text-align (sr/translate-text-align (get paragraph :text-align))
|
||||||
|
text-direction (sr/translate-text-direction (get paragraph :text-direction))
|
||||||
|
text-decoration (sr/translate-text-decoration (get paragraph :text-decoration))
|
||||||
|
text-transform (sr/translate-text-transform (get paragraph :text-transform))
|
||||||
|
line-height (get paragraph :line-height)
|
||||||
|
letter-spacing (get paragraph :letter-spacing)
|
||||||
|
|
||||||
|
typography-ref-file (get paragraph :typography-ref-file)
|
||||||
|
typography-ref-id (get paragraph :typography-ref-id)]
|
||||||
|
|
||||||
|
(-> offset
|
||||||
|
(mem/write-u8 dview text-align)
|
||||||
|
(mem/write-u8 dview text-direction)
|
||||||
|
(mem/write-u8 dview text-decoration)
|
||||||
|
(mem/write-u8 dview text-transform)
|
||||||
|
|
||||||
|
(mem/write-f32 dview line-height)
|
||||||
|
(mem/write-f32 dview letter-spacing)
|
||||||
|
|
||||||
|
(mem/write-uuid dview (d/nilv typography-ref-file uuid/zero))
|
||||||
|
(mem/write-uuid dview (d/nilv typography-ref-id uuid/zero))
|
||||||
|
(mem/assert-written offset PARAGRAPH-ATTR-U8-SIZE))))
|
||||||
|
|
||||||
|
(defn- write-leaves
|
||||||
|
[offset dview leaves paragraph]
|
||||||
|
(reduce (fn [offset leaf]
|
||||||
|
(let [font-style (sr/translate-font-style (get leaf :font-style))
|
||||||
|
font-size (get leaf :font-size)
|
||||||
|
font-weight (get leaf :font-weight)
|
||||||
|
font-id (f/normalize-font-id (get leaf :font-id))
|
||||||
|
font-family (hash (get leaf :font-family))
|
||||||
|
|
||||||
|
text-buffer (encode-text (get leaf :text))
|
||||||
|
text-length (mem/size text-buffer)
|
||||||
|
fills (get leaf :fills)
|
||||||
|
total-fills (count fills)
|
||||||
|
|
||||||
|
font-variant-id
|
||||||
|
(get leaf :font-variant-id)
|
||||||
|
|
||||||
|
font-variant-id
|
||||||
|
(if (uuid? font-variant-id)
|
||||||
|
font-variant-id
|
||||||
|
uuid/zero)
|
||||||
|
|
||||||
|
text-decoration
|
||||||
|
(or (sr/translate-text-decoration (:text-decoration leaf))
|
||||||
|
(sr/translate-text-decoration (:text-decoration paragraph))
|
||||||
|
(sr/translate-text-decoration "none"))
|
||||||
|
|
||||||
|
text-transform
|
||||||
|
(or (sr/translate-text-transform (:text-transform leaf))
|
||||||
|
(sr/translate-text-transform (:text-transform paragraph))
|
||||||
|
(sr/translate-text-transform "none"))]
|
||||||
|
|
||||||
|
(-> offset
|
||||||
|
(mem/write-u8 dview font-style)
|
||||||
|
(mem/write-u8 dview text-decoration)
|
||||||
|
(mem/write-u8 dview text-transform)
|
||||||
|
(+ 1) ;;padding
|
||||||
|
|
||||||
|
(mem/write-f32 dview font-size)
|
||||||
|
(mem/write-u32 dview font-weight)
|
||||||
|
|
||||||
|
(mem/write-uuid dview font-id)
|
||||||
|
(mem/write-i32 dview font-family)
|
||||||
|
(mem/write-uuid dview (d/nilv font-variant-id uuid/zero))
|
||||||
|
|
||||||
|
(mem/write-i32 dview text-length)
|
||||||
|
(mem/write-i32 dview total-fills)
|
||||||
|
(mem/assert-written offset LEAF-ATTR-U8-SIZE)
|
||||||
|
|
||||||
|
(write-leaf-fills dview fills))))
|
||||||
|
offset
|
||||||
|
leaves))
|
||||||
|
|
||||||
(defn write-shape-text
|
(defn write-shape-text
|
||||||
;; buffer has the following format:
|
;; buffer has the following format:
|
||||||
;; [<num-leaves> <paragraph_attributes> <leaves_attributes> <text>]
|
;; [<num-leaves> <paragraph_attributes> <leaves_attributes> <text>]
|
||||||
[leaves paragraph text]
|
[leaves paragraph text]
|
||||||
(let [le? true
|
(let [num-leaves (count leaves)
|
||||||
num-leaves (count leaves)
|
fills-size (* types.fills.impl/FILL-U8-SIZE
|
||||||
paragraph-attr-size 48
|
(get-total-fills leaves))
|
||||||
total-fills (total-fills-count leaves)
|
metadata-size (+ PARAGRAPH-ATTR-U8-SIZE
|
||||||
total-fills-size (* types.fills.impl/FILL-U8-SIZE total-fills)
|
(* num-leaves LEAF-ATTR-U8-SIZE)
|
||||||
leaf-attr-size 56
|
fills-size)
|
||||||
metadata-size (+ paragraph-attr-size (* num-leaves leaf-attr-size) total-fills-size)
|
|
||||||
text-buffer (utf8->buffer text)
|
|
||||||
text-size (.-byteLength text-buffer)
|
|
||||||
buffer (js/ArrayBuffer. (+ metadata-size text-size))
|
|
||||||
dview (js/DataView. buffer)]
|
|
||||||
|
|
||||||
(.setUint32 dview 0 num-leaves le?)
|
text-buffer (encode-text text)
|
||||||
|
text-size (mem/size text-buffer)
|
||||||
|
|
||||||
;; Serialize paragraph attributes
|
total-size (+ 4 metadata-size text-size)
|
||||||
(let [text-align (sr/serialize-text-align (:text-align paragraph))
|
heapu8 (mem/get-heap-u8)
|
||||||
text-direction (sr/serialize-text-direction (:text-direction paragraph))
|
dview (mem/get-data-view)
|
||||||
text-decoration (sr/serialize-text-decoration (:text-decoration paragraph))
|
offset (mem/alloc total-size)]
|
||||||
text-transform (sr/serialize-text-transform (:text-transform paragraph))
|
|
||||||
line-height (:line-height paragraph)
|
|
||||||
letter-spacing (:letter-spacing paragraph)
|
|
||||||
typography-ref-file (sr/serialize-uuid (:typography-ref-file paragraph))
|
|
||||||
typography-ref-id (sr/serialize-uuid (:typography-ref-id paragraph))]
|
|
||||||
|
|
||||||
(.setUint8 dview 4 text-align le?)
|
(-> offset
|
||||||
(.setUint8 dview 5 text-direction le?)
|
(mem/write-u32 dview num-leaves)
|
||||||
(.setUint8 dview 6 text-decoration le?)
|
(write-paragraph dview paragraph)
|
||||||
(.setUint8 dview 7 text-transform le?)
|
(write-leaves dview leaves paragraph)
|
||||||
|
(mem/write-buffer heapu8 text-buffer))
|
||||||
|
|
||||||
(.setFloat32 dview 8 line-height le?)
|
(h/call wasm/internal-module "_set_shape_text_content")))
|
||||||
(.setFloat32 dview 12 letter-spacing le?)
|
|
||||||
|
|
||||||
(.setUint32 dview 16 (aget typography-ref-file 0) le?)
|
|
||||||
(.setUint32 dview 20 (aget typography-ref-file 1) le?)
|
|
||||||
(.setUint32 dview 24 (aget typography-ref-file 2) le?)
|
|
||||||
(.setInt32 dview 28 (aget typography-ref-file 3) le?)
|
|
||||||
|
|
||||||
(.setUint32 dview 32 (aget typography-ref-id 0) le?)
|
|
||||||
(.setUint32 dview 36 (aget typography-ref-id 1) le?)
|
|
||||||
(.setUint32 dview 40 (aget typography-ref-id 2) le?)
|
|
||||||
(.setInt32 dview 44 (aget typography-ref-id 3) le?))
|
|
||||||
|
|
||||||
;; Serialize leaves attributes
|
|
||||||
(loop [index 0 offset paragraph-attr-size]
|
|
||||||
(when (< index num-leaves)
|
|
||||||
(let [leaf (nth leaves index)
|
|
||||||
font-style (f/serialize-font-style (:font-style leaf))
|
|
||||||
font-size (:font-size leaf)
|
|
||||||
font-weight (:font-weight leaf)
|
|
||||||
font-id (f/serialize-font-id (:font-id leaf))
|
|
||||||
font-family (hash (:font-family leaf))
|
|
||||||
font-variant-id (sr/serialize-uuid (:font-variant-id leaf))
|
|
||||||
leaf-text-decoration (or (sr/serialize-text-decoration (:text-decoration leaf)) (sr/serialize-text-decoration (:text-decoration paragraph)))
|
|
||||||
leaf-text-transform (or (sr/serialize-text-transform (:text-transform leaf)) (sr/serialize-text-transform (:text-transform paragraph)))
|
|
||||||
text-buffer (utf8->buffer (:text leaf))
|
|
||||||
text-length (.-byteLength text-buffer)
|
|
||||||
fills (:fills leaf)
|
|
||||||
total-fills (count fills)]
|
|
||||||
|
|
||||||
(.setUint8 dview offset font-style le?)
|
|
||||||
(.setUint8 dview (+ offset 1) leaf-text-decoration le?)
|
|
||||||
(.setUint8 dview (+ offset 2) leaf-text-transform le?)
|
|
||||||
|
|
||||||
(.setFloat32 dview (+ offset 4) font-size le?)
|
|
||||||
(.setUint32 dview (+ offset 8) font-weight le?)
|
|
||||||
(.setUint32 dview (+ offset 12) (aget font-id 0) le?)
|
|
||||||
(.setUint32 dview (+ offset 16) (aget font-id 1) le?)
|
|
||||||
(.setUint32 dview (+ offset 20) (aget font-id 2) le?)
|
|
||||||
(.setInt32 dview (+ offset 24) (aget font-id 3) le?)
|
|
||||||
|
|
||||||
(.setInt32 dview (+ offset 28) font-family le?)
|
|
||||||
|
|
||||||
(.setUint32 dview (+ offset 32) (aget font-variant-id 0) le?)
|
|
||||||
(.setUint32 dview (+ offset 36) (aget font-variant-id 1) le?)
|
|
||||||
(.setUint32 dview (+ offset 40) (aget font-variant-id 2) le?)
|
|
||||||
(.setInt32 dview (+ offset 44) (aget font-variant-id 3) le?)
|
|
||||||
|
|
||||||
(.setInt32 dview (+ offset 48) text-length le?)
|
|
||||||
(.setInt32 dview (+ offset 52) total-fills le?)
|
|
||||||
|
|
||||||
(let [new-offset (set-text-leaf-fills fills (+ offset leaf-attr-size) dview)]
|
|
||||||
(recur (inc index) new-offset)))))
|
|
||||||
|
|
||||||
;; Add text content to buffer
|
|
||||||
(let [text-offset metadata-size
|
|
||||||
buffer-u8 (js/Uint8Array. buffer)]
|
|
||||||
(.set buffer-u8 (js/Uint8Array. text-buffer) text-offset))
|
|
||||||
|
|
||||||
;; Allocate memory and set buffer
|
|
||||||
(let [total-size (.-byteLength buffer)
|
|
||||||
metadata-offset (mem/alloc total-size)
|
|
||||||
heap (mem/get-heap-u8)]
|
|
||||||
(.set heap (js/Uint8Array. buffer) metadata-offset)))
|
|
||||||
|
|
||||||
(h/call wasm/internal-module "_set_shape_text_content"))
|
|
||||||
|
|
||||||
(def ^:private emoji-pattern #"[\uD83C-\uDBFF][\uDC00-\uDFFF]|[\u2600-\u27BF]")
|
(def ^:private emoji-pattern #"[\uD83C-\uDBFF][\uDC00-\uDFFF]|[\u2600-\u27BF]")
|
||||||
|
|
||||||
@@ -199,10 +210,20 @@
|
|||||||
(defn contains-emoji? [text]
|
(defn contains-emoji? [text]
|
||||||
(boolean (some #(re-find emoji-pattern %) (seq text))))
|
(boolean (some #(re-find emoji-pattern %) (seq text))))
|
||||||
|
|
||||||
(defn get-languages [text]
|
(defn collect-used-languages
|
||||||
|
[used text]
|
||||||
(reduce-kv (fn [result lang pattern]
|
(reduce-kv (fn [result lang pattern]
|
||||||
(if (re-find pattern text)
|
(cond
|
||||||
|
;; Skip regex operation if we already know that
|
||||||
|
;; langage is present
|
||||||
|
(contains? result lang)
|
||||||
|
result
|
||||||
|
|
||||||
|
(re-find pattern text)
|
||||||
(conj result lang)
|
(conj result lang)
|
||||||
|
|
||||||
|
:else
|
||||||
result))
|
result))
|
||||||
#{}
|
used
|
||||||
unicode-ranges))
|
unicode-ranges))
|
||||||
|
|
||||||
|
|||||||
@@ -67,12 +67,6 @@
|
|||||||
[heap offset size]
|
[heap offset size]
|
||||||
(.slice ^js heap offset (+ offset size)))
|
(.slice ^js heap offset (+ offset size)))
|
||||||
|
|
||||||
(defn view
|
|
||||||
"Returns a new typed array on the same ArrayBuffer store and with the
|
|
||||||
same element types as for this typed array."
|
|
||||||
[heap offset size]
|
|
||||||
(.subarray ^js heap offset (+ offset size)))
|
|
||||||
|
|
||||||
(defn get-data-view
|
(defn get-data-view
|
||||||
"Returns a heap wrapped in a DataView for surgical write operations"
|
"Returns a heap wrapped in a DataView for surgical write operations"
|
||||||
[]
|
[]
|
||||||
@@ -80,10 +74,64 @@
|
|||||||
|
|
||||||
(defn write-u8
|
(defn write-u8
|
||||||
"Write unsigned int8. Expects a DataView instance"
|
"Write unsigned int8. Expects a DataView instance"
|
||||||
[target offset value]
|
[offset target value]
|
||||||
(buf/write-byte target offset value))
|
(buf/write-u8 target offset value)
|
||||||
|
(+ offset 1))
|
||||||
|
|
||||||
(defn write-f32
|
(defn write-f32
|
||||||
"Write float32. Expects a DataView instance"
|
"Write float32. Expects a DataView instance"
|
||||||
[target offset value]
|
[offset target value]
|
||||||
(buf/write-float target offset value))
|
(buf/write-f32 target offset value)
|
||||||
|
(+ offset 4))
|
||||||
|
|
||||||
|
(defn write-i32
|
||||||
|
"Write int32. Expects a DataView instance"
|
||||||
|
[offset target value]
|
||||||
|
(buf/write-i32 target offset value)
|
||||||
|
(+ offset 4))
|
||||||
|
|
||||||
|
(defn write-u32
|
||||||
|
"Write int32. Expects a DataView instance"
|
||||||
|
[offset target value]
|
||||||
|
(buf/write-i32 target offset value)
|
||||||
|
(+ offset 4))
|
||||||
|
|
||||||
|
(defn write-bool
|
||||||
|
"Write int32. Expects a DataView instance"
|
||||||
|
[offset target value]
|
||||||
|
(buf/write-bool target offset value)
|
||||||
|
(+ offset 1))
|
||||||
|
|
||||||
|
(defn write-uuid
|
||||||
|
"Write uuid. Expects a DataView instance"
|
||||||
|
[offset target value]
|
||||||
|
(buf/write-uuid target offset value)
|
||||||
|
(+ offset 16))
|
||||||
|
|
||||||
|
(defn write-buffer
|
||||||
|
[offset target value]
|
||||||
|
(assert (instance? js/Uint8Array target) "target should be u8 addressable heap")
|
||||||
|
|
||||||
|
(let [value (cond
|
||||||
|
(instance? js/ArrayBuffer value)
|
||||||
|
(new js/Uint8Array. value)
|
||||||
|
|
||||||
|
(instance? js/Uint8Array value)
|
||||||
|
value
|
||||||
|
|
||||||
|
:else
|
||||||
|
(throw (js/Error. "unexpected type")))]
|
||||||
|
(.set ^js target value offset)
|
||||||
|
(+ offset (.-byteLength value))))
|
||||||
|
|
||||||
|
(defn assert-written
|
||||||
|
[final-offset prev-offset expected]
|
||||||
|
(assert (= expected (- final-offset prev-offset))
|
||||||
|
(str "expected to be written " expected " but finally writted " (- final-offset prev-offset)))
|
||||||
|
final-offset)
|
||||||
|
|
||||||
|
(defn size
|
||||||
|
"Get buffer size"
|
||||||
|
[o]
|
||||||
|
(.-byteLength ^js o))
|
||||||
|
|
||||||
|
|||||||
@@ -227,7 +227,8 @@
|
|||||||
(case value
|
(case value
|
||||||
:fill 0
|
:fill 0
|
||||||
:fix 1
|
:fix 1
|
||||||
:auto 2))
|
:auto 2
|
||||||
|
1))
|
||||||
|
|
||||||
(defn translate-align-self
|
(defn translate-align-self
|
||||||
[value]
|
[value]
|
||||||
@@ -270,26 +271,51 @@
|
|||||||
:auto-height 2
|
:auto-height 2
|
||||||
0))
|
0))
|
||||||
|
|
||||||
(defn- serialize-enum
|
(defn translate-vertical-align
|
||||||
[value enum-map]
|
|
||||||
(get enum-map value 0))
|
|
||||||
|
|
||||||
(defn serialize-vertical-align
|
|
||||||
[vertical-align]
|
[vertical-align]
|
||||||
(serialize-enum vertical-align {"top" 0 "center" 1 "bottom" 2}))
|
(case vertical-align
|
||||||
|
"top" 0
|
||||||
|
"center" 1
|
||||||
|
"bottom" 2
|
||||||
|
0))
|
||||||
|
|
||||||
(defn serialize-text-align
|
(defn translate-text-align
|
||||||
[text-align]
|
[text-align]
|
||||||
(serialize-enum text-align {"left" 0 "center" 1 "right" 2 "justify" 3}))
|
(case text-align
|
||||||
|
"left" 0
|
||||||
|
"center" 1
|
||||||
|
"right" 2
|
||||||
|
"justify" 3
|
||||||
|
0))
|
||||||
|
|
||||||
(defn serialize-text-transform
|
(defn translate-text-transform
|
||||||
[text-transform]
|
[text-transform]
|
||||||
(serialize-enum text-transform {"none" 0 "uppercase" 1 "lowercase" 2 "capitalize" 3}))
|
(case text-transform
|
||||||
|
"none" 0
|
||||||
|
"uppercase" 1
|
||||||
|
"lowercase" 2
|
||||||
|
"capitalize" 3
|
||||||
|
nil))
|
||||||
|
|
||||||
(defn serialize-text-decoration
|
(defn translate-text-decoration
|
||||||
[text-decoration]
|
[text-decoration]
|
||||||
(serialize-enum text-decoration {"none" 0 "underline" 1 "line-through" 2 "overline" 3}))
|
(case text-decoration
|
||||||
|
"none" 0
|
||||||
|
"underline" 1
|
||||||
|
"line-through" 2
|
||||||
|
"overline" 3
|
||||||
|
nil))
|
||||||
|
|
||||||
(defn serialize-text-direction
|
(defn translate-text-direction
|
||||||
[text-direction]
|
[text-direction]
|
||||||
(serialize-enum text-direction {"ltr" 0 "rtl" 1}))
|
(case text-direction
|
||||||
|
"ltr" 0
|
||||||
|
"rtl" 1))
|
||||||
|
|
||||||
|
(defn translate-font-style
|
||||||
|
[font-style]
|
||||||
|
(case font-style
|
||||||
|
"normal" 0
|
||||||
|
"regular" 0
|
||||||
|
"italic" 1
|
||||||
|
0))
|
||||||
|
|||||||
Reference in New Issue
Block a user