Groundwork for the whole-repo `ruff format` sweep, kept separate so that sweep can be a commit with nothing in it but layout. An audit of `ruff format --diff` found the sweep is mechanical where it counts — 152 of 153 files come out AST-identical, the suite passes on the formatted tree, and `meshterm specimen` is byte-identical on both platforms — but it found three things worth handling first. One is a defect. `test_a_contact_the_device_never_held_is_still_removed_here` opens its docstring on a quote character, so the formatter breaks up the run of four quotes by inserting a space, and that trips `D210`. A straight sweep would therefore have taken `ruff check .` red — the one commit whose entire point is that both gates pass. The quoted phrase becomes curly quotes, which is already how the rest of the tests spell a quotation, and the collision goes away. One is readability. `sparkline` ends on a subscript of a call that no longer fits, and the formatter's answer is to hang `[` newline `0` newline `]` off the end. Naming the intermediate says the same thing in two plain lines. The rest are fences. Six tables in this codebase are hand-packed on purpose: the glyph map and the fold table read as two columns because that is how you check a substitution; `FONT_RANGES` is a device-verified inventory that a reader scans in rows; `_RAW_ROW_SKIP` groups its fields by which part of a packet they came from; `_NODE_SLOT_HEXES` runs the wheel in 60-degree steps with the angle in the lane. The formatter's layout is all-or-nothing — one line, or one item per line — so it would turn `FONT_RANGES` into two hundred lines and flatten every grouping into an undifferentiated list. `# fmt: off` says these are data laid out to be read, not code that happens to be wide. `test_theme16`'s heat ladder is fenced for a stronger reason: it pairs two steps per row under one comment naming the band, so exploding it would leave "under 5 minutes — white" attached to the second half of its own pair and the first half unlabelled. That is not alignment loss, it is a comment that starts lying. Not fenced: the `heat.*` ladder inside `MESH_THEME`. It wants the same treatment and cannot have it — ruff honours `# fmt: off` for a statement, and those rows are elements inside a dict inside a call, where the marker is simply ignored. It loses its aligned comment column in the sweep, along with about ninety other lanes across the repo. Each comment stays on its own entry, so nothing there starts lying; if the column is wanted back it needs the whole `Theme(...)` call fenced, which is a bigger decision than this commit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
62 lines
3.4 KiB
Python
62 lines
3.4 KiB
Python
"""The PicoCalc console font's codepoint inventory — the glyph contract.
|
||
|
||
The PicoCalc panel draws through the kernel console with one 512-glyph PSF font
|
||
(``meshterm.psf.gz``, built by ``scripts/calculinux-console-font.sh``): the stock
|
||
Terminus 6×12 base (a Cyrillic-coverage table — note there are **no accented Latin
|
||
letters**), the full braille block, MeshTerm's own marks drawn into donor slots, and a
|
||
few aliases. A character outside this set renders as a blank on the panel, so *nothing
|
||
outside it may ever be emitted* on the picocalc platform — the render boundary folds
|
||
text down to it (:func:`meshterm.ui.theme.fold_text`), and the dual-platform gallery
|
||
asserts the fold held.
|
||
|
||
This table is the **single source of truth** for that contract, shared by the runtime
|
||
fold and the tests. It mirrors the font actually installed on the device: the base
|
||
inventory was dumped live from the PSF's Unicode table (2026-08-01), minus the donor
|
||
codepoints the build script now repurposes, plus the marks it draws in their place.
|
||
If the build script's ``MARKS``/``DONORS``/``ALIASES`` change, this table must move in
|
||
the same commit — and vice versa.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
#: Inclusive ``(first, last)`` codepoint ranges present in the font. 519 codepoints over
|
||
#: 512 glyphs — aliases (the rounded corners onto the square ones, ``⋯`` onto ``…``) and
|
||
#: shared slots give a few glyphs more than one codepoint. Verified against a live table
|
||
#: dump of the installed font (2026-08-01, post-P3 build).
|
||
# fmt: off
|
||
FONT_RANGES: tuple[tuple[int, int], ...] = (
|
||
(0x0020, 0x007F), (0x00A0, 0x00A0), (0x00A7, 0x00A7), (0x00A9, 0x00A9),
|
||
(0x00B0, 0x00B0), (0x00B2, 0x00B2), (0x00B6, 0x00B7), (0x03C0, 0x03C0),
|
||
(0x0401, 0x0401),
|
||
(0x0404, 0x0404), (0x0406, 0x0407), (0x0410, 0x044F), (0x0451, 0x0451),
|
||
(0x0454, 0x0454), (0x0456, 0x0457), (0x0490, 0x0491), (0x2014, 0x2014),
|
||
(0x2022, 0x2022), (0x2026, 0x2026), (0x2190, 0x2195), (0x21A8, 0x21A8),
|
||
(0x21BB, 0x21BB), (0x21E7, 0x21E7), (0x221A, 0x221A), (0x221F, 0x221F),
|
||
(0x2248, 0x2248), (0x2264, 0x2265), (0x22EF, 0x22EF), (0x2302, 0x2302),
|
||
(0x2316, 0x2316), (0x232B, 0x232B), (0x2500, 0x2500), (0x2502, 0x2502),
|
||
(0x250C, 0x250C), (0x2510, 0x2510), (0x2514, 0x2514), (0x2518, 0x2518),
|
||
(0x251C, 0x251C), (0x2524, 0x2524), (0x252C, 0x252C), (0x2534, 0x2534),
|
||
(0x253C, 0x253C), (0x2550, 0x2551), (0x2554, 0x2554), (0x2557, 0x2557),
|
||
(0x2559, 0x255B),
|
||
(0x255D, 0x2561), (0x2563, 0x2563), (0x2566, 0x256A), (0x256C, 0x2570),
|
||
(0x2580, 0x2580), (0x2584, 0x2584), (0x2588, 0x2588), (0x258C, 0x258C),
|
||
(0x2590, 0x2593), (0x25A0, 0x25A0), (0x25AC, 0x25AC), (0x25B2, 0x25B2),
|
||
(0x25B6, 0x25B6), (0x25B8, 0x25B8), (0x25BA, 0x25BA), (0x25BC, 0x25BC),
|
||
(0x25C0, 0x25C0), (0x25C4, 0x25C4), (0x25C9, 0x25C9), (0x25CB, 0x25CB),
|
||
(0x25CF, 0x25CF), (0x25F7, 0x25F7), (0x2605, 0x2605), (0x263C, 0x263C),
|
||
(0x2699, 0x2699), (0x26A0, 0x26A0), (0x26BF, 0x26BF), (0x2713, 0x2713),
|
||
(0x2717, 0x2717), (0x276F, 0x276F), (0x2800, 0x28FF), (0xFFFD, 0xFFFD),
|
||
)
|
||
# fmt: on
|
||
|
||
#: Every codepoint the console font can draw, as one frozen set (built once at import;
|
||
#: 520 members, so the set is small and the per-character membership test is a dict hit).
|
||
FONT_CODEPOINTS: frozenset[int] = frozenset(
|
||
cp for first, last in FONT_RANGES for cp in range(first, last + 1)
|
||
)
|
||
|
||
|
||
def in_font(char: str) -> bool:
|
||
"""Whether the console font has a glyph for ``char``."""
|
||
return ord(char) in FONT_CODEPOINTS
|