From 3c7f94cf8e2b5070415f1cc78facd1672a170ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sof=C3=ADa=20Aritz?= Date: Mon, 15 May 2023 21:05:05 +0200 Subject: [PATCH] Fix default weight when the fonts are italic When the chosen font has a weight of 400 and the style is italic, a mode similar to `wght@` is enabled. For example, `Roboto+Mono:ital@0;1` means that both the normal and italic Roboto Mono 400 fonts should be added to the stylesheet. --- src/App.svelte | 2 +- src/lib/css2.ts | 38 ++++++++++++++++++++++++------------ src/lib/utils.ts | 51 +++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index b1b7a51..0c58638 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -2,7 +2,7 @@ import {css2_to_cssfile} from "./lib/utils.ts"; import PreCopy from "./lib/PreCopy.svelte"; - let gf_input = "https://fonts.googleapis.com/css2?family=Fira+Sans:ital,wght@0,300;1,200;1,500&family=Poppins:wght@300;400&family=Wix+Madefor+Display:wght@700&display=swap" + let gf_input = "https://fonts.googleapis.com/css2?family=Roboto+Mono:ital@0;1&family=Roboto:ital@0;1&display=swap" let mirror_input = "https://cdn.sofiaritz.com/fonts" let output = new Promise(resolve => resolve(null)) diff --git a/src/lib/css2.ts b/src/lib/css2.ts index d4cb2db..fd7b6c1 100644 --- a/src/lib/css2.ts +++ b/src/lib/css2.ts @@ -14,9 +14,11 @@ export function parse_family(input: string): Family { let font = rfont.replaceAll("+", "").toLowerCase() let variants: Variant[] = [] if(rvariants != null && rvariants.length > 0) { - let rfragments = rvariants.split("wght@").filter(v => v.length > 0) + let rfragments = rvariants.split("@").filter(v => v.length > 0) let fragments - if (rfragments[0].startsWith("ital")) { + let with_weight = rfragments[0].includes("wght") + let with_ital = rfragments[0].includes("ital") + if (with_ital || with_weight) { fragments = rfragments[1] } else { fragments = rfragments[0] @@ -24,17 +26,27 @@ export function parse_family(input: string): Family { let rsubvariants = fragments.split(";") for (let rvariant of rsubvariants) { - if (rvariant.includes(",")) { - let variant = rvariant.split(",") - variants.push({ - weight: Number(variant[1]), - style: Number(variant[0]) === 1 ? "italic" : "normal", - }) - } else { - variants.push({ - weight: Number(rvariant), - style: "normal", - }) + if (with_weight) { + if (rvariant.includes(",")) { + let variant = rvariant.split(",") + variants.push({ + weight: Number(variant[1]), + style: Number(variant[0]) === 1 ? "italic" : "normal", + }) + } else { + variants.push({ + weight: Number(rvariant), + style: "normal", + }) + } + } else if(with_ital) { + let italvariants = rvariant.split(",") + for (let variant of italvariants) { + variants.push({ + weight: 400, + style: Number(variant) === 1 ? "italic" : "normal" + }) + } } } } else { diff --git a/src/lib/utils.ts b/src/lib/utils.ts index b82c67f..3f351c0 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -28,14 +28,47 @@ function to_array(v) { } } -function font_base_url(font, mirror) { - return `${mirror}/ofl/${font}` +function font_base_url(font, folder, mirror) { + return `${mirror}/${folder}/${font}` } async function get_font_metadata(font, mirror) { - let response = await (await fetch(font_base_url(font, mirror) + "/METADATA.pb")) - .text() + let base_url + let response + // TODO(sofia@git.sofiaritz.com): Improve this re-trying logic. This feels wrong 😭 + try { + base_url = font_base_url(font, "ofl", mirror) + let rresponse = await (await fetch(base_url + "/METADATA.pb")) + if (rresponse.ok) { + response = await rresponse.text() + } else { + throw new Error("Font not found.") + } + } catch (e) { + try { + base_url = font_base_url(font, "ufl", mirror) + let rresponse = await (await fetch(base_url + "/METADATA.pb")) + if (rresponse.ok) { + response = await rresponse.text() + } else { + throw new Error("Font not found.") + } + } catch (e) { + try { + base_url = font_base_url(font, "apache", mirror) + let rresponse = await (await fetch(base_url + "/METADATA.pb")) + if (rresponse.ok) { + response = await rresponse.text() + } else { + throw new Error("Font not found.") + } + } catch (e) { + console.error("Font not found.") + throw new Error(`"${font}" not found in mirror "${mirror}".`) + } + } + } - return parse(response) + return {base_url, parsed: parse(response)} } export async function css2_to_cssfile(css2_url, mirror): Promise { @@ -50,18 +83,18 @@ export async function css2_to_cssfile(css2_url, mirror): Promise { .map(v => v.replace("?family=", "")) .map(parse_family) .map(async (v) => { - let metadata = await get_font_metadata(v.font, mirror) + let {base_url, parsed: metadata} = await get_font_metadata(v.font, mirror) let fonts = [] for (let variant of v.variants) { let { weight, style }: Variant = variant let rfonts = to_array(metadata.fonts) let matched = false for (let font of rfonts) { - if (font.weight === weight) { + if (font.weight === weight && matched === false) { if (style === "italic") { fonts.push({ name: metadata.name, - path: font_base_url(v.font, mirror) + "/" + font.filename, + path: base_url + "/" + font.filename, weight, style, }) @@ -73,7 +106,7 @@ export async function css2_to_cssfile(css2_url, mirror): Promise { if (matched === false) { fonts.push({ name: metadata.name, - path: font_base_url(v.font, mirror) + "/" + rfonts[0].filename, + path: base_url + "/" + rfonts[0].filename, weight, style, })