Commit Graph
2783 Commits
Author SHA1 Message Date
BFlat cde9ee8a71 Merge pull request #1862 from storytold/fix/audit-ids-batch-control
Fix #1718, #1697, #1725, #1717: id exhaustion, batch rollback, timed-out control requests, RGBA size before decoding
2026-10-14 09:51:14 +07:00
bflatastic 0cb55bc0aa Fix #1717: sampling and recolouring check an image's RGBA size before decoding
The decoder's 512 MB limit is on the file's samples; a grey image within it
is four times that once converted to RGBA for the Eyedropper or a recolour,
which the web build can't allocate. The size is now read from the header and
held to the allowance the importers and the renderer use.
2026-10-14 08:47:10 +07:00
bflatastic ea30e411e7 Fix #1725: a control request its caller timed out on is withdrawn, not run later
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").
2026-10-14 08:47:10 +07:00
bflatastic 355bb5c4f6 Fix #1697: a failed command.batch restores each document whole
The rollback undid the batch's interaction, which holds the art, the selection
and panel state only: a Save As step's new file, format and saved state stayed,
and an Undo step (which ends the interaction) left the art and the history
undone. The batch now keeps the documents as they were and puts them back,
and settles a drag or typing in progress first, as Undo does, instead of
running inside it and keeping its baseline as the batch's step. Files the
steps wrote stay written.
2026-10-14 08:47:10 +07:00
bflatastic 7aa00b41da Fix #1718: ids at their largest value in a file no longer exhaust the counters
A native file (or a pasted document) whose node, slice or asset ids or whose
next-id counter sit at u64::MAX made the next allocation overflow: a panic
with overflow checks, a wrapped counter handing out ids already in use
without. fix_next_id now leaves ids and counters from 2^62 up out of the
count, so new ids start under them; alloc_id saturates. Artboard and graphic
style ids take the smallest free id when the largest is u32::MAX instead of
wrapping to the reserved 0.
2026-10-14 08:47:10 +07:00
BFlat f3a3224745 Merge pull request #1839 from marcoarnulfo/fix/transform-panel-anchors
Transform panel: X/Y/W/H edit the anchors selected with Direct Selection
2026-10-14 08:38:19 +07:00
BFlat e6bf586556 Merge pull request #1840 from mjohnson7cd/fix/1816-snap-to-grid
fix(snap): snap Direct Selection anchor drags to grid intersections (#1816)
2026-10-14 08:38:03 +07:00
BFlat 263d2f23c8 Merge pull request #1850 from dotCooCoo/chore/docs-perf-and-gaps-facts
Docs: G15 and the parity doc cite budget runs and slowness reports since 2026-10-11
2026-10-14 08:37:41 +07:00
bflatastic 61ef472e71 object.setBounds: one helper for the asked width and height 2026-10-14 08:17:14 +07:00
Marco Arnulfo 4ef0cb76e6 Transform panel: X/Y/W/H edit the anchors selected with Direct Selection (fixes #1824) 2026-10-14 08:16:26 +07:00
Mara Johnson 891a58eff8 fix(snap): snap Direct Selection anchor drags to grid intersections (#1816) 2026-10-14 08:16:24 +07:00
dotCooCoo 318e6b07b7 Docs: G15 and the parity doc cite budget runs and slowness reports since 2026-10-11
The "Performance unverified" bullet in docs/target-app-parity.md said
that the budgets had not been run on an idle machine since 2026-10-01,
that the last loaded run missed the 16 ms frame budget at 50k paths,
and that no user had reported slowness in mainstream work beyond #575
and #758. On 2026-10-11 #1155 recorded idle-machine runs, made before
#1173 merged, and runs of #1173's change met every budget at 50k paths
(load average 4 to 7) and at 25k paths. #1097 (zoom and pan in 0.9.0)
and #1731 (a drag that stutters as it starts) are open. G15 in
docs/gaps.md called the 25k-path run the last one, but on 2026-10-13 a
comment on #1172 reported runs of 0.10.0 on Linux with 4 logical CPUs
that missed all three render budgets at 20k paths.

The bullet now gives the 25k-path run and the runs in #1172, and lists
#1097 and #1731 with #575 and #758 as open user reports of slowness.
G15 no longer calls the 25k-path run the last one and adds the runs in
#1172.
2026-10-14 08:16:23 +07:00
BFlat ba5447bbd9 Merge pull request #1855 from storytold/fix/1800-mac-save-sheet
Fix #1800: macOS Save As shows its sheet again
2026-10-14 08:12:38 +07:00
BFlat c3a830bc38 Merge pull request #1857 from storytold/fix/1747-prefs-on-ok
Fix #1747: Preferences are written when confirmed, not only at exit
2026-10-14 08:12:29 +07:00
BFlat b56400b5f9 Merge pull request #1856 from storytold/fix/1719-redo-interaction
Fix #1719: Redo keeps a drag in progress as a step, as Undo does
2026-10-14 08:12:19 +07:00
bflatastic 494ce39de5 Fix #1747: Preferences are written when confirmed, not only at exit
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.
2026-10-14 08:11:06 +07:00
bflatastic f97d57f859 Fix #1719: Redo keeps a drag in progress as a step, as Undo does
Redo swapped the document and the history under a live interaction, whose
snapshot was still the document from before: the next preview or a cancel
brought that one back while the history recorded the redo, so the redone edit
was lost. Redo now settles the interaction first, the way Undo already did: a
drag that changed something is kept as the newest step (which ends the steps
to redo), one that changed nothing is dropped.
2026-10-14 08:11:02 +07:00
bflatastic a60f7e1858 Fix #1800: macOS Save As shows its sheet again
The Format menu added to the save sheet after rfd began it (#866) made recent
macOS versions (26.6.2 and 27.0.1 reported) dismiss the sheet at once: Save As,
Save a Copy and Save of an untitled document flashed and answered as cancelled,
while panels without it (Open, Export As) worked. The accessory is withdrawn
until it can be set before the sheet is presented; the format still follows
the extension typed in the name field, as before #866.
2026-10-14 08:10:58 +07:00
BFlat 8fd0612069 Merge pull request #1836 from Muratv07/feature/marquee-select-guides
feat: marquee selection selects unlocked ruler guides
2026-10-14 08:10:45 +07:00
BFlat 3f5838843d Merge pull request #1833 from switch87/fix/1738-symbol-text-bounds
Native reopen: type in symbols gets its layout bounds back (#1738)
2026-10-14 08:10:33 +07:00
BFlat 1d62d75150 Merge pull request #1830 from switch87/fix/1735-mask-global-swatch
Global swatch edits reach opacity-mask art (#1735)
2026-10-14 08:10:15 +07:00
BFlat 7e3fc2d021 Merge pull request #1834 from saadkhantareen/fix/1703-svg-selector-backtracking
fix(svg): memoize descendant selector matching to stop combinatorial backtracking (#1703)
2026-10-14 08:09:53 +07:00
BFlat b45ceb9427 Merge pull request #1851 from storytold/docs/image-trace-1014
Docs: Image Trace Shapes rework, stroke caps, enhanced presets, gradients over noise
2026-10-14 08:02:09 +07:00
bflatastic ed96b2ff65 Marquee guide selection: one shared helper for both selection tools 2026-10-14 08:01:50 +07:00
Gert Pellin e54fe9c31e Native reopen: type in symbols gets its layout bounds back (#1738)
Type's layout bounds are a cache that isn't saved. On open they were
computed again only for type in the layers, so type in a symbol definition
(or a pattern tile, graph design or opacity mask) kept the rough estimate,
and an envelope warping it was fitted to a different box: warped type in a
symbol changed shape after a save and reopen. The refresh now goes through
every art tree, masks included.
2026-10-14 08:01:50 +07:00
Gert Pellin 904414aa7d Global swatch edits reach opacity-mask art (#1735)
A mask's art lives outside the layer tree (in the masked object's extras),
and the walks over linked colours skipped it: editing a global swatch
recoloured everything but the mask, which kept showing (or hiding) as
before, and a swatch used only in a mask counted as unused. The colour
walks now go into opacity masks: map_solid_paints (swatch edits, renames,
deletes, Merge and the like) and visit_paints (unused swatches).
2026-10-14 08:01:50 +07:00
Saad Abdullah ad165a5a00 fix(svg): memoize descendant selector matching to stop combinatorial backtracking (#1703) 2026-10-14 08:01:50 +07:00
Murat Vural 8796aa9d85 feat: marquee selection selects unlocked ruler guides 2026-10-14 08:01:50 +07:00
BFlat 225f3d7b0c Merge pull request #1751 from AyberkA0/feat/toolbar-drawer-groups
Fix #1736: toolbar without group labels, and an All Tools drawer with flyout groups, shortcuts, menu and Show section
2026-10-14 07:58:09 +07:00
BFlat 0ae6c288ea Merge pull request #1853 from storytold/fix/1629-actions-selection
Fix #1629: an action clicked in the Actions panel stays selected, so Play and Delete act on it
2026-10-14 07:57:26 +07:00
BFlat b25c106fbf Merge pull request #1852 from storytold/fix/deep-nesting
Importers: nesting is capped, so a deeply nested file can't overflow the stack
2026-10-14 07:57:01 +07:00
bflatastic 22118a3e8e Edit Toolbar: the drawer's groups have a named type (clippy's type-complexity) 2026-10-14 07:37:54 +07:00
Ayberk A. 8894da68d7 Part of #1736: one toolbar column runs on without group labels too
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.
2026-10-14 07:37:54 +07:00
Ayberk A. cdd656bd48 Part of #1736: two toolbar columns run on without group labels, and the drawer stays under the title bar
- 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.
2026-10-14 07:37:54 +07:00
Ayberk A. 03c0b8f355 Part of #1736: the toolbar without group labels, and the All Tools drawer's groups, flyout menu and Show section
- 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).
2026-10-14 07:37:54 +07:00
bflatastic 0934f97627 Fix #1629: an action clicked in the Actions panel stays selected, so Play and Delete act on it 2026-10-14 07:37:53 +07:00
bflatastic c10da25ce4 Importers: nesting is capped, so a deeply nested file can't overflow the stack 2026-10-14 07:37:52 +07:00
bflatastic 9c91c36e7e Docs: Image Trace Shapes rework, stroke caps, enhanced presets and gradients over noise (#1845 to #1848) 2026-10-14 07:19:49 +07:00
BFlat 8ab574b7de Merge pull request #1848 from storytold/u/trace-gradients2
Image Trace: gradients grown over noise and soft rims
2026-10-14 07:18:39 +07:00
bflatastic e0ba6e77d1 Image Trace: gradients grown over noise and soft rims
Gradients (off unless asked for) found a blurred or noisy linear gradient in
part or in pieces, with bands around it.

The areas that may be a gradient are tried largest first, and one that is a
gradient is grown over every pixel next to it whose colour is within 10 levels
of the gradient's there: the pixels noise put a little off, a soft rim, the
pieces noise cut off it.

Linear-gradient inputs with Gradients on, paths beside the gradient, before ->
after: blurred 3.0 -> 0.5 (6 Colors) and 55.5 -> 0.5 (High Fidelity Photo);
noisy 11.0 -> 0.5 and 23.5 -> 1.5; scanned 5.5 -> 3.0 and 46.5 -> 37.0; clean
and aliased as before; dE within 0.02. No gradient on any input that is flat
colour, with any preset (the harness fails if there is one).
2026-10-14 07:14:07 +07:00
BFlat 9c289db91d Merge pull request #1847 from storytold/u/trace-enhanced
Image Trace: enhanced versions of the presets
2026-10-14 07:08:27 +07:00
BFlat b1a5b79d67 Merge pull request #1846 from storytold/u/trace-caps
Image Trace: stroked lines get square caps where their ink is cut square
2026-10-14 07:07:45 +07:00
BFlat 156fbe9912 Merge pull request #1845 from storytold/u/trace-shapes2
Image Trace: Shapes finds rounded rectangles and shapes in aliased, blurred and scanned art
2026-10-14 07:07:15 +07:00
bflatastic 1f4daf519d Image Trace: enhanced versions of the presets
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.
2026-10-14 06:43:57 +07:00
bflatastic 638d55983f Image Trace: stroked lines get square caps where their ink is cut square
Create: Strokes drew every line with round caps: a square-ended line 10 px wide
had its corners 2.94 px outside the stroke.

- A line's ends are square when its ink reaches as far a third of the width to
  either side of its middle as along it (a round end stops short there by a
  seventh of the width); told from lines 3 px wide and more, all the ends of a
  line together. The stroke then has square caps (`TracedPath::square_caps`).
- The last points of a wide line's skeleton can turn towards a corner of its
  end. An end that has left the line the skeleton followed a width back (by a
  quarter of the width, 1 px at least) is put back on it; and an end may be
  pulled back as well as pushed out to where the ink ends.

Outline on the thin-line inputs: largest distance from the art 2.94 -> 0.88 px
(clean 2.94 -> 0.41; aliased 0.88 -> 0.81), mean 0.055 -> 0.050 px, anchors
14 -> 10.
2026-10-14 06:43:57 +07:00
bflatastic c6d9822f26 Image Trace: Shapes finds rounded rectangles and shapes in aliased, blurred and scanned art
- A sharp corner may fall up to 0.75 px short within 3 px of where it should be:
  anti-aliasing and blur take that much off a corner (not on a thin bar, which
  is all corners).
- A rounded rectangle gets the radius that fits its outline best, searched
  around the one its area says, instead of that one alone.
- A rectangle's direction is tried along its longest straight side, the longer
  axis of its area and the pixel grid: a blurred one may have no straight side.
- A regular polygon's sides, corners and size are read from the outline's shape
  (how its distance from the middle goes round, and its area), not from how many
  anchors the fitter gave it.
- An outline without anti-aliasing is known to half a pixel: it gets half as
  much room again.

Plain shapes found with Shapes on, all sizes and variants: Default 57% -> 98%,
6 Colors 62% -> 100%. The harness counts false shapes: none on any input but one
thin line (a rectangle 2 px wide) whose trace is 0.70 px off with or without
Shapes.
2026-10-14 06:43:57 +07:00
BFlat fe83800ed5 Merge pull request #1823 from dotCooCoo/feat/hidden-characters-kept-layout
Type: Show Hidden Characters keeps each text object's marks between frames
2026-10-14 06:15:01 +07:00
BFlat 567f5edaf3 Merge pull request #1819 from dotCooCoo/feat/rotate-view-keeps-old-texture
Canvas: the last frame turns with the view until the frame at the new angle is ready
2026-10-14 06:14:35 +07:00
BFlat 0a6a047fd9 Merge pull request #1817 from dotCooCoo/feat/translucent-type-layout-kept
Render: type with transparency, a blend mode or raster effects keeps its layout between frames
2026-10-14 06:14:20 +07:00
BFlat 534f00dfd3 Merge pull request #1820 from dotCooCoo/feat/font-alias-lookup-memo
Fonts: a missing font's name is looked up once until fonts are added or rescanned
2026-10-14 06:13:59 +07:00