Commit Graph
2159 Commits
Author SHA1 Message Date
ham9zah a141372cd9 Type tool icons: one family, the same T with a frame, wave, arrow or dotted box; the vertical Area and Path tools get their own 2026-11-02 14:36:09 +07:00
ham9zah 93b310c069 Type cursors: the I-beam with a frame or curve badge for area type and type on a path 2026-11-02 14:36:09 +07:00
ham9zah afd9ec036c Type tool: a click on a path's outline makes area type or type on a path, with cursors that say which 2026-11-02 14:36:08 +07:00
Taha-Mahmoodi 1b5d11ef4b Units: Preferences › East Asian Type reads, with Q and Ha units (#394)
Squashed from #4845 onto main.
2026-11-02 14:36:08 +07:00
Don Omondi 15a5e64134 #4919: Create Swatch Legend becomes an add-on under Object › Plug-ins › Color Effects with a dialog
addon.color.swatchLegend replaces swatch.legend. The dialog sets columns, chip size, gap, the values shown
and whether to use only the swatches selected in the Swatches panel, with a preview; duplicate value
kinds are refused. The Swatches panel menu item is removed. Catalog rows in all 26 languages.
2026-11-02 14:36:08 +07:00
Don Omondi c823e7f5b2 Fix #4919: Create Swatch Legend
swatch.legend draws a grid of chips, one per colour swatch (the given
ones, else every one), each filled with and linked to its swatch and
labelled with its name and colour values (HEX, RGB, CMYK, Lab or
Grayscale; by default its own model; spot swatches marked), black on
light chips and white on dark ones, as one selected group in one undo
step. The Swatches panel menu's Create Swatch Legend draws the selected
colour swatches, else every one.
2026-11-02 14:36:07 +07:00
el-j 601ab957e6 perf(canvas): zero-copy texture upload and progressive worker frame acceptance (#4615)
Squashed from #4961 onto main.
2026-11-02 14:36:07 +07:00
dotCooCoo 2fafe25c27 Asset Export: Import Preset and Export Preset read and write preset files
Squashed from #5032 onto main.
2026-11-02 14:33:29 +07:00
bflatastic 57a76f4f8d Paste: translate the two paste messages into Catalan 2026-11-02 14:33:02 +07:00
dotCooCoo b1c98821d6 Clipboard: a bitmap pasted from another app is decoded off the UI thread
Squashed from #4277 onto main.
2026-11-02 14:33:02 +07:00
dotCooCoo e8e09af782 Brushes: Calligraphic and Scatter values follow pen tilt, bearing and rotation
Squashed from #5031 onto main.
2026-11-02 14:33:02 +07:00
dotCooCoo 6d369d013c Toolbars: New Toolbar makes a named toolbar filled from the All Tools drawer
Squashed from #5038 onto main.
2026-11-02 14:33:01 +07:00
dotCooCoo adc3e75be4 Window: Arrange > Tile shows every open document side by side
Window > Arrange > Tile (window.arrange.tile) splits the document area
into one pane per open document, edge to edge, in a grid with as many
columns as the square root of the number of documents, rounded up. Each
document is fitted to its pane, and fitted again when its pane changes
size (a document opened or closed, the window resized) unless it was
zoomed or scrolled since. The current document's pane is the canvas;
the other panes draw their documents with their artboards, guides,
selected objects and Pixel Preview, and a press in one makes its
document the current one, as a click on its tab does. Window > Arrange >
Consolidate All Windows (window.arrange.consolidateAllWindows) goes back
to one document under its tab. It works the same on the desktop and the
web, and the arrangement is not saved.

Tile is enabled with two or more open documents, and Consolidate All
Windows while documents are tiled. ui.inspect reports tiled and the
panes.
2026-11-02 14:33:00 +07:00
dotCooCoo e13cf73ae0 Type: Tate-chu-yoko Settings move a block up, down, left or right
Squashed from #5206 onto main.
2026-11-02 14:32:59 +07:00
dotCooCoo c4dfe6bfc2 Selection: with Real-time Drawing off, the bounding box moves with a move drag
With Preferences › Performance › Real-time Drawing and Editing off, a
Selection tool move drag leaves the object in place until release, and
the bounding box was hidden for the whole drag. The box, with its
handles, now follows the pointer during the drag (Session::deferred_move
gives the offset the document has not taken yet). Scale and rotate
drags, and drags with Real-time Drawing on, hide the box as before.

Docs: docs/target-app-parity.md.
2026-11-02 14:32:58 +07:00
dotCooCoo 5685cc256c Tabs: Above Text keeps the ruler at the zoom when the panel comes out wider
Position Panel Above Text sizes the Tabs panel so its ruler spans the
text at the canvas zoom. A floating panel is at least 220 pt wide, so
for narrow text at a low zoom the panel comes out wider than asked, and
the ruler stretched the text's width across the whole panel. Its marks
then no longer sat over the text.

After Above Text, while the same text in the same document is selected
and the panel floats no wider than the narrowest panel, the ruler now
draws the text at its screen scale and runs on past the text's width.
Any other ruler fits the span to its width as before.
2026-11-02 14:32:58 +07:00
dotCooCoo 2a41c74690 .ai import: a group still open at the end of the art is an error
A group (`u`), clipping group (`q`) or compound path (`*u`) opened after
the last layer and never closed was accepted, and the art inside it was
dropped without a message. The reader now stops with "it ends inside a
group or compound path", as it already does for data that ends inside a
layer. Pattern and symbol definitions, which are read inside a group of
their own, are not affected.
2026-11-02 14:32:56 +07:00
dotCooCoo b9f4ea29f7 Actions: Save Actions… and Load Actions… save a set to a file and load it back
Squashed from #5192 onto main.
2026-11-02 14:32:55 +07:00
dotCooCoo 9c120c735e Keyboard Shortcuts: commands a key cannot run without a value are not listed
Edit > Keyboard Shortcuts listed commands whose params are all optional
but that do nothing or fail when a key runs them with none, such as
Transparency (transparency.set) and Opacity Mask Options
(transparency.setOpacityMask). These are now left out while they have
no shortcut, along with Align and Distribute, Delete Swatch, Move
Swatch, Spot Options, Adjust Color Balance, the library and data set
loaders, stroke.set, layer.setProps and menu queries that no menu item
runs. A key saved for one of them before keeps it listed so it can be
cleared.

A shortcut for a command whose menu bar items all give it the same
params now runs what a click on that item runs, so Clean Up..., Print
Ink Fixes... and Find and Replace... open their dialogs.
2026-11-02 14:32:55 +07:00
dotCooCoo e8cd6c173a Variables: Save Variable Library… writes the variables and data sets as an XML library
Squashed from #5147 onto main.
2026-11-02 14:32:52 +07:00
dotCooCoo 9031906abd Actions: deleting sets moves the selected action with its set
`ui.actionSet.delete` now moves the panel's selected action down with its
set, and clears it when its set is deleted. Before, the stored set and
action indexes stayed as they were, so a set made later at the deleted
set's index, and an action recorded into it, showed as selected, and
Action Options… renamed that action.
2026-11-02 14:32:51 +07:00
dotCooCoo b2c62c398e Actions: the panel menu reads the selected action only in the current set
The panel menu read the stored (set, action) pair without checking that
its set is still the current one, as the panel and Delete Selection do.
After `ui.actionSet.delete` removed a set above it, the pair pointed at
another set's action, and Action Options…, Batch… and Play Current
Selection acted on that action. They are now off until an action of the
current set is selected.
2026-11-02 14:32:51 +07:00
dotCooCoo 0212c2b00e Actions: Action Options and Set Options refuse a field that is not an index
The dialog's fields choose what OK does, as they choose its heading. A
`set` or `action` field that `ui.dialog.set` changed to null or to an
index past the last set or action is now an error: OK renames no set or
action, adds no set, and the dialog stays open. Before, an Action Options
dialog whose `action` was null renamed the set instead.
2026-11-02 14:32:51 +07:00
dotCooCoo 642df312b3 Actions: the panel menu's Action Options… renames the selected action
Action Options… opens the New Set and Set Options dialog, headed Action
Options, with the selected action's name; OK renames the action and keeps
its steps. The new command ui.action.rename {set, action, name} does the
rename and refuses an index past the last set or action or an empty name.

Part of #1629.
2026-11-02 14:32:50 +07:00
dotCooCoo f5da917b37 Actions: the current set is kept after a restart
The Actions panel did not save which set was current, so after a restart
Begin Recording put the new action into the first set (Default Actions)
instead of the set the user had picked. The current set is now saved
with the UI preferences as an index into the saved sets; a value that is
not an index, or is past the last set, leaves no set current.

With no set current, Begin Recording records into the first set as
before, and now makes that set current so the panel shows where the
recording goes.
2026-11-02 14:32:50 +07:00
dotCooCoo 0be7609bf7 Tabs: Above Text checks the place below text against the window's top
The place below the text was taken even when the text was panned above
the canvas, which put the panel above the main window. It is now taken
only when it is at or below the window's top. A docked Tabs panel is
measured at the 360-point height it floats at, not 240, so it is placed
below the text only when it fits there.
2026-11-02 14:32:49 +07:00
dotCooCoo 442430ff12 Tabs: Above Text puts the panel below text near the window's top
With no room above the text, the panel went to the top of the main
window's content and could cover the text. It now goes just below the
text when it fits there in the canvas, and at the window's top only when
it does not.
2026-11-02 14:32:49 +07:00
dotCooCoo 48e2bc6508 Tabs: Above Text keeps the panel's bar inside the window
With text near the top of the window, Position Panel Above Text put the
panel, and its OS window, above the main window's content and could put
the bar above every screen. The panel now goes no higher than the top of
the main window's content.
2026-11-02 14:32:49 +07:00
dotCooCoo d8394d5d87 Fix #4995: Above Text moves a Tabs panel that already floats
Position Panel Above Text moved a floating Tabs panel only in the layout's
in-window rect. On desktop builds a floating panel is an OS window, which
moves only when its desktop rect changes, so the panel stayed where it
was and the layout followed it back on the next frame. A docked panel
floated above the text as expected.

place_floating now also sets the window's desktop rect, from the main
window's content origin, when the panel's window already has one.
2026-11-02 14:32:49 +07:00
Brandon Thomas cfb30d8139 Merge pull request #5214 from dotCooCoo/feat/recolor-global-adjust
Recolor: the Global Adjust sliders change every color at once
2026-11-02 00:34:59 -05:00
Brandon Thomas 6daefef735 Merge pull request #5212 from dotCooCoo/feat/document-info-save-category
Document Info: Save writes the category the panel shows
2026-11-02 00:34:54 -05:00
Brandon Thomas a51391a7c3 Merge pull request #5195 from dotCooCoo/fix/release-moves
Canvas: a drag ends where its button went up
2026-11-02 00:34:37 -05:00
Brandon Thomas 3d59d874ac Merge pull request #5190 from dotCooCoo/fix/separations-gamut-count-plural
Separations Preview: Gamut Check counts colors in the singular and the plural
2026-11-02 00:34:26 -05:00
dotCooCoo ccc7e44078 .ai import: multi-layer masks open as a clipping group in each layer
Squashed from #5117 onto main.
2026-11-02 12:04:26 +07:00
bflatastic f6e262c92e .ai import: translate the note for a graph whose records don't end 2026-11-02 12:04:25 +07:00
dotCooCoo 795cbc060d .ai import: graphs open as their drawn art, with a note
A graph in a legacy .ai, or in a current file's editing data, is written
as `%_Gs`, its data and settings on `%_` lines, its drawn art in a group
with a `%_... Go` tag after each object, and `%_GS`. The reader stopped
on the graph operators as ones it doesn't know, so such a file did not
open through its layers.

The reader now leaves the graph's records out with their operands and
reads the drawn art as usual: the bars, lines and labels come in as the
groups, paths and type they are written as. Paint operators on `%_`
lines between `Gt` and `GT` set nothing. One note per file says the
graphs came in as plain art without their data or settings. A graph
that starts inside another, or doesn't end before its layer does, keeps
the art read so far with a second note. Graph operators outside a graph
stay unknown.
2026-11-02 12:04:24 +07:00
dotCooCoo ab0072a39e Variables: Edit Data Set's Name field renames the data set
Squashed from #5121 onto main.
2026-11-02 12:04:22 +07:00
dotCooCoo 7c1d73d818 Symbols: test the Symbols panel, panel menu and Control bar entries to symbol editing mode
Headless tests cover a double-click on a symbol in Thumbnail View and List View, the panel
menu's Edit Symbol with and without a selected instance, the Control bar's Edit Symbol button,
and the Control bar's Exit Symbol Editing Mode and Exit Isolation Mode buttons inside the
symbol's art. The panel's module comment now says a double-click opens the symbol in symbol
editing mode, and docs/mcp.md lists symbol.edit's ids parameter.
2026-11-02 12:04:18 +07:00
dotCooCoo 10235563ae Character Style Options: the dialog test sets Vertical Scale and checks it on the style and its text 2026-11-02 12:04:17 +07:00
dotCooCoo 94a6917c68 Character Styles: Advanced Character Formats takes scales and baseline shift up to the document limit
Horizontal Scale and Vertical Scale accept any number above 0 and at most 4000000 %, and Baseline Shift accepts -4000000 to 4000000 pt, the limits the document model keeps a character style in. Character Rotation is stored from -180 to 180 degrees, as text.setFormat stores it. A scale outside its limit shows the new message "{label} must be a number above 0 and at most {max}", translated in every catalog that has Basic Character Formats.
2026-11-02 12:04:17 +07:00
dotCooCoo 6e7945773e Character Styles: Style Options sets Advanced Character Formats
Character Style Options and New Character Style get an Advanced
Character Formats section with Horizontal Scale, Vertical Scale,
Baseline Shift, Character Rotation and Language. Empty fields stay
unset, an explicit 100%, 0 degrees or English: USA stays distinct from
unset, and Reset Panel on the section clears only these five. Scales
take 1% to 10000% and baseline shift -1296 pt to 1296 pt, as
text.setRangeStyle does; rotation is stored from -180 to 180 degrees.
Language sets the language the characters are shaped in; hyphenation
and spelling do not change.

A field still as it opened keeps its stored value without the range
check, so a style captured from a scaled type object can be renamed.
The same applies to Basic's Size and Leading minimum.

charStyle.edit keeps a language tag that is not in the list when the
style already has it, so a style read from a file with such a tag can
be edited.
2026-11-02 12:04:16 +07:00
dotCooCoo 3cb252198a OpenType: the panel's Position menu sets superscript, subscript, numerator or denominator glyphs
The OpenType panel gets a Position menu after Figure, with Default
Position, Superscript, Subscript, Numerator and Denominator. `numr` and
`dnom` join the extra features (the existing bits keep their indices),
so they round-trip through the stored tags and reach the shaper.

text.setStyle and text.setRangeStyle take `featureChanges`, which turns
features on or off on top of each character's own features in one
command and keeps every tag the list does not name. The Figure menu,
the Position menu and the checkboxes send it, so on a selection whose
characters have different features each character keeps its other
features. Reset OpenType Features still sends `features`.

Catalog rows for Position:, Default Position, Numerator and
Denominator; one line each in docs/type-parity.md and
docs/target-app-parity.md.
2026-11-02 12:04:15 +07:00
dotCooCoo 6788b9f85d Brushes: test Original in the corner tile menus of Pattern Brush Options 2026-11-02 12:04:13 +07:00
dotCooCoo 6045f100cd Brushes: Pattern Brush Options keeps Original after a swatch is chosen 2026-11-02 12:04:13 +07:00
dotCooCoo 5c5e1f90b1 Accessibility: test that Escape closes the Simplify and Smooth sliders after tabbing 2026-11-02 12:04:09 +07:00
dotCooCoo 8bccbf2f35 Accessibility: Tab no longer stops on the Simplify and Smooth sliders' backdrop
The backdrop that takes a click outside the slider strip sensed clicks
with Sense::click(), which egui makes focusable, so Tab stopped on an
invisible full-screen widget. It now uses Sense::CLICK, as the modal
dialog backdrop does; a click outside the strip still keeps the result.
2026-11-02 12:04:09 +07:00
dotCooCoo 8b8b0c371f Objects on Path: the Rotate All widget turns every attached object about its attachment point
With one Objects on Path group selected, the Selection and Objects on
Path tools show a round handle beyond the top of the group's first
object, joined by a line to its attachment point. Dragging it adds the
angle the pointer turns about that point to the group's Rotate, previewed
while dragging and kept as one undo step on release
(object.objectsOnPath.options). Shift turns in 15 degree steps, Escape
cancels the drag, and the pointer shows the rotate cursor over the
handle.

Docs: docs/target-app-parity.md, docs/mcp.md.
2026-11-02 12:04:07 +07:00
dotCooCoo f46427167c .ai import: area type keeps its rows, columns, gutters and first baseline
Area type made from the editing data's text document came in with one
row, one column, the 18 pt gutter and the Ascent first baseline,
whatever its frame kept. Each area frame now keeps its rows and columns,
the gutter between rows and the gutter between columns, and its first
baseline (Fixed, Cap Height, Leading or x Height) with its minimum,
scaled with the art's units. Each frame of a thread keeps its own, and a
key that is missing or can't be read leaves that option as it was. A
first baseline the frame keeps is no longer replaced by the fixed one
that matches the file's first line.

AreaOptions gets row_gutter (rowGutter, left out while unset), which
layout spaces rows by; text.areaOptions takes and reports rowGutter, a
gutter given alone sets both, and the Area Type Options dialog shows
Row Gutter.
2026-11-02 12:04:07 +07:00
dotCooCoo c3093fcafb .ai import: a wraparound group's graphics wrap with no offset
Every graphic in a version 7 wraparound group (`*w` … `*W`), before
or after its type, is now a wrap object with an offset of 0 instead of
the 6 pt default, and a group with no type in it marks all of its
graphics. A graphic before the type is below it, so the type flows
around it only after it is moved above. Operands on `*w` or `*W`, and
a `*w` inside a compound path, are errors.

Docs: docs/file-format-parity.md.
2026-11-02 12:04:06 +07:00
dotCooCoo 100730d4d3 .ai import: a file whose PDF part can't be read opens from its editing data
Squashed from #5051 onto main.
2026-11-02 12:04:04 +07:00