Commit Graph
13024 Commits
Author SHA1 Message Date
dotCooCoo 7b30424538 Merge main into feat/warichu 2026-11-13 04:06:56 -08:00
dotCooCoo 5e33ab2a61 Merge main into fix/nested-link-ids 2026-11-13 04:06:39 -08:00
dotCooCoo 2170ddcac4 Eyedropper: a pick that leaves a series mark's row without paint replaces the stored transparency
An Eyedropper pick that includes transparency now counts a fill or stroke
row that had paint before the pick and has none after it when it stores
the series' row opacity and blend mode on the graph, as graphic styles
already do. Before, such a pick left the opacity and blend mode another
mark of the series had stored, and the series was drawn with them again
after its data changed. A row that had no paint before the pick still
leaves the stored values as they are.
2026-11-13 04:05:56 -08:00
jmvergesandClaude Opus 5.5 728fd9ef14 Envelopes: a top object's side that is one split curve follows its parameter
A top-object envelope gives each piece of a side a share of the content
in proportion to its control polygon's length. When anchors split a
curve without changing its shape, the pieces' polygons don't divide the
side where the curve's own parameter does, so the envelope bent its
contents differently although its outline was the same: Add Anchor
Points on a top object moved the art, and a top object whose .ai mesh
saves each side's curve split into thirds drew its type up to about
half a point off its drawn art, which follows the whole curve's
parameter.

Coons::from_top_object now checks whether a side's pieces, from corner
to corner, are all pieces of one cubic. The pieces' spans of that
curve's parameter come from the handle lengths either side of each
split, the curve from the outer ends and handles, and every piece must
lie within 0.02 pt of the curve's piece over its span (each control
point). Such a side runs along that curve, by its parameter. Any other
side keeps the polygon shares, including a side only partly made of one
curve and a smooth side drawn in many pieces that isn't one curve as a
whole. Corners found from the outline can still move when anchors are
added, as before. Gradient meshes made from a path are unchanged.

Existing top-object envelopes with such sides redraw.
a_split_curve_moves_the_top_object_share_to_its_new_anchor, which
pinned the earlier behaviour, becomes a_split_curve_keeps_the_top_object_patch.

Tests: a_split_curve_keeps_the_top_object_patch,
a_top_object_joins_a_split_curve_saved_with_rounded_coordinates,
a_top_object_keeps_smoothly_joined_curves_apart,
a_top_object_side_partly_of_one_curve_keeps_the_polygon_shares and
a_top_object_side_of_many_arcs_stays_on_them (vectorcraft-doc),
envelope_top_object_keeps_its_look_when_anchors_are_added
(vectorcraft-engine) and
a_top_object_whose_top_is_one_curve_split_in_thirds_opens_live
(vectorcraft-eps).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 11:18:40 +00:00
dotCooCoo dc7b0d0c90 Layers: layer and object rows held near the list's top or bottom edge scroll a long list
While layer or object rows are dragged in the Layers panel, holding the
pointer within 28 points of the list's top or bottom edge scrolls the
list that way, faster nearer the edge, and it keeps scrolling while the
pointer stays still, so a row out of view can take the drop (a move, or
a copy with Alt). The Libraries panel's edge-scroll helper moves to
panels.rs and both panels use it. Scrolling stops on release, when the
pointer leaves the list's width, and for other drags such as the eye or
lock column.
2026-11-13 02:31:55 -08:00
dotCooCoo 6bf988a0e1 Clipboard: the Flatpak on GNOME copies and pastes pictures and SVG with other apps
Where arboard has neither data-control nor X11 (the Flatpak on a GNOME
Wayland session), Copy and Paste used smithay-clipboard on the window's
connection, which carries text only. They now use a core wl_data_device
client on that connection.

- One Copy offers the PNG as image/png, the SVG as image/svg+xml (with
  Include SVG Code on) and the text as text/plain;charset=utf-8,
  UTF8_STRING and text/plain. A format with no data is not offered.
- Paste reads SVG, then text, then PNG. Blank text, or text that only
  names a picture, gives way to the PNG, and a failed or empty SVG read
  falls back to the types after it. The Paste menu item is enabled by the
  types offered, without reading any data.
- The clipboard holds VectorCraft's Copy while its data source is not
  canceled and the offer has the Copy's types.
- A read takes 64 MiB at most. Text waits 2 s, SVG and PNG 10 s off the
  UI thread. Another app's paste is sent on its own thread, 8 at once.

smithay-clipboard is no longer a dependency of the app.
2026-11-13 02:31:04 -08:00
dotCooCoo 737d9bc5b8 PDF/.ai save: envelopes stay editable when the file is reopened
A PDF-compatible .ai saved with Include Editing Data for Other Apps now
writes warp, mesh and top-object envelopes as live envelope records in
its editing copy: the grid or contents, Envelope Options, Fidelity,
Edit Contents, a warp's settings and the contents' box, beside the
distorted art, in the form the .ai envelope reader reads. The file
opens with the same live envelopes.

Envelopes the reader would open in another shape or with other
settings are written as their distorted art with a warning: type in
the contents, a turned frame, an old warp map, a mesh laid out another
way round, a top object whose sides do not pair up, a Fidelity that is
not a whole number, bounds margins kept with Distort Appearance off,
envelopes in opacity masks, pattern tiles, clipped art or another
envelope's contents, on a large canvas, and after the first 256.
2026-11-13 02:28:11 -08:00
HassanKhan c6b22ad891 Merge remote-tracking branch 'upstream/main' into feat-6304-font-height-icons
# Conflicts:
#	docs/target-app-parity.md
2026-11-13 15:12:02 +05:00
BFlat 1dbdbce91f Merge pull request #7080 from dotCooCoo/feat/trace-create-strokes
Image Trace: Create Strokes makes a wide shape's thin features strokes and keeps its body a fill
2026-11-13 17:03:37 +07:00
BFlat 54f0c1b99b Merge pull request #7003 from mockydevs/fix/graphic-styles-list-height-2992
Graphic Styles: the list fills a taller panel above its footer
2026-11-13 17:03:22 +07:00
dotCooCoo 2129d00868 Dimension tool: a point on a Smart Guide stays on the guide
A Linear pick that the Smart Guides left where the pointer already was,
for example straight below the first point on the vertical construction
guide through it, or exactly in line with an object's center, was taken
as not snapped. The pick then moved to the closest point of a segment
within 8 pixels while the guide still showed it on the guide. The same
happened to a point already on a grid crossing with Snap to Grid on, or
on a whole pixel with Snap to Pixel on.

The pick now keeps the snapped point whenever the snap shows guides or
grid or pixel snapping is on. With Snap to Grid or Snap to Pixel on, a
pick off an anchor is no longer moved from the grid or the whole pixel
onto a segment. A point that no
anchor, guide, grid or pixel snapping places still lands on the closest
point of a segment. An anchor within 8 pixels, a segment within the
Smart Guides snapping tolerance and a nearby guide crossing still take
the point as before.

Docs: docs/dimensions.md, docs/target-app-parity.md.
2026-11-13 01:48:09 -08:00
dotCooCoo f81793d671 View: Pixel Snapping Options choose whether Snap to Pixel snaps drawing, moving and scaling
Control bar > Snapping > Pixel Snapping Options... opens a dialog with
three checkboxes: Snap to Pixel While Drawing, While Moving and While
Scaling. OK sets them; Cancel leaves them as they were. While View >
Snap to Pixel is off, the dialog notes that the options take effect once
it is on.

- view.snapToPixel.options {drawing?, moving?, scaling?} reads and sets
  them. They are kept in the preferences as the pixelSnap group, all on
  by default, so turning Snap to Pixel on behaves as before. An unknown
  key or a value that is not a boolean is refused and changes nothing.
  The command has a parameter schema, which raises the API level to 4.
- Drawing covers points the drawing tools place, the Knife's straight
  cut, the Measure tool and the rulers' origin. Moving covers Selection
  and Direct Selection moves, ruler guides, artboard moves and the
  Rotate, Reflect and Shear tools' drags. Scaling covers bounding-box,
  Free Transform, artboard and slice handles and the Scale tool's drag.
  An edit whose option is off snaps as it does with Snap to Pixel off.
- Align New Objects to Pixel Grid and the objects' pixel-aligned
  property do not depend on these options.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-13 01:38:58 -08:00
dotCooCoo 6c773585fa Type: the Every-line Composer sets mixed sizes in shaped and wrapped area type
A paragraph whose characters differ in line metrics (type size, font,
leading, vertical scale, or an inline graphic taller than the text) was
broken with the Single-line Composer in area type of a shape other than
a rectangle, or with text wrap. The every-line composer now composes it
there too.

- The composer takes each line's width from a measure that follows
  where the lines above it went (`composer::Measure`,
  `compose_with`). The fixed widths by line number are one such measure.
- In a frame whose lines are not all as wide, each line the composer
  tries is placed from the pen the lines above it left, at its own
  tallest metrics, as the line loop places it (`layout/shaped.rs`).
  Starts with the same placement are shared, and each start keeps the
  placements it was tried with.
- A line too long for its room does not end the search from its start
  while a glyph after it could make the line taller and set it lower,
  where the frame may be wider.
- The line loop places a composed line in such a frame at the line's
  tallest metrics, so it gets the room the composer measured for it.
- The search for one paragraph stops after 1,000,000 lines tried or
  2,000,000 baseline steps. The searches of all the paragraphs of one
  frame share a budget of 2,000,000 lines and 4,000,000 steps, kept
  apart from the line loop's own steps. A paragraph whose search stops
  is broken line by line. A paragraph the frame has no room for is
  broken line by line too, and overflows as before.

Tests: crates/text/src/tests/combos.rs (a stepped frame, a frame that
widens, text wrap with two spans on a baseline, overflow, a long
paragraph) and crates/text/src/layout/wrapping_tests.rs (the composer
with a measure, and the shared search budget).
2026-11-13 01:24:33 -08:00
dotCooCoo 345cd021dc i18n: Dutch translates status and error messages
Dutch was not in COMPLETE_MESSAGES, so with the interface in Dutch
script errors, plug-in manifest and permission errors, parameter
schema errors, 3D effect refusals, file-reader errors and data-set
messages showed in English.

- nl.tsv gains 557 `@msg` rows and one `@msgplural` row: the messages
  the German catalog translates and Dutch lacked. Most are one block
  with a header comment on their conventions, in the order de.tsv
  holds them; the rest sit next to the related existing rows.
  Backticked names, command ids, double-quoted values and bare true,
  false and null stay as the English writes them.
- nl joins COMPLETE_MESSAGES, so the message tests that iterate the
  list check Dutch too, and the untranslated report lists Dutch's
  missing messages. It lists the same set for Dutch as for German.
- The registry comment, docs/development.md, the Dutch row and
  introduction of docs/localization-parity.md, and the interface
  languages line of docs/target-app-parity.md list Dutch among the
  languages that translate messages.
2026-11-13 01:23:19 -08:00
dotCooCoo 78ee4d04b6 Panels: item drags start only with the primary button, as Layers does
A right or middle drag on a swatch or color group, a brush, a symbol, a
graphic style, a library item or group, a character or paragraph style,
an Appearance row or thumbnail, the Fill and Stroke squares, a Recent
Colors chip or the Gradient panel's thumbnail started the same drag as
the primary button, so it could reorder, copy, delete or apply the item.
These drags now start only with the primary button, as Layers rows
(#7016) and Artboards rows (#7005) do: `widgets::drag_source`, the
Swatches tiles, library panel items, text style rows and Appearance rows
check `drag_started_by(Primary)`, and the Appearance thumbnail shows the
grabbing hand only for a primary drag. Right-click menus and the Graphic
Styles panel's held right-button preview are unchanged.
2026-11-13 01:22:30 -08:00
dotCooCoo 7805479dad Libraries: a character style's menu offers Apply, Add to Character Styles, Rename and Delete
A right-click on a character style in the Libraries panel now opens Apply
Character Style, Add to Character Styles, Move to Group, Rename… and
Delete. Apply is enabled only with type selected. Opening the menu applies
nothing, and the paragraph style menu is unchanged.

- library.addToCharacterStyles adds the style to the document's character
  styles without applying it, so no type needs to be selected. A document
  style with the same name and attributes is reused with no undo step, and
  a name taken by other attributes gets a number.
- library.renameItem renames a library item in place and keeps its group.
  The name is trimmed and has 1 to 256 characters. Another item of the same
  kind with that name is an error, the item's own name writes nothing, and
  a rename is not a document undo step.
- library.use and library.addToCharacterStyles compare a library style
  with the document's in the form the document stores it in. A whole
  number size from a library file no longer adds a numbered copy.
- A character style color linked to a swatch that is not a global or spot
  swatch of the document keeps the color it shows without the link.
  Before, adding or applying such a style failed with "no swatch".

Help page: https://helpx.adobe.com/illustrator/desktop/design-with-text/fonts-and-scripts/add-and-use-text-and-character-styles-in-libraries.html
2026-11-13 01:22:29 -08:00
HassanKhan b219decd75 Character panel: the highlighted font height icon keeps its contrast (#6304)
On the open list's row of the current reference, drawn on the
accent-tinted selection fill, the icon draws its measure in the name's
colour instead of the accent, which lost its contrast there. The other
rows and the closed field keep the accent.
2026-11-13 14:19:58 +05:00
dotCooCoo 1c0310a1d5 Smooth: Fidelity is in screen pixels, so a drag smooths as much at any zoom
The Smooth tool, and an Alt smoothing drag with the Pencil, Paintbrush or
Blob Brush, now send path.smoothRegion their Fidelity divided by the zoom,
as the Pencil and the Paintbrush do since #5748. Smooth Tool Options shows
Fidelity in px. A saved Fidelity keeps its number, so it smooths as before
at 100% zoom.

path.smoothRegion now refits at tolerances from 0.05 px at the highest zoom
to 100 px at the lowest (0.000078125 to about 3195 pt) instead of clamping
to 0.05 to 100 pt, so the setting keeps scaling across the whole zoom range.
2026-11-13 01:18:06 -08:00
dotCooCoo bc92def89e Smooth tool: smoothing a path deselects its direct-selected anchors
path.smoothRegion replaced the anchors of each path it smoothed but left
the selection alone, so anchor and segment refs selected with Direct
Selection still named the old indices: after a smooth that removed
anchors, a ref could point past the end of the path or at another
anchor. The edit now drops those refs for each path it changes, so the
path stays selected whole. Selected paths the drag does not change keep
their anchors, and undo restores the earlier selection.
2026-11-13 01:12:38 -08:00
dotCooCoo eee96556e6 Simplify: a refitted curve becomes a line only when its joins stay smooth
Simplify, Object > Path > Smooth, the Smooth tool and freehand strokes
turned every refitted curve whose handles lay near its chord into a
straight line. A short curve whose end directions were off the chord
passed that test, and the anchor between it and the next curve became a
corner the path did not have: a Smooth tool drag along a line jagged by
up to 6 pt left corners of 7.7 to 40.6 degrees.

A curve now becomes a line only when the line runs within 0.5 degrees
of the directions the path arrives and leaves along. A nearly straight
piece that would turn more stays a flat curve. Convert to Straight Lines
is unchanged.
2026-11-13 01:09:38 -08:00
dotCooCoo 6e2fe9fddf SVG: right-to-left text with text-anchor start or end opens at its directional edge
SVG 2 defines text-anchor start for right-to-left text as placing the
right side of the text at its position, and end as placing the left
side there (https://www.w3.org/TR/SVG2/text.html#TextAnchoringProperties).
Import placed start at the left edge and end at the right edge whatever
the direction.

- Point type and type on a path swap start and end when the effective
  direction is rtl. On a path, right-to-left text anchored by start now
  ends at startOffset and text anchored by end begins there. Vertical
  type keeps its anchoring.
- Each line and each absolutely placed chunk is anchored by the
  text-anchor and direction of the element holding its first
  character, a tspan's own included. A later chunk no longer takes the
  first chunk's anchor.
- Each line of point type starts at its own x, also when it has the
  same anchor as the line before it or another line holds absolutely
  placed characters. Such lines were drawn at the first line's x.
- A test covers letter-spaced right-to-left lines: the layout keeps the
  tracking of every letter in such a line, so the whole advance sits
  on its anchor.
2026-11-13 01:06:53 -08:00
BFlat 3b48070751 Merge pull request #7061 from dotCooCoo/fix/dcs-transparency-clip
Place: DCS transparency interactions look only at what clipping paths show
2026-11-13 16:04:49 +07:00
BFlat d118fcb17c Merge pull request #7046 from dotCooCoo/fix/issue-3349
.ai import: graphic styles of one paint open with their fill and stroke
2026-11-13 16:04:36 +07:00
BFlat f0653da969 Merge pull request #7072 from kler/swedish-ui-2026-11-13
i18n(sv): translate 37 new strings, use the agreed terms in 9
2026-11-13 16:04:26 +07:00
dotCooCoo 093f04952c Image Trace: Create Strokes makes a wide shape's thin features strokes and keeps its body a fill
Stroke is the widest feature that can be stroked, and it was applied to
each connected shape as a whole: a thick body with thin arms stayed one
filled area. Now a shape wider than Stroke somewhere keeps as its area
every disc wider than Stroke that fits in it, and each piece outside
those discs that reaches out of them at least one and a half times its
own width (and 3 px) is traced as a stroked center line. A line's end at
the area goes to the cut, so the line's cap closes the join. Corners and
edge slivers stay in the area, and a piece that cannot be traced stays
in it too. Shapes no wider than Stroke trace as before.

Each line keeps one width; without Fills, the area is still a 1 px
outline.

Docs: docs/target-app-parity.md.
2026-11-13 01:01:59 -08:00
dotCooCoo 3792561e1a Learn: View more opens a tutorial's practice sample, and Next Up shows the next tutorial
Under a tutorial's steps, View more opens the tutorial's practice sample
as a new untitled document, which becomes the active one; open documents
stay as they are, and Save asks where to save the copy. Each of the 12
tutorials has its own small SVG drawing in panels/learn/samples.rs, read
only when View more is pressed.

Once the sample is open, Finish tutorial marks the tutorial finished.
A finished tutorial shows Next Up with the next tutorial's title in the
same skill, and Next Up shows that tutorial without opening its sample.
After a skill's last tutorial the panel says so and shows Back to
skills; Next Up never moves to another skill. Finished tutorials are
kept while the app runs; the skill rings and counts do not show them
yet. The help page's short video is not part of this change.

- learn.openSample, learn.finish and learn.next run the three controls
  and are listed in the UI command catalogs; a missing, non-string or
  unknown tutorial id, or a step out of order, is an error and changes
  nothing.
- New labels and messages have rows in every catalog.
- Docs: docs/mcp.md, docs/target-app-parity.md, docs/ui-parity.md and
  the ASSETS.md line for art generated in code.
2026-11-13 00:51:37 -08:00
HassanKhan 6dcbf804ca Character panel: icons for the font height references (#6304)
The Set Font Height Reference dropdown shows an icon before each
reference's name, in the open list and in the closed field: Em Box
frames the whole square around an A, Cap Height and x-Height put a bar
from the baseline to the top of a capital A or a lowercase x, and ICF
Box frames a square inset in the em square. The icons are painted with
egui's painter in the row's text colour and the theme accent.

widgets::dropdown_icon_names is a dropdown_names whose options carry a
painted icon.
2026-11-13 13:28:16 +05:00
Don Omondi cfa3221dd3 Roadmap M3 row: the #1638 note goes in the Status cell 2026-11-13 03:21:08 -05:00
Don Omondi ffc22ffc4c Merge remote-tracking branch 'upstream/main' into fix/graphic-styles-list-height-2992
# Conflicts:
#	docs/roadmap.md
#	docs/target-app-parity.md
2026-11-13 03:20:58 -05:00
BFlat 9a1a158a3f Merge pull request #7060 from dotCooCoo/fix/dcs-regained-clip
Place: a DCS file that regains its clipping path clips the group that stayed
2026-11-13 15:04:28 +07:00
BFlat 46be3af7f8 Merge pull request #7064 from dotCooCoo/feat/envelope-warp-points
Envelopes: the Mesh tool and Direct Selection edit a warp envelope's points
2026-11-13 15:04:18 +07:00
BFlat 806dd5ef5b Merge pull request #7049 from dotCooCoo/fix/3d-face-budget-per-object
3D: an object's fill and stroke solids share one face limit
2026-11-13 15:04:08 +07:00
BFlat dd8446f3a4 Merge pull request #7054 from dotCooCoo/feat/nine-slice-guides-outside-art
Symbols: 9-slice guides may lie outside the symbol's art
2026-11-13 15:03:59 +07:00
dotCooCoo f278364816 Type: a selection in a warichu block highlights its own block line
A selection inside a warichu block was highlighted across the whole
line of text, so selecting a character of the upper block line
highlighted the lower one too, and a selection from one block line to
the next spanned the wrong characters. Each block line now gets its own
band, out to halfway to the block lines next to it, with one highlight
over each run of selected characters drawn side by side on it. A
selection that runs past the line still covers the line break.

Glyphs now carry their block line, so the characters of one block line
stay together for the highlight and for a click whatever their own
Character Alignment.
2026-11-12 23:47:30 -08:00
Patrik LermonandClaude Opus 5.5 4e0b50bc9c i18n(sv): translate 37 new strings, use the agreed terms in 9
Brings the Swedish catalog up to date with upstream main (7d77f8aeb).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 08:40:41 +01:00
dotCooCoo a367065afc Links: a mask row's tooltip finds its object without walking the stored art
The panel collects the objects whose opacity masks hold a listed image in
the same pass over the stored art that collects the rows' objects, once per
list rebuild. Each frame then finds a row's mask object by the layer tree's
index or in that cache, instead of walking every stored root for objects
inside symbols, graph designs and patterns.
2026-11-12 23:26:25 -08:00
BFlat 8998d94cc8 Merge pull request #7057 from dotCooCoo/feat/paste-remembers-sublayers
Layers: Paste Remembers Layers puts art back into the sublayer it was copied from
2026-11-13 14:18:03 +07:00
BFlat 11a37082f7 Merge pull request #7058 from dotCooCoo/feat/touch-workspace
Touch: a two-finger tap switches between selection and drawing modes
2026-11-13 14:17:54 +07:00
BFlat 001660517c Merge pull request #7059 from dotCooCoo/fix/dcs-eps-proxy-plates
Place: DCS links reopen with their plates under the low-resolution EPS proxy
2026-11-13 14:17:44 +07:00
BFlat cc5a63d7dc Merge pull request #7062 from dotCooCoo/fix/para-style-options-height
Text styles: Paragraph Style Options keeps OK and Cancel on a small screen after a section switch
2026-11-13 14:17:31 +07:00
BFlat 7d417a0729 Merge pull request #7048 from dotCooCoo/fix/font-menu-shared-filters
Font menu: every font menu shares one set of filters
2026-11-13 14:17:18 +07:00
BFlat d0b4df357c Merge pull request #7063 from dotCooCoo/fix/ui-parity-pencil-fidelity-unit
Docs: the Pencil row gives Fidelity in screen pixels
2026-11-13 14:17:05 +07:00
BFlat 9ba02d41d7 Merge pull request #7038 from dotCooCoo/fix/schema-expected-phrases
i18n: parameter schema errors translate what the value must be
2026-11-13 14:16:56 +07:00
BFlat 77b0bbf1d3 Merge pull request #7066 from dotCooCoo/fix/package-scope-after-save
Package: a package started after its save keeps the automation roots
2026-11-13 14:16:46 +07:00
BFlat d5699579de Merge pull request #7017 from mockydevs/fix/pdf-empty-actualtext-art-6971
PDF import: glyphs in a span with an empty ActualText come in as outlines
2026-11-13 14:16:32 +07:00
dotCooCoo b1323f8da1 Tests: the one-paint style fuzz case checks C's red 2 pt stroke
The fuzz case counted objects that match the look style C applies, so a
C read with no paint also passed. It now also checks that C's look has
no fill and one red 2 pt stroke.
2026-11-12 23:07:03 -08:00
dotCooCoo 06a283232e Type: no justification gap inside a right-to-left warichu block
Justification gaps follow the drawn order, and right to left the bidi
order draws a block's first glyph after the others. The glyph drawn
second then did not continue the block, so Full Justify and CJK
justification opened a gap inside it. Both gap rules now also skip a
pair whose glyphs belong to the same block.
2026-11-12 23:03:39 -08:00
dotCooCoo c30e553f74 3D: build each solid as its mesh is exported
Mesh export checked the object's solids together by building all of them
before the first mesh. It now builds and counts each solid as the loop
reaches it, so a mesh past the triangle budget stops the export before
the solids after it are built.
2026-11-12 23:03:32 -08:00
dotCooCoo 467c874fa0 Merge main into fix/3d-face-budget-per-object 2026-11-12 22:53:49 -08:00
dotCooCoo 64241978ec Links: a nested row's tooltip names the symbol, graph design, pattern or mask holding it
Two rows of the same file in different symbols showed the same name,
thumbnail and status. The tooltip of a row outside the layer tree now
adds the symbol, graph design or pattern whose art holds the image, and
the object whose opacity mask holds it.
2026-11-12 22:50:22 -08:00