diff --git a/frontend/src/app/main/fonts.clj b/frontend/src/app/main/fonts.clj index 43b9fb7916..aba8df555a 100644 --- a/frontend/src/app/main/fonts.clj +++ b/frontend/src/app/main/fonts.clj @@ -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)})) diff --git a/frontend/src/app/main/fonts.cljs b/frontend/src/app/main/fonts.cljs index 5b06f449b4..50b3b00354 100644 --- a/frontend/src/app/main/fonts.cljs +++ b/frontend/src/app/main/fonts.cljs @@ -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))) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 5f72350baf..625374e826 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -176,6 +176,26 @@ (defn- get-string-length [string] (+ (count string) 1)) +(def ^:private fonts + (l/derived :fonts st/state)) + +(defn- google-font-id->uuid + [font-id] + (let [font (get @fonts/fontsdb font-id)] + (:uuid font))) + + +(defn ^:private font->ttf-id [font-uuid font-style font-weight] + (if (str/starts-with? font-uuid "gfont-") + font-uuid + (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)))))) + ;; IMPORTANT: It should be noted that only TTF fonts can be stored. (defn- store-font-buffer [font-data font-array-buffer] @@ -203,11 +223,29 @@ (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 @fonts/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 (str (u/join cf/public-uri "assets/by-id/" asset-id)) - id-buffer (uuid/get-u32 (:family-id font-data)) + (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 internal-module "_is_font_uploaded" (aget id-buffer 0) @@ -670,17 +708,6 @@ (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] @@ -692,9 +719,12 @@ (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))) + (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] @@ -723,17 +753,25 @@ [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 #"\-") + google-font? (str/starts-with? font-id "gfont-") + 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)) - 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-id (if google-font? + font-id + (uuid/uuid (subs font-id (inc (str/index-of font-id "-"))))) + asset-id (font->ttf-id font-id style weight) + wasm-id (if google-font? (google-font-id->uuid font-id) font-id) font-data {:family-id font-id + :wasm-id wasm-id + :font-variant-id font-variant-id :style (serialize-font-style style) :weight weight}] - (store-font-id font-data ttf-id))) fonts)) + (store-font-id font-data asset-id))) fonts)) (defn set-shape-text-content [content] (h/call internal-module "_clear_shape_text") @@ -1011,3 +1049,4 @@ (js/console.error cause) (p/resolved false))))) (p/resolved false)))) + diff --git a/render-wasm/src/render/fonts.rs b/render-wasm/src/render/fonts.rs index 2460fa27d0..0fb4d57e5d 100644 --- a/render-wasm/src/render/fonts.rs +++ b/render-wasm/src/render/fonts.rs @@ -66,6 +66,8 @@ impl FontStore { return Ok(()); } + println!("Adding font: {:?}", family); + let alias = format!("{}", family); let typeface = self .font_mgr