With one object that Start Global Edit accepts selected with the Selection
tool, the canvas now highlights the other objects a start would take with the
current Global Edit Options, before Global Edit starts. The outlines are kept
per document revision and options, and none are shown during a drag.
Docs: docs/mcp.md (Global Edit), docs/gaps.md (G5).
While the app draws a document on screen, the live-effect plug-in runs of
its first view share a 2,000 ms budget (VectorCraft's own value); each run
takes the lesser of its 5,000 ms limit and what is left. A stage left out
for time, or one that times out, fails, has no plug-in or meets Safe Mode,
draws its input art unchanged and is deferred, and the status bar says how
many. Later drawings leave a deferred stage as it is until its input or
parameters change.
- effect.deferredStatus lists the deferred stages with object, effect
index, fill or stroke, plug-in and reason, objects in symbol, pattern,
brush and opacity-mask art included.
- Effect › Refresh Deferred Effects (effect.refreshDeferred {ids?}) runs
them again with a fresh budget and returns {refreshed, stillDeferred,
failed}.
- Each document has its own budget and deferred stages; exports, Expand
Appearance and commands run every stage under the per-call limit.
- The web build has no clock for the budget: its first view runs no
plug-in effect, and a refresh runs them.
Docs: docs/mcp.md, docs/plugins.md, docs/target-app-parity.md.
Each command a script runs keeps a savepoint of the state it may need
to put back if it fails. The savepoint cloned every open document's
whole undo history, so a script that made N edits did O(N^2) work.
- The savepoint now clones each document's state without its history
and keeps a mark: the newest undo and redo steps and the serials of
the steps under them. Until the command ends, the history trims no
step, and a new step sets the redo steps aside instead of dropping
them. A failed command truncates both stacks back to the mark.
- file.close, file.closeAll, document.close and file.revert still keep
a whole copy, since they remove the history or the document.
- When a failed command removed or changed a step under the newest
one, the history cannot be put back exactly, and the run stops with
an error; its rollback restores the documents as they were before
the run.
- run_guarded no longer copies the histories during a script's run,
and a committed run moves the histories from before it back instead
of copying them.
- Symbol editing mode shares its saved redo steps between copies of a
document's state.
- A script cannot run edit.clearHistory. A run keeps each document's
undo steps from before it, so the command reported a clear that the
commit then undid.
A new test changes the document in place (Arc::make_mut, with no other
holder and no change of revision) and checks the answer is measured
again: keyed on the document's address alone, it would keep the old
answer. The kept answer's doc says what it holds after the measure,
and that the fonts set the bounds of all type. Should measuring ever
ask again while it runs, it is measured without being kept, rather
than borrowed twice.
The stack overflow fixed in d5d04f868 also hit EPS export, and the
parity rows now say so. Two test docs are corrected: the fill-only
clipping is an older bug on main, and the outline-view difference runs
both ways on a few dozen hairline pixels.
The answer whether Fit to Artwork Bounds has art to fit moves from a
function-local thread_local to DocState, beside any_empty_artboards, and
drops with the document. It is kept for that version of the document
(held weakly, as any_empty_artboards holds its own) and the artboards
asked about, and measured again when the installed plug-ins, whose
effects draw art, or the installed fonts, which set type drawn by its
effects' art, change: their generations are an explicit input of the
measure. A change of the selection or the view keeps it.
The test counts the measures, as the Delete Empty Artboards check's
does: a later frame, select.set and a view change keep the answer; an
edit, other artboards, and each generation measure again. Taking any
part out of the key fails it.
text.spelling.addWord, removeWord and changeWord are Check Spelling's Add
and Edit Custom Dictionary's Add, Delete and Change; text.spelling.dictionary
lists the words. They live in craft-proof, which every language's check
reads. The desktop app and vectorcraft-cli keep them in
`Custom Dictionary.txt` next to the preferences (none without preferences);
elsewhere they last until the app closes.
text.spelling.ignoreAll is Ignore All: the active document's checks skip the
word while it is open; not saved, not undoable, and not a change to the
document's revision.
Behaviour: https://helpx.adobe.com/illustrator/desktop/design-with-text/edit-format-text/check-and-correct-spelling.html
The Artboards panel menu asks whether Delete Empty Artboards can run on
every frame while it is open, and each ask measured the document. With
an open path of 200,000 anchors across two artboards, that took 70.4 ms
a frame in a release build.
The answer is now kept per open document with the version of the
document it was measured on, and is measured again when the document
changes. A later frame takes under 0.001 ms. The first frame after an
edit measures once. A change of the selection or the view keeps the
answer.
The editing copy of a .ai or .ait file that VectorCraft saves or exports
now has `%_<n> /Int (CropAreaActive) ,` after the ArtboardArray in its
recorded part, and marks that artboard as the selected one. The app
records its view's active artboard before each command
(DocState::active_artboard; an index past the last artboard is the last,
as in the Artboards panel); without a view, the artboard the document
opened on (Document::opened_artboard) is written, else the first. A .ai
file read from its editing copy opens on that artboard. Before, the copy
named no active artboard and always marked the first as selected.
Docs: docs/mcp.md, docs/file-format-parity.md, the editingData option text.
Preferences > User Interface > Open Documents As Tabs was stored but did
nothing. With the box cleared, each document opened or created afterwards
opens in a floating window of its own, at the next cascade place, as
Window > Arrange > Float in Window floats it. Documents already open, and
documents open when the app starts, keep their tabs; checking the box
again leaves floating documents in their windows.
The engine records the preference on each document as it opens
(DocState::opened_as_tab), and the UI finds new documents by uid, so a
command batch that closes and opens documents, or changes the preference
between opening them, places each one as the preference was when it
opened.
Undo, Redo and a canceled undo group put back an earlier document but
left the Variables panel highlight as it was. After renaming the
highlighted variable and undoing, the highlight still named the new
name: a variable defined later under that name showed highlighted
without a click, and Delete removed it.
Each of these paths now clears a highlight whose variable the restored
document does not define, as Delete Variables and Load Variable Library
already did.