The Legacy .ai Options dialog gains Hidden Objects (Hidden Layer, Omit, Make Visible) and Text
(Editable, Outlines), translated in every catalog. Docs: type and hidden objects in the legacy
.ai paragraphs, the restored revision rows and roadmap row.
The .ai options dialog offers Legacy (version 7). In that mode it shows Transparent Images
(Flatten, Omit) and, with more than one artboard, thumbnails to check with the file each is
saved to (long names keep their end). OK is greyed out until an artboard is checked. A save
panel's Enter no longer confirms the options dialog it opens.
Drag out from a segment, corner, circle or arc to place a dimension; plain clicks pick two points or two lines. Radial dimensions on perfect arcs, picas, Away/Between and Left/Center/Right text placement. The Properties panel edits a selected dimension, with Apply to All (dimension.applyToAll) and Set as Default. Dimension Selected Paths, the Arc/R/Ø prefixes and the custom defaults are left out. The refresh returns at once in documents without dimensions (Document::dimensions); a linked dimension moved on its own keeps its place; modes, units, line types, arrows and text placement are enums; the tool has its own icon.
A pen reports far more often than frames come (an Apple Pencil up to 240 times
a second): the canvas now hands the tool each move of the frame with its
pressure instead of the last one only, and the web shell feeds Safari's
coalesced pen events. Mouse input is unchanged.
Read pen and finger Pointer Events in the web shell (capture phase) instead of
eframe's touch handlers, which can't tell a pen from a finger and see every
touch twice. The pen drives the pointer with its pressure and hovers; fingers
are touch contacts for pinch, two-finger pan and undo/redo taps. Once a pen
has been seen (remembered in localStorage), a finger or a resting palm never
presses a tool on the canvas, and a pen landing cancels fingers already down.
A long press drops the tool press and opens the context menu.
The page no longer scrolls, zooms or selects under touch, and the canvas
stays inside the safe areas of a full-screen app.
Use automatic vector smooth shading without a separate control.
Enable Cap by default and keep continuous rim curves and bounded seam joins.
Integrate the shared dialog with the other three 3D effects.
The late-focus case in the original change has no reproducible path
(#1339 already covers focus on the press frame), so the button-down
defer is dropped. The real issue is the clicked_focus branch: a very
short drag inside one character produces no text selection, egui still
reports a click, and select-all on release replaced the drag. The press
position is now remembered and a release more than three points away
keeps the caret; a plain tap still selects all.
Also fixes the test placement bug: the new test sat between the #[test]
attribute and keyboard_focus_keeps_selecting_the_entire_numeric_field,
so that test no longer ran. The regression test fails on the fork-point
widgets.rs and passes with this change.
Preserve the writer and reader changes while integrating the current main.
The combined candidate passes all eight local CI gates and the 2,048-case
reader panic verification. Hosted checks remain required before landing.
Refs #1893, #1894.
Since #1352, #1498 and #1507, Korean, Polish and Vietnamese are complete
catalogs: every menu string, tl! literal and status or error message has
a row, and the i18n tests check it. ko.tsv, pl.tsv and vi.tsv get the
rows that the other complete catalogs have for Import Shortcut Set and
its commands: the dialog's strings, the labels Import Shortcut Set…,
Read Shortcut Set File, Import Matches, Remember Import Matches and
Forget Import Matches, the two plurals and the two error messages. Copy
Report and Not read are already in all three, and Shortcut and the
Imported message in pl, so they are not repeated. The dialog's rows go
after Import Print Presets in ko and vi and after the Keyboard Shortcuts
dialog's rows in pl, and the two messages after "not a VectorCraft
shortcut set".
Check Script (3374d077) added Copy Report and Not read to every catalog,
and es and fr gained Shortcut and the Imported message in a747daa3 and
9e39a6d1. The rows that Import Shortcut Set added for the same strings
became second entries, which bundled_catalogs_are_consistent rejects.
They are removed, 26 rows in cs, de, es, fr, hu, it, ja, ru, uk, zh-hans
and zh-hant, and the existing rows stay as they are.
Since b9716366 (#1302), Hungarian is a complete catalog: every menu
string, tl! literal and status or error message has a hu row, and the
i18n tests check it. hu.tsv gets the rows that the other complete
catalogs have for Import Shortcut Set and its commands: 35 strings, the
two plurals in the single form hu.tsv uses (a count takes the
singular), and the two error messages. Shortcut and the Imported
message already have hu rows on main, so they are not repeated. The
rows are placed after the Keyboard Shortcuts… row.
Since #1189, Czech is a complete catalog: every menu string, tl! literal
and status or error message has a cs row, and the i18n tests check it.
cs.tsv gets the rows that the other complete catalogs have for Import
Shortcut Set and its commands: 35 strings, the two plurals with one, few
and other forms, and the two error messages. Shortcut and the Imported
message already have cs rows on main, so they are not repeated. The rows
are placed after the Keyboard Shortcuts… row.
A shortcut set another app saved as slash-name text (a .kys file whose
text starts with a slash name and "{", such as "/Menus {") opens in
Import Shortcut Set from File › Open, from Edit › Keyboard Shortcuts ›
Import… in the desktop app, or from a drop on the window, whether or
not a document is open. The dialog proposes a target for an entry when
an earlier import kept one for that name, or else when one tool,
command or panel matches the name clearly by its id or by one of its
labels. It decodes the file's key and modifier codes from the codes
earlier imports kept, from the example in the AiCommandPalette README
(/Key 48 for the 0 key, with /Modifiers 0 taken as no modifiers), and
from VectorCraft's default shortcuts where at least two entries vote and
four votes in five agree. The user picks the remaining targets, presses
the key for each unknown key code or marks it No equivalent, and chooses
the modifiers for each unknown modifier code. Apply assigns the ready
rows with the Keyboard Shortcuts rules: a tool takes a single key,
optionally with Shift. It goes through the rows from the last one back
and leaves a row out when a later row it applies has the same shortcut
or the same tool, command or panel. Keyboard Shortcuts then shows the
result as unsaved changes until the user clicks OK. Copy Report copies
the set's name, the rows Apply leaves out and the parts of the file that
weren't read.
- shortcutSet.read is a query command: it reads a set and does not
modify the document or the preferences. It returns each entry with
its section, codes and line, and up to 1,000 skipped tokens, each cut
to 80 characters. It reads at most 4 MiB of text and 20,000 entries,
skips blocks nested more than 16 deep and cuts names at 1,024 bytes.
With a path it reads at most 4 MiB and 4 bytes of the file, and with
--automation-read-root (#832) the path must lie inside the read root.
A file whose text starts with "<", such as an XML shortcut file saved
as UTF-8, fails with "This shortcut file is in a form VectorCraft
can't read."
- importMatches.list, importMatches.set and importMatches.reset read
and change the matches kept with the preferences; resetting the
preferences keeps them. With Remember My Choices on (the default),
Apply keeps the targets and codes the user chose, and for the rows it
assigns, it also keeps the matched targets and the codes decoded by
agreement. A later import proposes them.
- The name matcher compares a name with ids by exact match and shared
words. It compares the name with labels, in English and in the
interface language, by exact match, shared words and character
pairs. It proposes a match only when one tool, command or panel
scores at least 0.6 and at least 0.1 more than the next one.
- When Import Shortcut Set is opened from Keyboard Shortcuts, Cancel,
Escape and ui.dialog.cancel close it and return to Keyboard Shortcuts
as it was (dialogs::PARENT). A document's queued Missing Fonts dialog
(#792) opens after Keyboard Shortcuts closes.
- File › Open has a "Shortcut sets" filter, and in the desktop app
Keyboard Shortcuts' Import… shows .json and .kys files.
Docs: docs/mcp.md, docs/control-protocol.md, docs/development.md,
docs/target-app-parity.md, docs/roadmap.md.
The section lists asked for a selectable button and then turned its frame
off while the pointer was elsewhere, which also dropped the selected row's
fill: the section shown looked like every other row. The selected row now
keeps its fill.
In the web build, now_ms() in crates/ui-egui/src/lib.rs returned 0.0.
The status bar read "render 0.0 ms · ui 0.0 ms" however long a frame
took, and the Layers panel's budget of 8 ms for the row thumbnails it
renders in a frame never ran out, so only its limit of 16 thumbnails
applied.
now_ms() now returns the milliseconds since its first call, read from
the browser's performance.now() through web-time, which the build
already has through eframe. The desktop clock is unchanged. In Chrome,
after a pan frame of 750 ms over a document of 50,000 paths, the status
bar now reads "render 750.7 ms". The Layers panel now renders the
thumbnails of 24 groups of 2,000 paths one per frame, where main
rendered nine of them in one frame of 217 ms. The canvas has no render
worker in the web build, so it still renders on the UI thread and draws
the same pixels.
Docs: docs/target-app-parity.md.
Show Hidden Characters keeps each text object's marks together with
the node it laid them out from. Only a frame that drew the overlay
changed what it kept. After the option was turned off, or the
document was closed, those nodes stayed alive until the overlay was
next drawn.
The canvas now takes the kept marks at the start of each frame and
puts them back only when it draws the overlay. A frame that does not
draw it, for example with the option off or with no document open,
drops the marks and their nodes. A frame that draws the overlay still
keeps the marks of the frame before.
A save that couldn't write its file (a read-only folder, a file another
program holds open, a full disk) was only reported in the status bar, a line
the next message replaces; a background save's failure arrived there some
time after the user had moved on. Save, Save As, Save a Copy, Save as
Template, Export As and the commands that write one file now also say it in a
dialog naming the file and the reason, which stays until it is closed. The
document stays modified and keeps the file it had. A message that arrives
while another dialog is open waits for it to close instead of replacing it.
An agent's request gets the error as its reply, without a dialog; a failed
recovery write stays in the status bar.
A document opened off the UI thread became the active one as soon as it was
ready, also under an open dialog, whose OK acts on the active document: Save
As options confirmed after another file had finished opening wrote that
file's art under the first document's name. Files that are ready now wait
until the dialog is closed.
The web app's download callback returned nothing, so a save whose Blob, URL or
anchor couldn't be made was reported as written: the document counted as
saved, its recovery copy was dropped, and Save Changes closed it. The callback
now returns the error, which fails the save, export or file command like a
refused write on the desktop. A timer that can't be set after the download
started is not a failure.
The worker answered "timeout" after 60 s and left the request on the queue, so
the app ran it whenever it next drained the queue: an edit nobody was waiting
for, and a second one if the caller had retried. A request now leaves the
queue once: taken by the app, or given up by its caller, whichever comes
first. The timeout reply says which ("will not run" / "still running").
The preferences file was written only when the app quit normally, so settings
confirmed with OK were lost when the session ended any other way (the system
shutting down, the process being ended, a crash). OK now asks the host to
write the file at once.
Without group labels, the single column no longer draws a dash between
the groups: its tools are evenly spaced from top to bottom, as two
columns already run on from group to group. With the labels, each group
still starts under its name.
- Without group labels, the double-column toolbar fills every row: a
group no longer starts a half-empty row, as the reference's Basic
toolbar runs on in two columns. One column keeps its faint dashes, and
with the labels each group still starts its own row under its name.
- The All Tools drawer, now a tall single column, never goes above the
toolbar's top: on macOS it ran under the window's buttons. Its scroll
height is what is left from there to the window's bottom.
- Preferences › User Interface › Show Tool Group Labels is off as it
ships: the toolbar sets its groups apart with a faint dash, as the
Basic and Advanced toolbars of the public toolbar reference do (the
categories there are the Getting Started toolbar's). It no longer cuts
"Navigate" to "Navi...". The labels are a preference away.
- The All Tools drawer lists the tools one per row (icon, full name,
shortcut on the right), each flyout group framed together under the
heading most of its tools have (the Pencil's group, led by the Shaper,
under Draw). Tools already in the toolbar stay dimmed; dragging and
picking are as before.
- Its ☰ menu has Reset and the Basic and Advanced toolbars, the drawer's
flyout menu of the reference.
- Its Show section shows or hides the controls under the toolbar's tools
(Fill and Stroke, Coloring, Draw Mode, Screen Mode), as the reference
describes; `toolbar.show {control?, on?}`, saved with the preferences
(`ui.toolbar_show`, all on for older ones). Edit Toolbar's ••• stays.
- New strings in every catalog.
Reference: https://helpx.adobe.com/illustrator/using/tools.html (the look
is VectorCraft's own, with its own icons).
Each documented preset has an enhanced version (`enhanced: true` in
`imageTrace.make`, an Enhanced checkbox under the panel's preset): the preset
with Auto Grouping, and with Shapes in all but High Fidelity Photo. Gradients
stay an option. Flat Logo, a preset of our own, has none. The legacy presets,
and documents traced with them, are as they were.
So that an enhanced preset is no worse than its preset on that preset's inputs:
- A hole that one colour fills is the same shape as the path that fills it, so
the two still share one outline (a shape beside a fitted hole left slivers).
- A rectangle is as large as where its sides lie on average, not their farthest
points.
- Auto Grouping keeps the paths of a group in the order they were traced in. It
put a path first and what is inside it on top: a white counter traced under
its black letter was then painted over the letter's edge, a light seam
(Default with Auto Grouping, edge dE 10.24 -> 9.88; legacy 10.05).
The harness measures every enhanced preset beside its preset.
With Type › Show Hidden Characters on, the canvas laid out every
visible text object in view in every frame to place the dots on
spaces and the ¶ and # marks. With 1,000 two-line labels in view,
drawing the marks took a median of 19.7 ms per frame in a release
build.
The overlay now keeps each text object's marks in document space,
together with the node it laid them out from. In a frame it lays out
a text object only when its node is a new `Arc` (an edit makes one)
or the frame before did not draw it, and it lays out all type in view
again when the fonts or the hyphenation exceptions change. The marks
are still placed for the current view in every frame. With the same
labels, drawing the marks takes 0.8 ms per frame, and the shapes drawn
are the same as before.
Docs: docs/target-app-parity.md.
When the last frame took more than 8 ms to render, the desktop app's
canvas sends the next frame to the render worker and draws the last
one until the new one arrives. After a pan or a zoom it draws the last
frame moved and scaled. After the view angle changed, it drew no art
until a frame at the new angle arrived. The angle changes during a
Rotate View drag and when the status bar's angle menu, Reset Rotate
View or a saved view sets it. In a headless run of the canvas on a
document of 50,000 paths, none of the 60 frames of a turn from 0° to
90° drew any art.
The canvas now draws the last frame as a mesh turned into the new
view. Each corner goes where the new view puts the document point that
the corner showed. The frame at the new angle replaces it when it
arrives, as before. Pixel Preview's frames already turned with the
view and are drawn as before.
Docs: docs/target-app-parity.md.
The VPORT view direction fix and its test stay. The Export Strokes as
Centerlines option and the preset button are not in the documented DXF/DWG
export options, so they wait for the owner's decision.