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.
This commit is contained in:
Sofía Aritz 2023-05-15 21:05:05 +02:00
parent dd55ccead4
commit 3c7f94cf8e
3 changed files with 68 additions and 23 deletions

View file

@ -2,7 +2,7 @@
import {css2_to_cssfile} from "./lib/utils.ts"; import {css2_to_cssfile} from "./lib/utils.ts";
import PreCopy from "./lib/PreCopy.svelte"; 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 mirror_input = "https://cdn.sofiaritz.com/fonts"
let output = new Promise(resolve => resolve(null)) let output = new Promise(resolve => resolve(null))

View file

@ -14,9 +14,11 @@ export function parse_family(input: string): Family {
let font = rfont.replaceAll("+", "").toLowerCase() let font = rfont.replaceAll("+", "").toLowerCase()
let variants: Variant[] = [] let variants: Variant[] = []
if(rvariants != null && rvariants.length > 0) { 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 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] fragments = rfragments[1]
} else { } else {
fragments = rfragments[0] fragments = rfragments[0]
@ -24,17 +26,27 @@ export function parse_family(input: string): Family {
let rsubvariants = fragments.split(";") let rsubvariants = fragments.split(";")
for (let rvariant of rsubvariants) { for (let rvariant of rsubvariants) {
if (rvariant.includes(",")) { if (with_weight) {
let variant = rvariant.split(",") if (rvariant.includes(",")) {
variants.push({ let variant = rvariant.split(",")
weight: Number(variant[1]), variants.push({
style: Number(variant[0]) === 1 ? "italic" : "normal", weight: Number(variant[1]),
}) style: Number(variant[0]) === 1 ? "italic" : "normal",
} else { })
variants.push({ } else {
weight: Number(rvariant), variants.push({
style: "normal", 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 { } else {

View file

@ -28,14 +28,47 @@ function to_array(v) {
} }
} }
function font_base_url(font, mirror) { function font_base_url(font, folder, mirror) {
return `${mirror}/ofl/${font}` return `${mirror}/${folder}/${font}`
} }
async function get_font_metadata(font, mirror) { async function get_font_metadata(font, mirror) {
let response = await (await fetch(font_base_url(font, mirror) + "/METADATA.pb")) let base_url
.text() 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<string> { export async function css2_to_cssfile(css2_url, mirror): Promise<string> {
@ -50,18 +83,18 @@ export async function css2_to_cssfile(css2_url, mirror): Promise<string> {
.map(v => v.replace("?family=", "")) .map(v => v.replace("?family=", ""))
.map(parse_family) .map(parse_family)
.map(async (v) => { .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 = [] let fonts = []
for (let variant of v.variants) { for (let variant of v.variants) {
let { weight, style }: Variant = variant let { weight, style }: Variant = variant
let rfonts = to_array(metadata.fonts) let rfonts = to_array(metadata.fonts)
let matched = false let matched = false
for (let font of rfonts) { for (let font of rfonts) {
if (font.weight === weight) { if (font.weight === weight && matched === false) {
if (style === "italic") { if (style === "italic") {
fonts.push({ fonts.push({
name: metadata.name, name: metadata.name,
path: font_base_url(v.font, mirror) + "/" + font.filename, path: base_url + "/" + font.filename,
weight, weight,
style, style,
}) })
@ -73,7 +106,7 @@ export async function css2_to_cssfile(css2_url, mirror): Promise<string> {
if (matched === false) { if (matched === false) {
fonts.push({ fonts.push({
name: metadata.name, name: metadata.name,
path: font_base_url(v.font, mirror) + "/" + rfonts[0].filename, path: base_url + "/" + rfonts[0].filename,
weight, weight,
style, style,
}) })