mirror of
https://github.com/penpot/penpot.git
synced 2025-06-10 10:41:38 +02:00
🎉 Render text that uses a Google Font
This commit is contained in:
parent
a109f11926
commit
f53cae0faa
4 changed files with 74 additions and 29 deletions
|
@ -7,33 +7,36 @@
|
||||||
(ns app.main.fonts
|
(ns app.main.fonts
|
||||||
"A fonts loading macros."
|
"A fonts loading macros."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
[clojure.data.json :as json]
|
[clojure.data.json :as json]
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[cuerdas.core :as str]))
|
[cuerdas.core :as str]))
|
||||||
|
|
||||||
(defn- parse-gfont-variant
|
(defn- parse-gfont-variant
|
||||||
[variant]
|
[variant files]
|
||||||
(cond
|
(cond
|
||||||
(= "regular" variant)
|
(= "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)
|
(= "italic" variant)
|
||||||
{:id "italic" :name "italic" :weight "400" :style "italic"}
|
{:id "italic" :name "italic" :weight "400" :style "italic" :ttf-url (get files "italic")}
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(when-let [[a b c] (re-find #"^(\d+)(.*)$" variant)]
|
(when-let [[a b c] (re-find #"^(\d+)(.*)$" variant)]
|
||||||
(if (str/empty? c)
|
(if (str/empty? c)
|
||||||
{:id a :name b :weight b :style "normal"}
|
{:id a :name b :weight b :style "normal" :ttf-url (get files a)}
|
||||||
{:id a :name (str b " (" c ")") :weight b :style c}))))
|
{:id a :name (str b " (" c ")") :weight b :style c :ttf-url (get files c)}))))
|
||||||
|
|
||||||
(defn- parse-gfont
|
(defn- parse-gfont
|
||||||
[font]
|
[font]
|
||||||
(let [family (get font "family")
|
(let [family (get font "family")
|
||||||
variants (get font "variants")]
|
variants (get font "variants")
|
||||||
|
files (get font "files")]
|
||||||
{:id (str "gfont-" (str/slug family))
|
{:id (str "gfont-" (str/slug family))
|
||||||
|
:uuid (uuid/random)
|
||||||
:family family
|
:family family
|
||||||
:name family
|
:name family
|
||||||
:variants (into [] (comp (map parse-gfont-variant)
|
:variants (into [] (comp (map (fn [variant] (parse-gfont-variant variant files)))
|
||||||
(filter identity))
|
(filter identity))
|
||||||
variants)}))
|
variants)}))
|
||||||
|
|
||||||
|
|
|
@ -253,6 +253,7 @@
|
||||||
|
|
||||||
(defn get-variant
|
(defn get-variant
|
||||||
[{:keys [variants] :as font} font-variant-id]
|
[{:keys [variants] :as font} font-variant-id]
|
||||||
|
(prn "get-variant" font-variant-id fonts)
|
||||||
(or (d/seek #(= (:id %) font-variant-id) variants)
|
(or (d/seek #(= (:id %) font-variant-id) variants)
|
||||||
(get-default-variant font)))
|
(get-default-variant font)))
|
||||||
|
|
||||||
|
|
|
@ -176,6 +176,26 @@
|
||||||
|
|
||||||
(defn- get-string-length [string] (+ (count string) 1))
|
(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.
|
;; IMPORTANT: It should be noted that only TTF fonts can be stored.
|
||||||
(defn- store-font-buffer
|
(defn- store-font-buffer
|
||||||
[font-data font-array-buffer]
|
[font-data font-array-buffer]
|
||||||
|
@ -203,11 +223,29 @@
|
||||||
(rx/mapcat wapi/read-file-as-array-buffer)
|
(rx/mapcat wapi/read-file-as-array-buffer)
|
||||||
(rx/map (fn [array-buffer] (store-font-buffer font-data 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
|
(defn- store-font-id
|
||||||
[font-data asset-id]
|
[font-data asset-id]
|
||||||
(when asset-id
|
(when asset-id
|
||||||
(let [uri (str (u/join cf/public-uri "assets/by-id/" asset-id))
|
(let [uri (font-id->ttf-url asset-id (:font-variant-id font-data))
|
||||||
id-buffer (uuid/get-u32 (:family-id font-data))
|
id-buffer (uuid/get-u32 (:wasm-id font-data))
|
||||||
font-data (assoc font-data :family-id-buffer id-buffer)
|
font-data (assoc font-data :family-id-buffer id-buffer)
|
||||||
font-stored? (not= 0 (h/call internal-module "_is_font_uploaded"
|
font-stored? (not= 0 (h/call internal-module "_is_font_uploaded"
|
||||||
(aget id-buffer 0)
|
(aget id-buffer 0)
|
||||||
|
@ -670,17 +708,6 @@
|
||||||
(let [encoder (js/TextEncoder.)]
|
(let [encoder (js/TextEncoder.)]
|
||||||
(.encode encoder text)))
|
(.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
|
(defn- serialize-font-style
|
||||||
[font-style]
|
[font-style]
|
||||||
|
@ -692,9 +719,12 @@
|
||||||
|
|
||||||
(defn- serialize-font-id
|
(defn- serialize-font-id
|
||||||
[font-id]
|
[font-id]
|
||||||
(let [no-prefix (subs font-id (inc (str/index-of font-id "-")))
|
(let [google-font? (str/starts-with? font-id "gfont-")]
|
||||||
as-uuid (uuid/uuid no-prefix)]
|
(if google-font?
|
||||||
(uuid/get-u32 as-uuid)))
|
(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
|
(defn- serialize-font-weight
|
||||||
[font-weight]
|
[font-weight]
|
||||||
|
@ -723,17 +753,25 @@
|
||||||
[fonts]
|
[fonts]
|
||||||
(keep (fn [font]
|
(keep (fn [font]
|
||||||
(let [font-id (dm/get-prop font :font-id)
|
(let [font-id (dm/get-prop font :font-id)
|
||||||
font-variant (dm/get-prop font :font-variant-id)
|
google-font? (str/starts-with? font-id "gfont-")
|
||||||
variant-parts (str/split font-variant #"\-")
|
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)
|
style (first variant-parts)
|
||||||
weight (serialize-font-weight (last variant-parts))
|
weight (serialize-font-weight (last variant-parts))
|
||||||
font-id (subs font-id (inc (str/index-of font-id "-")))
|
font-id (if google-font?
|
||||||
font-id (uuid/uuid font-id)
|
font-id
|
||||||
ttf-id (font->ttf-id font-id style weight)
|
(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
|
font-data {:family-id font-id
|
||||||
|
:wasm-id wasm-id
|
||||||
|
:font-variant-id font-variant-id
|
||||||
:style (serialize-font-style style)
|
:style (serialize-font-style style)
|
||||||
:weight weight}]
|
:weight weight}]
|
||||||
(store-font-id font-data ttf-id))) fonts))
|
(store-font-id font-data asset-id))) fonts))
|
||||||
|
|
||||||
(defn set-shape-text-content [content]
|
(defn set-shape-text-content [content]
|
||||||
(h/call internal-module "_clear_shape_text")
|
(h/call internal-module "_clear_shape_text")
|
||||||
|
@ -1011,3 +1049,4 @@
|
||||||
(js/console.error cause)
|
(js/console.error cause)
|
||||||
(p/resolved false)))))
|
(p/resolved false)))))
|
||||||
(p/resolved false))))
|
(p/resolved false))))
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,8 @@ impl FontStore {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("Adding font: {:?}", family);
|
||||||
|
|
||||||
let alias = format!("{}", family);
|
let alias = format!("{}", family);
|
||||||
let typeface = self
|
let typeface = self
|
||||||
.font_mgr
|
.font_mgr
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue