Commit Graph
6330 Commits
Author SHA1 Message Date
BFlat 6097cc11a2 Merge pull request #4418 from dotCooCoo/feat/hide-unselected-shortcut
Object: Cmd/Ctrl+Alt+Shift+3 hides every unselected object
2026-10-29 15:40:35 +07:00
dotCooCoo 6d66eaf3dc Object: Cmd/Ctrl+Alt+Shift+3 hides every unselected object
Squashed from #4418 onto main.
2026-10-29 15:16:05 +07:00
BFlat 20c9b363dd Merge pull request #4537 from nevarem/feat/rectangle-constrain-link
Shapes: the Rectangle and Ellipse dialogs link Width and Height
2026-10-29 15:12:34 +07:00
BFlat 1a9c746924 Merge pull request #4535 from dotCooCoo/fix/drop-shadow-additive-darkness
Drop Shadow: apply Darkness in the source color space
2026-10-29 15:12:15 +07:00
BFlat 001143f6d7 Merge pull request #4534 from dotCooCoo/fix/issue-3161
Fix #2249: macOS converts the canvas from sRGB to the display's profile
2026-10-29 15:11:58 +07:00
BFlat 76d78dda12 Merge pull request #4532 from dotCooCoo/fix/issue-3137
Part of #3137: Color Guide takes its base from colors chosen in Color, Swatches and the Color Picker
2026-10-29 15:11:46 +07:00
BFlat 92ac961719 Merge pull request #4530 from Silvertree2010/fix/h3704-hyphenation-exception-break-poin
Map hyphenation exception break points to the original word's chars
2026-10-29 15:11:35 +07:00
BFlat 64e216a7e0 Merge pull request #4525 from dotCooCoo/fix/blob-brush-keeps-shift-axis
Blob Brush: keep the first Shift axis without moving earlier points
2026-10-29 15:11:13 +07:00
BFlat 327aab50cf Merge pull request #4489 from dotCooCoo/fix/swatch-edits-reach-graph-designs
Swatches: global swatch edits also update graph designs and the art of brushes
2026-10-29 15:10:56 +07:00
BFlat 1fa7b896ab Merge pull request #4446 from dotCooCoo/feat/flare-options-alt-reset
Flare: preview options and restore defaults with Alt or Option
2026-10-29 15:10:38 +07:00
nevaremandClaude Opus 5.5 69d684ed36 Shapes: the size dialogs' link applies every change of its state
The link applied its state only when its button was clicked, so turning
it off and on again through `ui.dialog.set` kept the old proportions,
and the next dialog didn't open with the state set that way. A link
turned on at a side of zero also took new proportions on the next frame
once that side was a size again.

The dialog now keeps the link state it last applied and applies any
change from it, however it was made: turned on, the link keeps the
sizes the dialog shows then; turned off, it forgets them; either way
the next dialog opens with the new state. Nothing else recalculates the
proportions, so a link turned on at a side of zero stays unconstrained
until it is turned off and on again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjfPR4a1jPek7r3nyFFNYv
2026-10-29 14:36:42 +07:00
nevaremandClaude Opus 5.5 7d18b4481c Shapes: the Rectangle and Ellipse dialogs link Width and Height
A click with the Rectangle, Rounded Rectangle or Ellipse tool opens a
dialog with Width and Height. It now has a Constrain Width and Height
Proportions link beside the two rows, drawn like the Transform panel's:
while it is on, typing one side sets the other at the proportions the
shape had when the link was turned on. The next of these dialogs opens
with the link as the last one left it.

Width now comes before Height in these dialogs: the fields were listed
by name, so Height came first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjfPR4a1jPek7r3nyFFNYv
2026-10-29 14:36:42 +07:00
dotCooCoo dfa9f883c0 Fix Drop Shadow Darkness in source color space 2026-10-29 14:36:41 +07:00
dotCooCoo f55cbf313c Fix #2249: macOS converts the canvas from sRGB to the display's profile
The window's CAMetalLayer had no color space: wgpu 30.0.1 sets it to
nil for an sRGB surface each time it configures the surface, and Core
Animation does not color-match a layer without one. On a wide-gamut
display #FF0000 showed as the display's own red, (255, 0, 0) in a
capture where Preview shows the same sRGB red as (234, 51, 35).

