From 4d6d7a6a3d8a0518c96db84a4c448145f39b8f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Thu, 27 Nov 2025 14:06:55 +0100 Subject: [PATCH] :bug: Fix emoji font not being used as fallback in text editor dom --- .../ui/workspace/shapes/text/v2_editor.cljs | 12 ++++++++---- frontend/src/app/render_wasm/api.cljs | 8 ++++---- frontend/src/app/render_wasm/api/fonts.cljs | 3 ++- frontend/src/app/util/text/content/styles.cljs | 3 ++- .../text-editor/src/editor/content/dom/Style.js | 17 +++++++++++++++++ 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs index f5591e3f36..9d98998dd5 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs @@ -269,6 +269,11 @@ "bottom" "flex-end" nil)) +(defn- font-family-from-font-id [font-id] + (if (str/includes? font-id "gfont-noto-sans") + (let [lang (str/replace font-id #"gfont\-noto\-sans\-" "")] + (if (>= (count lang) 3) (str/capital lang) (str/upper lang))) + "Noto Color Emoji")) ;; Text Editor Wrapper ;; This is an SVG element that wraps the HTML editor. @@ -281,11 +286,10 @@ [{:keys [shape modifiers canvas-ref] :as props} _] (let [shape-id (dm/get-prop shape :id) modifiers (dm/get-in modifiers [shape-id :modifiers]) - fallback-fonts (wasm.api/get-fallback-fonts (:content shape) false) + + fallback-fonts (wasm.api/fonts-from-text-content (:content shape) false) fallback-families (map (fn [font] - (let [lang (str/replace (:font-id font) #"gfont\-noto\-sans\-" "") - lang (if (>= (count lang) 3) (str/capital lang) (str/upper lang))] - (str/concat "\"Noto Sans " lang "\""))) fallback-fonts) + (font-family-from-font-id (:font-id font))) fallback-fonts) clip-id (dm/str "text-edition-clip" shape-id) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index de6c2f1bb3..be85dc1fd7 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -785,7 +785,7 @@ hidden))) shadows)) -(defn get-fallback-fonts [content write-text-content?] +(defn fonts-from-text-content [content fallback-fonts-only?] (let [paragraph-set (first (get content :children)) paragraphs (get paragraph-set :children) total (count paragraphs)] @@ -806,7 +806,7 @@ langs (t/collect-used-languages langs text)] ;; FIXME: this should probably be somewhere else - (when write-text-content? (t/write-shape-text spans paragraph text)) + (when fallback-fonts-only? (t/write-shape-text spans paragraph text)) (recur (inc index) emoji? @@ -818,7 +818,7 @@ (f/add-noto-fonts langs)) fallback-fonts (filter #(get % :is-fallback) updated-fonts)] - fallback-fonts))))) + (if fallback-fonts-only? updated-fonts fallback-fonts)))))) (defn set-shape-text-content "This function sets shape text content and returns a stream that loads the needed fonts asynchronously" @@ -829,7 +829,7 @@ (set-shape-vertical-align (get content :vertical-align)) (let [fonts (fonts/get-content-fonts content) - fallback-fonts (get-fallback-fonts content true) + fallback-fonts (fonts-from-text-content content true) all-fonts (concat fonts fallback-fonts) result (f/store-fonts shape-id all-fonts)] (f/load-fallback-fonts-for-editor! fallback-fonts) diff --git a/frontend/src/app/render_wasm/api/fonts.cljs b/frontend/src/app/render_wasm/api/fonts.cljs index 8c6aeccda7..ea47a06b2b 100644 --- a/frontend/src/app/render_wasm/api/fonts.cljs +++ b/frontend/src/app/render_wasm/api/fonts.cljs @@ -283,7 +283,8 @@ :font-variant-id "regular" :style 0 :weight 400 - :is-emoji true})) + :is-emoji true + :is-fallback true})) (def noto-fonts {:japanese {:font-id "gfont-noto-sans-jp" :font-variant-id "regular" :style 0 :weight 400 :is-fallback true} diff --git a/frontend/src/app/util/text/content/styles.cljs b/frontend/src/app/util/text/content/styles.cljs index 078d870c0c..8cab737417 100644 --- a/frontend/src/app/util/text/content/styles.cljs +++ b/frontend/src/app/util/text/content/styles.cljs @@ -38,7 +38,8 @@ (str v "px") (and (= k :font-family) (seq v)) - (str/concat (str/quote v) ", var(--fallback-families)") + ;; pick just first family, avoid quoting twice, and add var(--fallback-families) + (str/concat (str/quote (str/unquote (first (str/split v ",")))) ", var(--fallback-families)") :else v)) diff --git a/frontend/text-editor/src/editor/content/dom/Style.js b/frontend/text-editor/src/editor/content/dom/Style.js index 30fc4c8324..63027d6b0c 100644 --- a/frontend/text-editor/src/editor/content/dom/Style.js +++ b/frontend/text-editor/src/editor/content/dom/Style.js @@ -19,6 +19,23 @@ const DEFAULT_FONT_WEIGHT = "400"; * @param {string} value */ export function sanitizeFontFamily(value) { + // NOTE: This is a fix for a bug introduced earlier that have might modified the font-family in the model + // adding extra double quotes. + if (value && value.startsWith('""')) { + //remove the first and last quotes + value = value.slice(1).replace(/"([^"]*)$/, "$1"); + + // remove quotes from font-family in 1-word font-families + // and repeated values + value = [ + ...new Set( + value + .split(", ") + .map((x) => (x.includes(" ") ? x : x.replace(/"/g, ""))), + ), + ].join(", "); + } + if (!value || value === "") { return "var(--fallback-families)"; } else if (value.endsWith(" var(--fallback-families)")) {