Commit Graph
6398 Commits
Author SHA1 Message Date
dotCooCoo 6f7a6b3e67 Docs: clarify initial Space sizing and record Flare history 2026-10-29 20:48:00 +07:00
dotCooCoo c479d2eeaf Flare: rotate rays by drag distance instead of event count 2026-10-29 20:47:57 +07:00
dotCooCoo ec2744f844 Flare: the rays turn a step for each drag update up or down, and Shift holds the turn
While the center was dragged out, the rays pointed at the pointer, as a
polygon's first corner does, and Shift put them back in their original
orientation. In the reference app they turn by a step for each update
of the drag as the pointer moves up or down, and Shift stops the turn
where it is.

Each update of the center drag in which the pointer's document y grows
now adds 0.1 radian (about 5.73°) to the rays' turn, one in which it
falls takes 0.1 radian away, and one at the same y leaves the turn as
it is. Shift held keeps the turn, and turning goes on from there once
Shift is let go. Space held moves the flare without turning the rays.
General › Constrain Angle no longer sets the turn under Shift.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-29 20:47:53 +07:00
dotCooCoo 997826c400 Flare: a release with Space held moves the flare to the release point
The release that places the rings' end point applied the pointer's last
movement to the end point only, so with Space held the flare changed
shape instead of moving. The release now moves the center by that
movement as well. The progress doc says how Shift and General >
Constrain Angle set the rays' orientation.
2026-10-29 20:47:50 +07:00
dotCooCoo 11d65eb8a8 Flare: the drag turns the rays, Shift keeps their orientation and Space moves the flare
The reference app's Flare tool rotates the rays as the center is dragged
out, Shift constrains them to their original orientation, and Space
held moves the shape being drawn. VectorCraft's Flare tool drew the
rays in one fixed orientation and ignored Shift and Space.

shape.flare takes rotation (degrees, clockwise), which turns the rays
about the center and leaves the halo, the center and the rings as they
are. While the center is dragged out, the rays turn with the pointer,
as a polygon's first corner does, and a drag straight up leaves them
unturned. Shift keeps them unturned, or turned by General › Constrain
Angle as a polygon drawn with Shift is. Space held during the center
drag or the drag that places the rings' end point moves the flare at
its current size, and the drag goes on from there when Space is let
go, as with the shape tools.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-29 20:47:47 +07:00
dotCooCoo 85a0adc5b8 Direct Selection: a further Alt-click adds the path's group, then the next group up
Squashed from #4381 onto main.
2026-10-29 20:47:39 +07:00
bflatastic e446a9a69b i18n: Turkish "Place" is the command (Yerleştir), not the noun (Yer)
The Place dialog's title and button, its undo step and the Libraries panel's Place item read "Yer" (a place, a location). They all name the command, "Yerleştir".
2026-10-29 20:36:15 +07:00
bflatastic 6b293a913b i18n: Turkish "Open" is the verb (Aç); the Arc tool's open arc keeps Açık (#4564)
The Turkish catalog translated the bare "Open" as the adjective (Açık), so the Home screen's Open button and the History panel's first row read "open" rather than "open it". The Arc tool's Type choice, where Open is the adjective, now looks its labels up in a "shape" context (falling back to the plain row in the other languages), and Turkish gives it Açık there.
2026-10-29 20:36:13 +07:00
Ridzzz0Alam 6661f2419b Fix #2033: an EPS whose layers can't be used keeps its layer tree
When the editing data's art is rejected (another page size, art the page
doesn't draw, too many text objects…), the file still comes in as its page,
but now on a layer above the editing data's layers. They come in empty, in
their order, with their names, visibility, lock, print option and sublayers.
The page's layer takes a free name when the file's layers have its Layer 1.
2026-10-29 20:36:11 +07:00
bflatastic 7afba9bde4 Keep the hit for the isolation check 2026-10-29 20:36:10 +07:00
bflatastic 3573d454c3 Fix #4466: a Direct Selection double-click outside isolated art leaves isolation mode
The Selection tool's double-click on nothing (or on art outside the isolated group) leaves isolation mode; Direct Selection's did nothing there. It now does the same.
2026-10-29 20:36:10 +07:00
G.J.R. Timmer 11f19da6dd Web build: show the app icon as the tab and home-screen icon
index.html had no icon link, so browsers requested /favicon.ico and got a 404. Trunk now copies the existing app icon (SVG, 32 px and 256 px PNG) from assets/app-icon into icons/ and index.html links them as icon and apple-touch-icon. No new artwork.
2026-10-29 20:36:09 +07:00
bflatastic 084f4f3240 Text: a line ending at the paragraph's start can't underflow 2026-10-29 20:36:07 +07:00
Taha-Mahmoodi 7511f84d5d Layout: end manual tate-chu-yoko at soft return, and use separator metrics for empty continuation line 2026-10-29 20:36:05 +07:00
Taha-Mahmoodi b6df1ef0b1 Type: handle soft return in no-break runs, event modifiers, trailing breaks, and tabs 2026-10-29 20:36:05 +07:00
Taha-Mahmoodi d89031848c Fix #2754: Shift+Enter inserts a soft return (forced line break)
In typography and Illustrator, Shift+Enter inserts a soft return (forced
line break) rather than ending the paragraph. Text wraps to the next line
without applying paragraph-level spacing (space before/after, first-line
indents), list continuation lines keep their parent item without repeating
markers, and justified text does not stretch lines ending with a soft return.

