Commit Graph
1947 Commits
Author SHA1 Message Date
Don Omondi 62f133fa0b Fix #2898: Up and Down change the corner kind while dragging a widget
Squashed from #5090 onto main.
2026-11-02 14:36:12 +07:00
Prin.IngandClaude Haiku 5.5 35de20b108 Limit the ZIP writer to 65534 files so Archive::open can read it
Found while testing crates/engine/src/cmd/fileio/zip.rs:26 (store, deflate) vs :178 (Archive::open)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-02 14:36:11 +07:00
FarmerGeorg 9c59a4dcb4 Appearance panel: UI parity for row editing
- Drag strokes, fills, characters and effects to move them, or drop them
  on the Duplicate or Delete button
- Select several rows with Shift/Cmd-click and move them as one block
- Delete and Backspace remove the highlighted rows, not the selected art
- Row links open their panel (Stroke, Character…) as a flyout
- Stroke weight spinner follows Units > Stroke
- Transparency panel edits the active fill's or stroke's opacity
2026-11-02 14:36:09 +07:00
ham9zah 601f4854cd Type tool: Alt-click on a closed path makes area type too; type along a closed path stays with Type on a Path 2026-11-02 14:36:09 +07:00
ham9zah 6fd542822d Type on a path made with the Type tool shows its brackets at once and flips across its path 2026-11-02 14:36:09 +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 236a3c264d Swatch legend: no unreachable! in the test
The workspace lints ban it; the test panics with a message instead.
2026-11-02 14:36:07 +07:00
Don Omondi aa71acc29f Swatch legend: linked chips, labels that fit, exact Gray
Each chip's fill links to its swatch as paint.setFill {swatch} does, so
editing a global or spot swatch recolours the legend. Labels are area
type the size of the chip that shrinks text to fit. Gray values use the
app's own Gray conversion, and fractional column counts are refused.
2026-11-02 14:36:07 +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
Wadah Badawi 66e22f4ba1 M2.1: recurse into groups and compound paths for path.average 2026-11-02 14:36:07 +07:00
NetterSilverandClaude Sonnet 5.5 88d8a7839e fix: validate parse_date calendar dates with chrono
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-02 14:36:06 +07:00
NetterSilverandClaude Haiku 5.5 83ed70acce Validate hyphen placement and days in month in parse_date
Found while testing crates/engine/src/cmd/fileio/naming.rs:103

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-02 14:36:06 +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
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
bflatastic d5edca7452 Type: the East Asian character settings get their own method 2026-11-02 14:32:59 +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 f69f7976b7 .ai import: legacy files without layers open through the format reader
Squashed from #5209 onto main.
2026-11-02 14:32:58 +07:00
dotCooCoo ec0a98a77b Selection: a drag with Real-time Drawing off shows the bounds of a selection too big to outline
With Real-time Drawing and Editing off, a drag drew one outline per selected
object with no limit, so a selection with hundreds of thousands of points
built the overlay mesh that the canvas's 100,000-point limit keeps it from
drawing at rest (#525, #2460). Past the same number of points the drag now
draws the moved selection's bounds, as the canvas does for the selection at
rest.
2026-11-02 14:32:58 +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 79c5218f8a Fix #5161: Shape Builder merges across a line under a merged shape's edge
Where a line lies under the outline of a closed path in front of it (such as
a shape an earlier merge made, which takes the place of the art in front of
the lines), the planar map gave that stretch only to the closed path, so the
line had no piece there. A merge or an erase across it left the line whole,
and the next map split the new shape along it into two regions.

- pathops: each planar edge records every input it lies on, and
  BuilderArrangement::lines_under holds the lines' pieces under a closed
  outline in front of them. lines, edges and Live Paint are unchanged.
- tools: BuilderMap adds those pieces to its lines, so a merge or an erase
  removes the stretch between the regions it takes, as it does elsewhere.
  An Alt-click where a line lies under an edge hits the one in front.
2026-11-02 14:32:57 +07:00
bflatastic 8913ba2440 Tests: the placed-files fuzz fixture goes in after the noted path 2026-11-02 14:32:57 +07:00
dotCooCoo 01bc69cc80 .ai import: placed EPS files in the version 7 form are read
Squashed from #5187 onto main.
2026-11-02 14:32:56 +07:00
dotCooCoo 82806d1441 Fonts: Find Font and Replace Missing Fonts reach the type in symbols
Exports warn about type in a symbol's art that is set in a missing
font and point to Find Font, but Find Font and Replace Missing Fonts
only looked at the type on the layers.

- text.fonts lists the fonts of the type in the document's symbols too;
  with selectionOnly, of the symbols the selected instances show.
- select.font (Find) also selects the instances of the symbols whose
  art uses the font in type that is not hidden or locked.
- text.replaceFont changes that type in the symbols in scope, so every
  instance follows. Type hidden or locked in a symbol's art, and the
  type of symbols that only a selected hidden or locked instance shows,
  keeps its font and is counted in skipped.
- addon.cleanup.replaceFonts replaces missing fonts in symbols' type.

While a symbol is edited, its type is taken from the editing layer
only, so it is counted and changed once.
2026-11-02 14:32:55 +07:00
dotCooCoo 405372555d .ai import: the document's graphic styles open in the panel with their objects linked
Squashed from #5155 onto main.
2026-11-02 14:32:53 +07:00
dotCooCoo 0e38796573 .ai import: placed files are found by the folder they keep relative to the document
Squashed from #5176 onto main.
2026-11-02 14:32:53 +07:00
dotCooCoo 56f6128f94 .ai import: a line width of 0 draws as a hairline
Squashed from #5174 onto main.
2026-11-02 14:32:53 +07:00
dotCooCoo dbb04905e0 .ai import: Offset Path, Outline Object and Outline Stroke open live
Squashed from #5148 onto main.
2026-11-02 14:32:52 +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 6be88a24b4 Fix #785: commands refuse an id that isn't an object id instead of using the selection
Commands whose `id` or `ids` the shared check in Session::execute does not
read still parsed them with id_param/ids_param, which drop anything that is
not a non-negative integer, and then acted on the selection or the current
layer. `object.blend.make {"ids": 3}` blended the selection,
`object.envelope.makeWithWarp {"ids": [2, "x"]}` warped the selection,
`graph.setData {"id": "2"}` changed the selected graph and
`layer.newSublayer {"parent": "2"}` added a sublayer to the current layer.

- cmd::named_ids and cmd::named_id read `ids`/`id` as targets does: a value
  that is not an object id, or an unresolved step reference, is an error.
- The symbol and brush, Live Paint, Shape Builder and Image Trace, blend,
  envelope and mesh, perspective, Liquify, Puppet Warp and graph helpers use
  them in place of the lenient readers.
- layer.clippingMask.toggle checks `id`, and layer.newSublayer checks
  `parent`, with checked_id before falling back to the highlighted row or the
  current layer.
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 c4a394c536 Merge pull request #5203 from dotCooCoo/fix/empty-text-clip-kept
Artwork Cleanup: Empty Text and Off-Artboard Art leave type that clips art
2026-11-02 00:34:49 -05:00
Brandon Thomas 9269cb7cf3 Merge pull request #5197 from dotCooCoo/fix/cleanup-leaves-hidden-locked-art
Artwork Cleanup: Simplify Anchors and Deep Ungroup leave hidden and locked art alone
2026-11-02 00:34:43 -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
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 69e5eecde0 .ai import: artboard display options, raster effects settings and the header's author come in
Squashed from #5102 onto main.
2026-11-02 12:04:24 +07:00
dotCooCoo 13db3cd602 .ai import: anchors are smooth or corners by the case of their segment operators
In editing data and legacy .ai files, a lower-case l, c, v or y makes the
anchor the segment ends on smooth and an upper-case L, C, V or Y makes it a
corner. The reader used to guess each anchor's kind from whether its
handles are in line, so a lower-case l always read as a corner and an
upper-case C with handles in line read as smooth. A closed path's first
anchor takes the case of the segment back to it. Points and handles do not
move. Paths, compound paths, clipping paths, guide paths, area type frames
and type-on-a-path paths all keep the kinds.
2026-11-02 12:04:23 +07:00
bflatastic ae46139b20 Variables: Edit Data Set's rename test undoes the one step it adds 2026-11-02 12:04:22 +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 899a4c2bcb Variables: Import Data Sets reads CSV files that are not UTF-8 as Windows-1252
Squashed from #5116 onto main.
2026-11-02 12:04:21 +07:00
dotCooCoo 2b7b12df33 Symbols: the edited symbol takes the text wrap its area type gets after a wrap object moves
Symbol editing copies the editing layer's art into the symbol before Text Wrap, list numbering and threaded re-flow update that layer, so moving a wrap object in the edit left the symbol, its other instances and the saved file with the old wrap. The edit now syncs the symbol again after those passes, and when that changes the symbol, inline graphics of it are refreshed and the threads holding them re-flow.
2026-11-02 12:04:20 +07:00
dotCooCoo 294d13d857 Symbols: an instance in an opacity mask follows an edit of its dynamic symbol
The appearance changes of the instances on the layers now follow the edited objects through the same pass as the instances in other symbols, graph designs, pattern tiles and brushes. That pass also reaches instances used as opacity-mask art, which keep their changes on the same objects when an edit reorders them and drop the change to an object the edit deletes.
2026-11-02 12:04:20 +07:00
dotCooCoo 5c678ed52c Symbols: instances in pattern tiles, graph designs and brushes follow an edit of their dynamic symbol 2026-11-02 12:04:20 +07:00
dotCooCoo 87dea538ae Symbols: instances inside other symbols' art follow an edit of their dynamic symbol
Editing a dynamic symbol moved each placed instance's appearance changes with the objects they
name, but an instance stored in the art of another symbol kept its changes at the old paths, so
placing that symbol showed a change on the wrong object. Those instances, opacity masks included,
now follow the edit too and keep only the changes to objects the art still has.
2026-11-02 12:04:19 +07:00
dotCooCoo 0af8096364 Symbols: a refused switch to another symbol keeps the current edit, and isolation stays on the editing layer
symbol.edit checks the new placement before it ends the symbol being edited, so a call with an out-of-range x or y fails and leaves the current edit open. While a symbol is edited, object.isolate refuses art outside the editing layer, and object.exitIsolation goes back to the editing layer only from a group inside it; from any other isolation it leaves symbol editing mode.
2026-11-02 12:04:18 +07:00
dotCooCoo 7a527fce64 Character Styles: New Character Style keeps a language tag the selected text holds
charStyle.new now validates attrs against the target text's attributes, so a
language tag that is not in the list but that the selected run already holds
(a native file can store any tag) is kept. Any other unlisted tag is still an
error.
2026-11-02 12:04:16 +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 a6c64e2cf2 Type: choosing Optical kerning clears manual pair values, as Auto does 2026-11-02 12:04:15 +07:00