mirror of
https://github.com/penpot/penpot.git
synced 2025-04-09 21:41:23 -05:00
Merge pull request #6178 from penpot/ladybenko-10528-google-fonts
🎉 Render text that uses a google font (wasm)
This commit is contained in:
commit
9fd0e9af66
7 changed files with 277 additions and 205 deletions
|
@ -4,7 +4,7 @@
|
|||
"license": "MPL-2.0",
|
||||
"author": "Kaleidos INC",
|
||||
"private": true,
|
||||
"packageManager": "yarn@4.7.0+sha512.5a0afa1d4c1d844b3447ee3319633797bcd6385d9a44be07993ae52ff4facabccafb4af5dcd1c2f9a94ac113e5e9ff56f6130431905884414229e284e37bb7c9",
|
||||
"packageManager": "yarn@4.8.0+sha512.85ec3149b1ec48f47c2690e13b29197a8a84b09c2c936cc596dddfb49c517e3bc3b1881ec52b5d35ca4b7c437c3f0daae3a80e39438c93bbcc5fcece2df5f15a",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/penpot/penpot"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"license": "MPL-2.0",
|
||||
"author": "Kaleidos INC",
|
||||
"private": true,
|
||||
"packageManager": "yarn@4.7.0+sha512.5a0afa1d4c1d844b3447ee3319633797bcd6385d9a44be07993ae52ff4facabccafb4af5dcd1c2f9a94ac113e5e9ff56f6130431905884414229e284e37bb7c9",
|
||||
"packageManager": "yarn@4.8.0+sha512.85ec3149b1ec48f47c2690e13b29197a8a84b09c2c936cc596dddfb49c517e3bc3b1881ec52b5d35ca4b7c437c3f0daae3a80e39438c93bbcc5fcece2df5f15a",
|
||||
"browserslist": [
|
||||
"defaults"
|
||||
],
|
||||
|
|
|
@ -7,33 +7,36 @@
|
|||
(ns app.main.fonts
|
||||
"A fonts loading macros."
|
||||
(:require
|
||||
[app.common.uuid :as uuid]
|
||||
[clojure.data.json :as json]
|
||||
[clojure.java.io :as io]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn- parse-gfont-variant
|
||||
[variant]
|
||||
[variant files]
|
||||
(cond
|
||||
(= "regular" variant)
|
||||
{:id "regular" :name "regular" :weight "400" :style "normal"}
|
||||
{:id "regular" :name "regular" :weight "400" :style "normal" :ttf-url (get files "regular")}
|
||||
|
||||
(= "italic" variant)
|
||||
{:id "italic" :name "italic" :weight "400" :style "italic"}
|
||||
{:id "italic" :name "italic" :weight "400" :style "italic" :ttf-url (get files "italic")}
|
||||
|
||||
:else
|
||||
(when-let [[a b c] (re-find #"^(\d+)(.*)$" variant)]
|
||||
(if (str/empty? c)
|
||||
{:id a :name b :weight b :style "normal"}
|
||||
{:id a :name (str b " (" c ")") :weight b :style c}))))
|
||||
{:id a :name b :weight b :style "normal" :ttf-url (get files a)}
|
||||
{:id a :name (str b " (" c ")") :weight b :style c :ttf-url (get files c)}))))
|
||||
|
||||
(defn- parse-gfont
|
||||
[font]
|
||||
(let [family (get font "family")
|
||||
variants (get font "variants")]
|
||||
variants (get font "variants")
|
||||
files (get font "files")]
|
||||
{:id (str "gfont-" (str/slug family))
|
||||
:uuid (uuid/random)
|
||||
:family family
|
||||
:name family
|
||||
:variants (into [] (comp (map parse-gfont-variant)
|
||||
:variants (into [] (comp (map (fn [variant] (parse-gfont-variant variant files)))
|
||||
(filter identity))
|
||||
variants)}))
|
||||
|
||||
|
|
|
@ -253,6 +253,7 @@
|
|||
|
||||
(defn get-variant
|
||||
[{:keys [variants] :as font} font-variant-id]
|
||||
(prn "get-variant" font-variant-id fonts)
|
||||
(or (d/seek #(= (:id %) font-variant-id) variants)
|
||||
(get-default-variant font)))
|
||||
|
||||
|
|
|
@ -19,22 +19,20 @@
|
|||
[app.main.fonts :as fonts]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.render :as render]
|
||||
[app.main.store :as st]
|
||||
[app.render-wasm.api.fonts :as f]
|
||||
[app.render-wasm.helpers :as h]
|
||||
[app.render-wasm.serializers :as sr]
|
||||
[app.render-wasm.wasm :as wasm]
|
||||
[app.util.debug :as dbg]
|
||||
[app.util.http :as http]
|
||||
[app.util.webapi :as wapi]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[goog.object :as gobj]
|
||||
[lambdaisland.uri :as u]
|
||||
[okulary.core :as l]
|
||||
[promesa.core :as p]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defonce internal-frame-id nil)
|
||||
(defonce internal-module #js {})
|
||||
;; (defonce internal-frame-id nil)
|
||||
;; (defonce internal-module #js {})
|
||||
(defonce use-dpr? (contains? cf/flags :render-wasm-dpr))
|
||||
|
||||
(def dpr
|
||||
|
@ -67,8 +65,8 @@
|
|||
;; the window started rendering elements so it could be useful to measure time between frames).
|
||||
(defn- render
|
||||
[_]
|
||||
(h/call internal-module "_render")
|
||||
(set! internal-frame-id nil))
|
||||
(h/call wasm/internal-module "_render")
|
||||
(set! wasm/internal-frame-id nil))
|
||||
|
||||
(defn- rgba-from-hex
|
||||
"Takes a hex color in #rrggbb format, and an opacity value from 0 to 1 and returns its 32-bit rgba representation"
|
||||
|
@ -91,20 +89,20 @@
|
|||
|
||||
(defn cancel-render
|
||||
[_]
|
||||
(when internal-frame-id
|
||||
(js/cancelAnimationFrame internal-frame-id)
|
||||
(set! internal-frame-id nil)))
|
||||
(when wasm/internal-frame-id
|
||||
(js/cancelAnimationFrame wasm/internal-frame-id)
|
||||
(set! wasm/internal-frame-id nil)))
|
||||
|
||||
(defn request-render
|
||||
[requester]
|
||||
(when internal-frame-id (cancel-render requester))
|
||||
(when wasm/internal-frame-id (cancel-render requester))
|
||||
(let [frame-id (js/requestAnimationFrame render)]
|
||||
(set! internal-frame-id frame-id)))
|
||||
(set! wasm/internal-frame-id frame-id)))
|
||||
|
||||
(defn use-shape
|
||||
[id]
|
||||
(let [buffer (uuid/get-u32 id)]
|
||||
(h/call internal-module "_use_shape"
|
||||
(h/call wasm/internal-module "_use_shape"
|
||||
(aget buffer 0)
|
||||
(aget buffer 1)
|
||||
(aget buffer 2)
|
||||
|
@ -113,7 +111,7 @@
|
|||
(defn set-parent-id
|
||||
[id]
|
||||
(let [buffer (uuid/get-u32 id)]
|
||||
(h/call internal-module "_set_parent"
|
||||
(h/call wasm/internal-module "_set_parent"
|
||||
(aget buffer 0)
|
||||
(aget buffer 1)
|
||||
(aget buffer 2)
|
||||
|
@ -121,19 +119,19 @@
|
|||
|
||||
(defn set-shape-clip-content
|
||||
[clip-content]
|
||||
(h/call internal-module "_set_shape_clip_content" clip-content))
|
||||
(h/call wasm/internal-module "_set_shape_clip_content" clip-content))
|
||||
|
||||
(defn set-shape-type
|
||||
[type]
|
||||
(h/call internal-module "_set_shape_type" (sr/translate-shape-type type)))
|
||||
(h/call wasm/internal-module "_set_shape_type" (sr/translate-shape-type type)))
|
||||
|
||||
(defn set-masked
|
||||
[masked]
|
||||
(h/call internal-module "_set_shape_masked_group" masked))
|
||||
(h/call wasm/internal-module "_set_shape_masked_group" masked))
|
||||
|
||||
(defn set-shape-selrect
|
||||
[selrect]
|
||||
(h/call internal-module "_set_shape_selrect"
|
||||
(h/call wasm/internal-module "_set_shape_selrect"
|
||||
(dm/get-prop selrect :x1)
|
||||
(dm/get-prop selrect :y1)
|
||||
(dm/get-prop selrect :x2)
|
||||
|
@ -141,7 +139,7 @@
|
|||
|
||||
(defn set-shape-transform
|
||||
[transform]
|
||||
(h/call internal-module "_set_shape_transform"
|
||||
(h/call wasm/internal-module "_set_shape_transform"
|
||||
(dm/get-prop transform :a)
|
||||
(dm/get-prop transform :b)
|
||||
(dm/get-prop transform :c)
|
||||
|
@ -151,17 +149,17 @@
|
|||
|
||||
(defn set-shape-rotation
|
||||
[rotation]
|
||||
(h/call internal-module "_set_shape_rotation" rotation))
|
||||
(h/call wasm/internal-module "_set_shape_rotation" rotation))
|
||||
|
||||
(defn set-shape-children
|
||||
[shape-ids]
|
||||
(let [ENTRY-SIZE 16
|
||||
ptr
|
||||
(h/call internal-module "_alloc_bytes" (* ENTRY-SIZE (count shape-ids)))
|
||||
(h/call wasm/internal-module "_alloc_bytes" (* ENTRY-SIZE (count shape-ids)))
|
||||
|
||||
heap
|
||||
(js/Uint8Array.
|
||||
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||
(.-buffer (gobj/get ^js wasm/internal-module "HEAPU8"))
|
||||
ptr
|
||||
(* ENTRY-SIZE (count shape-ids)))]
|
||||
|
||||
|
@ -172,51 +170,10 @@
|
|||
(.set heap (sr/uuid->u8 id) offset)
|
||||
(recur (rest entries) (+ offset ENTRY-SIZE)))))
|
||||
|
||||
(h/call internal-module "_set_children")))
|
||||
(h/call wasm/internal-module "_set_children")))
|
||||
|
||||
(defn- get-string-length [string] (+ (count string) 1))
|
||||
|
||||
;; IMPORTANT: It should be noted that only TTF fonts can be stored.
|
||||
(defn- store-font-buffer
|
||||
[font-data font-array-buffer]
|
||||
(let [id-buffer (:family-id-buffer font-data)
|
||||
size (.-byteLength font-array-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. font-array-buffer))
|
||||
(h/call internal-module "_store_font"
|
||||
(aget id-buffer 0)
|
||||
(aget id-buffer 1)
|
||||
(aget id-buffer 2)
|
||||
(aget id-buffer 3)
|
||||
(:weight font-data)
|
||||
(:style font-data))
|
||||
true))
|
||||
|
||||
(defn- store-font-url
|
||||
[font-data font-url]
|
||||
(->> (http/send! {:method :get
|
||||
:uri font-url
|
||||
:response-type :blob})
|
||||
(rx/map :body)
|
||||
(rx/mapcat wapi/read-file-as-array-buffer)
|
||||
(rx/map (fn [array-buffer] (store-font-buffer font-data array-buffer)))))
|
||||
|
||||
(defn- store-font-id
|
||||
[font-data asset-id]
|
||||
(when asset-id
|
||||
(let [uri (str (u/join cf/public-uri "assets/by-id/" asset-id))
|
||||
id-buffer (uuid/get-u32 (:family-id font-data))
|
||||
font-data (assoc font-data :family-id-buffer id-buffer)
|
||||
font-stored? (not= 0 (h/call internal-module "_is_font_uploaded"
|
||||
(aget id-buffer 0)
|
||||
(aget id-buffer 1)
|
||||
(aget id-buffer 2)
|
||||
(aget id-buffer 3)
|
||||
(:weight font-data)
|
||||
(:style font-data)))]
|
||||
(when-not font-stored? (store-font-url font-data uri)))))
|
||||
|
||||
(defn- store-image
|
||||
[id]
|
||||
|
@ -230,11 +187,11 @@
|
|||
(rx/mapcat wapi/read-file-as-array-buffer)
|
||||
(rx/map (fn [image]
|
||||
(let [image-size (.-byteLength image)
|
||||
image-ptr (h/call internal-module "_alloc_bytes" image-size)
|
||||
heap (gobj/get ^js internal-module "HEAPU8")
|
||||
image-ptr (h/call wasm/internal-module "_alloc_bytes" image-size)
|
||||
heap (gobj/get ^js wasm/internal-module "HEAPU8")
|
||||
mem (js/Uint8Array. (.-buffer heap) image-ptr image-size)]
|
||||
(.set mem (js/Uint8Array. image))
|
||||
(h/call internal-module "_store_image"
|
||||
(h/call wasm/internal-module "_store_image"
|
||||
(aget buffer 0)
|
||||
(aget buffer 1)
|
||||
(aget buffer 2)
|
||||
|
@ -243,7 +200,7 @@
|
|||
|
||||
(defn set-shape-fills
|
||||
[fills]
|
||||
(h/call internal-module "_clear_shape_fills")
|
||||
(h/call wasm/internal-module "_clear_shape_fills")
|
||||
(keep (fn [fill]
|
||||
(let [opacity (or (:fill-opacity fill) 1.0)
|
||||
color (:fill-color fill)
|
||||
|
@ -252,23 +209,23 @@
|
|||
(cond
|
||||
(some? color)
|
||||
(let [rgba (rgba-from-hex color opacity)]
|
||||
(h/call internal-module "_add_shape_solid_fill" rgba))
|
||||
(h/call wasm/internal-module "_add_shape_solid_fill" rgba))
|
||||
|
||||
(some? gradient)
|
||||
(let [stops (:stops gradient)
|
||||
n-stops (count stops)
|
||||
mem-size (* 5 n-stops)
|
||||
stops-ptr (h/call internal-module "_alloc_bytes" mem-size)
|
||||
heap (gobj/get ^js internal-module "HEAPU8")
|
||||
stops-ptr (h/call wasm/internal-module "_alloc_bytes" mem-size)
|
||||
heap (gobj/get ^js wasm/internal-module "HEAPU8")
|
||||
mem (js/Uint8Array. (.-buffer heap) stops-ptr mem-size)]
|
||||
(if (= (:type gradient) :linear)
|
||||
(h/call internal-module "_add_shape_linear_fill"
|
||||
(h/call wasm/internal-module "_add_shape_linear_fill"
|
||||
(:start-x gradient)
|
||||
(:start-y gradient)
|
||||
(:end-x gradient)
|
||||
(:end-y gradient)
|
||||
opacity)
|
||||
(h/call internal-module "_add_shape_radial_fill"
|
||||
(h/call wasm/internal-module "_add_shape_radial_fill"
|
||||
(:start-x gradient)
|
||||
(:start-y gradient)
|
||||
(:end-x gradient)
|
||||
|
@ -280,13 +237,13 @@
|
|||
offset (:offset stop)]
|
||||
[r g b a (* 100 offset)]))
|
||||
stops)))))
|
||||
(h/call internal-module "_add_shape_fill_stops"))
|
||||
(h/call wasm/internal-module "_add_shape_fill_stops"))
|
||||
|
||||
(some? image)
|
||||
(let [id (dm/get-prop image :id)
|
||||
buffer (uuid/get-u32 id)
|
||||
cached-image? (h/call internal-module "_is_image_cached" (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))]
|
||||
(h/call internal-module "_add_shape_image_fill"
|
||||
cached-image? (h/call wasm/internal-module "_is_image_cached" (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))]
|
||||
(h/call wasm/internal-module "_add_shape_image_fill"
|
||||
(aget buffer 0)
|
||||
(aget buffer 1)
|
||||
(aget buffer 2)
|
||||
|
@ -300,7 +257,7 @@
|
|||
|
||||
(defn set-shape-strokes
|
||||
[strokes]
|
||||
(h/call internal-module "_clear_shape_strokes")
|
||||
(h/call wasm/internal-module "_clear_shape_strokes")
|
||||
(keep (fn [stroke]
|
||||
(let [opacity (or (:stroke-opacity stroke) 1.0)
|
||||
color (:stroke-color stroke)
|
||||
|
@ -312,26 +269,26 @@
|
|||
cap-start (-> stroke :stroke-cap-start sr/translate-stroke-cap)
|
||||
cap-end (-> stroke :stroke-cap-end sr/translate-stroke-cap)]
|
||||
(case align
|
||||
:inner (h/call internal-module "_add_shape_inner_stroke" width style cap-start cap-end)
|
||||
:outer (h/call internal-module "_add_shape_outer_stroke" width style cap-start cap-end)
|
||||
(h/call internal-module "_add_shape_center_stroke" width style cap-start cap-end))
|
||||
:inner (h/call wasm/internal-module "_add_shape_inner_stroke" width style cap-start cap-end)
|
||||
:outer (h/call wasm/internal-module "_add_shape_outer_stroke" width style cap-start cap-end)
|
||||
(h/call wasm/internal-module "_add_shape_center_stroke" width style cap-start cap-end))
|
||||
|
||||
(cond
|
||||
(some? gradient)
|
||||
(let [stops (:stops gradient)
|
||||
n-stops (count stops)
|
||||
mem-size (* 5 n-stops)
|
||||
stops-ptr (h/call internal-module "_alloc_bytes" mem-size)
|
||||
heap (gobj/get ^js internal-module "HEAPU8")
|
||||
stops-ptr (h/call wasm/internal-module "_alloc_bytes" mem-size)
|
||||
heap (gobj/get ^js wasm/internal-module "HEAPU8")
|
||||
mem (js/Uint8Array. (.-buffer heap) stops-ptr mem-size)]
|
||||
(if (= (:type gradient) :linear)
|
||||
(h/call internal-module "_add_shape_stroke_linear_fill"
|
||||
(h/call wasm/internal-module "_add_shape_stroke_linear_fill"
|
||||
(:start-x gradient)
|
||||
(:start-y gradient)
|
||||
(:end-x gradient)
|
||||
(:end-y gradient)
|
||||
opacity)
|
||||
(h/call internal-module "_add_shape_stroke_radial_fill"
|
||||
(h/call wasm/internal-module "_add_shape_stroke_radial_fill"
|
||||
(:start-x gradient)
|
||||
(:start-y gradient)
|
||||
(:end-x gradient)
|
||||
|
@ -343,13 +300,13 @@
|
|||
offset (:offset stop)]
|
||||
[r g b a (* 100 offset)]))
|
||||
stops)))))
|
||||
(h/call internal-module "_add_shape_stroke_stops"))
|
||||
(h/call wasm/internal-module "_add_shape_stroke_stops"))
|
||||
|
||||
(some? image)
|
||||
(let [id (dm/get-prop image :id)
|
||||
buffer (uuid/get-u32 id)
|
||||
cached-image? (h/call internal-module "_is_image_cached" (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))]
|
||||
(h/call internal-module "_add_shape_image_stroke"
|
||||
cached-image? (h/call wasm/internal-module "_is_image_cached" (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))]
|
||||
(h/call wasm/internal-module "_add_shape_image_stroke"
|
||||
(aget buffer 0)
|
||||
(aget buffer 1)
|
||||
(aget buffer 2)
|
||||
|
@ -362,7 +319,7 @@
|
|||
|
||||
(some? color)
|
||||
(let [rgba (rgba-from-hex color opacity)]
|
||||
(h/call internal-module "_add_shape_stroke_solid_fill" rgba)))))
|
||||
(h/call wasm/internal-module "_add_shape_stroke_solid_fill" rgba)))))
|
||||
strokes))
|
||||
|
||||
|
||||
|
@ -375,25 +332,25 @@
|
|||
(merge style))
|
||||
str (sr/serialize-path-attrs attrs)
|
||||
size (count str)
|
||||
ptr (h/call internal-module "_alloc_bytes" size)]
|
||||
(h/call internal-module "stringToUTF8" str ptr size)
|
||||
(h/call internal-module "_set_shape_path_attrs" (count attrs))))
|
||||
ptr (h/call wasm/internal-module "_alloc_bytes" size)]
|
||||
(h/call wasm/internal-module "stringToUTF8" str ptr size)
|
||||
(h/call wasm/internal-module "_set_shape_path_attrs" (count attrs))))
|
||||
|
||||
(defn set-shape-path-content
|
||||
[content]
|
||||
(let [pdata (path/path-data content)
|
||||
size (* (count pdata) path/SEGMENT-BYTE-SIZE)
|
||||
offset (h/call internal-module "_alloc_bytes" size)
|
||||
heap (gobj/get ^js internal-module "HEAPU8")]
|
||||
offset (h/call wasm/internal-module "_alloc_bytes" size)
|
||||
heap (gobj/get ^js wasm/internal-module "HEAPU8")]
|
||||
(path/-write-to pdata (.-buffer heap) offset)
|
||||
(h/call internal-module "_set_shape_path_content")))
|
||||
(h/call wasm/internal-module "_set_shape_path_content")))
|
||||
|
||||
(defn set-shape-svg-raw-content
|
||||
[content]
|
||||
(let [size (get-string-length content)
|
||||
ptr (h/call internal-module "_alloc_bytes" size)]
|
||||
(h/call internal-module "stringToUTF8" content ptr size)
|
||||
(h/call internal-module "_set_shape_svg_raw_content")))
|
||||
ptr (h/call wasm/internal-module "_alloc_bytes" size)]
|
||||
(h/call wasm/internal-module "stringToUTF8" content ptr size)
|
||||
(h/call wasm/internal-module "_set_shape_svg_raw_content")))
|
||||
|
||||
|
||||
|
||||
|
@ -401,31 +358,31 @@
|
|||
[blend-mode]
|
||||
;; These values correspond to skia::BlendMode representation
|
||||
;; https://rust-skia.github.io/doc/skia_safe/enum.BlendMode.html
|
||||
(h/call internal-module "_set_shape_blend_mode" (sr/translate-blend-mode blend-mode)))
|
||||
(h/call wasm/internal-module "_set_shape_blend_mode" (sr/translate-blend-mode blend-mode)))
|
||||
|
||||
(defn set-shape-opacity
|
||||
[opacity]
|
||||
(h/call internal-module "_set_shape_opacity" (or opacity 1)))
|
||||
(h/call wasm/internal-module "_set_shape_opacity" (or opacity 1)))
|
||||
|
||||
|
||||
|
||||
(defn set-constraints-h
|
||||
[constraint]
|
||||
(when constraint
|
||||
(h/call internal-module "_set_shape_constraint_h" (sr/translate-constraint-h constraint))))
|
||||
(h/call wasm/internal-module "_set_shape_constraint_h" (sr/translate-constraint-h constraint))))
|
||||
|
||||
(defn set-constraints-v
|
||||
[constraint]
|
||||
(when constraint
|
||||
(h/call internal-module "_set_shape_constraint_v" (sr/translate-constraint-v constraint))))
|
||||
(h/call wasm/internal-module "_set_shape_constraint_v" (sr/translate-constraint-v constraint))))
|
||||
|
||||
(defn set-shape-hidden
|
||||
[hidden]
|
||||
(h/call internal-module "_set_shape_hidden" hidden))
|
||||
(h/call wasm/internal-module "_set_shape_hidden" hidden))
|
||||
|
||||
(defn set-shape-bool-type
|
||||
[bool-type]
|
||||
(h/call internal-module "_set_shape_bool_type" (sr/translate-bool-type bool-type)))
|
||||
(h/call wasm/internal-module "_set_shape_bool_type" (sr/translate-bool-type bool-type)))
|
||||
|
||||
(defn- translate-blur-type
|
||||
[blur-type]
|
||||
|
@ -438,7 +395,7 @@
|
|||
(let [type (-> blur :type sr/translate-blur-type)
|
||||
hidden (:hidden blur)
|
||||
value (:value blur)]
|
||||
(h/call internal-module "_set_shape_blur" type hidden value)))
|
||||
(h/call wasm/internal-module "_set_shape_blur" type hidden value)))
|
||||
|
||||
(defn set-shape-corners
|
||||
[corners]
|
||||
|
@ -446,7 +403,7 @@
|
|||
r2 (or (get corners 1) 0)
|
||||
r3 (or (get corners 2) 0)
|
||||
r4 (or (get corners 3) 0)]
|
||||
(h/call internal-module "_set_shape_corners" r1 r2 r3 r4)))
|
||||
(h/call wasm/internal-module "_set_shape_corners" r1 r2 r3 r4)))
|
||||
|
||||
(defn set-flex-layout
|
||||
[shape]
|
||||
|
@ -466,7 +423,7 @@
|
|||
padding-right (or (dm/get-prop padding :p2) 0)
|
||||
padding-bottom (or (dm/get-prop padding :p3) 0)
|
||||
padding-left (or (dm/get-prop padding :p4) 0)]
|
||||
(h/call internal-module
|
||||
(h/call wasm/internal-module
|
||||
"_set_flex_layout_data"
|
||||
dir
|
||||
row-gap
|
||||
|
@ -500,7 +457,7 @@
|
|||
padding-bottom (or (dm/get-prop padding :p3) 0)
|
||||
padding-left (or (dm/get-prop padding :p4) 0)]
|
||||
|
||||
(h/call internal-module
|
||||
(h/call wasm/internal-module
|
||||
"_set_grid_layout_data"
|
||||
dir
|
||||
row-gap
|
||||
|
@ -517,11 +474,11 @@
|
|||
;; Send Rows
|
||||
(let [entry-size 5
|
||||
entries (:layout-grid-rows shape)
|
||||
ptr (h/call internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||
ptr (h/call wasm/internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||
|
||||
heap
|
||||
(js/Uint8Array.
|
||||
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||
(.-buffer (gobj/get ^js wasm/internal-module "HEAPU8"))
|
||||
ptr
|
||||
(* entry-size (count entries)))]
|
||||
(loop [entries (seq entries)
|
||||
|
@ -531,16 +488,16 @@
|
|||
(.set heap (sr/u8 (sr/translate-grid-track-type type)) (+ offset 0))
|
||||
(.set heap (sr/f32->u8 value) (+ offset 1))
|
||||
(recur (rest entries) (+ offset entry-size)))))
|
||||
(h/call internal-module "_set_grid_rows"))
|
||||
(h/call wasm/internal-module "_set_grid_rows"))
|
||||
|
||||
;; Send Columns
|
||||
(let [entry-size 5
|
||||
entries (:layout-grid-columns shape)
|
||||
ptr (h/call internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||
ptr (h/call wasm/internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||
|
||||
heap
|
||||
(js/Uint8Array.
|
||||
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||
(.-buffer (gobj/get ^js wasm/internal-module "HEAPU8"))
|
||||
ptr
|
||||
(* entry-size (count entries)))]
|
||||
(loop [entries (seq entries)
|
||||
|
@ -550,16 +507,16 @@
|
|||
(.set heap (sr/u8 (sr/translate-grid-track-type type)) (+ offset 0))
|
||||
(.set heap (sr/f32->u8 value) (+ offset 1))
|
||||
(recur (rest entries) (+ offset entry-size)))))
|
||||
(h/call internal-module "_set_grid_columns"))
|
||||
(h/call wasm/internal-module "_set_grid_columns"))
|
||||
|
||||
;; Send cells
|
||||
(let [entry-size 37
|
||||
entries (-> shape :layout-grid-cells vals)
|
||||
ptr (h/call internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||
ptr (h/call wasm/internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||
|
||||
heap
|
||||
(js/Uint8Array.
|
||||
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||
(.-buffer (gobj/get ^js wasm/internal-module "HEAPU8"))
|
||||
ptr
|
||||
(* entry-size (count entries)))]
|
||||
|
||||
|
@ -603,7 +560,7 @@
|
|||
|
||||
(recur (rest entries) (+ offset entry-size)))))
|
||||
|
||||
(h/call internal-module "_set_grid_cells")))
|
||||
(h/call wasm/internal-module "_set_grid_cells")))
|
||||
|
||||
(defn set-layout-child
|
||||
[shape]
|
||||
|
@ -627,7 +584,7 @@
|
|||
has-min-w (some? min-w)
|
||||
is-absolute (boolean (dm/get-prop shape :layout-item-absolute))
|
||||
z-index (-> (dm/get-prop shape :layout-item-z-index) (or 0))]
|
||||
(h/call internal-module
|
||||
(h/call wasm/internal-module
|
||||
"_set_layout_child_data"
|
||||
margin-top
|
||||
margin-right
|
||||
|
@ -650,7 +607,7 @@
|
|||
|
||||
(defn set-shape-shadows
|
||||
[shadows]
|
||||
(h/call 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)
|
||||
|
@ -663,80 +620,34 @@
|
|||
y (dm/get-prop shadow :offset-y)
|
||||
spread (dm/get-prop shadow :spread)
|
||||
style (dm/get-prop shadow :style)]
|
||||
(h/call internal-module "_add_shape_shadow" rgba blur spread x y (sr/translate-shadow-style style) hidden)
|
||||
(h/call wasm/internal-module "_add_shape_shadow" rgba blur spread x y (sr/translate-shadow-style style) hidden)
|
||||
(recur (inc index)))))))
|
||||
|
||||
(defn utf8->buffer [text]
|
||||
(let [encoder (js/TextEncoder.)]
|
||||
(.encode encoder text)))
|
||||
|
||||
(def ^:private fonts
|
||||
(l/derived :fonts st/state))
|
||||
|
||||
(defn ^:private font->ttf-id [font-uuid font-style font-weight]
|
||||
(let [matching-font (d/seek (fn [[_ font]]
|
||||
(and (= (:font-id font) font-uuid)
|
||||
(= (:font-style font) font-style)
|
||||
(= (:font-weight font) font-weight)))
|
||||
(seq @fonts))]
|
||||
(when matching-font
|
||||
(:ttf-file-id (second matching-font)))))
|
||||
|
||||
(defn- serialize-font-style
|
||||
[font-style]
|
||||
(case font-style
|
||||
"normal" 0
|
||||
"regular" 0
|
||||
"italic" 1
|
||||
0))
|
||||
|
||||
(defn- serialize-font-id
|
||||
[font-id]
|
||||
(let [no-prefix (subs font-id (inc (str/index-of font-id "-")))
|
||||
as-uuid (uuid/uuid no-prefix)]
|
||||
(uuid/get-u32 as-uuid)))
|
||||
|
||||
(defn- serialize-font-weight
|
||||
[font-weight]
|
||||
(js/Number font-weight))
|
||||
|
||||
(defn- add-text-leaf [leaf]
|
||||
(let [text (dm/get-prop leaf :text)
|
||||
font-id (serialize-font-id (dm/get-prop leaf :font-id))
|
||||
font-style (serialize-font-style (dm/get-prop leaf :font-style))
|
||||
font-weight (serialize-font-weight (dm/get-prop leaf :font-weight))
|
||||
font-id (f/serialize-font-id (dm/get-prop leaf :font-id))
|
||||
font-style (f/serialize-font-style (dm/get-prop leaf :font-style))
|
||||
font-weight (f/serialize-font-weight (dm/get-prop leaf :font-weight))
|
||||
font-size (js/Number (dm/get-prop leaf :font-size))
|
||||
buffer (utf8->buffer text)
|
||||
size (.-byteLength buffer)
|
||||
ptr (h/call internal-module "_alloc_bytes" size)
|
||||
heap (gobj/get ^js internal-module "HEAPU8")
|
||||
ptr (h/call wasm/internal-module "_alloc_bytes" size)
|
||||
heap (gobj/get ^js wasm/internal-module "HEAPU8")
|
||||
mem (js/Uint8Array. (.-buffer heap) ptr size)]
|
||||
(.set mem buffer)
|
||||
(h/call internal-module "_add_text_leaf"
|
||||
(h/call wasm/internal-module "_add_text_leaf"
|
||||
(aget font-id 0)
|
||||
(aget font-id 1)
|
||||
(aget font-id 2)
|
||||
(aget font-id 3)
|
||||
font-weight font-style font-size)))
|
||||
|
||||
(defn- store-fonts
|
||||
[fonts]
|
||||
(keep (fn [font]
|
||||
(let [font-id (dm/get-prop font :font-id)
|
||||
font-variant (dm/get-prop font :font-variant-id)
|
||||
variant-parts (str/split font-variant #"\-")
|
||||
style (first variant-parts)
|
||||
weight (serialize-font-weight (last variant-parts))
|
||||
font-id (subs font-id (inc (str/index-of font-id "-")))
|
||||
font-id (uuid/uuid font-id)
|
||||
ttf-id (font->ttf-id font-id style weight)
|
||||
font-data {:family-id font-id
|
||||
:style (serialize-font-style style)
|
||||
:weight weight}]
|
||||
(store-font-id font-data ttf-id))) fonts))
|
||||
|
||||
(defn set-shape-text-content [content]
|
||||
(h/call internal-module "_clear_shape_text")
|
||||
(h/call wasm/internal-module "_clear_shape_text")
|
||||
(let [paragraph-set (first (dm/get-prop content :children))
|
||||
paragraphs (dm/get-prop paragraph-set :children)
|
||||
total-paragraphs (count paragraphs)
|
||||
|
@ -747,25 +658,25 @@
|
|||
(let [paragraph (nth paragraphs index)
|
||||
leaves (dm/get-prop paragraph :children)
|
||||
total-leaves (count leaves)]
|
||||
(h/call internal-module "_add_text_paragraph")
|
||||
(h/call wasm/internal-module "_add_text_paragraph")
|
||||
(loop [index-leaves 0]
|
||||
(when (< index-leaves total-leaves)
|
||||
(let [leaf (nth leaves index-leaves)]
|
||||
(add-text-leaf leaf)
|
||||
(recur (inc index-leaves))))))
|
||||
(recur (inc index))))
|
||||
(store-fonts fonts)))
|
||||
(f/store-fonts fonts)))
|
||||
|
||||
(defn set-view-box
|
||||
[zoom vbox]
|
||||
(h/call internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||
(h/call wasm/internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||
(render nil))
|
||||
|
||||
(defn clear-drawing-cache []
|
||||
(h/call internal-module "_clear_drawing_cache"))
|
||||
(h/call wasm/internal-module "_clear_drawing_cache"))
|
||||
|
||||
(defn update-shape-tiles []
|
||||
(h/call internal-module "_update_shape_tiles"))
|
||||
(h/call wasm/internal-module "_update_shape_tiles"))
|
||||
|
||||
(defn set-object
|
||||
[objects shape]
|
||||
|
@ -889,11 +800,11 @@
|
|||
(defn propagate-modifiers
|
||||
[entries]
|
||||
(let [entry-size 40
|
||||
ptr (h/call internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||
ptr (h/call wasm/internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||
|
||||
heap
|
||||
(js/Uint8Array.
|
||||
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||
(.-buffer (gobj/get ^js wasm/internal-module "HEAPU8"))
|
||||
ptr
|
||||
(* entry-size (count entries)))]
|
||||
|
||||
|
@ -905,35 +816,35 @@
|
|||
(.set heap (sr/matrix->u8 transform) (+ offset 16))
|
||||
(recur (rest entries) (+ offset entry-size)))))
|
||||
|
||||
(let [result-ptr (h/call internal-module "_propagate_modifiers")
|
||||
heap (js/DataView. (.-buffer (gobj/get ^js internal-module "HEAPU8")))
|
||||
(let [result-ptr (h/call wasm/internal-module "_propagate_modifiers")
|
||||
heap (js/DataView. (.-buffer (gobj/get ^js wasm/internal-module "HEAPU8")))
|
||||
len (.getUint32 heap result-ptr true)
|
||||
result
|
||||
(->> (range 0 len)
|
||||
(mapv #(data->entry heap (+ result-ptr 4 (* % entry-size)))))]
|
||||
(h/call internal-module "_free_bytes")
|
||||
(h/call wasm/internal-module "_free_bytes")
|
||||
|
||||
result)))
|
||||
|
||||
(defn set-canvas-background
|
||||
[background]
|
||||
(let [rgba (rgba-from-hex background 1)]
|
||||
(h/call internal-module "_set_canvas_background" rgba)
|
||||
(h/call wasm/internal-module "_set_canvas_background" rgba)
|
||||
(request-render "set-canvas-background")))
|
||||
|
||||
(defn set-modifiers
|
||||
[modifiers]
|
||||
(if (empty? modifiers)
|
||||
(h/call internal-module "_clean_modifiers")
|
||||
(h/call wasm/internal-module "_clean_modifiers")
|
||||
|
||||
(let [ENTRY-SIZE 40
|
||||
|
||||
ptr
|
||||
(h/call internal-module "_alloc_bytes" (* ENTRY-SIZE (count modifiers)))
|
||||
(h/call wasm/internal-module "_alloc_bytes" (* ENTRY-SIZE (count modifiers)))
|
||||
|
||||
heap
|
||||
(js/Uint8Array.
|
||||
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||
(.-buffer (gobj/get ^js wasm/internal-module "HEAPU8"))
|
||||
ptr
|
||||
(* ENTRY-SIZE (count modifiers)))]
|
||||
|
||||
|
@ -945,15 +856,15 @@
|
|||
(.set heap (sr/matrix->u8 transform) (+ offset 16))
|
||||
(recur (rest entries) (+ offset ENTRY-SIZE)))))
|
||||
|
||||
(h/call internal-module "_set_modifiers")
|
||||
(h/call wasm/internal-module "_set_modifiers")
|
||||
|
||||
(request-render "set-modifiers"))))
|
||||
|
||||
(defn initialize
|
||||
[base-objects zoom vbox background]
|
||||
(let [rgba (rgba-from-hex background 1)]
|
||||
(h/call internal-module "_set_canvas_background" rgba)
|
||||
(h/call internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||
(h/call wasm/internal-module "_set_canvas_background" rgba)
|
||||
(h/call wasm/internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||
(set-objects base-objects)))
|
||||
|
||||
(def ^:private canvas-options
|
||||
|
@ -965,7 +876,7 @@
|
|||
|
||||
(defn resize-viewbox
|
||||
[width height]
|
||||
(h/call internal-module "_resize_viewbox" width height))
|
||||
(h/call wasm/internal-module "_resize_viewbox" width height))
|
||||
|
||||
(defn- debug-flags
|
||||
[]
|
||||
|
@ -975,7 +886,7 @@
|
|||
|
||||
(defn assign-canvas
|
||||
[canvas]
|
||||
(let [gl (unchecked-get internal-module "GL")
|
||||
(let [gl (unchecked-get wasm/internal-module "GL")
|
||||
flags (debug-flags)
|
||||
context (.getContext ^js canvas "webgl2" canvas-options)
|
||||
;; Register the context with emscripten
|
||||
|
@ -986,15 +897,15 @@
|
|||
(.getExtension context "WEBGL_debug_renderer_info")
|
||||
|
||||
;; Initialize Wasm Render Engine
|
||||
(h/call internal-module "_init" (/ (.-width ^js canvas) dpr) (/ (.-height ^js canvas) dpr))
|
||||
(h/call internal-module "_set_render_options" flags dpr))
|
||||
(h/call wasm/internal-module "_init" (/ (.-width ^js canvas) dpr) (/ (.-height ^js canvas) dpr))
|
||||
(h/call wasm/internal-module "_set_render_options" flags dpr))
|
||||
(set! (.-width canvas) (* dpr (.-clientWidth ^js canvas)))
|
||||
(set! (.-height canvas) (* dpr (.-clientHeight ^js canvas))))
|
||||
|
||||
(defn clear-canvas
|
||||
[]
|
||||
;; TODO: perform corresponding cleaning
|
||||
(h/call internal-module "_clean_up"))
|
||||
(h/call wasm/internal-module "_clean_up"))
|
||||
|
||||
(defonce module
|
||||
(delay
|
||||
|
@ -1005,9 +916,10 @@
|
|||
(let [default (unchecked-get module "default")]
|
||||
(default))))
|
||||
(p/fmap (fn [module]
|
||||
(set! internal-module module)
|
||||
(set! wasm/internal-module module)
|
||||
true))
|
||||
(p/merr (fn [cause]
|
||||
(js/console.error cause)
|
||||
(p/resolved false)))))
|
||||
(p/resolved false))))
|
||||
|
||||
|
|
152
frontend/src/app/render_wasm/api/fonts.cljs
Normal file
152
frontend/src/app/render_wasm/api/fonts.cljs
Normal file
|
@ -0,0 +1,152 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.render-wasm.api.fonts
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cf]
|
||||
[app.main.fonts :as f]
|
||||
[app.main.store :as st]
|
||||
[app.render-wasm.helpers :as h]
|
||||
[app.render-wasm.wasm :as wasm]
|
||||
[app.util.http :as http]
|
||||
[app.util.webapi :as wapi]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[goog.object :as gobj]
|
||||
[lambdaisland.uri :as u]
|
||||
[okulary.core :as l]))
|
||||
|
||||
(def ^:private fonts
|
||||
(l/derived :fonts st/state))
|
||||
|
||||
(defn- google-font-id->uuid
|
||||
[font-id]
|
||||
(let [font (get @f/fontsdb font-id)]
|
||||
(:uuid font)))
|
||||
|
||||
(defn- custom-font-id->uuid
|
||||
[font-id]
|
||||
(uuid/uuid (subs font-id (inc (str/index-of font-id "-")))))
|
||||
|
||||
(defn- font-id->uuid [font-id]
|
||||
(if (str/starts-with? font-id "gfont-")
|
||||
(google-font-id->uuid font-id)
|
||||
(custom-font-id->uuid font-id)))
|
||||
|
||||
(defn ^:private font-id->ttf-id [font-id font-style font-weight]
|
||||
(if (str/starts-with? font-id "gfont-")
|
||||
font-id
|
||||
(let [font-uuid (custom-font-id->uuid font-id)
|
||||
matching-font (d/seek (fn [[_ font]]
|
||||
(and (= (:font-id font) font-uuid)
|
||||
(= (:font-style font) font-style)
|
||||
(= (:font-weight font) font-weight)))
|
||||
(seq @fonts))]
|
||||
(when matching-font
|
||||
(:ttf-file-id (second matching-font))))))
|
||||
|
||||
;; IMPORTANT: It should be noted that only TTF fonts can be stored.
|
||||
(defn- store-font-buffer
|
||||
[font-data font-array-buffer]
|
||||
(let [id-buffer (:family-id-buffer font-data)
|
||||
size (.-byteLength font-array-buffer)
|
||||
ptr (h/call wasm/internal-module "_alloc_bytes" size)
|
||||
heap (gobj/get ^js wasm/internal-module "HEAPU8")
|
||||
mem (js/Uint8Array. (.-buffer heap) ptr size)]
|
||||
(.set mem (js/Uint8Array. font-array-buffer))
|
||||
(h/call wasm/internal-module "_store_font"
|
||||
(aget id-buffer 0)
|
||||
(aget id-buffer 1)
|
||||
(aget id-buffer 2)
|
||||
(aget id-buffer 3)
|
||||
(:weight font-data)
|
||||
(:style font-data))
|
||||
true))
|
||||
|
||||
(defn- store-font-url
|
||||
[font-data font-url]
|
||||
(->> (http/send! {:method :get
|
||||
:uri font-url
|
||||
:response-type :blob})
|
||||
(rx/map :body)
|
||||
(rx/mapcat wapi/read-file-as-array-buffer)
|
||||
(rx/map (fn [array-buffer] (store-font-buffer font-data array-buffer)))))
|
||||
|
||||
(defn- google-font-ttf-url
|
||||
[font-id font-variant-id]
|
||||
(let [font (get @f/fontsdb font-id)
|
||||
variant (d/seek (fn [variant]
|
||||
(= (:id variant) font-variant-id))
|
||||
(:variants font))
|
||||
file (-> (:ttf-url variant)
|
||||
(str/replace "http://fonts.gstatic.com/s/" (u/join cf/public-uri "/internal/gfonts/font/")))]
|
||||
file))
|
||||
|
||||
(defn- font-id->ttf-url
|
||||
[font-id font-variant-id]
|
||||
(if (str/starts-with? font-id "gfont-")
|
||||
;; if font-id is a google font (starts with gfont-), we need to get the ttf url from Google Fonts API.
|
||||
(google-font-ttf-url font-id font-variant-id)
|
||||
;; otherwise, we return the font from our public-uri
|
||||
(str (u/join cf/public-uri "assets/by-id/" font-id))))
|
||||
|
||||
(defn- store-font-id
|
||||
[font-data asset-id]
|
||||
(when asset-id
|
||||
(let [uri (font-id->ttf-url asset-id (:font-variant-id font-data))
|
||||
id-buffer (uuid/get-u32 (:wasm-id font-data))
|
||||
font-data (assoc font-data :family-id-buffer id-buffer)
|
||||
font-stored? (not= 0 (h/call wasm/internal-module "_is_font_uploaded"
|
||||
(aget id-buffer 0)
|
||||
(aget id-buffer 1)
|
||||
(aget id-buffer 2)
|
||||
(aget id-buffer 3)
|
||||
(:weight font-data)
|
||||
(:style font-data)))]
|
||||
(when-not font-stored? (store-font-url font-data uri)))))
|
||||
|
||||
(defn serialize-font-style
|
||||
[font-style]
|
||||
(case font-style
|
||||
"normal" 0
|
||||
"regular" 0
|
||||
"italic" 1
|
||||
0))
|
||||
|
||||
(defn serialize-font-id
|
||||
[font-id]
|
||||
(let [google-font? (str/starts-with? font-id "gfont-")]
|
||||
(if google-font?
|
||||
(uuid/get-u32 (google-font-id->uuid font-id))
|
||||
(let [no-prefix (subs font-id (inc (str/index-of font-id "-")))
|
||||
as-uuid (uuid/uuid no-prefix)]
|
||||
(uuid/get-u32 as-uuid)))))
|
||||
|
||||
(defn serialize-font-weight
|
||||
[font-weight]
|
||||
(js/Number font-weight))
|
||||
|
||||
(defn store-fonts
|
||||
[fonts]
|
||||
(keep (fn [font]
|
||||
(let [font-id (dm/get-prop font :font-id)
|
||||
font-variant-id (dm/get-prop font :font-variant-id)
|
||||
variant-parts (str/split font-variant-id #"\-")
|
||||
variant-parts (if (= (count variant-parts) 1)
|
||||
(conj variant-parts "400")
|
||||
variant-parts)
|
||||
style (first variant-parts)
|
||||
weight (serialize-font-weight (last variant-parts))
|
||||
asset-id (font-id->ttf-id font-id style weight)
|
||||
wasm-id (font-id->uuid font-id)
|
||||
font-data {:wasm-id wasm-id
|
||||
:font-variant-id font-variant-id
|
||||
:style (serialize-font-style style)
|
||||
:weight weight}]
|
||||
(store-font-id font-data asset-id))) fonts))
|
4
frontend/src/app/render_wasm/wasm.cljs
Normal file
4
frontend/src/app/render_wasm/wasm.cljs
Normal file
|
@ -0,0 +1,4 @@
|
|||
(ns app.render-wasm.wasm)
|
||||
|
||||
(defonce internal-frame-id nil)
|
||||
(defonce internal-module #js {})
|
Loading…
Add table
Reference in a new issue