Commit Graph
1000 Commits
Author SHA1 Message Date
BFlat 9153900b1f Merge pull request #7322 from dotCooCoo/fix/graph-series-group-opacity
Graphs: the transparency set on a series group is kept
2026-11-15 05:30:04 +07:00
BFlat 052c1b1d77 Merge pull request #7465 from dotCooCoo/fix/blend-reversed-key-stroke-direction
Blend: stroke gradients and dashes follow a key path the blend turns
2026-11-15 05:27:01 +07:00
BFlat 20ae675b9b Merge pull request #7622 from dotCooCoo/fix/graph-label-restyle-keeps-plot
Graphs: restyling the labels leaves the plot where it is at the next redraw
2026-11-15 04:22:27 +07:00
BFlat 88b83a8689 Merge pull request #7546 from dotCooCoo/fix/svg-raster-keeps-resolution
SVG import: a raster stored again as PNG keeps its resolution
2026-11-15 04:22:10 +07:00
dotCooCoo c7c9e7f4db Merge main into fix/graph-series-group-opacity 2026-11-14 12:29:26 -08:00
dotCooCoo 81ec6498dc Merge main into fix/blend-reversed-key-stroke-direction 2026-11-14 12:28:54 -08:00
BFlat 1a8614f00c Merge pull request #7550 from dotCooCoo/fix/graph-wedge-legend-black-kept
Graphs: a black fill set on wedge legend labels stays black on dark wedges
2026-11-15 03:22:47 +07:00
BFlat 85ce363b93 Merge pull request #7548 from dotCooCoo/fix/objects-on-path-widgets-flatten-once
Objects on Path: the widgets flatten the group's path once per lookup
2026-11-15 03:22:27 +07:00
BFlat 46a7dd24f6 Merge pull request #7646 from dotCooCoo/fix/nine-slice-symbol-lookups
Symbols: measuring and picking in 9-slice instances reuse one set of symbol boxes
2026-11-15 03:20:12 +07:00
dotCooCoo df257c2d53 Merge main into fix/svg-raster-keeps-resolution 2026-11-14 12:12:06 -08:00
dotCooCoo 6a078a0030 Blend: dashes on a closed key reversed from its own start read back from its end
A closed key that winds the other way is reversed keeping its start anchor.
Its dash offset was computed as if the reversed path ran back from position
0 instead of from the end of the subpath, so the dashes shifted by the
subpath length modulo the pattern period. The offset now uses the full
length in that case, and the dash test covers a closed key 40 long with a
7.5 period.
2026-11-14 11:41:09 -08:00
dotCooCoo a512bf5ce6 Image resolution: a WebP chunk length past the end of the file reads no resolution
The WebP chunk walk added the chunk length to the offset without a
checked add, so a length near u32::MAX overflowed on 32-bit targets
(wasm32) with overflow checks on. It now reads the chunk through the
same checked slice helper as the PNG, JPEG and TIFF readers.
2026-11-14 11:37:16 -08:00
dotCooCoo 3534dd7343 Symbols: measuring and picking in 9-slice instances reuse one set of symbol boxes
Measuring an instance of a symbol with 9-slice guides looked its map up
through Document::symbol_slice_map, which scanned the symbol list and
measured the art box again in new quick boxes, and NineSliceMap::place
and most_placed made new quick boxes of their own. Each of those boxes
built the symbol name index over the whole list on its first lookup, so
every 9-slice instance measured read every symbol once or more. Picking
an object inside a 9-slice instance's art with Direct Selection did the
same for each object of the art that holds a symbol instance.

- SymbolBoxes cuts the guides through the art box it has measured
  (SymbolBoxes::slice_map), and places and counts the art with itself as
  the boxes, in the mode quick boxes use. Art with no 9-slice map is
  moved by the instance's transform without looking the map up again.
- Document::symbol_slice_map, place_symbol_art,
  place_symbol_art_unclipped and edited_nine_slice use one set of quick
  boxes for each call.
- symbol_part_at and symbol_part_outline keep one set of quick boxes
  for the instance's art.

