Commit Graph
4955 Commits
Author SHA1 Message Date
skylar taylor-barrick 1b29712515 #2278: test that the Properties flip buttons keep the reference app's names
The Properties panel's flip buttons had been renamed Flip Horizontal and Flip Vertical, which are the Transform panel menu's names. The test lays out the Transform section for a selected rectangle and reads the screen-reader names of its buttons: Flip Along Horizontal Axis and Flip Along Vertical Axis must be there and the old names must not. With the old labels the first is missing.
2026-10-22 13:11:34 -06:00
skylar taylor-barrick d978839468 #1807: test that a zstd block larger than its frame's window is refused
ruzstd 0.9.0 let a block decompress to more than its frame's window allows (RUSTSEC-2026-0344). The test swaps a hand-built Zstandard frame with a 1 KiB window and one 100,000-byte RLE block into an Affinity container entry and checks that reading the entry fails. With ruzstd pinned back to 0.9.0 the block is decompressed and the read succeeds.
2026-10-22 13:11:34 -06:00
skylar taylor-barrick 91e4c936f6 #3533: test that a popover stays open through its anchor click and a panel drag
The Fill/Stroke chip's popover closed on the click that finished a drag between its proxies. The test opens a popover and checks the three outcomes: a click elsewhere closes it, a click on its own anchor that does not toggle it keeps it open, and a click elsewhere during a panel drag keeps it open. Without the fix both of the last two close it.
2026-10-22 13:11:17 -06:00
skylar taylor-barrick beced07ded #2083: test that panel menu rows light up under the pointer
The rows of the panels' menus did not light up under the pointer as the menu bar's items do, because they were drawn with no frame at all. The test hovers a menu_item_name row and checks that a filled rectangle appears behind it, and that none is there at rest. With frame(false) the hovered row stays unfilled.
2026-10-22 13:11:11 -06:00
skylar taylor-barrick f5fc357b64 #1506: test that sliders show their rail filled up to the handle
The theme's widget fill matched the dialog background, so a slider in a dialog showed only its handle. The test draws widgets::slider in all four brightnesses and checks that a rail in the buttons' border colour and an accent fill from the rail's start up to the handle are painted. With a plain egui slider neither is drawn, only two rectangles in the panel's button fill.
2026-10-22 13:11:03 -06:00
skylar taylor-barrick 01975b7938 #1490: test that selected text in value fields is in the strong text colour
Selected text in a value field was drawn in the accent on a selection tinted with the same accent, hard to read in every brightness. The tests focus a panel number field and a dialog text field, select their text and read the colours of the glyphs drawn, in all four brightnesses: all must be the strong text colour. Without strong_selected_text the glyphs come out in the accent.
2026-10-22 13:10:56 -06:00
skylar taylor-barrick 34925229ca #916: test that a spinner field reads as one box in three parts
A number field with a spinner and preset chevron drew as three separate boxes, each joint with two borders. The test lays out a spin field and checks that its three boxes are the row's height and that neighbours overlap by one point so they share a border. Without the overlap (item spacing 0) the boxes touch edge to edge instead.
2026-10-22 13:10:48 -06:00
skylar taylor-barrick 2796790161 #815: test that the toolbar's scroll bar stays a slim line
The toolbar's and the dock icon column's scroll bar widened to 10 points while the pointer was on it, covering the group labels and the tool icons' right edge. The test lays out a scrolling strip, rests the pointer on its bar and measures the widest filled rectangle drawn: at most 4 points. Without the slim scroll style it measures 10 points.
2026-10-22 13:10:42 -06:00
skylar taylor-barrick f8eaa4571f #871: test that the Artboard tool names its active artboard once
With the Artboard tool the active artboard's name was drawn twice: by the canvas, as for every artboard, and by the tool, a little higher. The test draws a frame with two artboards and checks that each name is painted once and that the active artboard's sits where the other's does. It fails without the canvas skipping the tool-labelled artboard (two labels for the active one) and without the tool's label position (8 points to the right and 11 higher than the other name).
2026-10-22 13:10:20 -06:00
skylar taylor-barrick 350a4f408c #480: test that the Add and Delete Anchor Point tool icons are the Pen's icon with a badge
The Add and Delete Anchor Point tools' icons were drawn apart from the Pen tool's, so the three didn't read as one family. The test checks that both tools' icons contain every shape of the Pen tool's icon plus a badge of their own, and that plus and minus differ. With the tool mapping pointing back at the old dc-pen-add and dc-pen-delete icons it fails: the Add tool's icon lacks the Pen's outline.
2026-10-22 13:10:11 -06:00
BFlat 4ee7173f11 Merge pull request #3683 from Silvertree2010/fix/h1324-color-to-hsb-returns-hue-360-for
Wrap to_hsb hue of 360 back to 0 for near-red colours
2026-10-23 01:23:57 +07:00
BFlat 3d9656024e Merge pull request #3682 from Taha-Mahmoodi/fix/dither-stroke-null-swatch
Gradients: paint.setStroke refuses a dithered gradient when "swatch" is null
2026-10-23 01:23:40 +07:00
BFlat 5b0e60f865 Merge pull request #3677 from addibble/perf/svg-import-single-pass
SVG import: read the text once for the prepass's markers, with the data URLs left out
2026-10-23 01:23:21 +07:00
BFlat 03bf93c203 Merge pull request #3681 from dotCooCoo/fix/package-skips-page-parsing-without-fonts
Package: reads placed pages and document previews only for the options that use them
2026-10-23 01:23:02 +07:00
BFlat 165fea7f9b Merge pull request #3667 from MiQ71/fix/3646-display-doc-title
Fix #3646: display PDF document title
2026-10-23 01:22:45 +07:00
NetterSilverandClaude Haiku 5.5 4a29fd4112 Wrap to_hsb hue of 360 back to 0 for near-red colours
Found while testing crates/color/src/lib.rs:142

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-23 01:06:55 +07:00
Taha-Mahmoodi e20c330bd3 Gradients: paint.setStroke refuses a dithered gradient when "swatch" is null
Review follow-up (CodeRabbit): the refusal skipped any request carrying a
`swatch` key, so `"swatch": null` with a dithered gradient got through.
Only a named swatch (a gradient swatch keeps its own dither) is exempt now.
The dither test sends `"swatch": null`; it fails without the change.
2026-10-23 01:01:28 +07:00
Drew DibbleandClaude Opus 5.5 a7ee168efe perf --deep: the embedded-picture import row reports a failed import instead of timing it
One import is checked first and its document kept through the memory reading after the row, so
a failure stops the run with its error rather than being timed as an import (CodeRabbit). The
row's comment now gives the picture's real size, about 2 MB as a PNG.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 01:01:27 +07:00
Drew DibbleandClaude Fable 5.1 5b919c0529 SVG import: read the text once for the prepass's markers, with the data URLs left out
The prepass decided what to look for in the tree by a dozen substring searches over the whole
SVG text (`:not(`, the event attributes, `script`, `transform:` and nine more), and a separate
pass counted the elements' depth before roxmltree. With an embedded picture the text is mostly
its data URL: a 1.35 MB card SVG (a 968 KB PNG) paid about 7 ms of searches and 1 ms of depth
scan per import, on a 64 ms render, and a 54-page PDF export 54 times that.

