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).
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.
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.
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.
- 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.
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.
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.
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.
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
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
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
An image in a clipping mask, picked in the Layers panel, shows its
whole frame, but a press on the part the mask hides hit nothing: the
Selection, Direct Selection and Group Selection tools started a marquee
there, which dropped the selection, so the image could be dragged only
by the part that shows.
Such a press now grabs the selection by that art, as a press on its
visible part does: a drag moves the selected object (the image, not its
clip group) and a click keeps it selected. With nothing of it selected
there, or with Shift, a press there starts a marquee as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjfPR4a1jPek7r3nyFFNYv
With ruler guides selected on their own (a click on one), the
Properties panel showed the Document sections, so a guide's position
could be typed only in the Transform panel.
The panel now has a Guides heading and a Transform section with the
Transform panel's guide fields (#1597): X moves the vertical guides and
Y the horizontal ones, together. With art selected too, it shows the
art's sections as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjfPR4a1jPek7r3nyFFNYv
With a layer selected, Object > Hide > Unselected Artwork hid every object
on that layer, since the selected layer was dropped from the objects to
keep. The objects of a selected layer now count as selected.
While Lock Guides is on, a group that held a guide path was hidden whole,
which hid the guide with it. Guide paths now count as selected, so the
command keeps such a group visible and hides its other members one by one.
Found while testing crates/pathops/src/edit.rs:342-364 (smooth_level calls smooth_seam after the fit)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
svg_darkness_uses_rendered_shadow_in_non_srgb_working_space runs itself
again in a child process with --exact and checked only the exit status.
libtest exits 0 when --exact matches no test, so a rename of the test
would have left the parent passing without running the non-sRGB check.
The parent now also requires "1 passed" in the child's output, as
layout_cache_follows_fonts_added_later in crates/tools does.
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
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
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.
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>
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.