The new tests count the symbols read. Measuring 200 instances of a
symbol with guides and 200 of a symbol with guides holding it, among
2,002 symbols, read 1,205,204 symbols before; now each set of boxes
reads the list once. Picking in a 9-slice instance whose art holds 20
instances read 84,042 symbols among 2,001; now it reads the list at
most twice.
2026-11-14 10:32:20 -08:00
dotCooCoo 3be00f4bd3 Blend: a gradient steps where the other does only at a step of its own
When two gradients with different stop counts are blended, the second stop at the other
gradient's step took the last stop within the step tolerance, so two close but distinct stops
became a hard step. It now takes the last stop of a step of its own there, and otherwise paints
what the gradient paints at that place.
2026-11-14 10:14:38 -08:00
dotCooCoo 22ec066bb7 Blend: a turned hue gradient that reflects keeps its swatch links
A hue gradient that reflects unrolls through its curve, whose stops have no swatch links, so a
gradient along a closed key started elsewhere lost its links. The links now come from the
gradient's own stops unrolled as a Classic gradient's, in order, so stops at one place and the
stops where two runs meet keep their own links.
2026-11-14 10:03:08 -08:00
dotCooCoo 7e84899786 Merge main into fix/graph-series-group-opacity 2026-11-14 09:52:39 -08:00
BFlat e76f8d2c88 Merge pull request #7501 from dotCooCoo/fix/export-bakes-symbol-art-effects
Export: live effects in symbol art apply in PDF, EPS, print and DXF
2026-11-15 00:41:46 +07:00
BFlat 63129de08a Merge pull request #7595 from dotCooCoo/fix/image-scaling-alpha
Images: scaled-down images keep their color beside clear pixels
2026-11-15 00:41:27 +07:00
BFlat 3d895d9ac7 Merge pull request #7448 from dotCooCoo/fix/reverse-path-profiles
Paths: Reverse Path Direction turns the stroke's width profile and pen records with the path
2026-11-15 00:40:08 +07: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
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 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 43823fc844 Blend: a stroke gradient started on a step keeps the link after it
When a closed key path now starts where its stroke gradient steps between
two stops of one color linked to different swatches, the gradient's new
first stop takes the swatch link of the stop after the step instead of
the one before it.
2026-11-14 07:51:15 -08:00
dotCooCoo a3f65c677a Merge main into fix/graph-wedge-legend-black-kept 2026-11-14 07:24:01 -08:00
dotCooCoo 96a8a0c6d6 Merge main into fix/svg-raster-keeps-resolution 2026-11-14 07:23:45 -08:00
dotCooCoo 09eab2c93c Merge main into fix/blend-reversed-key-stroke-direction 2026-11-14 07:14:47 -08:00
dotCooCoo 9977ef2e01 Merge main into fix/graph-series-group-opacity 2026-11-14 07:11:27 -08:00
BFlat edefbd0e7d Merge pull request #7449 from dotCooCoo/fix/links-stored-brush-art
Links: placed images in stored brush art get Links rows
2026-11-14 21:55:20 +07:00
BFlat b541d97a06 Merge pull request #7586 from dotCooCoo/fix/blend-spot-stop-plates
Blend: steps between gradients linked to the same spot swatch keep its process plates
2026-11-14 21:54:47 +07:00
BFlat 35ac921b86 Merge pull request #7589 from dotCooCoo/chore/guides-shared-one-pass-helpers
Guides: document and layer guide edits share one set of one-pass helpers
2026-11-14 21:53:41 +07:00
BFlat 8863c41560 Merge pull request #7581 from dotCooCoo/fix/pdf-cmyk-image-keeps-icc
PDF export: CMYK images that keep their numbers carry their ICC profile
2026-11-14 21:53:33 +07:00
BFlat 5762ec729b Merge pull request #7598 from dotCooCoo/fix/symbol-art-bounds-nested
Symbols: a symbol nested in symbol art is measured by its own art
2026-11-14 21:53:07 +07:00
BFlat 64dd5eb174 Merge pull request #7418 from dotCooCoo/fix/reflected-dimension-line
Dimension tool: a reflected aligned dimension has its line on the reflected side
2026-11-14 21:52:10 +07:00
BFlat 508a0b0180 Merge pull request #7597 from dotCooCoo/fix/separations-spot-stop-plates
Print: a spot gradient stop prints its process plates on the separations
2026-11-14 21:51:47 +07:00
dotCooCoo 20529f1ffb Merge main into fix/graph-wedge-legend-black-kept 2026-11-14 06:08:51 -08:00
dotCooCoo 80854eb4b8 Merge main into fix/export-bakes-symbol-art-effects 2026-11-14 06:00:09 -08:00
dotCooCoo d233cd8291 Merge main into fix/graph-series-group-opacity 2026-11-14 05:57:05 -08:00
BFlat 3c15649730 Merge pull request #7427 from dotCooCoo/fix/live-paint-expand-drawn-stroke
Live Paint: Expand keeps the faces and edges that draw
2026-11-14 20:37:59 +07:00
BFlat 9800d48e58 Merge pull request #7571 from dotCooCoo/fix/cmyk-tiff-alpha-16-bit
TIFF: a 16-bit CMYK or gray TIFF with alpha converts at 16 bits
2026-11-14 20:37:26 +07:00
dotCooCoo b3c2fdab21 Merge main into fix/svg-raster-keeps-resolution 2026-11-14 05:11:34 -08:00
dotCooCoo bc24ad5352 Symbols: a symbol nested in symbol art is measured by its own art
Document::symbol_art_bounds measured a symbol's art without the
document, so an instance of another symbol in that art counted as the
20 x 20 square. It now measures the art through SymbolBoxes, so a nested
instance takes its own symbol's art, and an inline graphic of the outer
symbol is sized by it and follows it when that symbol changes.

