Commit Graph
3169 Commits
Author SHA1 Message Date
dotCooCoo 19be0bb880 Type: inline graphics in symbol, mask and pattern art follow their symbols
Type with an inline graphic was resolved only in the layers, so type in
the art of another symbol, a graph design, a pattern tile or an opacity
mask kept the size its graphic had when it was made. The symbol holding
that type, its instances and the inline graphics that show it were
measured from the stale layout.

- Inline graphics are resolved in every tree that holds type. Symbols
  are resolved in dependency order, so a symbol's type is laid out
  before the type that shows that symbol inline. Edits, opening,
  reverting and Refresh Font List use the same pass.
- The pass visits each object once: it resolves the children first and
  copies a node only when something below it changed. It measures each
  symbol's art once per pass.
- An inline graphic of a symbol whose art shows that symbol inline,
  directly or through other symbols, is an empty slot. The symbols on
  such a cycle are found once and cached until the symbols change.
- A changed inline graphic also clears the text's cached baselines.
2026-11-13 10:17:33 -08:00
BFlat 7553c1f679 Merge pull request #7182 from dotCooCoo/feat/objects-on-path-detach
Objects on Path: Detach takes the chosen object off the path
2026-11-14 00:51:59 +07:00
BFlat 3378e390ab Merge pull request #7175 from dotCooCoo/fix/graph-series-group-appearance
Graphs: Appearance commands and graphic styles given a series group edit its marks
2026-11-14 00:51:00 +07:00
BFlat 4f0d3f1eb3 Merge pull request #7111 from dotCooCoo/fix/freehand-tolerance-low-zoom
Pencil: Fidelity keeps its screen size at low zoom
2026-11-14 00:50:47 +07:00
BFlat 637d51df79 Merge pull request #7143 from dotCooCoo/feat/guides-layer-rows
Layers: ruler guide rows have their own eye and lock, and go to the trash
2026-11-14 00:50:35 +07:00
BFlat 8db4fe00dc Merge pull request #7179 from dotCooCoo/fix/place-read-own-document
Place: a file read apart from the session goes only into its document
2026-11-14 00:50:27 +07:00
BFlat 1f67fa13a5 Merge pull request #7190 from dotCooCoo/fix/item-4475
Expand: type reports a gradient only when Fill expands one of its outlines
2026-11-14 00:50:08 +07:00
BFlat c1c06a839a Merge pull request #7183 from dotCooCoo/feat/pdf-long-pages-points-default
PDF: pages longer than 200 in are written at full size in points by default
2026-11-14 00:49:30 +07:00
BFlat 3904a7396c Merge pull request #7120 from dotCooCoo/feat/revolve-graphics
3D and Materials: wrap graphics around the side of Revolve objects
2026-11-14 00:49:21 +07:00
BFlat d58452f287 Merge pull request #7167 from dotCooCoo/fix/image-icc-16bit-kept
Images: an image stored again keeps its ICC profile and 16-bit samples
2026-11-14 00:49:03 +07:00
BFlat f520e6f8c5 Merge pull request #7184 from dotCooCoo/fix/cleanup-one-pass
Artwork Cleanup: remove quadratic work from three path repairs
2026-11-14 00:48:45 +07:00
BFlat 60fd4bd644 Merge pull request #7090 from dotCooCoo/feat/pixel-snapping-options
View: Pixel Snapping Options choose whether Snap to Pixel snaps drawing, moving and scaling
2026-11-13 23:58:35 +07:00
BFlat 6a1b4c42de Merge pull request #7040 from dotCooCoo/fix/nested-link-ids
Links: list and manage linked art in symbols, graph designs, patterns and masks by id
2026-11-13 23:58:20 +07:00
BFlat a9613094a9 Merge pull request #7171 from dotCooCoo/fix/ai-export-art-bounds
.ai export: a .ai of the art's bounds carries no editing data
2026-11-13 23:58:07 +07:00
dotCooCoo bed4e9aa4b Merge main into fix/graph-series-group-appearance 2026-11-13 08:50:06 -08:00
BFlat 10c84a909e Merge pull request #7173 from dotCooCoo/fix/assigned-profile-follows-front-document
Color: assigned profiles follow the document in front
2026-11-13 23:45:03 +07:00
BFlat 7f92d8ffc2 Merge pull request #7149 from dotCooCoo/fix/document-info-labels-translated
i18n: Document Info shows every category title and count label in the interface language
2026-11-13 23:31:57 +07:00
BFlat 4c135b0ab8 Merge pull request #7165 from dotCooCoo/fix/trace-current-pixels
Image Trace: a background trace applies only to the pixels it traced
2026-11-13 23:31:46 +07:00
BFlat 4c072b320c Merge pull request #7136 from dotCooCoo/fix/command-batch-artboards
Artboards: a batch's Fit to Artwork Bounds step fits every selected artboard
2026-11-13 23:31:28 +07:00
BFlat b7a9bd6e29 Merge pull request #7169 from dotCooCoo/fix/join-coincident-one-pass
Join: merge a run of coincident anchors in one pass over the path
2026-11-13 23:31:00 +07:00
dotCooCoo bc7eddeb5d Expand: type reports a gradient only when Fill expands one of its outlines
object.expand.info reported a gradient (and a fill) to expand for any
type whose characters have a gradient fill. Expand outlines type first,
and each outline then holds the run's gradient on its own box, so a
gradient that repeats or reflects in more than 256 runs across every
outline stays a gradient: the dialog enabled options that changed
nothing.

