5.6 KiB · text History 38cca4c

Icon Studio

Designs application icons from the house palettes: pick a Material Symbols glyph or some text, a foreground colour and a background treatment, and see every combination your choices allow side by side.

all ten background generators

Provenance

The original icon studio was lost in the data-loss incident, and unlike the Android clients there was no artefact to decompile — an egui binary was not sitting on a phone somewhere. So this is a rebuild from two things that did survive:

  • its inputs — the palettes, which are still live (see below);
  • its outputs — the icons it produced, which ship inside the five cbz* Android apps.

That second point is what keeps this honest. tests/reproduce.rs renders a background with the reconstructed code and compares it against ic_icon_background.png taken from the installed cbzauth APK. The originals turn out to be an even two-tone diagonal split of the Casabeza brand colours with a hairline boundary — roughly one blended pixel per row — and the tests assert exactly that, so a change that turns the split into a soft gradient fails rather than quietly drifting.

What is attested, and what is not

Feature Evidence
Diagonal split background Attested — all five shipped cbz icons use it
Material Symbols foreground Attested — shipped icons are Symbols Rounded, outlined
Text foreground Attested — cbznumerics ships “1234”
Casabeza + neiam palettes Attested — recovered from the APK and live in dms
Solid, gradients, stripes, checks, dots, rays, wedge Invented — described as “gradients, patterns and other things”, but no shipped icon uses them
Sub-banner Invented — described, but no shipped icon has one, so the layout is a guess

The invented parts are reasonable, not recovered. Treat them as a starting point rather than as the tool you remember.

Documents

Configurations save as TOML, so they are readable and hand-editable:

version = 1
palette = "Casabeza"

[foreground]
kind = "icon"
codepoint = "e899"
name = "lock"        # informational; the codepoint wins

[colors.background_a]
role = "primary"
rgb = [0, 201, 212]

[background]
style = "diagonal-split"
angle = 45.0

Colours carry both a palette role and literal RGB. The role wins where the named palette still defines it, so retuning a theme in dms updates every document that references it; the RGB is the fallback that keeps old documents openable when a role is gone. A document from a newer version is refused rather than half-read, and an unknown background.style is an error rather than a silent default — but an unknown grid preference is dropped, since that should not block opening a file.

New / Open / Save / Save as are on the left panel, with Ctrl+N, Ctrl+O, Ctrl+S and Ctrl+Shift+S. The title bar shows the filename and a bullet for unsaved changes, and New/Open prompt before discarding them.

The cbz icon set

presets/ holds a document per shipped app — cbz-auth, cbz-lists, cbz-numerics, cbz-scanner, cbz-inventory — so each icon opens as an editable configuration instead of having to be rebuilt by hand.

These are reconstructions. The palette, the diagonal split and its orientation are measured from the shipped PNGs, and the scales are taken from each one’s ink extents; the glyph identifications are mine by eye, so cbz-scanner being satellite_alt is a judgement, not a recovered fact. A test loads all five and asserts they still reproduce the shipped background orientation.

Palettes

Nothing is retyped by hand. tools/regen_palettes.py writes src/palette/generated.rs from:

  • neiam — the daisyUI themes in dms/assets/f/css/style.css (her, afterdark, forest, sky, clays, stones, dark, light), converted from OKLCH to sRGB with the same transform the Android clients use;
  • Casabeza — the exact values recovered from the cbzauth APK after the loss, carried in the script.
tools/regen_palettes.py              # refresh after dms changes
tools/regen_palettes.py --check      # non-zero if stale, for CI

The Android themes and the dms themes agree exactly on primary and accent; Android’s backgrounds are deliberately darker (L 0.18 against 0.35). Both are offered.

Fonts

Vendored in assets/:

  • Material Symbols Rounded, outlined and filled, from egui_material_icons (MIT), with the .codepoints table parsed at startup so the icon list and the rasteriser cannot disagree about what a name means;
  • B612 regular and bold, the face the cbz apps ship in res/font, used for text marks and sub-banners. Rendering text through the Symbols font lands on .notdef, which is why text needs its own face.

Running

cargo run              # the studio
cargo test             # including the comparison against shipped icons
cargo run --example reproduce_cbz   # re-render the five cbz icons
cargo run --example showcase        # every background generator
cargo run --example make_presets    # regenerate presets/

Export writes ic_icon, ic_icon_background and ic_icon_foreground across mipmap-mdpi through mipmap-xxxhdpi (108–432px), matching the layout the cbz apps use.

Design notes

Rendering is tiny-skia and ab_glyph, deliberately independent of egui: the preview, the grid and the exported PNG all go through render::render_composed, so what you see is what lands on disk, and the renderer can be tested headlessly. Grid cells are cached by content hash — the cartesian product gets large quickly, and it is capped at 240 cells for that reason.