`depth::prescan` is the one pass: it counts the depth as `xml_too_deep` did (the DOCTYPE entity
count included) and, in the same walk, notes every `data:` attribute value, answering the text
with those values left out, their quotes kept. The prepass and `fx::blends` search that text;
the edits are still made in the source. A data URL can hold no tag, attribute name, selector or
CSS declaration, and everything else, a `style="display:none"` included, is kept, so what is
found is what was found before.

`vectorcraft-cli perf --deep` gains a tracked row, "import SVG, one embedded PNG", beside the
export row it had.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-23 01:01:27 +07:00
dotCooCoo 48792842ec Package: reads placed pages and document previews only for the options that use them
With Copy Links on and Copy Fonts off, File › Package still read every
placed PDF or .ai page to find the fonts of its type, and then dropped
them. With Copy Links on and Relink off, it still read the preview and
the PDF of each placed .vectorcraft document, which only the rewritten
copy uses.

Package now reads the placed pages for their fonts only with Copy Fonts
on, and it reads the preview and the PDF only with Relink on. With Copy
Fonts off, packaging a document that places the 60 pages of a PDF took
about 390 ms in a release build and now takes about 20 ms. The package
it writes is the same.
2026-10-23 01:01:26 +07:00
Mirko Kerezovic 97c173beb9 Handle PDF title edge cases 2026-10-23 01:01:26 +07:00
Mirko Kerezovic d548b4ff74 Fix PDF title display provenance 2026-10-23 01:01:25 +07:00
Mirko Kerezovic 5e9df83dd4 Fix #3646: display PDF document title 2026-10-23 01:01:24 +07:00
BFlat 524ecee6ca Merge pull request #3561 from lehni/feature/emoji-bitmaps
Type: colour emoji fonts with bitmap glyphs draw and export
2026-10-23 00:59:15 +07:00
BFlat 7fd4b33dc5 Merge pull request #3670 from dotCooCoo/fix/batch-revert-keeps-the-view-artboard
Artboards: an action or Batch… that reverts or switches documents keeps the active artboard
2026-10-23 00:46:58 +07:00
bflatastic 26b9cf84ad Type: colour emoji fonts with bitmap glyphs draw and export
Squashed from #3561 onto main.
2026-10-23 00:44:31 +07:00
BFlat 9b2173611f Merge pull request #2975 from nrq6993-a11y/stream/vc-feat3-g12-low-res-proxy-eps
G12: honor Use Low Resolution Proxy for Linked EPS (#394)
2026-10-23 00:37:02 +07:00
BFlat b50fbc08cf Merge pull request #3668 from Taha-Mahmoodi/fix/dither-followups
Gradients: dithered fills sample only what shows; review follow-ups to #3637
2026-10-23 00:23:42 +07:00
dotCooCoo 44c306f142 Artboards: an action or Batch… that reverts or switches documents keeps the active artboard
With the Artboard tool, File › Revert kept the active artboard, but a
command.batch with a file.revert step made artboard 1 the active one.
A batch that switched to another document and back, and the Actions
panel menu's Batch… over a folder whose files it closes or over data
sets with a Revert step, did the same. Each of them starts the tool
afresh and ends in the document it started in, and the app moved the
view to the fresh tool's artboard 1. Only a plain file.revert was
handled, by its command id.

The engine now counts the times switching or closing documents, or
replacing the active one, starts the tool afresh (Session::tool_resets),
and records whether the tool's options were set after that
(Session::tool_set_since_reset). When the count changes during a
command and nothing set the tool's options after it, the app starts
the tool on the active artboard, as it does when a command chooses
another document. When a later step chose the tool's artboards (a
Paste or Cut after the revert), the artboard the tool then has active
becomes the active one.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-23 00:20:54 +07:00
bflatastic 30360a67a0 G12: honor Use Low Resolution Proxy for Linked EPS (#394)
Squashed from #2975 onto main.
2026-10-23 00:14:52 +07:00
BFlat 24fadbd322 Merge pull request #3664 from dotCooCoo/feat/shape-builder-artwork-style-rule
Shape Builder: Pick Color From Artwork takes the look where the drag starts, else where it ends
2026-10-23 00:11:07 +07:00
BFlat 72dce93463 Merge pull request #3662 from nrq6993-a11y/stream/vc-featD-g8-art-style-filter-cap
G8: Regression test for art style filter cap
2026-10-23 00:10:48 +07:00
BFlat 40e40bf8cb Merge pull request #3660 from nrq6993-a11y/stream/vc-issue-3635-linux-maximize
Restore and remember maximized window state
2026-10-23 00:10:28 +07:00
BFlat ab330e4adc Merge pull request #3649 from nrq6993-a11y/stream/vc-feat3-g4-mixed-hyphenation-dialog
G4: Mixed Hyphenation dialog fields
2026-10-23 00:10:09 +07:00
BFlat dc38eb6bee Merge pull request #3648 from nrq6993-a11y/stream/vc-feat1-g4-mixed-paragraph-direction
G4: Mixed paragraph direction leaves direction buttons unselected
2026-10-23 00:09:51 +07:00
Taha-Mahmoodi 6b10b159b9 Gradients: dithered type in PDF keeps its resolution when scaled and stays searchable
Review follow-up (CodeRabbit): a gradient drawn as pixels was sized from its
area in the space it is drawn in, so type scaled 4 times got a quarter of the
raster effects resolution; the image is now sized from the area on the page,
within the same pixel caps. And type whose fill is drawn as art (a dithered
or freeform gradient's image, a pattern) went out as outlines only; its
characters are now also written as invisible text (rendering mode 3), as
unpainted type already is, so they can be selected and searched.
2026-10-23 00:08:53 +07:00
Taha-Mahmoodi 7c9edfaf7f Gradients: an outlined stroke leaves dither behind, and paint.setStroke refuses it
Review follow-up (CodeRabbit): paint.setStroke kept `dither: true` from its
gradient, and a stroke can hold dither anyway (swapped from a fill). Outline
Stroke and appearance expansion copied the stroke's paint into the outline's
fill, which then drew dithered although the stroke never did. The outline's
fill now goes without dither (Paint::stroke_as_fill), and paint.setStroke
refuses a gradient with `dither: true`, as paint.editGradient does.
2026-10-23 00:08:53 +07:00
Taha-Mahmoodi 159e20053c Gradients: a dithered gradient without stops draws nothing, as an undithered one does
Review follow-up (CodeRabbit): a dithered fill skipped set_paint's guard for
a gradient without stops and sampled a transparent grid to draw nothing. It
now takes the same no-fill path.
2026-10-23 00:08:52 +07:00
Taha-Mahmoodi 4062e74ff3 Gradients: a dithered fill samples only the part of its grid the view shows
Review follow-up (CodeRabbit): a large dithered gradient mostly off-screen
sampled its whole grid (up to 4096 x 4096 cells, 64 MiB) to draw a small
visible part, and did it again on each zoom step. The renderer now samples
only the cells the render target can show, a cell more each way for the
bilinear mix, snapped out to 256-cell tiles so a pan within them reuses the
grid. Cells keep their place in the whole grid, so the gradient and its
noise are the same pixels as before (GradientPaint::pixels_within).
2026-10-23 00:08:52 +07:00
dotCooCoo fffc8418d9 Shape Builder: Pick Color From Artwork takes the look where the drag starts, else where it ends
With Pick Color From Artwork, a Shape Builder merge took the look of
the front-most object over the first covered region the drag touched,
and the current fill when the drag touched only areas no object
covers. The reference app's combine page gives the look of the object
where the drag starts, else of the object where it ends, else of the
topmost selected object.

shapeBuilder.merge now follows that rule: the merged shape takes the
appearance, opacity and blending mode of the front-most of the objects
it is given (the selection by default) under the first point, else of
the one under the last point, else of the front-most of those objects.
A drag from a hole across a gray bar into a red square now gives a red
shape, where it gave the bar's look. A click in an area no selected
object covers, such as a hole that gray bars enclose or a triangle
that lines enclose, takes the front-most selected object's look
instead of the current fill. Pick Color From Color Swatches works as
before. The tool already sends the press point first and the release
point last.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-22 23:56:01 +07:00
Cursor Agentandnrq6993-a11y 00f557e02e G8: regression test for art style filter cap
## Summary
Illustrator `%AI9` art styles already stop reading filters after 4096 entries so
hostile styles cannot grow without bound. This adds a regression test that
importing a style with more than `MAX_FILTERS` basic filters finishes with a
bounded effect list, matching the existing hardening behaviour.

## Tests
- `art_styles_ignore_filters_beyond_the_cap` in `crates/eps/src/import/ai/style.rs`

Part of gap G8

Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
2026-10-22 23:56:01 +07:00
Cursor Agentandnrq6993-a11y 0490ca0788 fix(linux): restore and remember maximized window state
## Summary

On Linux, asking winit to maximize before the window is mapped often does
nothing, and egui sometimes omits the maximized viewport flag while the
window manager still has the window maximized. Defer maximize until the
first frames after startup, and read maximized state from winit when
saving geometry for the next launch.

## Tests

cargo test -p vectorcraft window::
cargo clippy -p vectorcraft --all-targets -- -D warnings

Closes storytold/vectorcraft#3635

Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
2026-10-22 23:56:01 +07:00
BFlat 45f6e99eb1 Merge pull request #3647 from dotCooCoo/fix/package-names-a-rejected-path-once
Package: a file the writer refuses is named once in the error
2026-10-22 23:54:23 +07:00
bflatastic 329916c2b8 G4: Mixed Hyphenation dialog fields
Squashed from #3649 onto main.
2026-10-22 23:46:14 +07:00
Cursor Agentandnrq6993-a11y 2f3ccb7b2c G4: mixed paragraph direction leaves direction buttons unselected
## Summary
When the Paragraph panel acts on more than one paragraph whose displayed
direction differs (explicit LTR/RTL or Auto resolved from content), neither
Left-to-Right nor Right-to-Left is highlighted, matching alignment and the
other mixed-value paragraph controls in Adobe Illustrator.

## Tests
- `paragraph_mixed_direction_buttons_show_neither` in `panels/paragraph.rs`

Part of gap G4

Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
2026-10-22 23:45:28 +07:00
BFlat dbf6258eae Merge pull request #3641 from pat26-dotcom/fix/3623-pdf-import-word-gap
Fix #3623: a word gap between two sizes reads as a space in PDF import
2026-10-22 23:41:26 +07:00
dotCooCoo 4a4c8c9d49 Package: a file the writer refuses is named once in the error
File › Package… put the file's path in front of every error its writer
returned. A refusal from the automation write root already names the
path, so the dialog's error and the status bar named the file twice,
for example on Windows for a document named aux:
`<path>: automation path rejected: reserved device names are not
allowed: <path>`.

The dialog now keeps a writer error that already contains the path as
it is, and puts the path in front of one that does not, such as the
desktop's "Access is denied. (os error 5)".
2026-10-22 23:36:57 +07:00
BFlat 6e091a33f5 Merge pull request #3636 from MiQ71/fix-3447-spiral-dialog
Fix Spiral tool click options dialog
2026-10-22 23:27:46 +07:00
Patrick LenzenandClaude Opus 5.5 6903bb7ef8 Fix #3623: a word gap between two sizes reads as a space in PDF import
PDF import measured each gap between two glyphs against the larger of
the line's first glyph size and the next glyph's. A word set beside a
much larger one, apart by positioning and no space glyph (a browser's
margin between two sizes), stayed under a fifth of that em: "≤ 4" at
20 pt and "hours" at 8 pt, 3.4 pt apart, came in as "≤ 4hours".

A gap is now measured against the smaller of the two glyphs beside it.
Lines in one size read their gaps as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 23:14:35 +07:00
BFlat b35a6b1573 Merge pull request #3638 from dotCooCoo/fix/cmd-enter-shortcut-skips-the-tool-enter
Shortcuts: a command on Cmd+Enter or Cmd+Escape runs without the tool's Enter or Escape
2026-10-22 23:11:43 +07:00