From 3917c26802145f57a19ba56ea57d6aaaa247b00f Mon Sep 17 00:00:00 2001 From: fede9234 Date: Wed, 14 Oct 2026 16:55:07 +0200 Subject: [PATCH] Text: colour-glyph comments say only what the fonts are documented to carry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Placeholder rectangles" was a claim about Apple Color Emoji's glyf outlines that no source I can show supports: the font's sbix chapter documents that most emoji are bitmaps while the flags are drawn from outlines, and it is Noto Color Emoji that has no outlines at all. The comments, the ROADMAP row and the parity row now say that instead. No behaviour change: comments and docs only. ๐Ÿค– Generated with Codebuff Co-Authored-By: Codebuff --- ROADMAP.md | 4 ++-- crates/text/src/color.rs | 9 +++++---- crates/text/src/fontdb.rs | 8 ++++---- docs/target-app-parity.md | 4 ++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 29f1f78a..179d7718 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,7 +2,7 @@ **Stage: alpha** ยท next: beta, ~26 points and ~162โ€“292 h away (one Opus 5.5 agent; ~33โ€“67 h wall-clock with 5 agents) -> **Last reviewed:** 2026-10-10 ยท **Last updated:** 2026-10-14 ยท **Change:** minor (colour emoji drawn from the system colour fonts (#268): bitmap strikes (sbix, CBDT/EBDT) and COLR v0 layers draw instead of the placeholder outlines; recent files as cards with thumbnails on the home screen; community fixes: lost images reported on loading (#207), SVG import budgets (#190), Leptos code (#223), full screen (#227), server snapshots readable again (#188), owner-only preferences (#200), ruzstd 0.9.1 (#182), layer cycle repair (#205), batch rollback, Direct3D 12 on Windows, plugin metering (#192); vector edit mode regions: hover hatch, selection and drag; SVG/PDF exports refuse over-depth documents (#208); bounded MCP/control framing, connections and queues (#201); plugin log limits (#191); live-session revert guard (#198); attached MCP no longer replays after a lost reply (#194); repeat command recursion fix; the Layout panel's constrain-proportions link scales the other side, #220; core editor leftovers: component playground, auto gap handles, variables inside styles, inner shadows and background blur on groups, command-made text readable on dark pages, a one-step frame/group convert, delays on mouse triggers and manual overlay offsets, wrapped-line alignment; `.fig` export: instance sizes, variables with modes, shared styles, variable-width strokes; starter templates, a Templates tab and Getting started tips on the home screen; your online files; everyday editing partials: number fields, outline options, Hide when publishing, cursors, panel widths, dark pages; sharing with a join code; text box sizes measured against documents re-saved by other software; live sessions per document; .fig export checked by opening written files in other software; a public figcraft-server: open hosting, owner tokens, per-address limits, idle expiry, moderation, install.sh; experimental .fig export; keyboard shortcut parity suite and bindings; Simplified Chinese draft catalog; Latin American Spanish overlay; prototyping tail: gamepad triggers, widgets in prototypes, mode lookups; plugin directory on figcraft-server; Japanese and Korean draft catalogs and CJK UI fonts; plugin widgets and the plugin panel tail; French, German and Brazilian Portuguese draft catalogs; cursor chat and spotlight in live sessions; layers and assets panels behaviour suite and fixes; vector multi-edit and edit tail; dev resources links; extended collections tail; branch version history and finer list merges; headline percentages recomputed from the area table: feature breadth ~84%, core ~94%, mainstream ~50%; text lists, hanging punctuation and decoration styles; comments and version history behaviour suite and fixes; canvas navigation, guides and grids behaviour suite and fixes; export and inspect behaviour suite and fixes; .fig import: editable vector networks and more layer kinds; shapes and vector behaviour suite and fixes; paint and effects behaviour suite and fixes; frames, groups, sections and masks behaviour suite and fixes; styles and variables behaviour suite and fixes; prototyping behaviour suite and fixes; components behaviour suite and fixes; embedded image colour profiles; layers panel keyboard: F2 rename, Shift+F10 context menu, keyboard box selection, 10k-layer QA; per-side stroke weight variables; text behaviour suite: CJK line breaking, metrics, vertical trim; selection and transform behaviour suite and fixes; `.fig` import, best effort; Windows QA pass with eight fixes; auto layout behaviour suite and fixes; Display P3: gamut warning and soft-proof (true P3 blocked upstream); several windows; localization layer with a draft Spanish catalog; hosting figcraft-server: wss in the desktop app, server releases, deployment guide; plugin panels and settings; canvas fixes: boolean hit testing on the result, group drags, frame outlines and slices; code connect; stretch and scatter brushes, pen pressure; text on a path and pattern fills; team libraries on the server and swap library; branches: create, update from main, review and merge; animated GIF fills and TIFF images; Open recent, outlines for the selection and mask outlines: menu breadth 100%; extended collections, variables import/export, gradient stop and variant bindings; feature breadth ~80%; ready ~49%) ยท **Target:** Figma Design (desktop app 126.10.7) +> **Last reviewed:** 2026-10-10 ยท **Last updated:** 2026-10-14 ยท **Change:** minor (colour emoji drawn from the system colour fonts (#268): bitmap strikes (sbix, CBDT/EBDT) and COLR v0 layers draw instead of the outlines; recent files as cards with thumbnails on the home screen; community fixes: lost images reported on loading (#207), SVG import budgets (#190), Leptos code (#223), full screen (#227), server snapshots readable again (#188), owner-only preferences (#200), ruzstd 0.9.1 (#182), layer cycle repair (#205), batch rollback, Direct3D 12 on Windows, plugin metering (#192); vector edit mode regions: hover hatch, selection and drag; SVG/PDF exports refuse over-depth documents (#208); bounded MCP/control framing, connections and queues (#201); plugin log limits (#191); live-session revert guard (#198); attached MCP no longer replays after a lost reply (#194); repeat command recursion fix; the Layout panel's constrain-proportions link scales the other side, #220; core editor leftovers: component playground, auto gap handles, variables inside styles, inner shadows and background blur on groups, command-made text readable on dark pages, a one-step frame/group convert, delays on mouse triggers and manual overlay offsets, wrapped-line alignment; `.fig` export: instance sizes, variables with modes, shared styles, variable-width strokes; starter templates, a Templates tab and Getting started tips on the home screen; your online files; everyday editing partials: number fields, outline options, Hide when publishing, cursors, panel widths, dark pages; sharing with a join code; text box sizes measured against documents re-saved by other software; live sessions per document; .fig export checked by opening written files in other software; a public figcraft-server: open hosting, owner tokens, per-address limits, idle expiry, moderation, install.sh; experimental .fig export; keyboard shortcut parity suite and bindings; Simplified Chinese draft catalog; Latin American Spanish overlay; prototyping tail: gamepad triggers, widgets in prototypes, mode lookups; plugin directory on figcraft-server; Japanese and Korean draft catalogs and CJK UI fonts; plugin widgets and the plugin panel tail; French, German and Brazilian Portuguese draft catalogs; cursor chat and spotlight in live sessions; layers and assets panels behaviour suite and fixes; vector multi-edit and edit tail; dev resources links; extended collections tail; branch version history and finer list merges; headline percentages recomputed from the area table: feature breadth ~84%, core ~94%, mainstream ~50%; text lists, hanging punctuation and decoration styles; comments and version history behaviour suite and fixes; canvas navigation, guides and grids behaviour suite and fixes; export and inspect behaviour suite and fixes; .fig import: editable vector networks and more layer kinds; shapes and vector behaviour suite and fixes; paint and effects behaviour suite and fixes; frames, groups, sections and masks behaviour suite and fixes; styles and variables behaviour suite and fixes; prototyping behaviour suite and fixes; components behaviour suite and fixes; embedded image colour profiles; layers panel keyboard: F2 rename, Shift+F10 context menu, keyboard box selection, 10k-layer QA; per-side stroke weight variables; text behaviour suite: CJK line breaking, metrics, vertical trim; selection and transform behaviour suite and fixes; `.fig` import, best effort; Windows QA pass with eight fixes; auto layout behaviour suite and fixes; Display P3: gamut warning and soft-proof (true P3 blocked upstream); several windows; localization layer with a draft Spanish catalog; hosting figcraft-server: wss in the desktop app, server releases, deployment guide; plugin panels and settings; canvas fixes: boolean hit testing on the result, group drags, frame outlines and slices; code connect; stretch and scatter brushes, pen pressure; text on a path and pattern fills; team libraries on the server and swap library; branches: create, update from main, review and merge; animated GIF fills and TIFF images; Open recent, outlines for the selection and mask outlines: menu breadth 100%; extended collections, variables import/export, gradient stop and variant bindings; feature breadth ~80%; ready ~49%) ยท **Target:** Figma Design (desktop app 126.10.7) FigCraft is a clean-room, open-source, pure-Rust reimplementation of the Figma design workflow, native on macOS, Windows, Linux and FreeBSD and in the browser, fully drivable by agents through @@ -312,7 +312,7 @@ Ranked; detail and milestones in [`docs/roadmap.md`](docs/roadmap.md). | Date | Change | Summary | |---|---|---| -| 2026-10-14 | minor | Colour emoji drawn (#268): a glyph that has colour ink draws that instead of its outline โ€” an embedded bitmap strike (sbix, CBDT/EBDT: decoded to premultiplied RGBA, placed by the strike's bearings the way Skia places it and scaled to the size the run asks for) or a COLR v0 glyph's layers filled from the palette; fonts that carry only colour tables (Apple Color Emoji's placeholder outlines, Noto Color Emoji's none at all) are indexed again, "Segoe UI Emoji" and "Noto Color Emoji" join "Apple Color Emoji" and all three are read only for a text that nothing else covers; left for later: COLR v1 paint graphs, alpha-only strikes, emoji in the SVG and PDF exports (text is outlines there). 9 tests (8 in the text crate: placement, PNG and raw-BGRA decoding, scaling, the machine's own colour font; one in the renderer), the font-free ones run everywhere. Numbers unchanged | +| 2026-10-14 | minor | Colour emoji drawn (#268): a glyph that has colour ink draws that instead of its outline โ€” an embedded bitmap strike (sbix, CBDT/EBDT: decoded to premultiplied RGBA, placed by the strike's bearings the way Skia places it and scaled to the size the run asks for) or a COLR v0 glyph's layers filled from the palette; fonts whose emoji are not their outlines (Apple Color Emoji draws most from `sbix`, Noto Color Emoji has no outlines at all) are indexed again, "Segoe UI Emoji" and "Noto Color Emoji" join "Apple Color Emoji" and all three are read only for a text that nothing else covers; left for later: COLR v1 paint graphs, alpha-only strikes, emoji in the SVG and PDF exports (text is outlines there). 9 tests (8 in the text crate: placement, PNG and raw-BGRA decoding, scaling, the machine's own colour font; one in the renderer), the font-free ones run everywhere. Numbers unchanged | | 2026-10-14 | minor | Home screen recent files as cards (M7): each card shows the picture its file carries on its first page's colour, the file's icon, name and "Edited ... ago"; sort by name, creation or last change either way; a table view; a click selects, a double-click or Enter opens, arrow keys move; Open, Show in folder and Remove from recents on right-click. Numbers unchanged. | | 2026-10-14 | minor | Lost images reported on loading (#207): a `.figcraft` file whose image member is damaged, too large or missing no longer loads in silence; each lost image (up to 20, then a count) is listed in `repairs` on `file.open` with its hash and the reason, and the app shows it as a toast. Saving still writes the file without the lost images. Numbers unchanged | | 2026-10-14 | minor | SVG import budgets (#190): gzipped SVG is unpacked by FigCraft within 64 MiB before parsing (it was unpacked without a limit), so the nesting check sees the real document; SVG documents embedded in `` data URIs share one 32 MiB budget and at most 4 levels, and one past a budget is left out. Linked files stay unread. Numbers unchanged | diff --git a/crates/text/src/color.rs b/crates/text/src/color.rs index 85509214..16e0c759 100644 --- a/crates/text/src/color.rs +++ b/crates/text/src/color.rs @@ -1,11 +1,12 @@ //! Colour glyphs: embedded bitmap strikes (sbix, CBDT/EBDT) and COLR v0 layers. //! -//! Colour emoji fonts don't draw like other glyphs: their outlines are placeholder rectangles -//! (Apple Color Emoji) or missing altogether (Noto Color Emoji), and the picture itself lives in a -//! bitmap strike or in a stack of coloured layers. This module gives the renderer either a +//! Colour emoji fonts don't draw like other glyphs: the picture itself lives in a bitmap strike +//! (sbix, CBDT/EBDT) or in a stack of coloured layers, not in the glyph's outline โ€” in Apple Color +//! Emoji most emoji are `sbix` bitmaps while the flags are drawn from outlines, and Noto Color +//! Emoji has no outlines at all. This module gives the renderer either a //! premultiplied RGBA raster at the size it asked for, or the layer glyphs and the palette colours //! to fill with its own outlines. Anything else (COLR v1's paint graphs, alpha-only strikes) is -//! left to the outline pipeline, which draws the placeholders as before. +//! left to the outline pipeline, which draws whatever outlines the face has, as before. use std::collections::HashMap; use std::sync::Arc; diff --git a/crates/text/src/fontdb.rs b/crates/text/src/fontdb.rs index 24e6495b..525af037 100644 --- a/crates/text/src/fontdb.rs +++ b/crates/text/src/fontdb.rs @@ -725,9 +725,9 @@ fn scan_dir(dir: &std::path::Path, depth: usize, out: &mut BTreeMap Option> { } /// (index, family, style) of each face in a font file: outline fonts and colour fonts (Apple Color -/// Emoji has placeholder outlines, Noto Color Emoji has none at all). +/// Emoji draws most emoji from `sbix`, Noto Color Emoji has no outlines at all). fn faces_in(bytes: &[u8]) -> Vec<(u32, String, String)> { let count = match FileRef::new(bytes) { Ok(FileRef::Collection(c)) => c.len(), diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index ac7fc428..5cf1f835 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -103,7 +103,7 @@ Breadth: does it exist. Ready: depth, correctness and fidelity for real projects | 7 | Effects | 4 | 100% | 75% | Glass and progressive blur tuned side by side (behaviour suite from the documentation, inner shadows and background blur on groups, shadows hidden behind translucent layers on the canvas and in every export landed) | 2โ€“5 | | 8 | Frames, groups, sections, masks | 5 | 97% | 80% | Visual QA with real files (a one-step frame/group convert, and a behaviour suite from the documentation landed: masked-out areas don't take clicks, mask group bounds and exports follow the mask, sections kept out of frames and groups, frames and sections drawn around layers take them, section resizing leaves contents in place, X/Y measured in the frame) | 1โ€“3 | | 9 | Auto layout & constraints | 9 | 98% | 74% | Behaviour against real Figma files (behaviour suite from the documentation, `fr` tracks like CSS, vertical wrap, auto gaps evenly/around, cell alignment and wrapped-line alignment landed) ([auto-layout-parity](auto-layout-parity.md)) | 3โ€“6 | -| 10 | Text | 8 | 90% | 70% | Spell check, text metrics on real files and in other fonts (text box sizes measured against documents re-saved by other software: all 230 self-sizing boxes in 7 documents come out to the pixel, one font family; behaviour suite with CJK line breaking, vertical trim and carets by grapheme cluster landed; lists per paragraph with nesting and list spacing, hanging punctuation and lists, decoration style, thickness, offset, skip ink and colour landed; colour emoji draw from the system colour fonts โ€” bitmap strikes (sbix, CBDT/EBDT) or COLR v0 layers โ€” where they used to draw the placeholder outlines, COLR v1 still falling back to outlines) | 3โ€“7 | +| 10 | Text | 8 | 90% | 70% | Spell check, text metrics on real files and in other fonts (text box sizes measured against documents re-saved by other software: all 230 self-sizing boxes in 7 documents come out to the pixel, one font family; behaviour suite with CJK line breaking, vertical trim and carets by grapheme cluster landed; lists per paragraph with nesting and list spacing, hanging punctuation and lists, decoration style, thickness, offset, skip ink and colour landed; colour emoji draw from the system colour fonts โ€” bitmap strikes (sbix, CBDT/EBDT) or COLR v0 layers โ€” where what drew before was the glyph's outline data, COLR v1 still falling back to outlines) | 3โ€“7 | | 11 | Components & variants | 9 | 96% | 72% | Real (not synthetic) libraries, `.fig` libraries (a component playground for variant, boolean and text properties, a behaviour suite from the documentation, overrides of padding, gap, grids, exports and interactions, refused geometry overrides, variant-switch and Assets-swap override rules, top-left default variant landed) ([components-parity](components-parity.md)) | 4โ€“9 | | 12 | Styles & variables | 5 | 95% | 76% | Real-library QA (variables inside styles, behaviour suite from the documentation, style folders and order, mode order, code syntax, extended collections with their tail (new library variables as updates, chains through libraries) and variables import/export landed) ([components-parity](components-parity.md)) | 2โ€“4 | | 13 | Prototyping | 6 | 92% | 74% | Video triggers and media actions, controllers on macOS, Linux and FreeBSD, real prototype QA (behaviour suite from the documentation, delays on mouse triggers, manual overlay offsets, key combinations, controller buttons on key/gamepad triggers (Windows and the browser), widgets reacting in prototypes, interactive components playing their variants, drag-driven animations, physical springs landed) ([prototyping-parity](prototyping-parity.md)) | 2โ€“5 | @@ -628,7 +628,7 @@ Carried over from the ROADMAP's "Shipped so far" (2026-10-10). The test count th | Date | Change | Summary | |---|---|---| -| 2026-10-14 | minor | Colour emoji drawn (#268): a glyph with colour ink draws it instead of its outline โ€” an embedded bitmap strike (sbix, CBDT/EBDT) decoded to premultiplied RGBA and placed the way Skia places it, or a COLR v0 glyph's layers filled from the palette; faces that carry only colour tables (Apple Color Emoji, Noto Color Emoji) are indexed again and "Segoe UI Emoji" and "Noto Color Emoji" join "Apple Color Emoji" in the fallbacks. Left: COLR v1 paint graphs, alpha-only strikes, the SVG and PDF exports. See [ui-parity](ui-parity.md); numbers unchanged | +| 2026-10-14 | minor | Colour emoji drawn (#268): a glyph with colour ink draws it instead of its outline โ€” an embedded bitmap strike (sbix, CBDT/EBDT) decoded to premultiplied RGBA and placed the way Skia places it, or a COLR v0 glyph's layers filled from the palette; faces whose glyphs come from colour data (Apple Color Emoji, Noto Color Emoji) are indexed again and "Segoe UI Emoji" and "Noto Color Emoji" join "Apple Color Emoji" in the fallbacks. Left: COLR v1 paint graphs, alpha-only strikes, the SVG and PDF exports. See [ui-parity](ui-parity.md); numbers unchanged | | 2026-10-13 | minor | Vector edit mode regions: the filled area under the pointer is hatched (clear of points and segments, holes left out, spacing by octave folding fitted to measurements at several zoom levels, fixed to the shape); click, Shift-click and drag select and move areas with their points (drawn unselected); a click on an empty spot clears them and stays in edit mode (see [ui-parity](ui-parity.md)) | | 2026-10-13 | minor | Plugin log limits (#191): cap each UTF-8 line at 8 KiB, total log bytes at 1 MiB and lines at 1,000 per run/callback before copying guest memory or forwarding to the host. Over-budget runs fail and roll back document edits; callbacks get fresh budgets. Added sandbox boundary/forwarding tests and an engine rollback regression. Percentages and hours unchanged. | | 2026-10-13 | minor | Component playground (M3): with an instance, a component or a component set selected, the Inspect tab shows a Playground: a preview of the component and a control for each variant, boolean and text property. What is tried there changes the preview and the code in the Code section, never the file (no undo step, the canvas instance stays as it is); Reset goes back to the component's or the instance's own values. `component.playground {id?, properties?, language?, path?}` gives the same to scripts: the properties with their values, the code, and a PNG on request (`playground_tests`). Left: instance-swap and slot properties in the playground (the command takes an instance swap; the panel has no control for it), a code connect template's snippet with the tried values. Numbers unchanged. |