diff --git a/frontend/src/app/main/fonts.cljs b/frontend/src/app/main/fonts.cljs index 146b78a46..cbdf0d35a 100644 --- a/frontend/src/app/main/fonts.cljs +++ b/frontend/src/app/main/fonts.cljs @@ -21,6 +21,8 @@ [clojure.set :as set] [app.util.object :as obj])) +(defonce default-font "sourcesanspro") + (def google-fonts (preload-gfonts "fonts/gfonts.2020.04.23.json")) @@ -120,6 +122,12 @@ variants (str/join "," (map :id variants))] (str base ":" variants "&display=block"))) +(defn font-url [font-id font-variant-id] + (let [{:keys [backend family] :as entry} (get @fontsdb font-id)] + (case backend + :google (gfont-url family {:id font-variant-id}) + (str "/fonts/" family "-" (or font-variant-id "regular") ".woff")))) + (defmulti ^:private load-font :backend) (defmethod load-font :builtin diff --git a/frontend/src/app/main/ui/shapes/text.cljs b/frontend/src/app/main/ui/shapes/text.cljs index d78db4bb0..de1a87f4f 100644 --- a/frontend/src/app/main/ui/shapes/text.cljs +++ b/frontend/src/app/main/ui/shapes/text.cljs @@ -54,7 +54,7 @@ text-transform (obj/get data "text-transform") line-height (obj/get data "line-height") - font-id (obj/get data "font-id") + font-id (obj/get data "font-id" fonts/default-font) font-variant-id (obj/get data "font-variant-id") font-family (obj/get data "font-family") @@ -97,25 +97,46 @@ (defn get-all-fonts [node] (let [current-font (if (not (nil? (:font-id node))) - #{(:font-id node)} + #{(select-keys node [:font-id :font-variant-id])} #{}) children-font (map get-all-fonts (:children node))] (reduce set/union (conj children-font current-font)))) -(defn fetch-font [font-id] - (let [{:keys [family variants]} (get @fonts/fontsdb font-id)] - (-> (js/fetch (fonts/gfont-url family variants)) +(defn fetch-font [font-id font-variant-id] + (let [font-url (fonts/font-url font-id font-variant-id)] + (-> (js/fetch font-url) (p/then (fn [res] (.text res)))))) -(defn embed-font [font-id] - (p/let [font-text (fetch-font font-id) - url-to-data (->> font-text - (re-seq #"url\(([^)]+)\)") - (map second) - (map df/fetch-as-data-uri) - (p/all))] - (reduce (fn [text [url data]] (str/replace text url data)) font-text url-to-data))) +(defonce font-face-template " +/* latin */ +@font-face { + font-family: '$0'; + font-style: $3; + font-weight: $2; + font-display: block; + src: url(/fonts/%(0)s-$1.woff) format('woff'); +} +") + +(defn get-local-font-css [font-id font-variant-id] + (let [{:keys [family variants]} (get @fonts/fontsdb font-id) + {:keys [name weight style]} (->> variants (filter #(= (:id %) font-variant-id)) first) + css-str (str/format font-face-template [family name weight style])] + (p/resolved css-str))) + +(defn embed-font [{:keys [font-id font-variant-id] :or {font-variant-id "regular"}}] + (let [{:keys [backend]} (get @fonts/fontsdb font-id)] + (p/let [font-text (case backend + :google (fetch-font font-id font-variant-id) + (get-local-font-css font-id font-variant-id)) + url-to-data (->> font-text + (re-seq #"url\(([^)]+)\)") + (map second) + (map df/fetch-as-data-uri) + (p/all))] + (reduce (fn [text [url data]] (str/replace text url data)) font-text url-to-data)) + )) (mf/defc text-node [{:keys [node index] :as props}] @@ -128,6 +149,7 @@ (fn [] (when (and embed-resources? (= type "root")) (let [font-to-embed (get-all-fonts node) + font-to-embed (if (empty? font-to-embed) #{{:font-id fonts/default-font}} font-to-embed) embeded (map embed-font font-to-embed)] (-> (p/all embeded) (p/then (fn [result] (reset! embeded-fonts (str/join "\n" result))))))))) diff --git a/frontend/src/app/main/ui/workspace/shapes/text.cljs b/frontend/src/app/main/ui/workspace/shapes/text.cljs index 2f9b9d9a3..c1df7db0d 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text.cljs @@ -23,6 +23,7 @@ [app.main.ui.workspace.shapes.common :as common] [app.main.ui.shapes.text :as text] [app.main.ui.keyboard :as kbd] + [app.main.ui.context :as muc] [app.main.fonts :as fonts] [app.util.color :as color] [app.util.dom :as dom] @@ -62,6 +63,8 @@ selected? (and (contains? selected id) (= (count selected) 1)) + embed-resources? (mf/use-ctx muc/embed-ctx) + on-mouse-down #(handle-mouse-down % shape) on-context-menu #(common/on-context-menu % shape) @@ -76,7 +79,7 @@ :on-mouse-down on-mouse-down :on-context-menu on-context-menu} [:* - (when (not edition?) + (when (and (not edition?) (not embed-resources?)) [:g {:opacity 0 :style {:pointer-events "none"}} ;; We only render the component for its side-effect @@ -127,7 +130,7 @@ text-transform (obj/get data "text-transform") line-height (obj/get data "line-height") - font-id (obj/get data "font-id") + font-id (obj/get data "font-id" fonts/default-font) font-variant-id (obj/get data "font-variant-id") font-family (obj/get data "font-family")