Commit Graph
8281 Commits
Author SHA1 Message Date
BFlat c647c0228d Merge pull request #5650 from storytold/about-credits-column-fixes
About: let every credits column be dragged and refit changed tables
2026-11-04 23:42:50 +07:00
BFlat 83cb464979 Merge pull request #5649 from dotCooCoo/fix/mcp-doc-byte-offset-commands
Docs: the byte-offset rule names only commands that take a range
2026-11-04 23:42:30 +07:00
FredAppsandClaude Opus 5.5 380366d3d2 Let every credits column be dragged, and refit changed tables
The last column was egui's remainder column, which has no drag handle, so
it could only be resized from the edge before it. It is now an ordinary
column with its own handle.

A table keeps its column widths, so switching to a longer name left the
Name column at its old width and clipped the text. The table now goes
back to the opening fit whenever that fit changes: a longer widest cell
or a resized window. Dragged widths are dropped at that point.

fit_widths could overflow the room when one column hit the minimum,
because the other columns did not take up its share. Columns now give
way in proportion to their width above the minimum.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 23:24:56 +07:00
dotCooCoo 40569eb267 Docs: the byte-offset rule names only commands that take a range
The type.size.* commands, type.resetTracking and type.resetHorizontalScale
do not take `id`, `start` or `end`, so they refuse those keys as unknown
parameters. The list in docs/mcp.md now leaves them out.
2026-11-04 23:24:54 +07:00
BFlat a3ce20b88f Merge pull request #5633 from ruchirguitar/feat/5525-select-by-artboards
Select by Artboards: select objects overlapping, inside or outside chosen artboards (#5525, #5548, #5549)
2026-11-04 23:23:04 +07:00
BFlat 4ac625b3e5 Merge pull request #5645 from dotCooCoo/fix/pxr-tile-pointer-table
File formats: Pixar tile pointers into the header or tile table are refused
2026-11-04 23:22:29 +07:00
BFlat 48f91f0650 Merge pull request #5644 from dotCooCoo/fix/linux-dialog-filters-any-case
File dialogs: Open and Place list files with capitalized extensions on Linux
2026-11-04 23:22:01 +07:00
BFlat 17eb727642 Merge pull request #5643 from dotCooCoo/fix/direct-cursor-long-path
Geometry: the nearest point on a long path skips segments whose box is farther than the best found
2026-11-04 23:21:45 +07:00
BFlat f488cffa9e Merge pull request #5640 from dotCooCoo/fix/tcy-settings-reject-bad-values
Type: Tate-chu-yoko Settings refuses a value that is not a length
2026-11-04 23:21:28 +07:00
ruchirguitarandClaude Opus 5.5 f140301aaa Select by Artboards dialog: None keeps hidden rows; translate its strings (#5548)
None now clears only the rows the search shows, as Select All adds only
those, so artboards hidden by the search stay chosen. The count reads
"Chosen: {n} of {total}". The dialog's new strings have rows in all 26
catalogs, written from their meaning with each catalog's own terms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 22:57:59 +07:00
ruchirguitarandClaude Opus 5.5 6e1c1c9377 Select by Artboards: test that a symbol instance is measured by its art (#5525)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 22:57:59 +07:00
ruchirguitarandClaude Opus 5.5 471cf3b81b Select by Artboards dialog: double-click a row to fit its artboard (#5549)
A double-click makes the row's artboard active and fits it in the
window (view.goToArtboard, as the Artboards panel does), keeping the
dialog open and the artboards chosen before it. Parity docs record the
Selection Tools add-on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 22:57:59 +07:00
ruchirguitarandClaude Opus 5.5 3a50b20b95 Select by Artboards dialog: artboard list, search and multi-select (#5548)
Object › Plug-ins › Selection Tools › Select by Artboards… lists each
artboard's number, name and size, filters by name, chooses rows with
click, Shift-click and Cmd/Ctrl-click, and runs addon.select.byArtboards
on OK.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 22:57:57 +07:00
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