From review:
- ru and pt-BR "Intensity" were too long for the glass field and ended
in "…"; they are now "Яркость" and "Brilho", which fit.
- A value too long for its field ends in "…" instead of being clipped,
so "100000" never shows as "10".
- A label cut short shows whole on hover.
- The every-language test now checks the Intensity label fits whole in
each catalog (it fails with the old ru translation); the panel test
checks the label isn't cut and that the field is the 98.5 points the
language test measures against.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
While drawing, the Pencil previewed its stroke in the theme's text
colour, 2 points wide: white in dark theme, so over a white shape
nothing showed until the mouse was let go. The preview now uses the
colour and weight the Pencil draws with (one constant, PENCIL_STROKE,
black at 2 pt), scaled by the zoom, at least 1 pt. It doesn't show pen
pressure or a brush, which only the finished vector has.
Refs #256 ("The 'draw' tool is not visible when you are drawing. You
can see it after you release the mouse.").
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The glass effect's light intensity field had no label, and "Refraction
80%" and "Dispersion 50%" ran into the edge of their fields. The field
is labelled "Intensity" in every catalog. Text labels of number fields
take their measured width instead of 7 points per character, and a
label too long for its field ends in "…" before the value, which is
clipped to its own area. This changes every text-labelled number field:
Latin labels sit a little tighter, CJK labels get their real width.
Refs #256 ("There is one parameter that is not signed in the glass
effect editing options. The inscriptions also go beyond their
borders.").
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Escape or Enter while the pen draws ends the path and keeps its vector in
edit mode with the pen, so the next path joins the same layer; another
Escape leaves edit mode. Entering edit mode on a layer that already is a
vector no longer records an empty undo step.
Current macOS keeps PingFang and other on-demand fonts in its asset
store, which the font scan never walked, so Chinese text showed as
boxes. The scan now also walks the com_apple_MobileAsset_Font* folders
of /System/Library/AssetsV2 (and the older /System/Library/Assets) with
the same depth, size and file checks, and Hiragino Sans GB and Heiti SC
(preinstalled) join the Chinese UI faces and the text fallbacks.
Tested with a folder laid out the same way; not run on a Mac.
gridColumnsSizing and gridRowsSizing are CSS grid-template strings: px
tracks are fixed, fr tracks fill, auto/min-content/max-content hug,
minmax(_, Nfr) fills and repeat(n, ...) expands; other tracks stay equal
(1fr). Tracks past the axis's own count are left out. Files from .fig
keep reading the tracks from their source.
The format's SPACE_EVENLY is its older name for equal gaps without edge
space, so files keep reading it as space between; true space evenly is
SPACE_EVENLY_CSS, which the export now writes.
- The import report translates an importer note when the catalog has it, but 30 notes added by the
`.fig` import series (#626–#639) had no catalog entries, so they showed in English: connector
labels and snapshots, grid track sizing, image filters, slots and their content, vector segment
styles, and text on a path.
- All 30 are now in `en.toml` and in every full catalog: es, de, fr, pt-BR, ru, ja, ko, zh-Hans, cs,
id, sv and tr (30 each). `es-419` overrides only the 3 notes about settings (configuración rather
than Spain's ajustes), as the overlay does elsewhere. The wording follows each catalog's existing
terms for connector, layer, frame, stroke, grid, slot and text on path. The translations are drafts,
like the catalogs, and wait for native speakers' review.
- `every_key_in_the_code_is_in_the_english_catalog_and_no_other` now counts each importer note (the
`warn("…")` literals in `crates/format/src/fig` and `crates/format/src/rest`) as a required key, not
only as an allowed one. A new note that isn't in `en.toml` fails the check, and because Spanish is
in `COMPLETE` it has to be translated there too, so the report can't fall behind again.
`docs/translating.md` says so.
- The importers' texts are unchanged. Notes built with `format!` (layer counts, type names, field
names) still show in English, since the report matches whole notes.
A frame's name above its top edge (or a section's pill) only selected and
dragged it; a double-click there did nothing, since the label lies outside
the frame and hits no layer. With the Move or Scale tool, a double-click on
a label now selects that frame and asks the UI (`canvas.renameLabel`) for a
field over the label with the name selected, as the layers panel and pages
list do. Enter or a click elsewhere renames it (`object.rename`, one undo
step) and Escape leaves the name as it was. Rotated labels work too.
Tests drive the canvas: a double-click on a label opens the field, typing
and Enter rename the frame without moving it, undo restores the name, and
Escape cancels on a rotated frame.
From review:
- The check ran after any file.open/openRecent/import result, so a
pasted or dropped image, reopening a file that was already open, or
Clear recent brought the window back. It now runs only for results
with a `summary` (a file opened, or pages imported), and never in the
browser.
- Text > Missing fonts... before the startup scan finished listed
installed fonts as missing. It now says it is checking the installed
fonts and lists them once that is done
(`figcraft_text::installed_fonts_known`, also true when system fonts
are opted out, where checks used to wait forever).
- ROADMAP progress log and file-format-parity status line.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Menus and tooltips showed boxes for ⌃ ⌥ ↵ ⌫ ⇥ ⇞ ⇟ (e.g. Present ⌥⌘↵):
egui's default face has ⌘ and ⇧ but not these. The desktop app now adds
a system face that has them after the UI fonts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings the progress docs up to date with what landed on 2026-10-17: community batches #727, #728, #733, #735, #736 and #753, plus #729, #745, #746 and #751. Docs only.
Text in a family that isn't installed was drawn in a fallback font
without a word. Now:
- `text.missingFonts` lists the families a document names that no
installed or built-in font provides: text layers and their styled
ranges, text styles, and string variables bound to a font family
(every mode, through aliases), with the number of text layers.
- The desktop app shows a Missing fonts window after the user opens a
file that has any: once installed fonts are indexed (before that every
one of them would count as missing) and after any import report is
closed. Files named on the command line count. Programmatic opens and
the browser build never open it by themselves. Text > Missing fonts...
shows it for the file in front; Escape closes it.
- `figcraft-cli info` prints `missing font` lines (`missingFonts` with
--json).
- file-format-parity: the row claimed REST import warnings that no code
produced.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
reverseLoop reversed the list and skipped shared segments, which only turns a
loop of three or more round: a one-segment loop has no order at all, and a
two-segment ring reads the same whichever way its list is turned, so both
answered reversed: true without moving.
Three or more segments: reverse the list and leave every stored end alone (a
shared one belongs to the neighbour too). One or two: store one segment the
other way round, skipping any segment another short loop lists; when none is
left to swap, refuse with a clear error and leave the document as it was.
Tests: two 2-segment areas over one line that share it, the shared segment
listed first in one area and last in the other; each reversal flips that area's
winding sign and leaves the shared segment and the neighbour alone. A shared
one-segment loop is refused. The 4-segment squares stay as the long-loop case.
Drop the two catalog.rs menu lines: they aren't in the reference app's menus,
and the Vector menu runs commands without parameters, so both would fail there.
- A minimised or covered window now answers every control request that acts on the app's state
(`engine.execute`, `document.inspect`, `node.get`, `ui.inspect`, `ui.pointer`, `ui.key`, `ui.type`,
`ui.set`, `ui.menu.invoke`, `ui.render`, `window.list`, `window.focus`, `app.quit`), in that window's
file, from the app's `logic` (no frame drawn). Before, only six methods were answered there.
- What only a drawn frame can answer (`ui.screenshot`, `ui.input`, `window.new`) is an error at once
for a hidden window: `window 0 is minimised or hidden: `ui.screenshot` needs it on screen
(`ui.render` draws the document without it)`. Before, these waited up to 60 s.
- `crates/ui-egui/src/control.rs`: the `NO_FRAME` allow-list becomes a short `NEEDS_FRAME` list;
`drain_hidden` answers the rest and fails the frame-only ones at once.
- Docs: `docs/control-protocol.md` (hidden windows, `ui.screenshot`) and `docs/mcp.md` (attached
mode while the window is minimised). ROADMAP progress log and revision history.
Part of #720.