UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

58 lines (57 loc) • 2.85 kB
import { fromBuffer } from "@capsizecss/unpack"; import { renderFontSrc } from "../utils.js"; // Source: https://github.com/unjs/fontaine/blob/main/src/metrics.ts function filterRequiredMetrics({ ascent, descent, lineGap, unitsPerEm, xWidthAvg }) { return { ascent, descent, lineGap, unitsPerEm, xWidthAvg }; } // Source: https://github.com/seek-oss/capsize/blob/b752693428b45994442433f7e3476ca4e3e3c507/packages/core/src/round.ts function round(value) { return Number.parseFloat(value.toFixed(4)); } // Source: https://github.com/seek-oss/capsize/blob/b752693428b45994442433f7e3476ca4e3e3c507/packages/core/src/createFontStack.ts#L5 function toPercentString(value) { return `${round(value * 100)}%`; } export class CapsizeFontMetricsResolver { #cache = {}; #fontFetcher; #cssRenderer; constructor({ fontFetcher, cssRenderer }) { this.#fontFetcher = fontFetcher; this.#cssRenderer = cssRenderer; } async getMetrics(name, font) { return this.#cache[name] ??= filterRequiredMetrics(await fromBuffer(await this.#fontFetcher.fetch(font))); } // Adapted from Capsize // Source: https://github.com/seek-oss/capsize/blob/b752693428b45994442433f7e3476ca4e3e3c507/packages/core/src/createFontStack.ts generateFontFace({ metrics, fallbackMetrics, name: fallbackName, font: fallbackFontName, properties }) { // Calculate size adjust const preferredFontXAvgRatio = metrics.xWidthAvg / metrics.unitsPerEm; const fallbackFontXAvgRatio = fallbackMetrics.xWidthAvg / fallbackMetrics.unitsPerEm; const sizeAdjust = preferredFontXAvgRatio && fallbackFontXAvgRatio ? preferredFontXAvgRatio / fallbackFontXAvgRatio : 1; const adjustedEmSquare = metrics.unitsPerEm * sizeAdjust; // Calculate metric overrides for preferred font const ascentOverride = metrics.ascent / adjustedEmSquare; const descentOverride = Math.abs(metrics.descent) / adjustedEmSquare; const lineGapOverride = metrics.lineGap / adjustedEmSquare; // Calculate metric overrides for fallback font const fallbackAscentOverride = fallbackMetrics.ascent / adjustedEmSquare; const fallbackDescentOverride = Math.abs(fallbackMetrics.descent) / adjustedEmSquare; const fallbackLineGapOverride = fallbackMetrics.lineGap / adjustedEmSquare; return this.#cssRenderer.generateFontFace(fallbackName, { ...properties, src: renderFontSrc([{ name: fallbackFontName }]), "size-adjust": sizeAdjust && sizeAdjust !== 1 ? toPercentString(sizeAdjust) : undefined, "ascent-override": ascentOverride && ascentOverride !== fallbackAscentOverride ? toPercentString(ascentOverride) : undefined, "descent-override": descentOverride && descentOverride !== fallbackDescentOverride ? toPercentString(descentOverride) : undefined, "line-gap-override": lineGapOverride !== fallbackLineGapOverride ? toPercentString(lineGapOverride) : undefined }); } }