A paint callback that draws nothing runs after egui configures the
surface and before the frame is presented. It sets sRGB on each
window's Metal layer that has no color space and leaves any other color
space as it is. wgpu's own fix (gfx-rs/wgpu#10286) is in no release yet.

Fixes #3161.
2026-10-29 14:36:37 +07:00
dotCooCoo e31e04e545 Part of #3137: Color Guide takes its base from colors chosen in Color, Swatches and the Color Picker
The Color Guide kept the base color it took when the panel first showed,
and only the base chip changed it. In a new document the current fill is
white, so every harmony and variation was white or gray until the base
chip was clicked with another current color.

A color chosen in the Color panel (spectrum, sliders, fields, chips and
Recent Colors), in the Swatches panel or a swatch library panel, or with
OK in the Color Picker for a fill or stroke now becomes the guide's base
color, and the guide shows its harmonies. A color applied from the guide
itself leaves the base as it is, and so does selecting artwork. The base
chip (Set base color to the current color) still makes the current color
the base. A new base clears the cells selected for Save Colors as
Swatches.

The base moves from egui's temporary memory to UiState::color_guide_base,
which is not saved, so the Color panel, the Swatches panels and the Color
Picker can set it.
2026-10-29 14:36:35 +07:00
NetterSilverandClaude Haiku 5.5 520f390c9c Map hyphenation exception break points to the original word's chars
Found while testing crates/text/src/hyphen.rs:74-90 (parse_exception)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:36:33 +07:00
dotCooCoo c1c07efc95 Blob Brush: keep the first Shift axis without moving earlier points
Squashed from #4525 onto main.
2026-10-29 14:36:32 +07:00
dotCooCoo bb869dd9df Swatches: global swatch edits also update graph designs and the art of brushes
Squashed from #4489 onto main.
2026-10-29 14:36:04 +07:00
dotCooCoo b9f9099d91 Flare: preview options and restore defaults with Alt or Option
Squashed from #4446 onto main.
2026-10-29 14:35:57 +07:00
BFlat f1ab585170 Merge pull request #4531 from dotCooCoo/fix/macos-app-modules
macOS: the app builds and passes clippy again after main.rs was split
2026-10-29 14:32:41 +07:00
dotCooCoo 59711d61f3 macOS: the app builds and passes clippy again after main.rs was split
`cargo build -p vectorcraft` on macOS stops with nine E0433 errors:
app.rs and host_services.rs use `mac_menu`, `mac_window`,
`open_documents`, `gpu`, `mac_save_format`, `mac_tablet` and
`mac_screen_color` without importing them since those items moved out
of main.rs. The two files now import them under the same cfg as the
code that uses them.

`cargo clippy -p vectorcraft --all-targets -- -D warnings` on macOS then
stops at the wildcard import in clipboard.rs's macOS module, which now
names the two items it uses.

