0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-27 15:11:26 -05:00

🐛 Fix problems with font initialization

This commit is contained in:
alonso.torres 2022-05-24 23:29:30 +02:00
parent 35681c3af8
commit 97c9035cfd
7 changed files with 98 additions and 32 deletions

View file

@ -82,6 +82,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defonce loaded (l/atom #{}))
(defonce loading (l/atom {}))
(defn- create-link-element
[uri]
@ -199,11 +200,34 @@
(p/create (fn [resolve]
(ensure-loaded! id resolve))))
([id on-loaded]
(if (contains? @loaded id)
(on-loaded id)
(when-let [font (get @fontsdb id)]
(load-font (assoc font ::on-loaded on-loaded))
(swap! loaded conj id)))))
(let [font (get @fontsdb id)]
(cond
;; Font already loaded, we just continue
(contains? @loaded id)
(on-loaded id)
;; Font is currently downloading. We attach the caller to the promise
(contains? @loading id)
(-> (get @loading id)
(p/then #(on-loaded id)))
;; First caller, we create the promise and then wait
:else
(let [on-load (fn [resolve]
(swap! loaded conj id)
(swap! loading dissoc id)
(on-loaded id)
(resolve id))
load-p (p/create
(fn [resolve _]
(-> font
(assoc ::on-loaded (partial on-load resolve))
(load-font))))]
(swap! loading assoc id load-p)
nil)))))
(defn ready
[cb]

View file

@ -73,8 +73,12 @@
;; Creates a style tag by replacing the urls with the data uri
style (replace-embeds fonts-css fonts-urls fonts-embed)]
(when (d/not-empty? style)
[:style {:data-loading loading?} style])))
(cond
(d/not-empty? style)
[:style {:data-loading loading?} style]
(d/not-empty? fonts)
[:style {:data-loading true}])))
(defn shape->fonts
[shape objects]

View file

@ -110,7 +110,10 @@
(let [font-variant (d/seek #(= font-variant-id (:id %)) (:variants font))]
[(str/quote (or (:family font) (:font-family data)))
(or (:style font-variant) (:font-style data))
(or (:weight font-variant) (:font-weight data))]))]
(or (:weight font-variant) (:font-weight data))]))
base (-> base
(obj/set! "--font-id" font-id))]
(cond-> base
(some? fills)

View file

@ -115,7 +115,7 @@
(fn []
(when (and (some? @node-ref) @regenerate-thumbnail)
(let [loading-images? (some? (dom/query @node-ref "[data-loading='true']"))
loading-fonts? (some? (dom/query (dm/str "#frame-container-" (:id shape) " style[data-loading='true']")))]
loading-fonts? (some? (dom/query (dm/str "#frame-container-" (:id shape) " > style[data-loading='true']")))]
(when (and (not loading-images?) (not loading-fonts?))
(generate-thumbnail)
(reset! regenerate-thumbnail false))))))

View file

@ -23,6 +23,7 @@
[app.util.text-editor :as ted]
[app.util.text-svg-position :as utp]
[app.util.timers :as ts]
[promesa.core :as p]
[rumext.alpha :as mf]))
(defn strip-position-data [shape]
@ -73,25 +74,25 @@
(st/emit! (dwt/resize-text id width height)))))
;; Update the position-data of every text fragment
(let [position-data (utp/calc-position-data node)]
(p/let [position-data (utp/calc-position-data node)]
(st/emit! (dwt/update-position-data id position-data)))
(st/emit! (dwt/clean-text-modifier id)))
(defn- update-text-modifier
[{:keys [grow-type id]} node]
(let [position-data (utp/calc-position-data node)
props {:position-data position-data}
(p/let [position-data (utp/calc-position-data node)
props {:position-data position-data}
props
(if (contains? #{:auto-height :auto-width} grow-type)
(let [{:keys [width height]} (-> (dom/query node ".paragraph-set") (dom/get-client-size))
width (mth/ceil width)
height (mth/ceil height)]
(if (and (not (mth/almost-zero? width)) (not (mth/almost-zero? height)))
(assoc props :width width :height height)
props))
props)]
props
(if (contains? #{:auto-height :auto-width} grow-type)
(let [{:keys [width height]} (-> (dom/query node ".paragraph-set") (dom/get-client-size))
width (mth/ceil width)
height (mth/ceil height)]
(if (and (not (mth/almost-zero? width)) (not (mth/almost-zero? height)))
(assoc props :width width :height height)
props))
props)]
(st/emit! (dwt/update-text-modifier id props))))

View file

@ -548,3 +548,11 @@
(seq (.-children node)))]
(->> root-node
(tree-seq branch? get-children))))
(defn check-font? [font]
(let [fonts (.-fonts globals/document)]
(.check fonts font)))
(defn load-font [font]
(let [fonts (.-fonts globals/document)]
(.load fonts font)))

View file

@ -9,9 +9,11 @@
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.common.transit :as transit]
[app.main.fonts :as fonts]
[app.main.store :as st]
[app.util.dom :as dom]
[app.util.text-position-data :as tpd]))
[app.util.text-position-data :as tpd]
[promesa.core :as p]))
(defn parse-text-nodes
"Given a text node retrieves the rectangles for everyone of its paragraphs and its text."
@ -27,6 +29,27 @@
(map parse-entry)
(tpd/parse-text-nodes parent-node text-node))))
(def load-promises (atom {}))
(defn load-font
[font]
(if (contains? @load-promises font)
(get @load-promises font)
(let [load-promise (dom/load-font font)]
(swap! load-promises assoc font load-promise)
load-promise)))
(defn resolve-font
[^js node]
(let [styles (js/getComputedStyle node)
font (.getPropertyValue styles "font")]
(if (dom/check-font? font)
(p/resolved font)
(let [font-id (.getPropertyValue styles "--font-id")]
(-> (fonts/ensure-loaded! font-id)
(p/then #(when (not (dom/check-font? font))
(load-font font))))))))
(defn calc-text-node-positions
[base-node viewport zoom]
@ -58,22 +81,25 @@
:width (- (:x p2) (:x p1))
:height (- (:y p2) (:y p1)))))
text-nodes (dom/query-all base-node ".text-node, span[data-text]")]
(->> text-nodes
(mapcat
(fn [parent-node]
(let [direction (.-direction (js/getComputedStyle parent-node))]
(->> (.-childNodes parent-node)
(mapcat #(parse-text-nodes parent-node direction %))))))
(mapv #(update % :position translate-rect))))))
text-nodes (dom/query-all base-node ".text-node, span[data-text]")
load-fonts (->> text-nodes (map resolve-font))]
(-> (p/all load-fonts)
(p/then
(fn []
(->> text-nodes
(mapcat
(fn [parent-node]
(let [direction (.-direction (js/getComputedStyle parent-node))]
(->> (.-childNodes parent-node)
(mapcat #(parse-text-nodes parent-node direction %))))))
(mapv #(update % :position translate-rect)))))))))
(defn calc-position-data
[base-node]
(let [viewport (dom/get-element "render")
zoom (or (get-in @st/state [:workspace-local :zoom]) 1)]
(when (and (some? base-node) (some? viewport))
(let [text-data (calc-text-node-positions base-node viewport zoom)]
(p/let [text-data (calc-text-node-positions base-node viewport zoom)]
(when (d/not-empty? text-data)
(->> text-data
(mapv (fn [{:keys [node position text direction]}]