🔧 Normalize font attributes to support old formats

This commit is contained in:
Elena Torro
2025-11-28 12:53:47 +01:00
committed by Belén Albeza
parent 4282cdcd2c
commit 786f73767b
4 changed files with 91 additions and 28 deletions

View File

@@ -342,8 +342,8 @@
(fn [result {:keys [font-id] :as node}]
(let [current-font
(if (some? font-id)
(select-keys node [:font-id :font-variant-id])
(select-keys txt/default-typography [:font-id :font-variant-id]))]
(select-keys node [:font-id :font-variant-id :font-weight :font-style])
(select-keys txt/default-typography [:font-id :font-variant-id :font-weight :font-style]))]
(conj result current-font)))
#{})))

View File

@@ -20,7 +20,6 @@
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid]
[app.config :as cf]
[app.main.fonts :as fonts]
[app.main.refs :as refs]
[app.main.render :as render]
[app.main.store :as st]
@@ -828,7 +827,7 @@
(set-shape-vertical-align (get content :vertical-align))
(let [fonts (fonts/get-content-fonts content)
(let [fonts (f/get-content-fonts content)
fallback-fonts (fonts-from-text-content content true)
all-fonts (concat fonts fallback-fonts)
result (f/store-fonts shape-id all-fonts)]

View File

@@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.logging :as log]
[app.common.types.text :as txt]
[app.common.uuid :as uuid]
[app.config :as cf]
[app.main.fonts :as fonts]
@@ -49,10 +50,13 @@
:builtin))
(defn- font-db-data
[font-id font-variant-id]
[font-id font-variant-id font-weight-fallback font-style-fallback]
(let [font (fonts/get-font-data font-id)
closest-variant (fonts/find-closest-variant font font-weight-fallback font-style-fallback)
variant (fonts/get-variant font font-variant-id)]
variant))
(if (or (nil? closest-variant) (= closest-variant variant))
variant
closest-variant)))
(defn- font-id->uuid [font-id]
(case (font-backend font-id)
@@ -63,22 +67,22 @@
:builtin
uuid/zero))
(defn ^:private font-id->asset-id [font-id font-variant-id]
(defn ^:private font-id->asset-id [font-id font-variant-id font-weight font-style]
(case (font-backend font-id)
:google
font-id
:custom
(let [font-uuid (custom-font-id->uuid font-id)
matching-font (d/seek (fn [[_ font]]
(let [variant-id (or (:font-variant-id font) (dm/str (:font-style font) "-" (:font-weight font)))]
(and (= (:font-id font) font-uuid)
(or (nil? font-variant-id)
(= variant-id font-variant-id)))))
(seq @fonts))]
matching-font (some (fn [[_ font]]
(and (= (:font-id font) font-uuid)
(= (str (:font-weight font)) (str font-weight))
font))
(seq @fonts))]
(when matching-font
(:ttf-file-id (second matching-font))))
(:ttf-file-id matching-font)))
:builtin
(let [variant (font-db-data font-id font-variant-id)]
(let [variant (font-db-data font-id font-variant-id font-weight font-style)]
(:ttf-url variant))))
(defn update-text-layout
@@ -100,6 +104,7 @@
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 shape-id-buffer 0)
@@ -134,17 +139,17 @@
(rx/empty))))})
(defn- google-font-ttf-url
[font-id font-variant-id]
(let [variant (font-db-data font-id font-variant-id)]
[font-id font-variant-id font-weight font-style]
(let [variant (font-db-data font-id font-variant-id font-weight font-style)]
(if-let [ttf-url (:ttf-url variant)]
(str/replace ttf-url "https://fonts.gstatic.com/s/" (u/join cf/public-uri "/internal/gfonts/font/"))
nil)))
(defn- font-id->ttf-url
[font-id asset-id font-variant-id]
[font-id asset-id font-variant-id font-weight font-style]
(case (font-backend font-id)
:google
(google-font-ttf-url font-id font-variant-id)
(google-font-ttf-url font-id font-variant-id font-weight font-style)
:custom
(dm/str (u/join cf/public-uri "assets/by-id/" asset-id))
:builtin
@@ -153,7 +158,7 @@
(defn- store-font-id
[shape-id font-data asset-id emoji? fallback?]
(when asset-id
(let [uri (font-id->ttf-url (:font-id font-data) asset-id (:font-variant-id font-data))
(let [uri (font-id->ttf-url (:font-id font-data) asset-id (:font-variant-id font-data) (:weight font-data) (:style 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"
@@ -187,6 +192,30 @@
(catch :default _e
uuid/zero)))
(defn normalize-span-font
[span paragraph]
(let [font-id (:font-id span)
font-variant-id (:font-variant-id span)
font-weight-fallback (or (:font-weight span) (:font-weight paragraph))
font-style-fallback (or (:font-style span) (:font-style paragraph))
font-data (font-db-data font-id font-variant-id font-weight-fallback font-style-fallback)]
(-> span
(assoc :font-variant-id (or (:name font-data) (:id font-data) font-variant-id)
:font-weight (or (:weight font-data) font-weight-fallback)
:font-style (or (:style font-data) font-style-fallback)))))
(defn normalize-paragraph-font
[paragraph]
(let [font-id (:font-id paragraph)
font-variant-id (:font-variant-id paragraph)
font-weight-fallback (:font-weight paragraph)
font-style-fallback (:font-style paragraph)
font-data (font-db-data font-id font-variant-id font-weight-fallback font-style-fallback)]
(-> paragraph
(assoc :font-variant-id (or (:name font-data) (:id font-data) font-variant-id)
:font-weight (or (:weight font-data) font-weight-fallback)
:font-style (or (:style font-data) font-style-fallback)))))
(defn serialize-font-size
[font-size]
(cond
@@ -244,26 +273,36 @@
(string? letter-spacing)
(or (d/parse-double letter-spacing) default-letter-spacing)))
(defn normalize-font-variant
[font-variant-id]
(if (or (nil? font-variant-id) (str/blank? font-variant-id))
"regular"
font-variant-id))
(defn store-font
[shape-id font]
(let [font-id (get font :font-id)
font-variant-id (get font :font-variant-id)
font-weight-fallback (or (get font :font-weight) 400)
font-style-fallback (or (get font :font-style) "normal")
emoji? (get font :is-emoji false)
fallback? (get font :is-fallback false)
font-data (font-db-data font-id font-variant-id font-weight-fallback font-style-fallback)
wasm-id (font-id->uuid font-id)
raw-weight (or (:weight (font-db-data font-id font-variant-id)) 400)
raw-weight (or (:weight font-data) font-weight-fallback)
weight (serialize-font-weight raw-weight)
style (serialize-font-style (cond
(str/includes? font-variant-id "italic") "italic"
(str/includes? raw-weight "italic") "italic"
:else "normal"))
asset-id (font-id->asset-id font-id font-variant-id)
:else font-style-fallback))
variant-id (or (:name font-data) font-variant-id)
asset-id (font-id->asset-id font-id variant-id raw-weight style)
font-data {:wasm-id wasm-id
:font-id font-id
:font-variant-id font-variant-id
:font-variant-id variant-id
:style style
:weight weight}]
(store-font-id shape-id font-data asset-id emoji? fallback?)))
;; FIXME: This is a temporary function to load the fallback fonts for the editor.
@@ -273,6 +312,29 @@
(doseq [font fonts]
(fonts/ensure-loaded! (:font-id font) (:font-variant-id font))))
(defn get-content-fonts
"Extends from app.main.fonts/get-content-fonts. Extracts the fonts used by the content of a text shape, resolving the correct font variant info."
[content]
(let [paragraph-set (first (get content :children))
paragraphs (get paragraph-set :children)]
(->> paragraphs
(mapcat #(get % :children))
(filter txt/is-text-node?)
(reduce
(fn [result {:keys [font-id font-variant-id font-weight font-style] :as node}]
(let [resolved-font-id (or font-id (:font-id txt/default-typography))
resolved-variant-id (or font-variant-id (:font-variant-id txt/default-typography))
font-weight-fallback (or font-weight (:font-weight txt/default-typography) 400)
font-style-fallback (or font-style (:font-style txt/default-typography) "normal")
font-data (font-db-data resolved-font-id resolved-variant-id font-weight-fallback font-style-fallback)
font-ref {:font-id resolved-font-id
:font-variant-id (or (:name font-data) (:id font-data) resolved-variant-id)
:font-weight (or (:weight font-data) font-weight-fallback)
:font-style (or (:style font-data) font-style-fallback)}]
(conj result font-ref)))
#{}))))
(defn store-fonts
[shape-id fonts]
(keep (fn [font] (store-font shape-id font)) fonts))

View File

@@ -142,7 +142,9 @@
;; buffer has the following format:
;; [<num-spans> <paragraph_attributes> <spans_attributes> <text>]
[spans paragraph text]
(let [num-spans (count spans)
(let [normalized-paragraph (f/normalize-paragraph-font paragraph)
normalized-spans (map #(f/normalize-span-font % normalized-paragraph) spans)
num-spans (count normalized-spans)
fills-size (* types.fills.impl/FILL-U8-SIZE MAX-TEXT-FILLS)
metadata-size (+ PARAGRAPH-ATTR-U8-SIZE
(* num-spans (+ SPAN-ATTR-U8-SIZE fills-size)))
@@ -157,8 +159,8 @@
(-> offset
(mem/write-u32 dview num-spans)
(write-paragraph dview paragraph)
(write-spans dview spans paragraph)
(write-paragraph dview normalized-paragraph)
(write-spans dview normalized-spans normalized-paragraph)
(mem/write-buffer heapu8 text-buffer))
(h/call wasm/internal-module "_set_shape_text_content")))