- The query now measures the paths type.createOutlines makes of the
  glyphs, ruby glyphs and underline and strikethrough bars, each with
  its run's paint, and reports a gradient when one of them expands. It
  lays the text out only when a run has a gradient fill, stops at the
  first outline that expands, and does not change the document. Type in
  symbol art, blends and repeats goes through the same check.
- docs/mcp.md says when gradient is false; docs/target-app-parity.md
  gets an evidence line.
2026-11-13 08:27:09 -08:00
dotCooCoo d41cf0d053 Merge main into feat/objects-on-path-detach 2026-11-13 08:26:49 -08:00
dotCooCoo 9b027bb43a Merge main into fix/image-icc-16bit-kept 2026-11-13 08:25:53 -08:00
BFlat 9395fb9cec Merge pull request #7160 from dotCooCoo/fix/svg-image-orientation
SVG import: raster images follow their EXIF or TIFF orientation
2026-11-13 23:16:49 +07:00
dotCooCoo 87ad60ec42 Merge main into fix/graph-series-group-appearance 2026-11-13 08:15:48 -08:00
BFlat 43d0b50760 Merge pull request #7157 from dotCooCoo/fix/remove-anchors-one-pass
Paths: Remove Anchor Points removes many anchors of a subpath in one pass
2026-11-13 23:15:10 +07:00
BFlat f97e81afd7 Merge pull request #7159 from dotCooCoo/fix/delete-cut-per-subpath-anchors
Paths: Delete, Cut and Cut Path read each subpath's own selected anchors
2026-11-13 23:14:36 +07:00
dotCooCoo 3348b41796 Merge main into fix/freehand-tolerance-low-zoom 2026-11-13 08:12:01 -08:00
dotCooCoo cd7e209934 PDF: pages longer than 200 in are written at full size in points by default
PDF export without a PDF/X or PDF/A standard writes pages longer than
200 in at full size in points instead of with a UserUnit scale.
longPagesInPoints is now on by default in PdfSettings, the built-in
presets and the Save PDF dialog. Turning it off writes such a page with a
UserUnit from PDF 1.6 on, as before. PDF/A-2b files keep the UserUnit,
and .ai saves keep it unless longPagesInPoints: true is passed.

