Commit Graph
8268 Commits
Author SHA1 Message Date
ruchirguitarandClaude Opus 5.5 7e016a0bcc Select by Artboards: select objects overlapping, inside or outside several artboards (#5525)
addon.select.byArtboards {artboards, relation} in a new Selection Tools
add-on. Overlapping is All on Active Artboard's test, now one shared
helper (select::on_artboard); Fully inside is within one artboard, edges
included; Fully outside is on none. Objects are those Select All takes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 22:57:57 +07:00
dotCooCoo aee5671734 File formats: Pixar tile pointers into the header or tile table are refused
A nonzero tile pointer below the end of the tile pointer table made the reader decode header or table bytes as pixels. The table end is now computed with checked arithmetic, and such a pointer is refused as damaged image data.
2026-11-04 22:57:53 +07:00
dotCooCoo a2947df1fa File dialogs: Open and Place list files with capitalized extensions on Linux
GTK and the desktop portal match a filter's *.ext patterns case-sensitively,
so on Linux and the BSDs files such as image.DIB, photo.PNG or art.Svg did not
show under any Open or Place filter, "All readable files" and "All placeable
files" included. On those systems each open and place filter now also lists
every extension with each letter as a [xX] pair, the form the portal's
FileChooser documentation recommends. Save dialogs and the other platforms
keep the plain extensions.
2026-11-04 22:57:50 +07:00
dotCooCoo a07ca35c47 Geometry: the nearest point on a long path skips segments whose box is farther than the best found
PathData::nearest, which the Direct Selection cursor runs to find the
segment under the pointer, projected the pointer onto every segment of
the path.

It now projects the pointer first onto a segment at the anchor nearest
to it, then skips each segment whose control-point box lies farther
away than that distance or the nearest point found so far. Each box is
measured once and the search allocates no memory. The result is the
same, including which of equal distances wins. A segment is never
skipped when the pointer or one of its control points is past 1e100 or
not finite.

Over a segment of an open path of 200,000 anchors, the cursor takes
51 ms instead of 59 ms in a release build (anchor_bench). The progress
line in docs/target-app-parity.md gives the timing.

Tests compare nearest with every segment projected over 400 random
paths, each probed at 30 points on a coarse grid (ties included), and
on open, closed, compound, one-anchor, empty, huge and non-finite
paths.
2026-11-04 22:57:47 +07:00
dotCooCoo 0c3bf975d2 Type: Tate-chu-yoko Settings refuses a value that is not a length
OK in Tate-chu-yoko Settings read an Up/Down or Left/Right that is not a
length as 0 and applied it. It now returns "Up/Down must be a number" or
"Left/Right must be a number" and keeps the dialog open, and a blank
field leaves its value alone.
2026-11-04 22:57:43 +07:00
BFlat 0692609fc4 Merge pull request #5442 from dotCooCoo/feat/glyphs-alternates-for-selection
Glyphs panel: alternates for the current text selection
2026-11-04 22:56:07 +07:00
BFlat 357c3c8130 Merge pull request #5639 from dotCooCoo/feat/ai-editing-data-s2
.ai save: the editing copy keeps transparency, clipping and opacity masks
2026-11-04 22:55:50 +07:00
BFlat f7f5654b9e Merge pull request #5630 from d8abyte-dk/plugins-color-param-guide-locked
Plug-ins: color parameters, and filters that make guides and lock
2026-11-04 22:55:34 +07:00
BFlat a982524fae Merge pull request #5637 from dotCooCoo/fix/place-idle-test-race
Tests: a file placed while idle renders on the test thread
2026-11-04 22:55:19 +07:00
BFlat 66fdd0fb10 Merge pull request #5635 from mockydevs/fix/first-frame-busy-ui-5160
Fix #5160: a slow first frame is waited for, not blamed on the graphics adapter
2026-11-04 22:55:03 +07:00
BFlat 097d963a76 Merge pull request #5634 from dotCooCoo/fix/same-layers-skips-unreachable
Select: All on Same Layers takes the layers of objects that can be selected
2026-11-04 22:54:47 +07:00
BFlat 77450de94b Merge pull request #5631 from dotCooCoo/fix/opentype-caret-position
OpenType: a menu choice at a Type tool caret reaches every character
2026-11-04 22:54:31 +07:00
BFlat 3280c58fde Merge pull request #5628 from dotCooCoo/fix/rtl-kerning-whole-point-widths
Type: right-to-left manual kerning keeps whole-point spacing on both sides
2026-11-04 22:54:15 +07:00
BFlat 2758dbc413 Merge pull request #5629 from dotCooCoo/fix/type-doc-one-tate-chu-yoko-row
Docs: type-parity lists manual tate-chu-yoko once
2026-11-04 22:53:59 +07:00
dotCooCoo 88b5170622 Glyphs panel: alternates for the current text selection
Squashed from #5442 onto main.
2026-11-04 22:29:53 +07:00
dotCooCoo 0990bfb244 .ai save: the editing copy keeps transparency, clipping and opacity masks
The editing copy of the art that a PDF-compatible .ai carries now holds:

- Transparency: `mode opacity isolate knockout shape Xy` (the blending
  mode's number, Knockout Group 0 off, 1 on, 2 neutral), written when it
  changes: in a path's paint after its colors, before a guide, and after
  a group's end followed by `0 0 Xd` and `6 () XW`. A group without
  transparency of its own ends `9 () XW`, and a group's name comes
  before its state block. A layer's transparency follows its art: `Xy`,
  `0 0 Xd`, `7 () XW`, `LB`.
- Clipping groups as `q`, the art, the clipping path or compound path last
  with `h` (or `H`) and `W` before its painting operator, `Q`, as section
  5.6.2 of the version 7 specification shows them
  (http://mercator.elte.hu/~saman/hu/okt/AI7FileFormat.pdf). A clipping
  layer whose clipping object is a path or compound path sets the last
  `Lb` flag and writes its clipping path last.
- Opacity masks as an `AI9_Mask` entry in the object's dictionary: the
  mask's art between `X=` and `X+`, and Clipping, Inverted, Disabled and
  Linked.

Before, clipping groups were written as their art cut to the clipping
path, and transparency and opacity masks were left out. Still left out,
with a warning: the opacity and blending mode of single fills and
strokes, opacity masks on layers (disabled ones too), and opacity masks
nested more than 8 deep. A clipping group or layer whose clipping object
isn't a path or compound path is written as a group of the art cut to
that object, in a layer that doesn't clip, and so are the clipping
groups inside that art. A clipping path's paint that a plain fill and
line can't draw is written as paths inside the clipping, fills under the
art and strokes over it, each side in a group of its own when it has
several, with the clipping path's transparency, lock and hidden state;
the clipping path's opacity mask stays on the clipping path, with a
warning. A clipping group without members is an empty group, and an
empty clipping layer is an empty layer.

Each of these is written in the form VectorCraft's .ai reader reads, and
the tests read the written data back through that reader.

Reading .ai editing data: an `Xy` after a layer's last group or compound
path, followed by the layer's `7 () XW`, is the layer's (a following
`6 () XW` keeps it the group's); groups, compound paths and layers keep
Opacity & Mask Define Knockout Shape.

The `.ai` option `editingData` and docs/file-format-parity.md describe
what the copy now holds.
2026-11-04 22:29:43 +07:00
d8abyte-dkandClaude Opus 5.5 b9594b233c Plug-ins: color parameters, and filters that make guides and lock
A `color` parameter shows a color button that opens the color picker in plug-in
dialogs and the Appearance panel's effect editor; its default and values may be
a color object or a hex string, and the plug-in gets a color object. A filter's
returned objects may set `guide` and `locked`; objects it locked or made guides
are left out of the selection after the run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 22:29:38 +07:00
dotCooCoo 9b8561b225 Tests: a file placed while idle renders on the test thread
a_file_placed_while_idle_follows_its_changes asserts that an idle
document without links asks for no frame. Its app started the real render
worker, and once a frame took over 8 ms the canvas sent the next render to
it. The worker asks for a repaint when it finishes, at a time the test
does not control, so under heavy CPU load the asserted frame could report
a repaint delay of 0 instead of none.

The test now sets canvas.worker_started, as the cursor idle test does, so
every frame renders on the test thread. It also dates the rewritten file
2 s after the original with File::set_times, as the opening tests do,
instead of sleeping 30 ms before the write. Shipped code is unchanged.
2026-11-04 22:29:35 +07:00
Don Omondi 609528220b Fix #5160: a slow first frame is waited for, not blamed on the graphics adapter
Squashed from #5635 onto main.
2026-11-04 22:29:32 +07:00
dotCooCoo 3c80b314e1 Select: All on Same Layers takes the layers of objects that can be selected
Select > Object > All on Same Layers took the layer of every selected
object, including one that select.set had kept while it is hidden or
locked, on a template layer, on a locked artboard, or outside the
isolated group. That object's layer then decided which art was
selected. The command now takes the layers only of the selected
objects that the Select commands could select. When the selection
holds no such object, it clears the selection.
2026-11-04 22:29:22 +07:00
dotCooCoo 83f5b7eead OpenType: a menu choice at a Type tool caret reaches every character
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.
2026-11-04 22:29:18 +07:00
dotCooCoo e0ebc13a2e Type: right-to-left manual kerning keeps whole-point spacing on both sides
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.
2026-11-04 22:29:14 +07:00
dotCooCoo 75ba71618a Docs: type-parity lists manual tate-chu-yoko once
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.
2026-11-04 22:29:11 +07:00
BFlat 6b66f1d75f Merge pull request #5627 from dotCooCoo/fix/plural-message-count-backtrack
i18n: a count in a translated message matches only a number
2026-11-04 22:25:16 +07:00
BFlat d7820bde59 Merge pull request #5626 from dotCooCoo/fix/edit-layer-nested-save
Symbols: saving leaves out a nested editing layer and keeps layers named in file data
2026-11-04 22:24:58 +07:00
BFlat 9602a422df Merge pull request #5625 from dotCooCoo/fix/quick-bounds-nine-slice
Symbols: the quick box of a 9-slice instance holds art its guides move
2026-11-04 22:24:41 +07:00
BFlat 240fc57daf Merge pull request #5623 from mockydevs/fix/export-artboards-5502
Fix #5502: Export As PNG exports the active artboard, not always the first
2026-11-04 22:24:24 +07:00
BFlat 98f0ab78f1 Merge pull request #5621 from dotCooCoo/fix/perceptual-pdf-shading-docs
Gradient: PDF shading notes name linear and radial gradients and DeviceN
2026-11-04 22:24:07 +07:00
BFlat dd1786a42b Merge pull request #5620 from dotCooCoo/fix/upright-vertical-baseline-shift
Type: baseline shift moves an upright glyph across the column in vertical type
2026-11-04 22:23:49 +07:00
BFlat c605283f80 Merge pull request #5619 from dotCooCoo/fix/touch-type-upright-vertical-move
Type: Touch Type moves an upright character in vertical type down and across its column
2026-11-04 22:23:33 +07:00
BFlat 9ab54db91a Merge pull request #5618 from dotCooCoo/fix/perceptual-ink-mix-fallback
Gradient: Perceptual spot ink mixes stay continuous from red to blue
2026-11-04 22:23:17 +07:00
dotCooCoo a574139814 i18n: a count in a translated message matches only a number
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.
2026-11-04 21:59:15 +07:00
dotCooCoo 32456839eb Native format: a saved mask-editing id drops only a top-level layer
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.
2026-11-04 21:59:11 +07:00
dotCooCoo 9992fa0bf6 Symbols: saving leaves out a nested editing layer and keeps layers named in file data
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.
2026-11-04 21:59:11 +07:00
dotCooCoo 9dc172a26d Symbols: the quick box of a 9-slice instance holds art its guides move
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.
2026-11-04 21:59:07 +07:00
Don Omondi ef5a4d967a Fix #5502: Export As PNG exports the active artboard, not always the first
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.
2026-11-04 21:59:04 +07:00
dotCooCoo 204b57e046 Docs: American spelling in the PDF shading notes 2026-11-04 21:58:59 +07:00
dotCooCoo eb03e8943f Gradient: PDF shading notes name linear and radial gradients and DeviceN
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.
2026-11-04 21:58:59 +07:00
dotCooCoo d639508a9a Type: baseline shift moves an upright glyph across the column in vertical type
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.
2026-11-04 21:58:55 +07:00
dotCooCoo a883874a73 Type: Touch Type moves an upright character in vertical type down and across its column
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.
2026-11-04 21:58:52 +07:00
dotCooCoo ebbbf29f1e Gradient: Perceptual spot ink mixes stay continuous from red to blue
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.
2026-11-04 21:58:48 +07:00
BFlat 8890eb9304 Merge pull request #5624 from storytold/fix/font-menu-test-race
Tests: the font menu and idle-socket tests don't fail on a busy machine
2026-11-04 21:56:48 +07:00
BFlat bb0d913d50 Merge pull request #5614 from FractalEncrypt/fix/new-doc-units-per-template
New Document: units belong to the chosen preset, not the whole tab
2026-11-04 21:56:32 +07:00
BFlat ff9c3f585f Merge pull request #5617 from dotCooCoo/fix/angle-rail-set-value
Accessibility: screen readers can set a dialog slider's number
2026-11-04 21:56:14 +07:00
BFlat 6b59723677 Merge pull request #5616 from dotCooCoo/fix/kerning-manual-parentheses
Character: Kerning reads (10+5) with a manual value too
2026-11-04 21:55:58 +07:00
BFlat 55d3588e5c Merge pull request #5615 from dotCooCoo/fix/opening-test-handshake
Tests: the opening queue tests wait on the worker's signal instead of the clock
2026-11-04 21:55:42 +07:00
BFlat 89af74f345 Merge pull request #5613 from mockydevs/fix/huge-font-library-5483
Fix #5483: a large font library no longer keeps the window from opening
2026-11-04 21:55:26 +07:00
bflatastic 292b385a66 Tests: the font menu and idle-socket tests don't fail on a busy machine
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.
2026-11-04 21:46:50 +07:00
FractalEncryptandDevin dc9b2f087f Contributors: credit FractalEncrypt by their GitHub profile name
Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-11-04 21:38:01 +07:00
FractalEncryptandDevin 985ef69cb7 New Document: units belong to the chosen preset, not the whole tab
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>
2026-11-04 21:38:01 +07:00