Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 3abb3691161cdf73f9d4398a911c44b007aa80c2
parent d481ba6a7a1c83e36ad0ec21fac25917ca456956
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Mon, 28 Sep 2026 03:16:45 -0400

umtool: vendor IBM Plex Mono Bold; `render.fontBold` is the preset's too

IBMPlexMono-Bold.ttf, unmodified from google/fonts ofl/ibmplexmono at
0b58fb37 (the commit S4 took Regular from; Regular there is byte-identical
to the vendored file): 137,784 bytes, sha256 ac27abd6…e0be, blob 17b406d2.
Plex carries the Reserved Font Name "Plex", so it ships whole; OFL.txt
already holds Plex's licence verbatim, and fonts.conf's relative <dir>
picks it up: under FONTCONFIG_FILE, "IBM Plex Mono:bold" now resolves to
it (it resolved to Regular, emboldened, before).

resolveBrandRender sets `fontBold` to it beside `fontRegular`, so
compose-chrome's HyperFrames band sets its bold in the brand's mono
instead of whatever the manifest named. No brand: unchanged, the same
object back.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Mumtool/report-to-video/brand.mjs | 9+++++++--
Mumtool/report-to-video/brand.test.mjs | 28+++++++++++++++++++++++++---
Aumtool/report-to-video/fonts/IBMPlexMono-Bold.ttf | 0
3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/umtool/report-to-video/brand.mjs b/umtool/report-to-video/brand.mjs @@ -9,8 +9,9 @@ // // OWNS the palette (render.palette) and the faces: Archivo at wdth 118 for // display, IBM Plex Sans for body, IBM Plex Mono for the header and -// meta lines. A manifest that opts in and also sets `palette` or -// `fontRegular` gets the preset's -- the brand is the point. +// meta lines. A manifest that opts in and also sets `palette`, +// `fontRegular` or `fontBold` gets the preset's -- the brand is the +// point. // ADDS the title card's lockup and found line, the mark leading the clip // header, an end card, and a thumbnail step. // @@ -43,6 +44,8 @@ export { BRAND_CHOICES, BRAND_IDS }; export const FONTS_DIR = path.join(HERE, "fonts"); export const FONTCONFIG_FILE = path.join(FONTS_DIR, "fonts.conf"); export const MONO_FONT_FILE = path.join(FONTS_DIR, "IBMPlexMono-Regular.ttf"); +/** Plex Mono's static Bold: `render.fontBold`, which compose-chrome's HyperFrames band sets its bold in. */ +export const MONO_BOLD_FONT_FILE = path.join(FONTS_DIR, "IBMPlexMono-Bold.ttf"); /** The end card's default length: YouTube's end screen runs in the last 5–20 s. */ export const END_CARD_DEFAULT_SECONDS = 20; @@ -102,6 +105,8 @@ export function resolveBrandRender(render) { palette: { ...kit.palette }, // drawtext's face: the header and the image header read `fontRegular`. fontRegular: MONO_FONT_FILE, + // compose-chrome's HyperFrames band: its bold weight, beside that regular. + fontBold: MONO_BOLD_FONT_FILE, endCard: endCardConfig(render.endCard), }; } diff --git a/umtool/report-to-video/brand.test.mjs b/umtool/report-to-video/brand.test.mjs @@ -15,8 +15,8 @@ import path from "node:path"; import { BRAND_IDS, END_CARD_DEFAULT_SECONDS, END_CARD_DEFAULT_URL, END_CARD_ID, FACES, FONTCONFIG_FILE, - FONTS_DIR, MONO_FONT_FILE, brandFaces, brandHeaderGeometry, brandKit, brandManifest, childOpts, - endCardConfig, resolveBrandRender, + FONTS_DIR, MONO_BOLD_FONT_FILE, MONO_FONT_FILE, brandFaces, brandHeaderGeometry, brandKit, brandManifest, + childOpts, endCardConfig, resolveBrandRender, } from "./brand.mjs"; import { headerFilters, selectVariant } from "./build-video.mjs"; import { renderCard } from "./render-cards.mjs"; @@ -66,6 +66,12 @@ test("the preset owns palette and face, and resolves the end card", () => { bg: "#151b20", fg: "#e7edf1", muted: "#8496a2", accent: "#5fa8a0", amber: "#e3b15c", dim: "#586977", }); assert.equal(r.fontRegular, MONO_FONT_FILE); + // The HyperFrames band's bold: the vendored Plex Mono Bold, whatever the manifest said. + assert.equal(r.fontBold, MONO_BOLD_FONT_FILE); + assert.equal( + resolveBrandRender({ ...PLAIN_RENDER, fontBold: "/usr/share/fonts/TTF/FiraSans-Bold.ttf", brand: "archilyzer-media" }).fontBold, + MONO_BOLD_FONT_FILE, + ); assert.deepEqual(r.endCard, { seconds: END_CARD_DEFAULT_SECONDS, url: END_CARD_DEFAULT_URL }); // Everything else is still the manifest's. assert.equal(r.headerHeight, 56); @@ -129,9 +135,13 @@ test("branded header: mono face, no tick, the channel drawn again in the foregro }); test("the vendored faces: every file the preset names is there, under the OFL", () => { - for (const f of ["Archivo[wdth,wght].ttf", "IBMPlexSans[wdth,wght].ttf", "IBMPlexMono-Regular.ttf", "OFL.txt", "fonts.conf"]) { + for (const f of [ + "Archivo[wdth,wght].ttf", "IBMPlexSans[wdth,wght].ttf", "IBMPlexMono-Regular.ttf", "IBMPlexMono-Bold.ttf", + "OFL.txt", "fonts.conf", + ]) { assert.ok(existsSync(path.join(FONTS_DIR, f)), f); } + assert.ok(existsSync(MONO_BOLD_FONT_FILE)); assert.equal(FONTCONFIG_FILE, path.join(FONTS_DIR, "fonts.conf")); const ofl = readFileSync(path.join(FONTS_DIR, "OFL.txt"), "utf8"); assert.match(ofl, /The Archivo Project Authors/); @@ -150,6 +160,18 @@ test("the kit: the lockup and the mark are outlines, not text", () => { assert.ok(kit.lockup.blockTop > 0 && kit.lockup.blockHeight > 0); }); +// fontconfig, pointed at fonts.conf, finds the vendored faces -- the bold mono +// included -- and without it the system's fonts are what it has. +const hasFcMatch = spawnSync("fc-match", ["--version"], { stdio: "ignore" }).status === 0; + +test("fonts.conf: the preset's children resolve the vendored faces, bold mono included", { skip: !hasFcMatch && "fc-match not available" }, () => { + const match = (pattern) => + execFileSync("fc-match", [pattern, "file"], { encoding: "utf8", env: { ...process.env, FONTCONFIG_FILE } }).trim(); + assert.equal(match("IBM Plex Mono:bold"), `:file=${MONO_BOLD_FONT_FILE}`); + assert.equal(match("IBM Plex Mono"), `:file=${MONO_FONT_FILE}`); + assert.match(match("IBM Plex Sans:bold"), /IBMPlexSans\[wdth\\?,wght\]\.ttf$/); +}); + // Rendering needs ImageMagick with Pango and rsvg-convert; a machine without // them skips rather than fails. const hasTools = diff --git a/umtool/report-to-video/fonts/IBMPlexMono-Bold.ttf b/umtool/report-to-video/fonts/IBMPlexMono-Bold.ttf Binary files differ.