iris: ship an icon font subset, and delete the drawn mark
Iris asked why `mark` existed at all -- "the font should be working if
it's working for compose and nerd fonts are bundled". It was not: the
Compose app draws its icons from its own committed Nerd Fonts subset,
while iris, which bundles no font since 2026-09-07, was setting the
disclosure mark with bare geometric codepoints (U+25B8/25BE/25B4) out of
whatever face the platform resolved -- an empty box on her phone, a dot
on this VM. The 2026-09-07 note that "iris had no equivalent icon font to
keep" is the gap: it had none because it had never had one.
So iris ships the same kind of subset. iris/core/build-icon-font.sh is
the Compose script with its own GLYPHS list, writing a 992-byte
nerd_icons.ttf with three Material Design glyphs from the Mono face;
iris::icon names the codepoints; Family::Icons is how text asks for them.
The variant names an intention rather than a font name -- only TextData
knows what the file registered as, and it resolves it during shaping --
and it is a named family, never a generic one, so nothing falls back into
it for text and an icon cannot fall back out of it onto a system face
that happens to have the codepoint.
every_icon_is_in_the_bundled_font maps each constant through the shipped
font's charmap, which is the guard the script's "the two lists have to
agree" comment asks for. FontDiagnostics gains icon_family, so a build
whose font failed to register says so instead of drawing tofu; the
emulator reports icons=Some("Symbols Nerd Font Mono").
widget/mark.rs is deleted. It drew one correct triangle, but every
further icon would have been another rasteriser, and an icon as text
takes the size, colour and baseline of the line it sits in for free.
Looked at rather than only compiled: closed and open marks in
run-headless.sh phone --phone either side of a tap, and the collapse
bar's up mark under IRIS_TOOLS_EXPANDED=1.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
341b7a5922
commit
9e301f30c6
17 files changed
+423
-313
No files matched your search
@@ -5,6 +5,31 @@ they can be judged and reversed later. Detail lives in RUST.md (and IRIS.md
|
||||
for iris API changes); this file is only the summary. Newest first. Items
|
||||
marked **DEFERRED** are ones the agent chose not to decide alone.
|
||||
|
||||
## 2026-09-08 (iris ships an icon font, and the drawn mark is deleted)
|
||||
|
||||
- **Directed by Iris.** Her question on seeing `widget::mark`: "why does
|
||||
mark exist? The font should be working if it's working for compose and
|
||||
nerd fonts are bundled." It was not: the Compose app draws its icons
|
||||
from **its own committed Nerd Fonts subset**, while iris was setting
|
||||
the disclosure mark with bare Unicode geometric codepoints
|
||||
(U+25B8/25BE/25B4) out of whatever face the platform resolved -- an
|
||||
empty box on her phone, a dot on this VM. The 2026-09-07 entry below,
|
||||
which said "iris had no equivalent icon font to keep", is what left
|
||||
that gap: iris had no icon font because it had never had one, not
|
||||
because it needed none.
|
||||
- **So iris now bundles the same kind of subset**:
|
||||
`iris/core/build-icon-font.sh` writes
|
||||
`iris/core/assets/fonts/nerd_icons.ttf` (992 bytes, three Material
|
||||
Design glyphs today), `iris::icon` names the codepoints, and
|
||||
`Family::Icons` draws them. This does **not** reopen the platform-fonts
|
||||
decision: body and monospace text still come from the platform, and an
|
||||
icon is the opposite case -- a small, closed, known set of codepoints,
|
||||
which is exactly the division the Compose app already makes.
|
||||
- **`iris::widget::mark` is deleted** (added earlier the same day). It
|
||||
drew a correct triangle, but only a triangle, and every further icon
|
||||
would have been another bespoke rasteriser. An icon as text also takes
|
||||
the size, colour and baseline of the line it sits in for free.
|
||||
|
||||
## 2026-09-08 (the emulator is a GLES machine, and Vulkan is verified elsewhere)
|
||||
|
||||
- **Directed by Iris, carried out here**: "make sure the setup uses GL for
|
||||
|
||||
@@ -1422,3 +1422,47 @@ which is exactly the run nobody needs.
|
||||
`LogRing::try_tail_text`, because a panic raised while the ring's own
|
||||
lock was held would otherwise deadlock the hook and hang the process
|
||||
instead of aborting it.
|
||||
|
||||
## 2026-09-08: iris ships an icon font, and `widget::mark` is gone
|
||||
|
||||
Iris's question -- "why does mark exist? The font should be working if
|
||||
it's working for compose and nerd fonts are bundled" -- and its answer:
|
||||
the Compose app draws icons from its own committed Nerd Fonts subset,
|
||||
while iris was setting the disclosure mark with bare Unicode geometric
|
||||
codepoints out of whatever face the platform resolved. So iris now does
|
||||
what Compose does.
|
||||
|
||||
- **`iris::icon`** (new module): the codepoints iris draws, one constant
|
||||
each -- `OPEN`, `CLOSED`, `COLLAPSE` today. Every one has to have a
|
||||
matching entry in `iris/core/build-icon-font.sh`'s `GLYPHS`, which is
|
||||
what builds the shipped `iris/core/assets/fonts/nerd_icons.ttf` (992
|
||||
bytes, Material Design, Mono face). `every_icon_is_in_the_bundled_font`
|
||||
fails the build if the two lists drift.
|
||||
- **`Family::Icons`** (new variant): how any text asks for that family.
|
||||
Before/after:
|
||||
|
||||
// was
|
||||
mark(if open { Dir::DOWN } else { Dir::RIGHT }, 9.0, MUTED)
|
||||
// now
|
||||
text(if open { icon::OPEN } else { icon::CLOSED }, 9.0, MUTED)
|
||||
.family(Family::Icons)
|
||||
|
||||
It names an intention, not a font name: only `TextData` knows what the
|
||||
bundled file registered as, and it resolves the variant during shaping
|
||||
(`TextData::resolve_family`, also public). A *named* family rather than
|
||||
a generic one, so nothing falls back into it for ordinary text and an
|
||||
icon cannot fall back out of it onto a system face that happens to have
|
||||
the codepoint.
|
||||
- **`iris::widget::mark` is removed** -- added earlier the same day and
|
||||
superseded within it. It drew one correct triangle; every further icon
|
||||
would have been another rasteriser, and an icon as text takes the size,
|
||||
colour and baseline of the line it sits in for free.
|
||||
- **`FontDiagnostics::icon_family`** (new field), in the startup log line
|
||||
and the Diagnostics pane: which family the icons resolved to, so a
|
||||
build whose bundled font failed to register says so instead of drawing
|
||||
tofu.
|
||||
|
||||
This does not reopen the 2026-09-07 platform-fonts decision. Body and
|
||||
monospace text still come from the platform's own collection; an icon is
|
||||
the opposite case, a small closed set of codepoints no system font is
|
||||
guaranteed to have, and it is the same division the Compose app makes.
|
||||
+19
-17
@@ -819,23 +819,25 @@ has the fuller account.
|
||||
nothing on screen says it was cut. Whichever end is cut has to be a
|
||||
choice when this lands: a path is identified by its tail, a command by
|
||||
its head.
|
||||
- [x] **A drawn chevron.** **Done 2026-09-08**: `iris::widget::mark(dir,
|
||||
dp, colour)` rasterises an antialiased triangle into the ordinary
|
||||
texture path and scales it into the box asked for, so no line/path
|
||||
primitive was needed after all. `tool.rs` uses it for all three marks.
|
||||
The original entry, for the record: *the bundled fonts
|
||||
were removed on 2026-09-07 in favour of the platform collection, so the
|
||||
mark is a codepoint the phone's own faces may not have -- Iris's
|
||||
2026-09-08 screenshot shows an empty box where it should be, and the
|
||||
desktop render draws it as a small dot. UI_RULES: "don't rely on
|
||||
characters the platform might not have." iris has rects, text and
|
||||
textures, so the smallest honest fix is a generated texture rather than
|
||||
a new primitive.* `Chevron.kt` draws its own strokes precisely
|
||||
because a chevron from a font is a glyph a system font may not have --
|
||||
and the bundled `NotoSans-Regular.ttf` indeed has no U+25B8/25BE/25B4,
|
||||
while `NotoSansMono-Regular.ttf` does. `tool.rs` sets the mark in the
|
||||
monospace face as a result. A real fix needs a line/path primitive;
|
||||
iris has rects, text and textures only.
|
||||
- [x] **A chevron the platform cannot fail to have.** **Done
|
||||
2026-09-08**, twice. First as `iris::widget::mark(dir, dp, colour)`,
|
||||
which rasterised an antialiased triangle into the ordinary texture path
|
||||
-- correct, but one bespoke shape, and it built a texture *per widget*,
|
||||
which is what crashed the bench (RUST.md's 2026-09-08 evening entry).
|
||||
Then, on Iris's question -- "why does mark exist? The font should be
|
||||
working if it's working for compose and nerd fonts are bundled" -- as
|
||||
what the Compose app has always done: **iris ships its own Nerd Fonts
|
||||
subset** (`iris/core/build-icon-font.sh` -> `iris/core/assets/fonts/
|
||||
nerd_icons.ttf`, 992 bytes, three Material Design glyphs), named in
|
||||
`iris::icon` and drawn with `Family::Icons`. `mark` is deleted. That
|
||||
serves every future icon rather than one triangle, and an icon is text,
|
||||
so it takes the size, colour and baseline of the line it sits in for
|
||||
free. The original entry, for the record: *the bundled fonts were
|
||||
removed on 2026-09-07 in favour of the platform collection, so the mark
|
||||
is a codepoint the phone's own faces may not have -- Iris's 2026-09-08
|
||||
screenshot shows an empty box where it should be, and the desktop render
|
||||
draws it as a small dot. UI_RULES: "don't rely on characters the
|
||||
platform might not have."*
|
||||
- [ ] **A tool card's text is not selectable.** `Selection` is keyed
|
||||
`(RowKey, block index)` and a card has no markdown blocks, so nothing in
|
||||
a card registers. Compose's `SelectionContainer` covers tool output,
|
||||
|
||||
+43
-11
@@ -8143,16 +8143,48 @@ recorded anywhere. It is the crash this code had; the devlog fix above is
|
||||
what will say whether it was hers. Ask for the Runtime tab after the next
|
||||
bench APK.
|
||||
|
||||
### Open: why `mark` exists at all (Iris asked, 2026-09-08)
|
||||
### Why `mark` existed, and what replaced it (Iris asked, 2026-09-08)
|
||||
|
||||
Her question, mid-fix: "why does mark exist? The font should be working if
|
||||
it's working for compose and nerd fonts are bundled." The Compose app
|
||||
draws its chevron from **its own committed Nerd Fonts subset**
|
||||
(`app/build-icon-font.sh`, `NerdIcons.kt`); iris bundles no font at all
|
||||
since 2026-09-07, and `tool.rs` was using bare geometric codepoints
|
||||
(U+25B8/25BE/25B4) out of whatever system face resolved -- which her phone
|
||||
had none for. So the two apps were never doing the same thing, and the
|
||||
2026-09-07 note that "iris had no equivalent icon font to keep" is what
|
||||
left the gap. The alternative to `mark` is to bundle the same ~100-glyph
|
||||
subset in iris and take icons from it, which would serve every future icon
|
||||
rather than one triangle. Not done: it is hers to choose.
|
||||
it's working for compose and nerd fonts are bundled." It was not working,
|
||||
and the two apps were never doing the same thing. The Compose app draws
|
||||
its icons from **its own committed Nerd Fonts subset**
|
||||
(`app/build-icon-font.sh`, `NerdIcons.kt`); iris bundles no font since
|
||||
2026-09-07, and `tool.rs` was setting its mark with bare geometric
|
||||
codepoints (U+25B8/25BE/25B4) out of whatever system face resolved --
|
||||
which her phone had none for. The 2026-09-07 note that "iris had no
|
||||
equivalent icon font to keep" is the gap: iris had none because it had
|
||||
never had one.
|
||||
|
||||
**Done, on her instruction.** iris ships the same kind of subset:
|
||||
|
||||
- `iris/core/build-icon-font.sh` -- a copy of the Compose app's script
|
||||
with its own `GLYPHS` list, writing
|
||||
`iris/core/assets/fonts/nerd_icons.ttf`. **992 bytes** for three
|
||||
Material Design glyphs (`md-menu_down`, `md-menu_right`, `md-menu_up`),
|
||||
from the **Mono** face for the reason the Compose script gives.
|
||||
- `iris::icon` names the codepoints, one constant each, and
|
||||
`iris_core::Family::Icons` is how a `TextBuilder` asks for the family.
|
||||
The name behind it is read back from the collection at registration
|
||||
rather than written down, and resolved during shaping
|
||||
(`TextData::resolve_family`), so nothing outside `TextData` needs to
|
||||
know what the file calls itself. A *named* family, never a generic one:
|
||||
nothing should fall back into it for text, and an icon must not fall
|
||||
back out of it onto a system face that happens to have the codepoint.
|
||||
- `iris::widget::mark` and `src/widget/mark.rs` are **deleted**.
|
||||
`tool.rs`'s three call sites are `disclosure(icon::OPEN | CLOSED |
|
||||
COLLAPSE)`, which is `text(...).family(Family::Icons)`.
|
||||
- `every_icon_is_in_the_bundled_font` is the guard the script's comment
|
||||
asks for: it maps each `icon::` constant through the shipped font's own
|
||||
charmap, so a constant added on one side and not the other fails a test
|
||||
instead of drawing nothing.
|
||||
- The startup font line and the Diagnostics pane now say which family the
|
||||
icons resolved to, so a build whose font failed to register says so
|
||||
rather than drawing tofu. On the emulator:
|
||||
`icons=Some("Symbols Nerd Font Mono")`.
|
||||
|
||||
Looked at, per UI_RULES, rather than only compiled: the closed and open
|
||||
marks in `run-headless.sh phone --phone` (before and after a tap that
|
||||
opens the card), and the collapse bar's up mark in `IRIS_TOOLS_EXPANDED=1
|
||||
run-headless.sh transcript`. All three draw, at the size and alignment the
|
||||
drawn triangle had.
|
||||
Reference in new issue
Block a user