Docs: params text, docs/mcp.md, docs/target-app-parity.md.
2026-11-13 08:10:42 -08:00
BFlat 6326acb122 Merge pull request #7070 from dotCooCoo/feat/recolor-prominent-colors
Recolor Artwork: the Prominent Colors bar weighs the art's colors
2026-11-13 23:05:19 +07:00
BFlat d26413c3fb Merge pull request #7117 from dotCooCoo/fix/smooth-tool-smooths
Smooth tool: each drag smooths the path under it, and repeated drags keep smoothing
2026-11-13 23:04:21 +07:00
BFlat de93bef121 Merge pull request #7101 from dotCooCoo/fix/eyedropper-series-opacity
Eyedropper: a pick that leaves a series mark's row without paint replaces the stored transparency
2026-11-13 23:04:12 +07:00
BFlat dd8f8ed2bd Merge pull request #7115 from dotCooCoo/fix/settle-keeps-preview-warnings
Edit: settling an interaction keeps the warning of the preview it applies
2026-11-13 23:03:55 +07:00
BFlat c68b2775e4 Merge pull request #7125 from dotCooCoo/fix/plugin-install-checks-first
Plug-ins: plugin.install writes nothing to the store until the module is checked
2026-11-13 23:02:12 +07:00
BFlat 017db27090 Merge pull request #7131 from dotCooCoo/fix/flatten-grouping-sweep-meets
Flatten: grouping sweeps skip boxes that a box already holds or cannot join
2026-11-13 23:01:18 +07:00
BFlat 0455c12162 Merge pull request #7127 from dotCooCoo/fix/thread-empty-last-paragraph-style
Type: a threaded frame's empty last paragraph keeps a format given to it
2026-11-13 23:00:36 +07:00
BFlat e9459df52b Merge pull request #7099 from jmverges/fix/7097-top-object-split-curve
Envelopes: a top object's side that is one split curve follows its parameter
2026-11-13 23:00:21 +07:00
dotCooCoo 3e53884b7e Artwork Cleanup: remove quadratic work from three path repairs
Three repairs in crates/pathops/src/addons/cleanup.rs grew with the square
of the input. Each now gives the same results as before, bit for bit.

- Collinear anchors: removing an anchor called Vec::remove, so a straight
  run of n anchors took O(n^2) moves. The repair now tests each anchor once
  against the nearest kept neighbors, with the same test order, neighbors
  and stop rule, and moves the kept anchors into place once.
- Nearly Coincident Anchors (near_point_groups): every pair of anchors in
  touching grid cells was compared, so a cluster of A anchors cost O(A^2)
  checks. Groups now grow one anchor at a time and look only at anchors no
  group has taken, by exact position, skipping quarter-cell squares that
  lie out of reach.
- Rejoin Path Pieces (rejoin): every pair of ends within the gap was listed
  and sorted, O(P^2 log P) for P pieces meeting at one place. Each end now
  finds its first partner in the same order (turn, distance, then end
  order), searching by direction among the ends still free, and two ends
  that are each other's first partner meet.

Tests compare each repair with a copy of the old algorithm on generated
and focused inputs, count the work on dense cases (20,000-anchor runs,
4,000-anchor clusters, 2,000 pieces meeting at one point), and check Health
Check, Show and Fix on a 5,001-anchor path.
2026-11-13 07:58:36 -08:00
dotCooCoo 9fad6eb952 Objects on Path: Detach takes the chosen object off the path
With one Objects on Path group selected and an object chosen with its
Select/Move widget, Detach in the Properties panel's Objects on Path
Options section takes that object out of the group
(`object.objectsOnPath.detach {member?}`). The object goes just above
the group in the Layers panel, stays where it is drawn and is selected
alone. The other objects move up the path in their order: Auto Space
spreads them evenly again, and a Space value and the start are kept.
The group and its path stay with one object or none left. Hidden or
locked objects and groups are refused, and Detach is one undo step.
When the group is itself on another group's path, the object goes
above the outer group so it does not join that path.

