From c0ba92f50340ab09386d39fa19674e3f39c96c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Tue, 8 Apr 2025 16:45:27 +0200 Subject: [PATCH] :tada: Add support for default font variants (wasm) --- frontend/src/app/main/fonts.cljs | 20 ++--- frontend/src/app/render_wasm/api/fonts.cljs | 82 +++++++++++++-------- 2 files changed, 63 insertions(+), 39 deletions(-) diff --git a/frontend/src/app/main/fonts.cljs b/frontend/src/app/main/fonts.cljs index 5b06f449b4..4ee3c80b39 100644 --- a/frontend/src/app/main/fonts.cljs +++ b/frontend/src/app/main/fonts.cljs @@ -33,16 +33,16 @@ :name "Source Sans Pro" :family "sourcesanspro" :variants - [{:id "200" :name "200" :weight "200" :style "normal" :suffix "extralight"} - {:id "200italic" :name "200 (italic)" :weight "200" :style "italic" :suffix "extralightitalic"} - {:id "300" :name "300" :weight "300" :style "normal" :suffix "light"} - {:id "300italic" :name "300 (italic)" :weight "300" :style "italic" :suffix "lightitalic"} - {:id "regular" :name "regular" :weight "400" :style "normal"} - {:id "italic" :name "italic" :weight "400" :style "italic"} - {:id "bold" :name "bold" :weight "bold" :style "normal"} - {:id "bolditalic" :name "bold (italic)" :weight "bold" :style "italic"} - {:id "black" :name "black" :weight "900" :style "normal"} - {:id "blackitalic" :name "black (italic)" :weight "900" :style "italic"}]}]) + [{:id "200" :name "200" :weight "200" :style "normal" :suffix "extralight" :ttf-url "sourcesanspro-extralight.ttf"} + {:id "200italic" :name "200 (italic)" :weight "200" :style "italic" :suffix "extralightitalic" :ttf-url "sourcesanspro-extralightitalic.ttf"} + {:id "300" :name "300" :weight "300" :style "normal" :suffix "light" :ttf-url "sourcesanspro-light.ttf"} + {:id "300italic" :name "300 (italic)" :weight "300" :style "italic" :suffix "lightitalic" :ttf-url "sourcesanspro-lightitalic.ttf"} + {:id "regular" :name "regular" :weight "400" :style "normal" :ttf-url "sourcesanspro-regular.ttf"} + {:id "italic" :name "italic" :weight "400" :style "italic" :ttf-url "sourcesanspro-italic.ttf"} + {:id "bold" :name "bold" :weight "bold" :style "normal" :ttf-url "sourcesanspro-bold.ttf"} + {:id "bolditalic" :name "bold (italic)" :weight "bold" :style "italic" :ttf-url "sourcesanspro-bolditalic.ttf"} + {:id "black" :name "black" :weight "900" :style "normal" :ttf-url "sourcesanspro-black.ttf"} + {:id "blackitalic" :name "black (italic)" :weight "900" :style "italic" :ttf-url "sourcesanspro-blackitalic.ttf"}]}]) (defonce fontsdb (l/atom {})) (defonce fonts (l/atom [])) diff --git a/frontend/src/app/render_wasm/api/fonts.cljs b/frontend/src/app/render_wasm/api/fonts.cljs index 3797a0bce4..4c13618bf4 100644 --- a/frontend/src/app/render_wasm/api/fonts.cljs +++ b/frontend/src/app/render_wasm/api/fonts.cljs @@ -34,20 +34,46 @@ [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- font-backend + [font-id] + (cond + (str/starts-with? font-id "gfont-") + :google + (str/starts-with? font-id "custom-") + :custom + :else + :builtin)) -(defn ^:private font-id->ttf-id [font-id font-variant-id] - (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-variant-id font) font-variant-id))) - (seq @fonts))] - (when matching-font - (:ttf-file-id (second matching-font)))))) +(defn- font-db-data + [font-id font-variant-id] + (let [font (fonts/get-font-data font-id) + variant (fonts/get-variant font font-variant-id)] + variant)) + +(defn- font-id->uuid [font-id] + (case (font-backend font-id) + :google + (google-font-id->uuid font-id) + :custom + (custom-font-id->uuid font-id) + :builtin + uuid/zero)) + +(defn ^:private font-id->asset-id [font-id font-variant-id] + (case (font-backend font-id) + :google + font-id + :custom + (let [font-uuid (custom-font-id->uuid font-id) + matching-font (d/seek (fn [[_ font]] + (and (= (:font-id font) font-uuid) + (= (:font-variant-id font) font-variant-id))) + (seq @fonts))] + (when matching-font + (:ttf-file-id (second matching-font)))) + :builtin + (let [variant (font-db-data font-id font-variant-id)] + (:ttf-url variant)))) ;; IMPORTANT: It should be noted that only TTF fonts can be stored. (defn- store-font-buffer @@ -78,26 +104,25 @@ (defn- google-font-ttf-url [font-id font-variant-id] - (let [font (fonts/get-font-data font-id) - variant (fonts/get-variant font font-variant-id)] + (let [variant (font-db-data font-id font-variant-id)] (if-let [ttf-url (:ttf-url variant)] (str/replace ttf-url "http://fonts.gstatic.com/s/" (u/join cf/public-uri "/internal/gfonts/font/")) - (do - (println "Variant TTF URL not found for" font-id font-variant-id) - nil)))) + nil))) (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. + [font-id asset-id font-variant-id] + (case (font-backend font-id) + :google (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)))) + :custom + (dm/str (u/join cf/public-uri "assets/by-id/" font-id)) + :builtin + (dm/str (u/join cf/public-uri "fonts/" asset-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)) + (let [uri (font-id->ttf-url (:font-id font-data) 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" @@ -136,17 +161,16 @@ (let [font-id (dm/get-prop font :font-id) font-variant-id (dm/get-prop font :font-variant-id) wasm-id (font-id->uuid font-id) + raw-weight (or (:weight (font-db-data font-id font-variant-id)) 400) - weight (serialize-font-weight - (if-let [weight-match (re-find #"\d+" font-variant-id)] - (js/parseInt weight-match) - 400)) + weight (serialize-font-weight raw-weight) style (serialize-font-style (cond (str/includes? font-variant-id "italic") "italic" :else "normal")) - asset-id (font-id->ttf-id font-id font-variant-id) + asset-id (font-id->asset-id font-id font-variant-id) font-data {:wasm-id wasm-id + :font-id font-id :font-variant-id font-variant-id :style style :weight weight}]