Take the typescale's tracking from Compose, and reset roundness
Tracking now comes from androidx's TypeScaleTokens.kt as sp/16 rem, so Display Large is -0.0125rem, Title Medium and Body Medium 0.0125rem where material-web's pre-Expressive numbers stood. The emphasized set gets its own --md-sys-typescale-emphasized-<style>-tracking, which the emphasized utilities read: M3 widens four of them and takes Display Large back to zero. Every regular utility sets `font-variation-settings: normal`, because the property inherits and body copy inside an emphasized heading is meant to read as itself. bin/check-font.mjs (fontkit) prints the packaged woff2's fvar axes, so a re-subset cannot silently drop the ROND axis the emphasized styles depend on; `npm run check:font` runs it and tests/Feature/FontTest.php runs it through the configured node binary, skipping when node cannot run (PHP cannot open a woff2 without Brotli). Plan: docs/plans/material-3-alignment.md step 4, findings core C5, C6, C7. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
b1fc0c9cfa
commit
2feb623ec0
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Checks that the packaged Google Sans Flex subset still carries the variable axes the CSS uses.
|
||||
*
|
||||
* Run from the repository root with `npm run check:font` (or `node bin/check-font.mjs [woff2]`).
|
||||
* tests/Feature/FontTest.php runs it through the configured `node` binary as well, because PHP
|
||||
* cannot open a woff2 without the Brotli extension.
|
||||
*
|
||||
* wght 400–700 — every typescale weight (font.css `font-weight: 400 700`, type.css's regular,
|
||||
* medium and bold reference tokens).
|
||||
* ROND 0–100 — the roundness axis every `type-emphasized-*` utility sets to 100. Re-subset
|
||||
* the font without it and the emphasized styles quietly stop being round.
|
||||
*
|
||||
* Output is one JSON object on stdout — {file, postscriptName, numGlyphs, axes: {tag: {name, min,
|
||||
* default, max}}} — and the exit status is 1, with the reason on stderr, when an axis is missing
|
||||
* or narrower than the range above.
|
||||
*/
|
||||
import { openSync } from 'fontkit'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
/** The axes the stylesheets depend on, and the range each one has to cover. */
|
||||
const REQUIRED = {
|
||||
wght: { min: 400, max: 700 },
|
||||
ROND: { min: 0, max: 100 },
|
||||
}
|
||||
|
||||
const file = process.argv[2] ?? fileURLToPath(new URL('../resources/fonts/google-sans-flex/GoogleSansFlex-Latin.woff2', import.meta.url))
|
||||
|
||||
let font
|
||||
|
||||
try {
|
||||
font = openSync(file)
|
||||
} catch (error) {
|
||||
process.stderr.write(`${file}: ${error.message}\n`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const axes = font.variationAxes ?? {}
|
||||
const problems = Object.entries(REQUIRED).flatMap(([tag, range]) => {
|
||||
const axis = axes[tag]
|
||||
|
||||
if (!axis) {
|
||||
return [`${tag} is missing; the subset has ${Object.keys(axes).join(', ') || 'no variable axes'}.`]
|
||||
}
|
||||
|
||||
return axis.min > range.min || axis.max < range.max
|
||||
? [`${tag} covers ${axis.min}–${axis.max}, not the ${range.min}–${range.max} the stylesheets ask for.`]
|
||||
: []
|
||||
})
|
||||
|
||||
process.stdout.write(`${JSON.stringify({
|
||||
file,
|
||||
postscriptName: font.postscriptName,
|
||||
numGlyphs: font.numGlyphs,
|
||||
axes,
|
||||
})}\n`)
|
||||
|
||||
if (problems.length > 0) {
|
||||
process.stderr.write(`${file}\n${problems.map((problem) => ` ${problem}`).join('\n')}\n`)
|
||||
process.exit(1)
|
||||
}
|
||||
Reference in New Issue
Block a user