- Forward active modifier keys for Enter in ui-egui shortcuts so the tool
  detects Shift+Enter.
- Type tool inserts U+2028 (LINE SEPARATOR) on Shift+Enter.
- Text shaping and layout treat U+2028 as an invisible zero-advance control
  character, breaking the line in point and area type.
- Paragraph spacing and list markers apply once per paragraph as intended.
2026-10-29 20:36:05 +07:00
bflatastic 569b1416dc Fix #4565: preview Pencil and Paintbrush strokes at half a pixel at most 2026-10-29 19:58:00 +07:00
bflatastic 1238a2550f docs: the Eyedropper's Alt-click with nothing selected 2026-10-29 19:57:59 +07:00
bflatastic 906e496fbb Keep the existing message 2026-10-29 19:57:59 +07:00
bflatastic bbbc711b6a Fix #4382: the Eyedropper's Alt-click puts what it picked up on the object clicked when nothing is selected
With nothing selected, a click with the Eyedropper picks up an object's attributes and an Alt/Option-click on another object applies them, as the reference app's Eyedropper does. Alt-click only copied from a selected object, and with nothing selected it failed. The session now keeps a copy of what appearance.copyFrom picked up last, and a reversed copy with nothing selected applies it.
2026-10-29 19:57:59 +07:00
bflatastic d3d1e31219 Format 2026-10-29 19:57:58 +07:00
bflatastic a353ad3e7a Fix #4523: a new document's VectorCraft Options start as the last native save used them
Preview, Embed ICC Profiles, Create PDF-Compatible File and the other VectorCraft Options went back to their defaults for every document not saved yet. A native Save or Save As now records the options it used in the preferences (not the artboards it picked, nor Use Compression, which its preference decides), and file.formatOptions offers them for a document not yet saved as a native file. A document saved before keeps its own.
2026-10-29 19:57:57 +07:00
bflatastic 098c147b60 Isolation bar: step up a level without indexing 2026-10-29 19:54:57 +07:00
el-j 6e2e0740b0 Isolation mode: breadcrumbs are clickable to navigate hierarchy levels (#4468) 2026-10-29 19:54:35 +07:00
bflatastic 9534a36416 Fix #4538: New Layer and New Sublayer are refused while an opacity mask is edited
While an opacity mask is edited the Layers panel lists only the mask, so a new layer was added where no row showed it, and only the panel's layer count went up. Both commands are now disabled then, as isolation commands already are (outside_mask_editing).
2026-10-29 19:54:34 +07:00
bflatastic 536a98d17f Tests: give the covering window its sizing pass 2026-10-29 19:54:33 +07:00
bflatastic 8f5d14c7f7 Format 2026-10-29 19:54:33 +07:00
bflatastic 2c1713e90b Fix #4518: a dialog or floating panel over the canvas hides the pointer from it
The document point under the pointer (Object Highlighting, the rulers' marks, the status bar and the Info panel) was taken wherever the pointer was over the canvas's rectangle, even over a dialog, a floating panel or a menu on top of it, so objects under the Print or Export for Screens dialog lit up as the pointer moved over the dialog. It now takes the same check as the tool's hover (the canvas's own layer under the pointer), except during a drag that began on the canvas.
2026-10-29 19:54:33 +07:00
bflatastic 5438ed12d3 Fix #4542: Edit › Color Settings… and Assign Profile… show the Separations Preview panel
The commands opened the panel as an icon column's flyout, but Separations Preview isn't in an icon column, so the dock dropped the request on the next frame and nothing showed. They now show it the way Window › Separations Preview does (in its group, its remembered place, or floating), and leave it showing when it already does.
2026-10-29 19:21:34 +07:00
el-j 752bbb050d Fix #4567: vertically center numbers and text in input fields
In single-line text and numeric inputs across panels and dialogs, egui
0.37 defaulted TextEdit alignment to Align2::LEFT_TOP, placing the text
galley at the very top of the allocated input box (e.g. 1pt top margin,
11pt bottom margin in 26pt rows).

Align single-line TextEdit instances to Align2::LEFT_CENTER across
recessed_text, opt_field_named (dash/gap cells), hex fields, search
fields, and dialog inputs, matching DesignCraft's vertical centering.
Add regression assertions in look_tests verifying balanced vertical
spacing.
2026-10-29 19:21:33 +07:00
dotCooCoo cdf4453051 Libraries: gradients and patterns can be added to a library and applied from it
Squashed from #4442 onto main.
2026-10-29 19:21:33 +07:00
dotCooCoo c9853094d4 Image Trace: Manage Presets saves, renames and deletes custom tracing presets
Squashed from #4071 onto main.
2026-10-29 19:21:32 +07:00
dotCooCoo e492c4298c Blend: a click picks again when the Blend tool's first pick is gone
Squashed from #4447 onto main.
2026-10-29 19:21:32 +07:00
bflatastic c4d23f4af7 i18n: drop two stale Georgian rows the #4169 squash brought back 2026-10-29 19:21:32 +07:00
Taha-Mahmoodi b41599f657 Fix #3089: a stroked line with an effect expands to a stroked line, then Expand outlines it
Squashed from #4169 onto main.
2026-10-29 18:54:59 +07:00
dotCooCoo 3cfdb58b90 Transparency: pattern editing mode and opacity mask editing can't be entered from each other
Squashed from #4458 onto main.
2026-10-29 18:54:45 +07:00
dotCooCoo c8a7420b93 Place: an image whose pixels can't be read is refused instead of placed blank
Squashed from #4257 onto main.
2026-10-29 18:54:38 +07:00
dotCooCoo e764d770db Image Trace: Document Library fills link to the document's global swatches
Squashed from #4396 onto main.
2026-10-29 18:50:56 +07:00
dotCooCoo 3aebccaf06 Zoom tool: Space held while dragging moves the zoom marquee
Squashed from #4372 onto main.
2026-10-29 18:50:45 +07:00
dotCooCoo 74b408e8da Blend: choosing the Blend tool again finishes the blend
Squashed from #4454 onto main.
2026-10-29 18:50:34 +07:00
dotCooCoo 6fd042e4be Tests: the MCP concurrency, folder search and artboard export tests pass on a loaded machine
Squashed from #4473 onto main.
2026-10-29 18:50:24 +07:00
el-j 31a482bade perf(engine): rerun objects_on_path when dimension refresh mutates artwork 2026-10-29 18:46:48 +07:00
el-j 3e70c38d7b perf(engine): gate post-edit Shaper and Text-Wrap maintenance via edited-root diffing (#4554)
- In `shaper::refresh`, replace full document walks with `changed_shaper_groups`,
  diffing `before` and `after` layers and short-circuiting on pointer-equal (`Arc::ptr_eq`)
  subtrees in O(1).
- Return whether Shaper groups rebuilt or modified artwork (`Result<bool>`),
  allowing `Session::edit` to skip the second `cmd::objects_on_path::refresh`
  call when no artwork was modified.
- In `textwrap::refresh`, check pointer equality on layers against `before.layers`,
  skipping untouched layers in O(1) and checking only modified layers.
2026-10-29 18:46:47 +07:00
ham9zah 0cd82d8d7d Import: the page's type of a right-to-left or turned label is its text object's
A file's PDF part draws a right-to-left paragraph's words in the order
they show ("mm 120.5"), while its text object keeps them in the order
they are typed (" 120.5 mm "). The page's type was matched to the text
objects by their letters in order, so it matched none and stayed beside
the label as a second copy. It is now matched word by word.

A point type label turned a quarter (a vertical dimension's) lay outside
the box its text object was looked for in, which was always level; that
box now runs along the type's baseline.
2026-10-29 18:46:47 +07:00
ham9zah 2dcfbb0bf0 Import: a right-to-left paragraph of the editing data lays out right to left
The text document's paragraph key 33 (from the paragraph or the
document's defaults) said a paragraph runs right to left, but the reader
only used it to swap left and right alignment: the paragraph's direction
stayed unset, so it went by its first strong letter, and a label with no
Arabic or Hebrew letters (" 120.5 mm ") laid out left to right instead of
reading "mm 120.5". The paragraph style now gets that direction.
2026-10-29 18:46:47 +07:00
ham9zah 027884b0a4 Import: read one alternative of versioned content, not two
Versioned content can hold three alternatives: newer files write a
Dimension tool group, the same group again after
`%AI17_Alternate_Content_if_version_gt:…` for a version in between, then
plain art after `%AI17_Alternate_Content`. The reader skipped from the
plain `Alternate_Content` marker only, so the middle alternative was read
as art too and those objects came in twice.

The reader now reads the first alternative and skips from the next one,
whatever its marker, to the end of the block, nested blocks included. A
block that doesn't end is read whole with a note instead of failing the
file. The palette reader tracked alternatives with one flag that a block
nested in an alternative reset; it now tracks the depth.
2026-10-29 18:46:47 +07:00
HassanKhan 1c1ca30a11 Fix #4283: a wheel notch zooms at once without Animated Zoom
Squashed from #4313 onto main.
2026-10-29 18:46:47 +07:00
nevaremandClaude Opus 5.5 87fc61df79 Selection: a selected object's masked art is reached the way a click goes
The check of a selected object's masked art looked at its own place
only. A click goes down from the layer (or the isolated container) and
never reaches a Shaper group's original shapes outside Construction
mode, however deep the object lies in them; and below a layer whose
Preview is off it hits art in outline. A press inside such a path's
fill, or on a path in a Shaper group's hidden shapes, started a move.

The way down to the selected object is now checked as a click goes:
a Shaper group's part a click can't reach on it rules the object out,
and a Preview-off layer on it (below the isolated container) makes the
object count by its outline.

Tests also cover Shift with Direct and Group Selection (a marquee) and
an object a click hits over the masked art (it is selected).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjfPR4a1jPek7r3nyFFNYv
2026-10-29 18:46:47 +07:00
nevaremandClaude Opus 5.5 f793547a7f Selection: a selected object's masked art counts only where a click reaches it
The selected object itself was checked for being hidden, locked or a
template, but not as a click checks it: a selected guide path was
grabbed where a mask hid it while guides were locked or hidden, though
a click on it there hits nothing.

The selected object now passes the same test a click applies to it
before its art is tried: guides while guides are locked or hidden, and
a Shaper group's hidden part, don't count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjfPR4a1jPek7r3nyFFNYv
2026-10-29 18:46:47 +07:00
nevaremandClaude Opus 5.5 6ecea97fdb Selection: a selected group's masked art counts only where a click hits
A selected group was grabbed by any of its contents under the pointer
where an outer mask hides them, including a hidden or locked child and
art the group's own clipping mask leaves out: none of these is drawn or
hit by a click.

A container's art now counts as a click would hit it: its contents as
the hit test tries them, through its own mask and without its hidden,
locked or template contents. The check for locked objects shares it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjfPR4a1jPek7r3nyFFNYv
2026-10-29 18:46:47 +07:00