- The inline resolve order also follows the instances that size a
  symbol's art, so a symbol is measured after the type in the art of
  the symbols it holds is laid out again.
- A symbol whose art reaches itself through an instance and an inline
  graphic is an empty slot. Only instances that the measurement uses
  count, so one a clipping path hides adds no dependency.
- A missing symbol, a symbol without art, a symbol that holds an
  instance of itself, and nesting 32 deep still measure as the square.
- SymbolBoxes finds symbols through a name index built once, and the
  inline resolve pass and inline_art_bounds share one index, instead
  of scanning the symbol list for each lookup.
2026-11-14 05:10:41 -08:00
dotCooCoo 786dcc5581 Images: scaled-down images keep their color beside clear pixels
The image crate's filtered resize filters each channel on its own, which
is correct only for premultiplied pixels, and its thumbnail averages each
channel on its own too. Placed images, linked-image previews, MCP
captures and previews, metafile bitmaps, PDF downsampling and library
thumbnails passed straight RGBA to them, so the color under clear pixels
(usually black) bled into the opaque pixels beside them and darkened
cut-out edges.

vectorcraft_doc::resample scales such images with each pixel's color
weighted by its alpha: filtered resampling premultiplies the pixels in
place and divides them back after, and averaging takes the area-weighted
mean of the pixels each new one covers. Opaque and alpha-free images are
scaled as before. PDF export also multiplies the inks of a CMYK image
with alpha by that alpha before resampling them, and divides them by the
resampled alpha after.
2026-11-14 05:07:39 -08:00
dotCooCoo 98bf61bb53 Merge main into fix/objects-on-path-widgets-flatten-once 2026-11-14 05:00:14 -08:00
dotCooCoo 0c892b5500 Merge main into fix/blend-reversed-key-stroke-direction 2026-11-14 04:51:02 -08:00
dotCooCoo 3597752c63 Merge main into fix/graph-wedge-legend-black-kept 2026-11-14 04:50:46 -08:00
dotCooCoo add6938441 Merge main into fix/links-stored-brush-art 2026-11-14 04:49:13 -08:00
dotCooCoo 1fe52fc5b6 Merge main into fix/separations-spot-stop-plates 2026-11-14 04:47:00 -08:00
dotCooCoo 6ab46b5fd8 Print: a spot gradient stop prints its process plates on the separations
A gradient stop linked to a spot ink that also carries process plates
(a DeviceN stop opened from a PDF) printed only its spot tint: print
separations and Separations Preview left its Cyan, Magenta, Yellow and
Black plates blank. They now print the stop's plates beside the tint.
With spots printed as process, each process plate prints the stop's
plate layered with the spot tint's process equivalent, as a separated
image's spot plates layer. Plates beside no spot link, or beside
Registration, still print nothing of their own.

The color visitor also skipped a freeform gradient's points, so print
plates kept their display colors and Document Color Mode left them
unconverted. The points are now visited as unlinked colors.
2026-11-14 04:46:10 -08:00
dotCooCoo 173a057beb Merge main into fix/reverse-path-profiles 2026-11-14 04:39:50 -08:00
dotCooCoo 7f17649731 Guides: document and layer guide edits share one set of one-pass helpers
Document::guides_to_saved, remove_edit_layer, retain_guides and the
artboard guide moves now call the layer helpers in node/ops.rs
(held_guides, strip_held, map_held), which Node::strip_ruler_guides and
Node::map_ruler_guide_positions already use. The copies in
document_guides.rs (picked_in_layers, drop_picked, edit_picked) are
removed. Picked stays for the walks through objects and opacity-mask art.

Results, guide order, copies kept for undo and the number of nodes each
walk looks at are unchanged.
2026-11-14 04:34:05 -08:00