Commit Graph
3142 Commits
Author SHA1 Message Date
BFlat e67a9f558a Merge pull request #2082 from fabian-co/feat/swatches-follow-selection
Swatches panel follows the selection's swatch
2026-10-16 04:32:01 +07:00
BFlat a9d72d01b1 Merge pull request #2081 from fabian-co/feat/image-replace
Replace a selected image from the Control bar, with its own aspect ratio
2026-10-16 04:31:45 +07:00
BFlat 81e2c81890 Merge pull request #2080 from fabian-co/feat/recolor-library-swatches
Recolor Artwork: library colours apply as their swatches; import a library
2026-10-16 04:31:30 +07:00
BFlat fe5c78f6a5 Merge pull request #2079 from fabian-co/feat/recolor-shortcuts
Recolor Artwork from the Contextual Task Bar and the Control bar
2026-10-16 04:31:13 +07:00
BFlat 57a3cfab73 Merge pull request #1930 from turtwig/fix/glyphs-preview-zoom
Glyphs panel: zoom buttons resize the preview and the step is kept
2026-10-16 04:30:54 +07:00
BFlat 4dcb0900a6 Merge pull request #2265 from andeecollard/tests/shared-closed-boundaries
Image Trace: regression tests for shared boundaries in Abutting traces
2026-10-16 04:30:35 +07:00
BFlat 80be476b04 Merge pull request #2264 from andeecollard/fix/trace-grayscale-gradients
Image Trace: grayscale gradients use grey stops
2026-10-16 04:30:29 +07:00
BFlat cddc5a6848 Merge pull request #2263 from andeecollard/fix/trace-seam-guard
Image Trace: keep shared corners identical at nearby junctions
2026-10-16 04:30:23 +07:00
BFlat d6f6cb9b5f Merge pull request #2025 from andeecollard/fix/trace-snap-collapsed-loops
Image Trace: preserve thin closed outlines after straightening
2026-10-16 04:30:15 +07:00
BFlat 5aab51bf87 Merge pull request #2012 from andeecollard/fix/trace-small-closed-contours
Image Trace: retain tiny components and holes after fitting
2026-10-16 04:29:57 +07:00
BFlat 3bcce6593a Merge pull request #2144 from dotCooCoo/fix/twisted-walls-depth-order
3D and Materials: twisted walls and bevels are drawn back to front
2026-10-16 04:25:17 +07:00
BFlat 192ca0b8e6 Merge pull request #2180 from dotCooCoo/feat/scribble-separate-variations
Effects: Scribble has a Variation for Path Overlap, Curviness and Spacing, and stores 270° as -90°
2026-10-16 04:25:00 +07:00
BFlat b64c88b4d9 Merge pull request #2154 from dotCooCoo/feat/smart-blur-edge-modes
Effects: Smart Blur's Mode menu has Edge Only and Overlay Edge
2026-10-16 04:24:44 +07:00
BFlat 78c5973609 Merge pull request #1925 from dotCooCoo/feat/clipboard-flavors-off-ui-thread
Clipboard: Copy and Cut make the system clipboard's formats on the background thread
2026-10-16 04:24:28 +07:00
BFlat 99a6c06681 Merge pull request #2032 from dotCooCoo/fix/issue-1876
Artboards: the options icon and the panel menu open Artboard Options
2026-10-16 04:24:10 +07:00
BFlat c42b31f48a Merge pull request #2039 from dotCooCoo/fix/pathfinder-effect-keeps-type
Effects: Effect › Pathfinder uses the glyph outlines of type in the group
2026-10-16 04:23:53 +07:00
BFlat 4f794ea8db Merge pull request #2056 from dotCooCoo/feat/perf-deep-peak-working-set
CLI: perf --deep reports the peak working set on Windows and the peak resident memory on Linux
2026-10-16 04:23:37 +07:00
BFlat cc467d1ef4 Merge pull request #2063 from dotCooCoo/feat/plugin-geometry-follows-registry
Render: objects with plug-in effects follow the plug-ins installed
2026-10-16 04:23:18 +07:00
BFlat bfe6670539 Merge pull request #2064 from dotCooCoo/fix/fit-artboard-active
Artboards: Fit to Artwork Bounds and Fit to Selected Art resize the active artboard
2026-10-16 04:23:01 +07:00
BFlat bf10fd64f6 Merge pull request #2065 from dotCooCoo/feat/auto-size-type-fewer-layouts
Type: Auto Size area type in columns usually lays the columns out twice an edit
2026-10-16 04:22:45 +07:00
BFlat 2346a4acfb Merge pull request #2067 from dotCooCoo/feat/alt-drag-copies-once-more-tools
Part of #1429: Alt-drags of objects and plane widgets in perspective copy the objects once per drag
2026-10-16 04:22:29 +07:00
BFlat 5b9a9b6d6c Merge pull request #2068 from dotCooCoo/fix/active-artboard-outline
Artboards: the canvas outlines the active artboard in black
2026-10-16 04:22:13 +07:00
BFlat 82d9143502 Merge pull request #2087 from dotCooCoo/feat/layers-panel-filter
Layers: the panel filters its rows by object kind, lock and visibility
2026-10-16 04:21:55 +07:00
BFlat cebc4ed93e Merge pull request #2093 from dotCooCoo/feat/presentation-mode-artboard-keys
View: in Presentation Mode, the left and right arrow keys and a click go between artboards
2026-10-16 04:21:32 +07:00
BFlat 29bf7b7e06 Merge pull request #2099 from dotCooCoo/feat/artboard-navigator-list
Status bar: the artboard navigator lists the artboards by number and name
2026-10-16 04:21:15 +07:00
BFlat e965c0daa2 Merge pull request #2102 from dotCooCoo/feat/properties-artboard-name-options
Properties: Edit Artboards renames the active artboard and opens Artboard Options
2026-10-16 04:21:00 +07:00
BFlat aaeb658292 Merge pull request #2106 from dotCooCoo/feat/rotate-view-menu
View: Rotate View turns the view to a preset angle, and `view.rotate` sets any angle
2026-10-16 04:20:42 +07:00
BFlat d541eb9476 Merge pull request #2116 from dotCooCoo/feat/export-screens-selected-artboards
Export for Screens: the dialog opens with the Artboard tool's selected artboards checked
2026-10-16 04:20:26 +07:00
BFlat cf0be249ba Merge pull request #2134 from dotCooCoo/feat/free-distort-dialog-corners
Effects: Free Distort's corners are dragged in its dialog
2026-10-16 04:20:09 +07:00
BFlat 0594f04e30 Merge pull request #2136 from dotCooCoo/feat/color-panel-options-command
Color panel: Hide Options comes back after a restart, and `ui.colorPanel` sets the mode and options
2026-10-16 04:19:47 +07:00
BFlat b15c28b7c0 Merge pull request #2138 from dotCooCoo/fix/glowing-edges-raster-stylize
Effect menu: Glowing Edges moves to a Stylize submenu under Raster Effects
2026-10-16 04:19:23 +07:00
BFlat fc51d66659 Merge pull request #2140 from dotCooCoo/feat/save-template-ait
Templates: Save as Template can also write a PDF-compatible .ait
2026-10-16 04:19:04 +07:00
Fabian GrajalesandClaude Opus 5.5 91e1434cbf Swatches panel follows the selection's swatch
Selecting art scrolls the tiles to its swatch once (centred) and clears the
panel's own selection, so the art's swatch is the one highlighted; so does a
change of the selection's paint (after Recolor Artwork). An unlinked process
colour highlights the swatch of that very colour. A selected image, or text
in a colour no swatch has, highlights nothing (not None).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:08:08 +07:00
Fabian GrajalesandClaude Opus 5.5 5a43337a42 Replace a selected image from the Control bar, with its own aspect ratio
The Control bar's file name is a menu: Replace…, Go To Link, Edit Original,
Update Link and Placement Options…. Replace… (also in the Properties panel,
in place of Relink…) puts the picked file in the image's place fitted inside
the old bounds and centred, keeping the new file's aspect ratio instead of
stretching it into the old one. links.relink takes `preserve` (transforms,
bounds, fileDimensions, fit or fill) to override the Placement Options for
that read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:08:06 +07:00
Fabian GrajalesandClaude Opus 5.5 5252c3d86a Recolor Artwork: library colours apply as their swatches; import a library
With Limit to Library, a row's new colour is the library swatch itself: art
links to a global or spot colour (a Pantone-style spot colour stays a spot
colour in its own model, tints keep their tint) and a process swatch gives
its colour in its own model, instead of being converted to the model of the
colour it replaces. The swatches used join the document's swatches (one the
document already has, same name and colour, is reused); recolor.apply
reports them as `swatches`. A folder button next to Limit to Library loads a
library file (.ase, .acb, .gpl, .vcswatches or a document's swatches) and
limits to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:08:04 +07:00
Fabian GrajalesandClaude Opus 5.5 1ba448f7f3 Recolor Artwork from the Contextual Task Bar and the Control bar
A palette button opens Recolor Artwork when the selection has colours to
recolour (solid colours, gradient stops or mesh points, inside groups too):
in the Contextual Task Bar, before Lock, and in the Control bar, after the
Graphic Style picker. Art painted with None shows no button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:08:01 +07:00
turtwig 032b7b7be1 Glyphs panel: zoom buttons resize the preview and the step is kept
Zoom Out and Zoom In sit to the right of the font family and style menus. They step the preview cells through 16, 22, 30, 42, 56, 72 and 96 pt; the grid still opens at 30 pt, and the buttons stop at the ends. The step is stored on the UI state and written with the other panel choices in ui.json when the app quits. Zero is the default and is left out of the file, so older preferences stay as they are.
2026-10-16 04:07:59 +07:00
andeecollardandClaude Opus 5.5 8fffa4f6f9 Image Trace: regression tests for shared closed boundaries
Abutting traces must draw each edge between two neighbouring regions once:
the filled paths on either side follow one curve, one of them reversed, and
together cover the image without gaps or overlaps. These tests check that
from the trace output alone, with no renderer: points along each path's
outline must lie within 0.001 px of another path's outline, the paths' areas
must sum to the image's, and every point of a 4 x 4 per-pixel grid must lie
in exactly one path.

The images are drawn in code, hard-edged and anti-aliased, and traced in
Color (Abutting) and Black and White, each at the default settings, Paths and
Corners 0 and 100, Snap Curves To Lines, and Shapes. They cover a closed island
in a background, a ring with and without a core of a third colour, a wavy
two-colour seam, a three-region junction, outlines that leave a junction and
return to it (the 111 / 101 / 110 pattern at 1, 2, 3 and 6 px, and framed),
squares touching at a corner, a one-pixel hole and a one-pixel island (kept at
Noise 1, dropped together with what they leave at Noise 25), separate areas of
one colour, and slanted hatches with one-pixel paper channels. A further test
shows the check finds a 0.01 px shift and stacked (Overlapping) layers.

Two tests are ignored as documented current gaps:
- At Paths 0 and Corners 0, a piece returning to its own junction collapses:
  its region is dropped and its area left uncovered (draft #2205 fixes it).
- With Shapes, a region whose outline runs through a junction becomes an exact
  shape its neighbour does not share (up to 0.0039 px in Black and White).

No tracer code changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tBcdwNhptqtmX32JCGFzB
2026-10-16 04:07:57 +07:00
andeecollardandClaude Opus 5.5 dbcd32d21a Image Trace: grayscale gradients use grey stops
In Grayscale mode with Gradients on, the trace could fill paths with
coloured linear gradients (for example a blue-to-orange ramp) beside
grey flat fills. Gradient detection ran on the RGB image, so the stops
and the gradient's palette colour (its middle) were the source colours,
while Grayscale's flat fills come from each pixel's luma.

Grayscale now finds gradients, and settles their edges, in a copy of the
image reduced to the same Rec. 601 luma the flat grays are quantised
from. Every channel of that copy is equal, so the fitted stops, the ends
carried to the area's edges and the palette entry are all grey. Color
mode is unchanged: it still detects on the RGB image (trace output for
gradient fixtures is byte-identical before and after).

Adds grayscale_gradients_are_grey: a code-drawn sky ramp over flat
shapes with a ramp rectangle, traced in Grayscale with 4 grays and
Gradients on, must still produce a gradient, and every path colour,
gradient stop and palette entry must be grey.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tBcdwNhptqtmX32JCGFzB
2026-10-16 04:07:55 +07:00
andeecollardandClaude Opus 5.5 5d8b5ddc6c Image Trace: keep shared corners identical at nearby junctions
When a long horizontal or vertical run crosses a three-colour junction one
or two pixels before a corner, the corner correction for that run borrowed
a neighbouring crack's shift that the region on the other side of the
junction never applied, leaving hairline gaps between abutting colours.
The correction now applies only when all three cracks it uses lie in the
same shared piece.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tBcdwNhptqtmX32JCGFzB
2026-10-16 04:07:53 +07:00
andeecollardandClaude Opus 5.5 75b91e9ef3 Docs: leave the status lines to main
The 'Last updated · Change' status lines in docs/roadmap.md, docs/target-app-parity.md and docs/image-trace-quality.md change with almost every merge to main, so this PR's edits to them conflicted each time main moved. They are reverted to main's text; this PR's evidence bullets, history rows and table entries stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tBcdwNhptqtmX32JCGFzB
2026-10-16 04:07:51 +07:00
andeecollard 4714567240 M12: retain the interior of collapsed closed trace outlines 2026-10-16 04:07:50 +07:00
andeecollardandClaude Opus 5.5 477ff16357 Docs: leave the status lines to main
The 'Last updated · Change' status lines in docs/roadmap.md, docs/target-app-parity.md and docs/image-trace-quality.md change with almost every merge to main, so this PR's edits to them conflicted each time main moved. They are reverted to main's text; this PR's evidence bullets, history rows and table entries stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018tBcdwNhptqtmX32JCGFzB
2026-10-16 04:07:45 +07:00
andeecollard c7aac7c250 M12: preserve tiny traced components and holes 2026-10-16 04:07:45 +07:00
bflatastic fd8cd62d17 i18n(bg): rows for the Layers panel filters and Color Panel Options 2026-10-16 04:04:51 +07:00
dotCooCoo 04ed30a23d Effects: Scribble has a Variation for Path Overlap, Curviness and Spacing, and stores 270° as -90°
The reference app's Scribble Options have a Variation for each of Path
Overlap, Curviness and Spacing. Scribble had one `variation`, which
moved each line's ends both along the line and across it, and every
turn of a scribble took the same curviness. An angle such as 270 was
stored as given.

Scribble now takes `overlapVariation` (pt, default 0.5), which moves
the ends along the line, `spacingVariation` (pt, 0.5), which moves
them across it, and `curvinessVariation` (%, 0), which varies the
curviness from one turn to the next. The dialog shows each Variation
after the option it varies, and the Appearance panel lists all three.
A Scribble saved or scripted with the earlier `variation` reads it as
the Path Overlap and Spacing variations. With the defaults, and with
the earlier `variation`, Scribble draws the same outline as before.
`effect.apply` and `effect.setParams` store an angle above -180 and up
to 180, so 270 is stored as -90, and the dialog shows the stored value.

The Appearance panel's inline editor lists an effect's values in
their current form, as the dialog does. It listed an earlier key next
to the defaults of the keys that replace it.

Docs: docs/effects-parity.md (Stylize row), docs/target-app-parity.md.
2026-10-16 04:04:51 +07:00
dotCooCoo 6f9ee7825b Effects: Smart Blur's Mode menu has Edge Only and Overlay Edge
Effect › Blur › Smart Blur had only its Normal mode: the dialog and
blur.smart took Radius, Threshold and Quality and drew the blur.

Smart Blur now takes a `blurMode` param ("normal", "edgeOnly" or
"overlayEdge"; "normal" by default), which its dialog shows as a Mode
menu. Edge Only draws the edges in white on black, and Overlay Edge
draws them in white over the Normal blur. A pixel is on an edge when
one of its four nearest pixels differs from it by more than the
threshold in a channel and its channels, alpha included, add up to at
least that pixel's. The white and the black keep each pixel's
coverage. Normal draws the same pixels as before, and an effect saved
without `blurMode` draws as Normal.

Docs: docs/effects-parity.md, docs/gaps.md, docs/target-app-parity.md.
2026-10-16 04:04:51 +07:00
dotCooCoo 580aa8daa5 Clipboard: Copy and Cut make the system clipboard's formats on the background thread
Copy and Cut made the system clipboard's formats in the frame that ran
them. The formats include the SVG markup and a PNG of the selection at
1 px per pt, up to 4,096 px a side. In a release build on Windows, Copy
of 50,002 rectangles on a 1600 x 1200 pt page took 1.00 s in its frame.

The thread that writes background saves and exports now makes the
formats from a copy of the clipboard, and the app writes them in a
later frame. The same Copy takes 0.18 s in its frame, and the SVG and
PNG are the same bytes. While that thread has a save, an export, a print or
a recovery copy to finish, Copy and Cut make and write the formats at
once. A later Copy or Cut, or text copied in a field or with the Type
tool, drops formats that are not written yet. Until they are written,
Paste on the canvas takes the internal clipboard, and while a text
field or the Type tool has the keyboard the app waits for them.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-16 04:04:51 +07:00
dotCooCoo f14fbded0e Artboards: the options icon and the panel menu open Artboard Options
In the Artboards panel, a click or a double-click on a row's options
icon (the page at the right end of the row) chose the Artboard tool on
that row's artboard and opened no dialog. The panel menu's Artboard
Options… also only chose the Artboard tool.

A click on the active artboard's icon, or a double-click on another
row's icon, now opens Artboard Options for that row's artboard. The
first click on another row's icon makes its artboard active, as a
click on the row does. The panel menu's Artboard Options… opens the
dialog for the active artboard. Both run tool.options with tool
"artboard", as a double-click on the Artboard tool's button does, and
they no longer choose the Artboard tool. The icon's tooltip is now
Artboard Options, and the old tooltip's row is removed from the 15
catalogs.

Opened with another tool, Artboard Options did not move the art with a
new X or Y. It now moves the art when the Artboard tool's Move Artwork
with Artboard option is on, as it does while that tool is in use.

Docs: docs/target-app-parity.md.
2026-10-16 04:04:51 +07:00
dotCooCoo 446ccb1fd0 3D and Materials: twisted walls and bevels are drawn back to front
At 180° and 360° of twist, Extrude & Bevel and Inflate drew some wall
strips in the wrong order, and a far strip showed through a near one.
Each strip ran the whole length of an outline edge and was sorted by
the depth of its center, while a twisted wall can cross it far from
that center. The caps were sorted the same way.

Twisted walls and bevels are now drawn in pieces about as long as a
wall slice is wide (fewer near the 32,768-facet limit), and twisted
bevel steps turn at most 6° each, as wall slices do. A cap, or
Inflate's flat back, that faces the viewer is drawn after the walls,
and edge-on pieces of a twisted wall keep their own depth. Pieces that
face the viewer are drawn where their strip as a whole faces away, so
a twisted solid seen from behind shows its walls' corners around the
back cap. Untwisted solids give the same facets as on main.

Over 80 twisted squares, the facet seen over a point lay up to 79.7 pt
behind a nearer facet on main and now lies at most 5.0 pt behind.
"Twisted" in 72 pt type, extruded with a 360° twist, takes 12,311
facets instead of 7,622 and 3.1 ms instead of 1.9 ms.

Docs: docs/three-d.md.
2026-10-16 04:04:51 +07:00