Docs: docs/mcp.md, docs/target-app-parity.md. Detach and its undo name
have rows in every catalog, and the new message in the complete-message
catalogs.
2026-11-13 07:54:06 -08:00
dotCooCoo a12de6a39a Merge main into feat/guides-layer-rows 2026-11-13 07:51:49 -08:00
dotCooCoo c76e89c6ea Merge main into feat/revolve-graphics 2026-11-13 07:49:32 -08:00
dotCooCoo 036079902b Merge main into feat/pixel-snapping-options 2026-11-13 07:46:25 -08:00
dotCooCoo 39441540f7 Merge main into fix/nested-link-ids 2026-11-13 07:44:19 -08:00
dotCooCoo 5741c7bba0 Color: assigned profiles follow the document in front
The profiles Edit > Assign Profile gives a document stayed the active
color settings after another document came to the front, so a new,
opened or switched-to document drew and converted its colors through the
previous document's profile, and closing the last document left it in
use.

The session now puts the front document's profiles in use (the working
spaces where it has none, or no document is open) after a new or opened
document, a tab switch, a close, File > Revert, every command including
each batch step and Undo or Redo of Assign Profile, a failed batch or
plug-in call, a script's rollback and slice boundaries, a canceled
preview, undo group or undo scope, and for each document Export All Open
and the update of placed documents work in. The active settings are
rebuilt, and the documents redrawn, only when they change.
2026-11-13 07:44:19 -08:00
dotCooCoo 1c8cec3e7b Merge main into fix/document-info-labels-translated 2026-11-13 07:36:52 -08:00
dotCooCoo fdbe4ea32d Merge main into fix/command-batch-artboards 2026-11-13 07:36:48 -08:00
dotCooCoo 393078b4f2 .ai export: a .ai of the art's bounds carries no editing data
document.export and document.serialize to .ai with useArtboards: false
wrote the one page of the visible art, but embedded the one-artboard
stand-in as the native document and as the editing copy for other apps.
Reopened, the file replaced the document's artboards with one artboard
around the art.

- The .ai of the art's bounds now leaves out both editing copies and
  returns the warning "Preserve editing was left out: an .ai file of the
  art's bounds would replace the document's artboards when reopened",
  as the PDF of the art's bounds does.
- useArtboards: false with pdfCompatible: false is refused, with or
  without editingData, since the file would have blank pages and no
  editing copy.
- Save, Save As, Save a Copy and exports of the artboards keep both
  copies. Legacy version 7 .ai files are written as before.

Docs: docs/mcp.md, docs/target-app-parity.md, document.export params.
2026-11-13 07:28:12 -08:00
dotCooCoo 4cd998dce0 Place: a file read apart from the session goes only into its document
Session::place_read and Session::place_queue_read placed a file, or
loaded the place cursor, in whichever document was active when the read
finished. A job prepared in one document could land in another one that
was activated meanwhile, or that stayed open after the first was closed.
Replace did not stop it when the other document held an equal object
under the same id.

PlaceJob, QueueJob and QueueRead now keep the uid of the document they
were prepared in. Both calls refuse a read whose document is not the
active one with "the document it was prepared for is no longer active",
before any selection, edit, tool change or journal entry. Switching back
to the original document places the file as before.
2026-11-13 07:28:07 -08:00
BFlat 77970c6924 Merge pull request #7082 from dotCooCoo/fix/smooth-resets-anchor-selection
Smooth tool: smoothing a path deselects its direct-selected anchors
2026-11-13 22:26:18 +07:00
dotCooCoo 8b990de004 Join: merge a run of coincident anchors in one pass over the path
Join removed each merged anchor from the path's anchor list as it went,
which moved every anchor after it, so a long selected run in front of
many other anchors took time quadratic in the path's length. It also
looked up each anchor's selection in the selected-anchor set.

Join now marks the merged anchors and removes them in one pass at the
end, reading the selection from one flag per anchor. Each corner or
smooth conversion sees the same neighbors as before, so the resulting
anchors are unchanged. Anchor::smooth_between holds the smoothing that
SubPath::smooth_anchor applies.

Tests compare the new merge bit for bit with the old one on 30,000
generated paths, and count the anchors moved when 300,000 selected
anchors in front of 300,000 others merge: each of the others moves
once.
2026-11-13 07:25:49 -08:00