Skip to main content

max / shop

Cut the bundled face through quasi_type::cut_native The build script hand-rolled the ttf write, the licence write and the weight default in about thirty lines, which is the copy every other native consumer would have taken. cut_native does all three and returns the family, style and weight to export beside them. The face and licence paths now come back from the call rather than being spelled again in the crate: the licence is named for the family (OFL-QuasiMono.txt), and a second spelling of that is one rename away from a build failure.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-28 14:54 UTC
Signed with PGP, not checked
Commit: ace19a7a9d042705b720b434a05a3a37fa371e7d
Parent: 60c61db
4 files changed, +43 insertions, -26 deletions
M Cargo.lock +18 -14
@@ -1179,7 +1179,7 @@
1179 1179
1180 1180 [[package]]
1181 1181 name = "quasi-type"
1182 - version = "0.1.0"
1182 + version = "0.1.1"
1183 1183 dependencies = [
1184 1184 "brotli",
1185 1185 "font-types",
@@ -2382,18 +2382,18 @@
2382 2382 "simd-adler32",
2383 2383 ]
2384 2384
2385 - [[patch.unused]]
2386 - name = "docengine"
2387 - version = "0.7.0"
2388 -
2389 2385 [[patch.unused]]
2390 2386 name = "synckit-client"
2391 - version = "0.8.0"
2387 + version = "0.9.1"
2392 2388
2393 2389 [[patch.unused]]
2394 2390 name = "synckit-config"
2395 2391 version = "0.2.0"
2396 2392
2393 + [[patch.unused]]
2394 + name = "docengine"
2395 + version = "0.7.0"
2396 +
2397 2397 [[patch.unused]]
2398 2398 name = "kberg"
2399 2399 version = "0.1.0"
@@ -2408,27 +2408,31 @@
2408 2408
2409 2409 [[patch.unused]]
2410 2410 name = "tagtree"
2411 - version = "0.4.0"
2411 + version = "0.4.1"
2412 2412
2413 2413 [[patch.unused]]
2414 2414 name = "quasi-axum"
2415 - version = "0.28.1"
2415 + version = "0.71.0"
2416 2416
2417 2417 [[patch.unused]]
2418 2418 name = "quasi-basics"
2419 - version = "0.28.1"
2419 + version = "0.71.0"
2420 2420
2421 2421 [[patch.unused]]
2422 2422 name = "quasi-http"
2423 - version = "0.28.1"
2423 + version = "0.71.0"
2424 2424
2425 2425 [[patch.unused]]
2426 2426 name = "quasi-immediate"
2427 - version = "0.28.1"
2427 + version = "0.71.0"
2428 +
2429 + [[patch.unused]]
2430 + name = "quasi-notifs"
2431 + version = "0.71.0"
2428 2432
2429 2433 [[patch.unused]]
2430 2434 name = "quasi-router"
2431 - version = "0.28.1"
2435 + version = "0.71.0"
2432 2436
2433 2437 [[patch.unused]]
2434 2438 name = "quasi-store"
@@ -2436,8 +2440,8 @@
2436 2440
2437 2441 [[patch.unused]]
2438 2442 name = "quasi-tauri"
2439 - version = "0.28.1"
2443 + version = "0.71.0"
2440 2444
2441 2445 [[patch.unused]]
2442 2446 name = "quasi-webview"
2443 - version = "0.28.1"
2447 + version = "0.71.0"
@@ -30,4 +30,4 @@
30 30 # rev is ignored, which is the point of that block; off the tree it is what a
31 31 # build resolves. Bump it in the same pass as a glyph-set change, alongside
32 32 # Alloy's `QUASI_TYPE_REV`.
33 - quasi-type = { git = "https://makenot.work/git/max/quasi-type.git", version = "0.1", rev = "e40330602e68fbdd2a9d2917bdec33a7ce573a1f" }
33 + quasi-type = { git = "https://makenot.work/git/max/quasi-type.git", version = "0.1.1", rev = "e57a57f35563252b5ed00a8caf1262517f3d51f4" }
@@ -12,28 +12,41 @@
12 12 println!("cargo:rerun-if-changed=build.rs");
13 13
14 14 let out = std::path::PathBuf::from(std::env::var("OUT_DIR").expect("cargo sets OUT_DIR"));
15 - let cut = match quasi_type::cut("quasi-mono", &out.join("bases"), false) {
16 - Ok(cut) => cut,
15 + // cut_native writes the ttf and the OFL text and hands back what has to be
16 + // exported beside them. It used to be written out here, and every other
17 + // native consumer would have copied it from here.
18 + let written = match quasi_type::cut_native(
19 + &out,
20 + &out.join("bases"),
21 + false,
22 + &[("quasi-mono", "face.ttf")],
23 + ) {
24 + Ok(written) => written,
17 25 Err(e) => panic!(
18 26 "could not cut the bundled face: {e}\n\
19 27 The base is fetched from its pinned url on the first build and cached in \
20 28 OUT_DIR after that, so this needs network once per target directory."
21 29 ),
22 30 };
23 - let face = cut
24 - .faces
31 + let face = written
25 32 .first()
26 33 .unwrap_or_else(|| panic!("quasi-mono cut no faces"));
27 34
28 - std::fs::write(out.join("face.ttf"), &face.ttf).expect("write the cut face");
29 - std::fs::write(out.join("OFL.txt"), &cut.license).expect("write the licence");
35 + // Both paths come back from cut_native rather than being spelled again here:
36 + // the licence file is named for the family (`OFL-QuasiMono.txt`), and a
37 + // second spelling of that is a rename away from a build failure.
38 + println!("cargo:rustc-env=SHOP_FONT_FACE={}", face.path.display());
39 + println!(
40 + "cargo:rustc-env=SHOP_FONT_LICENSE={}",
41 + face.license_path.display()
42 + );
43 + println!("cargo:rustc-env=SHOP_FONT_FAMILY={}", face.family);
44 + println!("cargo:rustc-env=SHOP_FONT_STYLE={}", face.style);
30 45 // The style is the base's default instance and is not always `Regular`:
31 46 // Atkinson Mono's is `ExtraLight`, which is the whole reason shop names a
32 47 // weight when it renders rather than taking what the file opens at.
33 - println!("cargo:rustc-env=SHOP_FONT_FAMILY={}", cut.family);
34 - println!("cargo:rustc-env=SHOP_FONT_STYLE={}", face.style);
35 48 println!(
36 49 "cargo:rustc-env=SHOP_FONT_DEFAULT_WEIGHT={}",
37 - face.variation.as_ref().map_or(400.0, |axis| axis.default)
50 + face.default_weight
38 51 );
39 52 }
@@ -9,11 +9,11 @@
9 9 /// Variable on `wght` 200-800 in one file. **At rest it is `wght` 200**, since
10 10 /// a cut keeps its base's default instance and Atkinson Hyperlegible Mono's is
11 11 /// ExtraLight, so anything rendering it names a weight — see [`WEIGHT`].
12 - pub static FACE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/face.ttf"));
12 + pub static FACE: &[u8] = include_bytes!(env!("SHOP_FONT_FACE"));
13 13
14 14 /// The base's licence text. OFL 1.1 requires it to travel with a modified
15 15 /// build, so it travels inside the binary and `shop --license` prints it.
16 - pub static LICENSE: &str = include_str!(concat!(env!("OUT_DIR"), "/OFL.txt"));
16 + pub static LICENSE: &str = include_str!(env!("SHOP_FONT_LICENSE"));
17 17
18 18 /// The family name the face carries, for a fontconfig query or a log line.
19 19 pub const FAMILY: &str = env!("SHOP_FONT_FAMILY");