|
2 | 2 | "https://www.w3.org/TR/SVG/text.html
|
3 | 3 | https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/text"
|
4 | 4 | (:require
|
5 |
| - ["opentype.js" :as opentype] |
6 | 5 | [clojure.core.matrix :as matrix]
|
7 | 6 | [clojure.string :as string]
|
8 | 7 | [re-frame.core :as rf]
|
|
16 | 15 | [renderer.tool.events :as tool.events]
|
17 | 16 | [renderer.tool.handlers :as tool.handlers]
|
18 | 17 | [renderer.tool.subs :as-alias tool.subs]
|
19 |
| - [renderer.utils.attribute :as utils.attribute] |
20 | 18 | [renderer.utils.bounds :as utils.bounds]
|
21 |
| - [renderer.utils.dom :as utils.dom] |
22 | 19 | [renderer.utils.element :as utils.element]
|
| 20 | + [renderer.utils.font :as utils.font] |
23 | 21 | [renderer.utils.length :as utils.length]))
|
24 | 22 |
|
25 | 23 | (derive :text ::element.hierarchy/shape)
|
|
119 | 117 | :font-size font-size
|
120 | 118 | :font-weight font-weight}}]]))
|
121 | 119 |
|
122 |
| -(defn get-computed-styles! |
123 |
| - [{:keys [content] :as el}] |
124 |
| - (when-let [svg (utils.dom/canvas-element!)] |
125 |
| - (let [dom-el (utils.element/->dom-element el)] |
126 |
| - (.appendChild svg dom-el) |
127 |
| - (set! (.-innerHTML dom-el) (if (empty? content) "\u00a0" content)) |
128 |
| - (let [computed-style (.getComputedStyle js/window dom-el nil) |
129 |
| - font-style (.getPropertyValue computed-style "font-style") |
130 |
| - font-size (.getPropertyValue computed-style "font-size") |
131 |
| - font-weight (.getPropertyValue computed-style "font-weight") |
132 |
| - bbox (utils.bounds/dom-el->bbox dom-el)] |
133 |
| - (.remove dom-el) |
134 |
| - {:font-style font-style |
135 |
| - :font-size font-size |
136 |
| - :font-weight font-weight |
137 |
| - :bbox bbox})))) |
138 |
| - |
139 |
| -(defn font-file->path-data |
140 |
| - [file content x y font-size] |
141 |
| - (-> (.blob file) |
142 |
| - (.then (fn [blob] |
143 |
| - (-> (.arrayBuffer blob) |
144 |
| - (.then (fn [buffer] |
145 |
| - (let [font (opentype/parse buffer) |
146 |
| - path (.getPath font content x y font-size)] |
147 |
| - (.toPathData path))))))))) |
148 |
| - |
149 |
| -(defn includes-prop? |
150 |
| - [v prop] |
151 |
| - (when v |
152 |
| - (string/includes? (string/lower-case v) (string/lower-case prop)))) |
153 |
| - |
154 |
| -(defn match-font-by-weight |
155 |
| - [weight fonts] |
156 |
| - (let [weight-num (js/parseInt weight) |
157 |
| - weight-names (get utils.attribute/weight-name-mapping weight) |
158 |
| - includes-weight? (fn [font] |
159 |
| - (some #(includes-prop? % (.-style font)) weight-names)) |
160 |
| - matched-weight (filter includes-weight? fonts)] |
161 |
| - (if (or (seq matched-weight) (< weight-num 100)) |
162 |
| - matched-weight |
163 |
| - (recur (str (- weight-num 100)) fonts)))) |
164 |
| - |
165 |
| -(defn match-font |
166 |
| - [fonts family style weight] |
167 |
| - (let [matched-family (filter #(includes-prop? family (.-family %)) fonts) |
168 |
| - matched-style (filter #(includes-prop? style (.-style %)) matched-family) |
169 |
| - matched-weight (match-font-by-weight weight (if (seq matched-style) |
170 |
| - matched-style |
171 |
| - matched-family))] |
172 |
| - (or (first matched-weight) |
173 |
| - (first matched-style) |
174 |
| - (first matched-family) |
175 |
| - (first fonts)))) |
176 |
| - |
177 |
| -(defn default-font-path |
178 |
| - [font-style font-weight] |
179 |
| - (str "./css/files/noto-sans-latin-" font-weight "-" font-style ".woff")) |
180 |
| - |
181 | 120 | (defmethod element.hierarchy/path :text
|
182 | 121 | [el]
|
183 | 122 | (let [{:keys [attrs content]} el
|
184 | 123 | {:keys [x y font-family]} attrs
|
185 |
| - {:keys [font-size font-style font-weight]} (get-computed-styles! el) |
| 124 | + {:keys [font-size font-style font-weight]} (utils.font/get-computed-styles! el) |
186 | 125 | [x y font-size] (mapv utils.length/unit->px [x y font-size])]
|
187 | 126 | (if font-family
|
188 | 127 | (-> (js/window.queryLocalFonts)
|
189 | 128 | (.then (fn [fonts]
|
190 |
| - (when-let [font (match-font fonts |
191 |
| - font-family |
192 |
| - font-style |
193 |
| - font-weight)] |
194 |
| - (font-file->path-data font content x y font-size))))) |
195 |
| - (-> (js/fetch (default-font-path font-style font-weight)) |
| 129 | + (when-let [font (utils.font/match-font fonts |
| 130 | + font-family |
| 131 | + font-style |
| 132 | + font-weight)] |
| 133 | + (utils.font/font-file->path-data font content x y font-size))))) |
| 134 | + (-> (js/fetch (utils.font/default-font-path font-style font-weight)) |
196 | 135 | (.then (fn [response]
|
197 |
| - (font-file->path-data response content x y font-size))))))) |
| 136 | + (utils.font/font-file->path-data response content x y font-size))))))) |
198 | 137 |
|
199 | 138 | (defmethod element.hierarchy/bbox :text
|
200 | 139 | [el]
|
201 |
| - (:bbox (get-computed-styles! el))) |
| 140 | + (:bbox (utils.font/get-computed-styles! el))) |
0 commit comments