Ungroup multiplied each member's opacity by the group's, so a member of a
50% group stayed at 50% after the group was gone, and members that
overlapped showed through each other. Each member now keeps its own
opacity, and the group's opacity is removed with the group.
The reader cut every trailing zero byte off the Zstandard editing data
before decoding it, to drop the padding after the last frame. A frame can
end in a zero byte itself (a raw or RLE block, or a checksum whose last
byte is zero), and cutting it left the frame short, so the file failed to
open with "its Zstandard compression is damaged". The reader now decodes
frame after frame and stops when only zeros are left.
Regions that only the pointer uses were made with Sense::drag() or
Sense::click_and_drag(), which egui makes focusable, so Tab stopped on
each of them and no key acted there. They now sense drags (and clicks
where they use them) without taking the keyboard focus: the custom
title bar's background and the window's resize zones, the band that
moves a dialog, the Tools panel's grip, a flyout's and a floating
strip's tear-off bar, the isolation bar's background, and the rulers
and their origin box. Their pointer behavior is unchanged, and the grip
and tear-off bars keep their screen-reader names.
Each region has a test that tabs through its UI and fails without the
change.
Found while testing crates/doc/src/setup.rs:308-316 (keep_in_range)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
locate_within maps a point outside the outline to the nearest point of the outer edges, so a patch folded past the outline does not take an edge click as an interior one.
A Mesh tool click within the hit tolerance outside a gradient mesh hit the
mesh, but object.mesh.addLine looked for the point inside the outline only
and failed with "point is outside the mesh". The same click on a path's edge
made a 1x1 mesh without the line.
- GradientMesh::locate_within takes a tolerance: a point outside the mesh
within it of the outline gives the nearest point of the edge.
- object.mesh.addLine and object.mesh.create take an optional `tolerance`
(0 by default), and the Mesh tool sends its hit tolerance.
A package status with a note, such as "Packaged 1 file in /out/card (draft) (fonts not copied: Mono)", was translated after a language switch as if the folder ended at its first " (", so German showed "1 Datei in /out/card verpackt (draft) ...". The English status now puts the note before the folder ("Packaged 1 file (fonts not copied: Mono) in /out/card (draft)"), and each catalog's @msgplural row for it reads the folder as the rest of the line after ") in ".
The package status now says "file" or "files", and the catalogs' `@msg`
rows for it still matched only the old "file(s)" text, so a status
written in English stayed in English after a switch to another
language.
- Catalogs take a new `@msgplural` row: the English one|other forms as
the source and the language's plural forms as the translation. The
`{n}` value picks the form, so Czech shows "Zabaleny 3 soubory" for 3
files and "Zabaleno 5 souborů" for 5.
- Every catalog replaces its four package status rows with `@msgplural`
rows. The row for a status with a note finds the note by its opening
parenthesis, so a folder name with spaces stays whole.
- `package_status` builds the status line for the folder and the web
download.
A save in the native, template or .ai formats with separateArtboards writes an
artboard file even when the document has one artboard, so an existing file with
that name now gives the data set the next free suffix too.
The Package status and question, the missing-links note, the Missing Fonts
and Find Linked Files search counts, the modified-links questions, Apply to
All, and the CSS Properties panel's notes no longer use a fixed "(s)" or
plural template. They use the plural rows of each catalog, so "1 linked file
not found" and Czech "Nenalezeny 2 propojené soubory" read correctly.
The searched line is built from two plural phrases, "{n} folder" and
"{n} file", in a "{folders} and {files} searched" frame. Package rows that
joined the note to the folder without a space now keep the space.
When a step can write one file per artboard (Save in the native, template or
.ai formats, or Export in SVG, EPS, the raster formats, DXF, EMF, WMF or .ai)
and the document has more than one artboard, an existing file with one of the
stem's artboard file names now gives the data set the next free -2, -3 suffix,
as the stem's own file does. Names a data set's outputs will take are also
reserved for the later data sets of the same batch.
Destination and Override Save/Export paths reject only the current platform's
path separators, so a folder batch writes `a\b.svg` into the destination
folder on systems where that is one file name.
The naming choice reaches batch_datasets as a field of the run, and the short
Batch entry in docs/mcp.md is back to main's text; the longer Batch section
names datasetFileNaming and when an existing output gets a suffix.
The `-2`, `-3` suffix for a data set output that already exists is now
looked up only when the destination folder and the output path pass the
read and write access checks, so a call cannot learn which files exist in
a folder it may not use.
The lookup uses only extensions of formats the app knows, without path
separators or `..`, and only paths whose parent is the destination folder.
A step whose `format` is unknown keeps its own path instead of being
pointed into the destination folder. A data set or document named `.` or
`..` gets the `Untitled` stem with its three-digit number.
The Batch dialog has a File Name choice for a Data Sets source, starting
with File + Number (`source001`), as well as File + Data Set Name
(`source_Alpha`) and Data Set Name (`Alpha`). `action.batch` takes it as
`datasetFileNaming`; a call without it keeps File + Data Set Name, and a
folder source ignores it. An unknown value is an error.
A data set output whose name already exists in the destination folder
now takes the next free `-2`, `-3` suffix instead of replacing the file,
and a Windows device name under Data Set Name gets a trailing `-`.
File › Open and File › Place read JP2 files and raw JPEG 2000
codestreams (.jpf, .jpx, .jp2, .j2k, .j2c, .jpc) through hayro-jpeg2000,
and store the pixels as PNG. Gray, RGB, CMYK and ICC-tagged images, with
or without alpha, are converted to RGBA. Several codestreams, JPX
composition or layers, other color spaces, inconsistent or oversize
palettes, inconsistent channel definitions, oversize tile grids and
images past the pixel allowance are refused with a message before the
pixels are decoded.
The capture and display resolution boxes size the image: the box that
comes last sets each axis, and an axis without a usable value uses
72 ppi.
IccProfile::to_srgb_into converts a pixel with the cached transform and
no heap allocation.
A menu under each of the five tiles in Pattern Brush Options lists None,
Original and the document's pattern swatches; the corner menus keep the
four automatic corners. A swatch choice copies the swatch's whole art and
its tile frame into the brush, so the brush keeps drawing after the swatch
is deleted, and the menu then shows that art as Original. Side cannot be
None: OK shows "You must choose a side pattern." and keeps the dialog open.
brush.options takes side_tile, outer_corner_tile, inner_corner_tile,
start_tile and end_tile (a pattern name, none, original, the corner auto
ids, or {"pattern": name} for a swatch named like one of those words), and
rejects side_tile "none" and unknown names before editing.