Other platforms compile the same code as before.
2026-10-29 14:31:10 +07:00
BFlat 705bf80f10 Merge pull request #4543 from storytold/feat/path-smooth
Path: Object › Path › Smooth with a slider and Auto-Smooth (#4115)
2026-10-29 14:27:38 +07:00
bflatastic efc1501ac9 Path: Object › Path › Smooth smooths the selected paths with a slider and Auto-Smooth (#4115) 2026-10-29 13:51:51 +07:00
BFlat 5769caaa95 Merge pull request #4293 from mockydevs/fix/eps-original-format-save
Support EPS Save and Save As with editable data
2026-10-29 13:49:38 +07:00
BFlat ec354ee173 Merge pull request #4256 from dotCooCoo/fix/canvas-fills-uncovered-area
Canvas: a pan or zoom-out fills the uncovered area with low-resolution art
2026-10-29 13:49:21 +07:00
BFlat f0d2cbf432 Merge pull request #4094 from dotCooCoo/fix/shape-builder-merge-keeps-unused-objects
Shape Builder: a merge replaces only the paths it uses, where they are
2026-10-29 13:49:09 +07:00
BFlat 16368083e8 Merge pull request #3954 from saad-mughal435/fix/pattern-brush-keeps-curves
Pattern Brush: keep the tile's curves on a straight run (#3926)
2026-10-29 13:48:56 +07:00
BFlat 0a9d791e33 Merge pull request #4453 from krosk93/i18n/catalan-localization
i18n: add Catalan (ca) localization
2026-10-29 13:48:33 +07:00
BFlat 2df6ab5b91 Merge pull request #4374 from devius/ka-new-strings
i18n(ka): Georgian for the batch dialog, PDF presets, dimension options and swatch names
2026-10-29 13:48:13 +07:00
BFlat 4f1a1bcad1 Merge pull request #4327 from devius/ka-wording-fixes
i18n(ka): Georgian wording fixes for 10 rows
2026-10-29 13:48:00 +07:00
BFlat 814d85c8db Merge pull request #4320 from JaffarSk24/i18n-ru-catalog-gaps
i18n(ru): 363 rows the Russian catalog was missing
2026-10-29 13:47:43 +07:00
BFlat 865986c629 Merge pull request #4540 from storytold/land/4292
Fix canvas pointer mapping under subpixel dock layouts
2026-10-29 13:47:04 +07:00
BFlat df74fa3f0b Merge pull request #4520 from mockydevs/fix/gpu-start-tests-spawn-race
test(app): keep a child's start from holding the GPU start file's lock
2026-10-29 13:46:29 +07:00
BFlat 28ed176ea0 Merge pull request #4500 from dotCooCoo/fix/document-color-mode-converts-all-art
Document Color Mode: also converts graph designs, graphic styles, opacity masks and brush art
2026-10-29 13:46:16 +07:00
BFlat 74b808475c Merge pull request #4480 from dotCooCoo/fix/portal-save-response-race
Save As: on Linux an older portal's answer to the save dialog is no longer lost
2026-10-29 13:45:57 +07:00
BFlat 8558ce3031 Merge pull request #4478 from dotCooCoo/fix/mcp-remote-tests-load-waits
Tests: the MCP remote-backend tests pass on a loaded machine
2026-10-29 13:45:47 +07:00
BFlat a389fbb116 Merge pull request #4464 from dotCooCoo/fix/shape-builder-source-no-isolation-in-mask-editing
Shaper: Shaper Group edits keep the opacity mask and pattern editing layers isolated
2026-10-29 13:45:29 +07:00
BFlat 3c54a4a1cb Merge pull request #4457 from dotCooCoo/fix/isolate-error-catalog-rows
i18n: Enter Isolation Mode's errors show in the interface language
2026-10-29 13:45:13 +07:00
BFlat 04e6699f04 Merge pull request #4456 from dotCooCoo/feat/live-paint-selection-marquee
Live Paint: a Live Paint Selection marquee selects the faces and edges it touches
2026-10-29 13:44:54 +07:00
BFlat ced45272f8 Merge pull request #4452 from dotCooCoo/fix/culling-tests-bound-work-not-time
Tests: the nested-instance culling tests count the symbol art a frame measures
2026-10-29 13:44:39 +07:00
BFlat ff107f0f96 Merge pull request #4450 from dotCooCoo/fix/load-sensitive-tests
Tests: tests that depend on wall-clock time or font loads pass on a loaded machine
2026-10-29 13:44:24 +07:00
Don Omondi 1196d9a335 fix(eps): import bool_or after main's explicit command imports
Main replaced the glob import of the command helpers in fileio/eps.rs
with an explicit list; the EPS Save path's selectedOnly check uses
bool_or, so it is added to that list.
2026-10-29 13:00:49 +07:00
Don Omondi 88cf3c817c Docs: record EPS Save in status lines and revision histories
CodeRabbit follow-up for #4293. Add 2026-10-26 revision-history rows and
status-line updates for EPS Save and Save As in file-format-parity, gaps
(G9), roadmap and target-app-parity; move the completed EPS Save note in
roadmap's M4 row out of "Left:". Save-back is recorded as done; G9 import
fidelity and Illustrator editing-data writing (#868) are unchanged. Scores
and estimates unchanged. Docs only.
2026-10-29 13:00:48 +07:00
dotCooCoo 95ce4d5cb4 Canvas: a pan or zoom-out fills the uncovered area with low-resolution art
Squashed from #4256 onto main.
2026-10-29 13:00:47 +07:00
Don Omondi c6070f633e Support original-format EPS Save and Save As 2026-10-29 13:00:47 +07:00
bflatastic 828d784c8c Shape Builder: import replace_leaves in buildcmds/shape_builder.rs (#4299 made the imports explicit) 2026-10-29 13:00:46 +07:00
dotCooCoo f30819b7eb Shape Builder: a merge replaces only the paths it uses, where they are
Squashed from #4094 onto main.
2026-10-29 13:00:46 +07:00
Muhammad Saad 18e916ddf5 Pattern Brush: decide straightness from the track, not from samples (#3926 review)
Messhias is right that a sampled check cannot promise a run is straight, and my
own write-up overstated what the grid did: I said the fit was "used only where
it reproduces the real map", which five sample positions cannot establish. A
bend narrower than the sample spacing passes between the samples, and the grid
then approves an affine that is simply wrong.

It is not a theoretical gap. A zigzag of amplitude 4 pt and half-period 20 pt,
turning 11.3 degrees (under CORNER_DEG, so the vertices are not corners and
their tangents blend flat), lands its y = 0 vertices exactly on the five sample
positions. All 25 grid points then agree with the affine to the last digit while
the art between them is thrown 4.000 pt off, against the 0.0613 pt tolerance the
grid believed it was enforcing: 65 times over, measured, not estimated.

`Track::is_straight(s0, s1)` reads the answer off the track instead. A bend in
the span is two segment directions that differ, so no bend can hide in it
whatever its size. It also checks the vertex tangents, because `frame` blends
them across a segment unless the vertex is a corner, so a neighbour outside the
span can bend the tangent inside it: directions alone would call `d, d, e`
straight over the first two segments and be wrong. It fails closed on a closed
track's seam, a non-finite bound and a track with no segments.

`AlongMap::is_linear` covers the other half: Between Guides bends the arc-length
map itself, which no amount of looking at the track would reveal.

The grid stays, demoted to a second opinion that can reject and never admit, and
`affine_fit`'s doc comment now says that rather than claiming to be the gate.

Tests. `a_bend_shorter_than_the_sample_grid_is_still_a_bend` builds the zigzag
above, asserts the sampled check accepts it, measures how far out the approved
affine is, and then asserts the track-based gate refuses it; end to end through
`bend` it asserts the aliased bend is subdivided while a genuinely straight run
of the same span keeps the tile's four anchors. Restoring the sampled gate reds
it with `the aliased bend is subdivided, not affine-mapped: 4 anchors`, so the
old code really did lay a flat tile along a waving track.

`straightness_is_read_off_the_track_not_sampled` covers the predicate directly:
collinear segments and their extrapolation, a 0.2 pt detour, a span around it
and a span before it, the blended-tangent case above, the closed seam and a NaN
bound. Writing it caught a bug in my own guard: `f64::min` discards a NaN rather
than propagating it, so `is_straight(NAN, 10.0)` was reporting straight until
the finiteness check moved ahead of the min/max.
2026-10-29 13:00:45 +07:00
Muhammad Saad 955660bee0 Pattern Brush: make the straight-run route match warp_node exactly (#3926 review)
FredApps noted a real divergence: the affine route kept whatever the tile held
(it only required bounds) while warp_node drops every node kind but paths,
groups, layers and compound paths, and it did not clear `live` on paths. For a
tile of paths and groups the result was the same, so nothing was visibly wrong,
but "this changes the curves and nothing else" was a wider claim than the code
made: a symbol instance arrived untouched on a straight run and vanished on a
bend.

affine_node now mirrors warp_node's walk through `prepared` and applies one
transform at the end: the same kinds are kept and the rest dropped, `live` is
cleared on every path, an empty path or a group left with no children is
dropped, and strokes are scaled by `width_scale` rather than by the transform's
own factor. The two routes now differ in the tile's curves and in nothing else,
which is what the change was always meant to be.

Test: a_straight_run_keeps_the_same_node_kinds_as_a_bend puts a symbol instance
beside a path in one tile and asserts both routes return the same kinds. On the
old code it reds with `left: ["group", "path", "symbol"] right: ["group",
"path"]`.
2026-10-29 13:00:45 +07:00
krosk93 7a79935c10 i18n: add Catalan (ca) localization
Squashed from #4453 onto main.
2026-10-29 13:00:44 +07:00