diff --git a/common/src/app/common/media.cljc b/common/src/app/common/media.cljc index 05b072047d..a1d699cdc7 100644 --- a/common/src/app/common/media.cljc +++ b/common/src/app/common/media.cljc @@ -136,6 +136,11 @@ "italic" "normal"))) +(defn first-nonblank-string + "Return the first nonblank string from the candidates, or nil." + [& candidates] + (first (filter #(and (string? %) (not (str/blank? %))) candidates))) + (defn font-weight->name [weight] (case (long weight) diff --git a/common/test/common_tests/media_test.cljc b/common/test/common_tests/media_test.cljc index 8b02d87318..874dd67ca1 100644 --- a/common/test/common_tests/media_test.cljc +++ b/common/test/common_tests/media_test.cljc @@ -89,6 +89,18 @@ (t/testing "falls back to the base name when everything is stripped" (t/is (= "BoldItalic" (media/parse-font-family "BoldItalic"))))) +(t/deftest test-first-nonblank-string + (t/testing "returns the first nonblank string" + (t/is (= "Bold" (media/first-nonblank-string " " "Bold"))) + (t/is (= "Bold" (media/first-nonblank-string "Bold" "Light"))) + (t/is (= "Bold" (media/first-nonblank-string nil "Bold"))) + (t/is (= "Inter" (media/first-nonblank-string "" "Inter")))) + + (t/testing "returns nil when every candidate is blank or not a string" + (t/is (nil? (media/first-nonblank-string nil " "))) + (t/is (nil? (media/first-nonblank-string))) + (t/is (nil? (media/first-nonblank-string 42 " "))))) + (t/deftest test-strip-image-extension (t/testing "removes extension from supported image files" (t/is (= (media/strip-image-extension "foo.png") "foo")) diff --git a/frontend/src/app/main/data/fonts.cljs b/frontend/src/app/main/data/fonts.cljs index ac1d34897e..7df874626e 100644 --- a/frontend/src/app/main/data/fonts.cljs +++ b/frontend/src/app/main/data/fonts.cljs @@ -144,10 +144,15 @@ [{:keys [font type name data] :as _params}] (if font ;; Font was parsed with opentype.js (ttf, otf, woff) - (let [family (or (.getEnglishName ^js font "preferredFamily") - (.getEnglishName ^js font "fontFamily")) - variant (or (.getEnglishName ^js font "preferredSubfamily") - (.getEnglishName ^js font "fontSubfamily")) + (let [;; Select the first nonblank name candidate: a blank + ;; preferredFamily/preferredSubfamily must not shadow a valid + ;; fontFamily/fontSubfamily. + family (cm/first-nonblank-string + (.getEnglishName ^js font "preferredFamily") + (.getEnglishName ^js font "fontFamily")) + variant (cm/first-nonblank-string + (.getEnglishName ^js font "preferredSubfamily") + (.getEnglishName ^js font "fontSubfamily")) ;; Vertical metrics determine the baseline in a text and the space between lines of ;; text. For historical reasons, there are three pairs of ascender/descender diff --git a/frontend/test/frontend_tests/data/fonts_test.cljs b/frontend/test/frontend_tests/data/fonts_test.cljs index d8ae34e57b..0bbd806bff 100644 --- a/frontend/test/frontend_tests/data/fonts_test.cljs +++ b/frontend/test/frontend_tests/data/fonts_test.cljs @@ -142,4 +142,17 @@ (t/is (= "Pretendard" (:font-family result))) (t/is (= 600 (:font-weight result))) (t/is (= "normal" (:font-style result))) - (t/is (false? (:height-warning? result)))))) + (t/is (false? (:height-warning? result))))) + + (t/testing "a blank first candidate does not shadow a valid second one" + (let [result (df/prepare-font-entry + {:font (fake-font {"preferredFamily" " " + "preferredSubfamily" " " + "fontSubfamily" "Bold"}) + :type "font/ttf" + :name "Roboto-Light.ttf" + :data (js/Uint8Array. 4)})] + (t/is (= "Roboto" (:font-family result))) + (t/is (= 700 (:font-weight result))) + (t/is (= "normal" (:font-style result))) + (t/is (= "Bold" (:variant-name result))))))