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:
parent
dd55ccead4
commit
3c7f94cf8e
3 changed files with 68 additions and 23 deletions
|
@ -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))
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<string> {
|
||||
|
@ -50,18 +83,18 @@ export async function css2_to_cssfile(css2_url, mirror): Promise<string> {
|
|||
.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<string> {
|
|||
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,
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue