Commit Graph
14082 Commits
Author SHA1 Message Date
dotCooCoo d8a25c4e9b Merge main into fix/clip-effects-hit-test 2026-11-14 09:30:12 -08:00
dotCooCoo 1d94c97425 Selection: symbol parts count the Preview of the instance's layers
Direct Selection on a dynamic symbol's instance below a layer whose
Preview is off tested and outlined the art in Preview, where the canvas
draws it in outline with the plain clipping paths. When a clipping
path's effects left no region, a selected object in its clip group kept
an outline cut to the plain clipping path.

- `hit::symbol_part_at` and `hit::symbol_part_outline_in_view` count the
  layers around the instance, the isolated container and the layers
  around it apart, as clicks outside symbols do.
  `symbol_part_outline_in_view` takes the click options in place of the
  outline flag.
- The outline of an object is empty when the effects of a clipping path
  around it leave no region.
2026-11-14 09:30:12 -08:00
dotCooCoo 4b5c09c543 Merge main into fix/paste-copied-file-size-limit 2026-11-14 09:28:46 -08:00
dotCooCoo 9838e4897d Merge main into fix/type-no-op-undo-more 2026-11-14 09:28:29 -08:00
dotCooCoo 2925fb4487 Merge main into feat/da-complete-messages 2026-11-14 09:25:42 -08:00
dotCooCoo 4872620853 Merge main into fix/svg-raster-keeps-resolution 2026-11-14 09:25:37 -08:00
dotCooCoo 4832f06ea4 Merge main into fix/pdf-tiff-keeps-icc 2026-11-14 09:25:31 -08:00
dotCooCoo d8605229cd Merge main into fix/3d-shadow-builds-once 2026-11-14 09:22:36 -08:00
dotCooCoo 40eafe9c64 Merge main into fix/ai-wrap-options-edge-cases 2026-11-14 09:22:28 -08:00
dotCooCoo f05455a259 Merge main into fix/blend-reversed-key-stroke-direction 2026-11-14 09:19:23 -08:00
dotCooCoo 87da8132eb Merge main into fix/ai-envelope-budget-warped-type 2026-11-14 09:19:15 -08:00
dotCooCoo ed03357502 Merge main into feat/arrange-nest 2026-11-14 09:12:06 -08:00
dotCooCoo 77d4c1cc33 Merge main into fix/graph-series-group-opacity 2026-11-14 09:06:41 -08:00
dotCooCoo f8e4a186bd Merge main into perf/remove-breaks-thread-frames-once 2026-11-14 08:59:36 -08:00
dotCooCoo ae39914b9f Remove Breaks: a partly selected story's frames are gone through once
When only some frames of a threaded story are selected, Remove Line
Breaks and Remove Paragraph Breaks built the story's frame list again
for every selected frame of it, so the work grew with the square of the
frame count. The command now notes a thread once its story is found not
to be selected in full, and reads that thread's other selected frames
on their own without going through the thread again. Each selected
frame still loses its own breaks, in the order selected, as one undo
step.

A test-only counter in threads.rs counts story_in calls, and
remove_breaks_goes_through_a_partly_named_story_once checks both break
kinds with frames named out of order and twice.
2026-11-14 08:58:57 -08:00
dotCooCoo 40d0b31cbe Effects: the clipping path doc comment says what the member limit leaves of a compound path
When the member limit is reached among the paths of a compound clipping
path that has geometry effects of its own, the compound path still
becomes one path of its reshaped geometry. The paths that were not
visited go into that geometry as they are, and their own effects are
not applied. The doc comment of with_clip_effects_applied_while said
that they keep their effects, which holds for the members of a group or
layer only.

New test a_compound_clipping_path_takes_its_own_effect_at_the_member_limit
covers the compound path.
2026-11-14 08:54:44 -08:00
dotCooCoo 11bd1659f5 Selection: symbol parts follow the region a clipping path's effects give it
Direct Selection on a dynamic symbol's instance picked an object in the
region its clipping path's effects give it, but cut the object's outline
to the plain clipping path, so the outline came out empty or cut short.
In a layer of the art whose Preview is off, it tested the effect-shaped
region and the fills, where the canvas draws the plain clipping path and
outlines.

- `hit::symbol_part_outline` cuts to the bounds of the effect-shaped
  region. The new `hit::symbol_part_outline_in_view` takes the view's
  outline state, and the Direct Selection overlay passes it.
- `hit::symbol_part_at` tests art in a layer whose Preview is off in
  outline.
2026-11-14 08:51:22 -08:00
dotCooCoo 10225d82e5 Export: an HP-GL plot of the art's bounds leaves out images in symbol art
The bounds of a plot of the art's bounds no longer count the objects a
plot leaves out (placed images, objects at 0% opacity, unpainted paths)
when they sit in the art of a symbol. An instance whose symbol holds
nothing else is left out, so a document with only such instances is
refused with "nothing to export". The art of a dynamic symbol, and of a
group with effects, fills or strokes of its own, is measured whole.
2026-11-14 08:50:21 -08:00
dotCooCoo dac3fe54d8 Learn: Gujarati rows for the new command labels
The Gujarati catalog lists every menu and command label, and it had no
rows for Show Learn Tab, Show Skill and Back One Level. It now has them.

docs/mcp.md said the For you and Skills tab buttons run learn.tab. A tab
button runs it only when the panel shows the other tab, and the page now
says so.
2026-11-14 08:49:48 -08:00
dotCooCoo d3789f2b0c Graphs: outlined labels and opened .ai graphs keep the plot in place at the next redraw
- A graph opened from a .ai file now saves `placedArt` too. Moving or
  restyling one of its labels before the first redraw no longer moves or
  stretches the plot.
- Type > Create Outlines on a graph's labels now adjusts the saved bounds,
  so the outlines do not read as a move at the next redraw. A move of
  the graph made before the outlining is still followed.
- A `placedArt` with no width or height falls back to the bounds of all
  of the art, as a graph saved without it does.
- `art_bounds` moves to the doc crate so the .ai reader can use it.
- docs/mcp.md describes `placedArt`, `placed` and when a redraw follows
  a move.
- Tests: a legend across the top, a legend after a right value axis and
  legend labels of several lines keep the plot in place through label
  size changes; moving a category label on its own; outlining labels
  before and after a move; a flat `placedArt`; a label moved in an
  opened .ai graph.
2026-11-14 08:47:03 -08:00
BFlat 460d211995 Merge pull request #7615 from storytold/fix/brush-freehand-needs-points
Keyboard Shortcuts: Paintbrush stroke needs points (fix main)
2026-11-14 23:46:08 +07:00
dotCooCoo 04df80f4e5 Docs: the Image Trace evidence lines give the continuous-tone cutoff as a tenth 2026-11-14 08:42:56 -08:00
dotCooCoo 2046c646fa Image Trace: blend settling caps its pairs of label changes at the size of a label copy
The pairs a band or group of strips keeps for its changed labels now grow
by doubling only up to the count that fits in a copy of its labels, so they
never take more memory than that copy. The next change moves them into the
copy.

- Tests: most of a share changing gives the same labels as when few change,
  for both settle passes and every share size (the copy path); both settle
  passes return a picture with no pixels unchanged.
2026-11-14 08:42:53 -08:00
dotCooCoo a4c513f101 Live Paint: Make starts a closed edge where its path starts
The edge built from a closed path that nothing cuts started at the anchor the
planar map gave it, so dashes, a width profile or a brush began at a different
place than on the path. The edge now starts at the anchor where its path
starts. An edge with no anchor there takes its dashes from its own start and
leaves off the profile and brush.

The command description and the progress doc say that dashes aligned to
corners and path ends are not fitted to cut edges.
2026-11-14 08:39:47 -08:00
dotCooCoo 3de44da6a6 Image Trace: a gray photo with little noise counts as continuous tone
The continuous-tone check exempts a neutral or single-curve picture when
sixteen colors leave at most a fifth of the error of eight. The
exemption is for flat art of up to sixteen clean levels, where sixteen
colors leave no error. A gray photo with 0 to 2 levels of noise measures
0.19, under the cutoff, so it was classed as flat art and traced without
smoothing, while its color original and the same photo with more noise
were smoothed.

The cutoff is now a tenth (VectorCraft's own value). Clean gray, sepia,
single-hue and duotone art of up to sixteen levels stays flat art.

Docs: docs/target-app-parity.md.
2026-11-14 08:37:49 -08:00
dotCooCoo da8f6ab721 Smooth tool: a whole closed path with a corner starts nearest its old start
When a drag reaches every anchor of a closed path that has a corner, the
path is cut open at the corner and refitted. The result started at the
corner unless the refit kept an anchor exactly at the old first anchor.
It now starts at its point nearest the old first anchor, at an anchor
there or at a new anchor split into the curve, as the other closed-path
cases do.
2026-11-14 08:31:41 -08:00
ruchirguitar 415783e926 Symbols: add right-click context menu to panel items 2026-11-14 21:59:45 +05:30
dotCooCoo e001227ce1 Selection: effects on a hidden member of a clipping group leave clicks alone
A clipping path that is a group clips by its visible members only. A
geometry effect on a hidden member made clicks inside the clip group
count the group's type by its glyph outlines, where they count it by its
frame when nothing has an effect.

Clicks now ask `effects::reshaped_clip_outline`, which gives a region
only when an object the clipping path clips by has a geometry effect.
`clip_outline` uses the same function.
2026-11-14 08:29:00 -08:00
dotCooCoo 9954ad8a4d Canvas: the monitor profile conversion skips artboards outside the frame
convert_over looked up every artboard of the document for each row with
a translucent pixel, so a frame of 2,160 rows over a document with 1,000
artboards made about 2.16 million lookups. Over::new now takes the
frame's size and keeps only the artboards whose rectangles meet the
frame in the document, a pixel wider on every side.
2026-11-14 08:28:44 -08:00
dotCooCoo ef74b358f6 Docs: a clipping path that paints applies its fill and stroke effects after the group's
The geometry effects of a clipping path's own fills and strokes stay live when the clipping path has a fill or stroke, so they reshape it after the geometry effects of the clip group and of the groups around it.
2026-11-14 08:28:38 -08:00
dotCooCoo c3341be03c Effects: the member limit's doc comment covers clipping paths walked twice
A group or layer in a clipping path that has geometry effects of its
own is walked once for its members' effects and once for its own, and
its members count toward the member limit each time. The doc comment
of members_as_drawn now states this.
2026-11-14 08:28:31 -08:00
dotCooCoo 4aa2147fba Image Trace: blend settling keeps its changes within the labels' size
Each band of rows (settled) and each group of strips (settled_wide) now
keeps its changed labels as pixel and label pairs only until the pairs
would take more memory than a copy of that part's labels, and then keeps
the copy with the changes made. settled_wide splits the picture into
ranges of columns instead of first listing the start of every strip.

- The tests of settled and settled_wide move into cut_edge.rs, and both
  functions are private again.
- A new test checks that the changes switch to a copy at that size and
  give the same labels either way.
- parallel_map is imported from the crate root, as in deblock.rs and
  smooth.rs.
2026-11-14 08:27:52 -08:00
dotCooCoo 335ded4b0a Learn: a click on the shown tab runs no command
A click on the For you or Skills tab the panel already shows ran learn.tab
although the view did not change. The tab buttons now run it only for the
other tab.
2026-11-14 08:27:23 -08:00
dotCooCoo 501dad41a1 Merge main into fix/file-folder-param-classification 2026-11-14 08:23:36 -08:00
dotCooCoo be44f10b6a Effects: a clipping path's members count toward the member limit of a group's effects
When a group's geometry effects evaluate the members of the group, a
clip group's clipping path takes the geometry effects in it first. A
clipping path that is a group, layer or compound path had each of its
members reshaped at every depth without counting them, so a large
clipping path was reshaped past the SYMBOL_ART_MAX_NODES members that
members_as_drawn documents.

Each member of a clipping path now counts as one visited member. Once
the limit is reached, that member and the members after it keep their
effects, as the other members past the limit do. The canvas, the
export bake and clipping type are unchanged: they do not count members.
2026-11-14 08:21:58 -08:00
dotCooCoo 845a3bc9ca Merge main into fix/monitor-profile-after-blending 2026-11-14 08:16:04 -08:00
dotCooCoo 46c9f922c2 Type: a document draws only its own composite font definitions
While a document's composite fonts are lent, type naming a composite font
the document does not define is set as in a missing font, even when the
front document or the document a placed document sits in defines one of
that name. A document that defines no composite font gets an empty scope
too, so a document in the back, a tiled window, a thumbnail or an export
made while another document is in front no longer borrows the front
document's definitions. A temporary document drawn while a document draws
keeps that document's fonts, and type laid out with nothing lent still uses
the registered ones.

- FontDb::composite_font looks only in the latest loan of the database.
- lend_composite_fonts lends an empty set at the top level when the
  database holds composite fonts; lend_document_composite_fonts also lends
  one inside another loan, for placed documents, back-document measuring
  and threaded reflow on open.
- A loan that leaves out a registered font gets its own generation, so
  layouts made with that font are not reused under it.
2026-11-14 08:16:02 -08:00
dotCooCoo 745dccb376 Merge main into fix/learn-panel-commands 2026-11-14 08:15:49 -08:00
dotCooCoo 6be8f3095b Metafile import: a clip that runs back over its own edges still clips
A clip path is left out only when it is one rectangle around the whole
picture. One figure through a box's four corners that runs back over its
edges encloses less than the box, and the objects under such a clip are no
longer imported unclipped.
2026-11-14 08:14:18 -08:00
dotCooCoo 261fa40d24 Merge main into fix/convert-to-text-locked-frames 2026-11-14 08:11:13 -08:00
dotCooCoo 4c67b8f73c Graphs: swatch edits reach the kept black legend fill of graphs that draw it
Only a pie with Legends in Wedges picks its legend labels' fill, white on
dark wedges. Paint visits and swatch mappings now leave its default black
legend fill out only for such a pie; other graphs draw the kept fill, so
it is visited and mapped like the other label fills. A color mode change
still leaves the default black legend fill as the default, so turning on
Legends in Wedges later keeps the white labels on dark wedges.
2026-11-14 08:02:17 -08:00
dotCooCoo 62604c38bd Merge main into fix/wireframe-transform-measures-shadow 2026-11-14 08:01:42 -08:00
dotCooCoo 5c9717474f Graphs: restyling the labels leaves the plot where it is at the next redraw
The next redraw of a graph compared the bounds of all its generated art,
labels included, with the bounds stored at the last generation, and took
any difference for a move or scale of the graph. Label edits that change
the size of the type (a new size, an indent, a legend size) changed those
bounds without a move, so the plot shifted and stretched when the graph
was drawn again.

The spec now also stores the bounds of the art without type
(`placedArt`), and moves and scales are measured on those. Graphs saved
without them are measured on the whole bounds as before. Moving one
label with Direct Selection no longer moves or stretches the plot at the
next redraw.
2026-11-14 08:00:54 -08:00
dotCooCoo ddae31bad4 TIFF: alpha after another extra sample places and opens as transparency
A CMYK or grayscale TIFF reads its alpha from the first extra sample whose
ExtraSamples value is 1 or 2, wherever it comes among the extra samples, at
8 and 16 bits, chunky or planar. TIFF 6.0 gives each extra sample its own
ExtraSamples value, in order, and asks readers to skip extra samples they do
not use.

- A CMYK file with alpha after an unspecified extra sample was kept as
  opaque inks; it is now shown as RGB with its alpha.
- A grayscale file with alpha after an unspecified extra sample opened
  opaque.
- A six-sample CMYK file whose ExtraSamples tag lists only an unspecified
  value no longer reads that sample as transparency.
- A white-is-zero grayscale file with an alpha channel opens; it failed to
  read before.
2026-11-14 08:00:43 -08:00
dotCooCoo bbe9480656 Shape Builder: an open path counts as filled by the fill rows that draw
Consider Open Filled Paths as Closed decided whether an open path was
filled from its top fill row only. A path whose top fill is None over a
painted lower fill stayed open, and one whose only painted fill was
hidden or at 0% opacity closed. The region map, merge inputs and the
Clicking Stroke Splits the Path cut now use Appearance::has_drawn_fill,
so any shown, painted fill row above 0% opacity counts, as the canvas
paints it.

The Shape Builder's Live Paint face and edge filters had the same
top-row check; they now use has_drawn_fill and has_drawn_stroke, so a
face or edge is taken when one of its rows draws.
2026-11-14 08:00:35 -08:00
dotCooCoo 93f9ec0346 Docs: only learn.markStep checks a tutorial id, not learn.resetProgress
docs/mcp.md said that for both learn.markStep and learn.resetProgress a
missing, non-string or unknown `tutorial` is an error. learn.resetProgress
takes no params and clears the progress without reading `tutorial`
(crates/ui-egui/src/panels/learn.rs), so the sentence now names the
tutorial errors under learn.markStep alone, and the rule that an error
changes nothing stays with them.
2026-11-14 07:59:21 -08:00
dotCooCoo 10f94b544d MCP: livePaint.info lists every appearance row of a face or edge
livePaint.info reported only the top fill of each face and the top
stroke and weight of each edge, so a lower row that draws under an
unpainted top row was not visible to a client. Each face and edge now
also carries `appearance`: every fill and stroke row, bottom first, as
{index, kind, paint, opacity, visible, width (strokes only), drawn}.
`drawn` follows Expand's rule row by row: the part is shown with an
opacity above 0, and the row is shown, has paint and an opacity above
0, and a stroke has a weight above 0. The existing `fill`, `stroke`,
`width`, `bounds`, `sources`, `gapOptions` and `gaps` fields are
unchanged.

The params text no longer says the group defaults to the selection:
the command takes `group`, or `id` when `group` is left out, and
returns an error without either.
2026-11-14 07:57:56 -08:00
dotCooCoo fbf2bee87b MCP: a malformed artboard or history index is reported as not a whole number
The artboard commands that take `index` or `indices`, a replayed
`selectedArtboards`, the artboard Align and Distribute commands
(`artboard`, `activeArtboard`), `edit.newDocumentFromState` and Paste in
Place, in Front and in Back now report a value that is not a whole number
with "`<key>` must be a whole number" or "`<key>` must contain whole
numbers", naming the key. A whole number that names no artboard or state
keeps `no such artboard`, `no history state N` or the paste range message.

- A null artboard `index` is `missing index`, as for other required keys.
- An `indices` value that is not a list, an empty list and a malformed
  entry each have their own message naming the key.
- `edit.newDocumentFromState` still uses the current state for an omitted
  or null `index`.
- Paste checks the form of both `artboard` and `artboards` before either
  range.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-14 07:57:00 -08:00
dotCooCoo f7d1643a83 Live Paint: Make keeps the direction of gradient strokes along or across the path
A stroke whose only setting that depends on direction is a gradient along or
across the stroke now goes through the same edge fitting as dashed strokes, so
each cut edge runs the way its source path does and the gradient keeps its
direction.
2026-11-14 07:56:39 -08:00
dotCooCoo 9e85368a44 Metafile import: a file that reaches the most objects one file may hold says so
The reader keeps at most 200,000 objects from one file and stops reading
there. A picture that reaches that count now carries a warning that any
objects after them were not read, and objects dropped past the import's own
object limit carry a warning too.
2026-11-14 07:55:40 -08:00