At a caret the panel sends text.setRangeStyle with no range, which
styles all of the text, but the check that skips a choice that changes
nothing read only the insertion style. When the characters at the caret
already had the chosen feature and others did not, the choice did
nothing. The check now covers every character of the text at a caret,
so the choice applies, and a choice that changes no character still
adds no undo step.
With System Layout on or Fractional Widths off, each advance is rounded
to whole points, but a right-to-left character with manual kerning
still moved by the unrounded kerning value. The difference between the
two changed the space after the character before it in reading order.
The character now moves by the change the kerning makes to its rounded
advance, so only the space before the next character changes.
The CJK table had an older manual tate-chu-yoko row that still said the
Up/Down and Left/Right settings remain, next to the current row that
lists Tate-chu-yoko Settings as done. The ruby row also said manual
tate-chu-yoko is missing, and a separate row marked ruby as missing.
Remove the older tate-chu-yoko row and the "ruby missing" row, and
leave the ruby row about ruby only.
A plural status message such as "Saved {path} with {n} note: {first}"
matched a path that holds " with " by taking the first split, so for
"/out/art with notes.pdf" the count became "notes.pdf with 1". The
count did not parse, the translation took the plural form and split
the path.
The {n} of a @msgplural template now matches only a number, and the
matcher tries the next split when it does not. {n} in a @msg template
still matches any text, since those name brushes, symbols and presets.
Files saved mid-edit by older versions carry the opacity-mask editing
layer at the top level. An id there that names a sublayer is ignored on
load, so that sublayer and its art are kept.
Leaving opacity-mask or symbol editing now removes the editing layer
wherever it is, so a save or export after Layers moved it into another
layer no longer writes it. An editing id that names anything other than
a layer is left alone.
symbol_edit is no longer read from files: a value in file data is
dropped on load, so the layer it names is kept and saving does not
write the value again.
An object in 9-slice art that crosses a guide and draws symbol art is
placed by the map of the cell its center is in, so it can draw outside
the instance's transformed art box. Bounds measured without placing the
art (the renderer's culling, and placements past the object limit) used
that box alone, so the displaced art could be culled and not drawn.
The fallback now takes in the art box placed by each of the nine cells'
maps (NineSliceMap::placement_bounds), grown by the art's reach as
before.
File > Export > Export As PNG... opened PNG Options with no artboard
chosen, and a single-image export without one writes the first
artboard, whichever was in use. With no artboard choice given, it now
takes the active artboard, or each artboard the Artboard tool has
selected (one file each). A choice the caller gives is kept.
The PDF writer writes a spot gradient as a Separation or DeviceN shading
only when it is linear or radial; freeform gradients and dithered fills
are written as images in process colors.
- `paint.editGradient`'s method help and the Method paragraph in
docs/mcp.md limit the Perceptual exception to linear and radial
gradients.
- The Linked gradient stops paragraph in docs/mcp.md no longer says the
writer has no DeviceN: a gradient mixing spot inks with other spot,
CMYK or gray inks exports as a DeviceN shading, and only a mix with RGB
or Lab colors is written in process colors, with a warning.
Baseline shift on an upright glyph in vertical type moved it up the column
instead of across it, at any Character Rotation, because the shift was
applied before the glyph was turned upright. The shift is now taken off
before the turn and put back after it, so an upright glyph moves across the
column by the shift as a letter lying on its side does, and still turns
about its shifted pen position.
An upright glyph in vertical type has its frame's up axis along its column, parallel to the
line, so Touch Type split no drag or arrow-key nudge into kerning and baseline shift and sent
no movement. Such a glyph now takes the line's cross axis, right of its column, as the way
baseline shift moves it.
Mixed in display RGB, red and blue darken past blue's lightness and come
back. The weight search for a Perceptual DeviceN shading then found a
red-side weight for stops near the blue stop, and the inks jumped there.
When the display RGB mix's lightness turns back between two stops, the
inks are mixed at each stop's mix position instead.
type_font_menu_lists_every_available_family compared two reads of Type › Font while a test running alongside could add a font in between, so the menu was rebuilt with one more family. It now judges a run in which the font generation held still.
idle_expiry_closes_without_writing_a_line took a connection reset as a failure; on Windows the server's close of an idle connection can reach the client as one.
Choosing units in Preset Details restyled every preset card in the Recent
and Saved tabs, so switching between inches and millimetres rewrote all the
user's templates at once. The pane's options apply to the selected preset
(helpx, "Create and save custom document presets"), so only the chosen card
follows the chosen units now; the others keep the units their document or
preset was made in, and clicking one brings its units back. The built-in
category tabs still show the chosen units (#2078).
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
A dialog slider whose field shows another unit, such as Transform Each's
Move in millimeters, converted the number back to points and held it to
the rail's range, so a set value past the rail that the field holds came
back as the rail's end.
Dialog sliders and the Blob Brush tip preview offered screen readers only
the increment and decrement actions. They now also offer the set-value
action: the last request in a frame sets the number within the slider's
range, rounded to the places its field shows, and a value that is not a
finite number leaves it as it is.
Kerning read one pair of parentheses around its text only while it
showed an automatic value as (12), so typing (10+5) over a manual value
committed nothing. spin_kerning now reads that pair in both states;
the field still shows parentheses only for an automatic value, and
(10+5)*2 is still refused.
The opening tests waited 400 or 500 ms of wall-clock time for files read off
the UI thread, and up to 30 s in loops that polled until the queue emptied.
Under load a read could take longer, and
a_file_that_opens_and_asks_holds_back_the_next_one_ready failed.
wait_read now blocks on each pending file's own result channel and keeps the
result for poll, and open_ready waits and then polls once. The background save
in long_operation_busy_while_a_file_opens_or_a_background_save_runs waits with
background::wait_all, and its job waits on the release channel without a
timeout. Shipped code is unchanged.
On macOS the menu bar is native and is read again only when its state
hash changes. Type > Font now lists the loaded fonts until the installed
ones are scanned, so the hash takes the font generation and whether the
scan has ended. The tests that wait for process-wide generations to
hold still wait for the fonts too.
The menu bar builds Type > Font in every frame, the first included, and
its family list waited for the scan of every installed font. When that
scan took longer than the 20 s first-frame watchdog (thousands of fonts
on a slow disk, or each file checked by antivirus), the app took the
graphics adapter for hung and started again without it, until none was
left and no window ever showed.
The menu now lists the fonts already loaded until the scan ends, then
all of them (FontDb::menu_family_list_now, installed_fonts_ready).
text.tabs.set and text.tabs.clear return without an edit when every
targeted paragraph already holds the stops. A Ctrl-drag that the 0 pt
bound keeps from moving, or a drag released where it started, no longer
adds an undo step that changes nothing. When one targeted paragraph
holds other stops, the command still sets them all.
appearance.addFill copies the active fill row only when the call has no
`ids`, no `id` and no `target: "contents"`; the params text now names
`id` too. appearance.addStroke gives the new stroke at least 1 pt, so a
0.5 pt top stroke gives a 1 pt stroke; the params text now says so.
Tests pin both: `id` alone leaves the active row alone and puts the new
fill on top, and Add New Stroke on a 0.5 pt stroke adds a 1 pt one.
OK in Shape Builder Tool Options sent highlightColor to tool.setOption,
which keeps only #rrggbb, so #ff000080 was applied as #ff0000 with no
error. OK now gives the same error as the Live Paint tool options for a
hex color with an alpha part (#rrggbbaa or #rgba), the dialog stays open
and the tool's options do not change. The tool.options params text,
docs/mcp.md and the progress doc say so.
A command bound to plain Escape no longer runs when that Escape
cancels a floating Tools panel move or a ruler-origin drag, nor on the
key repeats while Escape stays held. The next separate Escape press
runs it as before. A test binds Select None to Escape and holds Escape
through both cancels.
File > Package stored its status line in the interface language, so after
a language switch the status bar kept the old language, and the control
channel and MCP read a translated message. The status line and its notes
are now English, and only the "Package created" dialog is translated when
it is shown. Each catalog gets message rows for the notes, so the status
bar translates them too. On the desktop, where the dialog names every font
left out, a long font list is cut short in the status line so the line
stays short enough to translate.