Commit Graph
20 Commits
Author SHA1 Message Date
Taha-Mahmoodi fd345e0c56 Pathfinder: Trap spreads the lighter colour into the darker as an overprinting strip where solid colours meet
The Pathfinder panel menu's Trap… (object.pathfinder.trap) and Effect › Pathfinder › Trap… (pathfinder.trap, live on groups) share one geometry (vectorcraft_pathops::trap_band, vectorcraft_effects::trap): Thickness, Height/Width, Tint Reduction, Traps with Process Color and Reverse Traps, plus the effect's Precision and Remove Redundant Points. The panel's Trap is one undo step and groups the traps above the topmost selected object. Behaviour from https://helpx.adobe.com/illustrator/using/trapping.html and https://helpx.adobe.com/illustrator/using/pathfinder-panel-overview.html.
2026-10-24 03:09:08 +07:00
bflatastic 2e572c7805 Count Repeats inside symbol art toward the Repeat instance budget
Squashed from #3788 onto main.
2026-10-24 02:06:39 +07:00
bflatastic c27ff0d96b Live Pathfinder budget: allow the manual lowest-bit form clippy flags, for rust-version 1.95 2026-10-23 11:08:06 +07:00
bflatastic d50afbcc1d Live Pathfinder budget: lowest set bit without the unstable isolate_lowest_one (rust-version 1.95) 2026-10-23 11:08:06 +07:00
NetterSilverandClaude Opus 5.5 c770e900e3 Cap the input of live Pathfinder effects
Fixes #3591

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 11:08:06 +07:00
Taha-Mahmoodi 4bb6f32911 Gradients: built with Gradient::new, so a new option touches one place 2026-10-22 22:38:41 +07:00
bflatastic a5c0c29b25 G2: Effect › Pathfinder › Soft Mix blends overlapping CMYK fills
Squashed from #3063 onto main.
2026-10-22 00:54:43 +07:00
bflatastic c895f64063 Format: rustfmt after the batch 2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 3f3888d040 G2: Effect › Pathfinder › Hard Mix mixes CMYK per face
Overlapping faces take the highest of each CMYK channel from every covering shape and drop strokes, matching Illustrator's Hard Mix effect.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
vangel76andClaude Opus 5.5 27230233cc Effects: a Transform effect on a group paints each copy with its own gradient (#2451)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:20:25 +07:00
vangel76andClaude Opus 5.5 b28e8490c2 Effects: skip type tests when built without craft-fonts (#2476)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 13:20:25 +07:00
dotCooCoo 4440463315 Effects: Effect › Pathfinder uses the glyph outlines of type in the group
Effect › Pathfinder left type in the group out of all ten operations,
on the canvas, in Expand Appearance and in exports. The text outliner
returns type as a group with one path per run. `leaves` in
crates/effects/src/group.rs took that group as one leaf, and
`geometry` gives no path for a group. A 100 x 100 pt square grouped
with a 100 pt "H" inside it kept all of its 10,000 pt² after Subtract
and Expand Appearance. In the shape modes a member group with type in
front also lost its paint, because it took the style of the outline
group, which has none.

`leaves` now takes the paths and compound paths of the outline art at
every depth, as it does for a member group, and gives each one the
type's opacity and blend mode. The same square keeps 8,684.88 pt² after
Subtract and Expand Appearance, its 10,000 pt² less the glyph's
1,315.12 pt².

Docs: docs/target-app-parity.md.
2026-10-16 04:04:50 +07:00
dotCooCoo 3bef84aaa6 Type: type drawn as glyph outlines keeps its underline, stroke weight, gradients and patterns
Type is drawn as its glyph outlines under a geometry effect, in EMF and
WMF export, in DXF export when it is written as outlines, through
Flatten Transparency with Convert All Text to Outlines, and inside an
envelope. Those outlines differed from the type the canvas draws in
four ways. They had no underline or strikethrough bars. A character
stroke on scaled type kept its unscaled weight. An unplaced gradient was
fitted to the glyphs it painted instead of the layout box. A run's
pattern tiles stayed in document space instead of scaling and turning
with the type. A group's or layer's own fills and strokes also painted
the glyphs of the type in it without the bars.

The outlines now include each run's underline and strikethrough bars,
as the canvas has drawn them since #850. Each run's path is made in
text space with its unplaced gradients fixed to the layout box, then
placed by the type's transform, which also scales its stroke weight
and dashes and transforms its pattern tiles. The type's own fills and
strokes have their unplaced gradients fixed to the bounding box of the
layout box in the document, where the canvas fits them.

Geometry effects that move or scale the outlines move and scale the
type's gradients with them: the type's own effects, also inside an
envelope and after Flatten Transparency has converted the type to
outlines, and the effects of a group, symbol instance or envelope that
holds the type. outline_text marks its group with a new node field,
type_outlines, which is saved with the document. reshape_leaves maps
the placed gradients in each marked group through the map that takes
the group's bounds before the effects onto its bounds after them. A
scale out of proportion stretches a radial gradient into an ellipse
and turns the isolines of a diagonal linear gradient, as it does on
type scaled by its own transform. Placed gradients outside those
groups stay where they are.
2026-10-16 02:26:15 +07:00
dotCooCoo 5473e3a5c5 Effects: type in a group with a geometry effect keeps its transparency, mask, effects and visibility
Geometry effects on a group or layer, and effects on a symbol instance,
blend or repeat, outline the type inside it. outline_nested_text
replaced each type object with a plain group of its outlines, so the
type lost its opacity, blend mode, opacity mask, knockout shape
option, own effects and perspective, and hidden type was drawn,
exported and made visible by Expand Appearance.

outline_nested_text now replaces type with the art that as_art makes
for it, which is also what reshape makes for type with geometry
effects of its own. That art has the type's own geometry effects and
perspective applied and keeps its name, transparency, opacity mask
and other effects. as_art also keeps the object's visibility and
knockout shape option, so hidden type with a geometry effect of its
own is left out of exports. Type in a clip group's clipping path still
becomes its plain outlines and now keeps its visibility.
2026-10-16 02:21:47 +07:00
bflatasticandClaude Opus 5.5 20e5a746bd Part of #885: the Transform effect's dialog takes Transform Each's controls
Effect › Distort & Transform › Transform… was a plain list of fields.
It now has Transform Each's layout: Scale and Move with sliders, Rotate
with an angle dial, then Copies, Reflect X and Y, the reference point and
Random, kept with the effect so editing it from the Appearance panel
shows them again.

- The effect scales, rotates and reflects about the chosen point of the
  9-point grid (`reference`, the centre by default).
- Random takes a share of each value, drawn from the object's id: each
  object varies its own way and keeps its result on every redraw; a
  group's members move together.
- Copies stop before one reaches past 1e9 pt, and the scale and move are
  capped, so large values can't overflow.
- Transform Each and the effect share the sections and options code; the
  angle dial is a new widget.
- A plain number field now takes the focus when it is a dialog's first
  field, so both dialogs open with Scale › Horizontal ready for typing.

Transform Objects, Transform Patterns and Scale Strokes & Effects are not
in the effect yet: the geometry effects reshape paths only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 14:32:10 +07:00
bflatasticandClaude Opus 5.5 e967c31be6 M4.58: raster effects in PDF on every kind of object
PDF export now renders the shadows, glows, blurs and feathers of groups,
layers, type, images, symbol instances, live objects and single fills and
strokes (and those inside opacity masks, symbol definitions and pattern
tiles) as images at the document raster effects resolution, instead of
leaving them out with a warning. Shadows and outer glows go under the
untouched vector art; a path whose fills or strokes carry effects is
written as one piece per fill and stroke. Expand Appearance shares the
image helpers (moved to rasterfx.rs); effect images now cover what the
renderer paints (members' shadows included).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 11:52:34 +07:00
Brandon ThomasandClaude Opus 5.5 3e323bfa2a Robustness: VectorCraft never crashes — no panics in shipped code
Shipped code no longer unwraps, expects or panics: every one of the 124
unwrap()/expect()/panic!/unreachable! sites outside tests now handles the
failure (Result/Option, ?, let-else, defaults) and reports errors to the user.

- Lints: workspace clippy denies unwrap_used, expect_used, panic, todo,
  unimplemented and unreachable; clippy.toml allows them in tests, and
  integration tests, examples and testkit opt out explicitly.
- Safety net (vectorcraft_engine::guard): a panic in a top-level command rolls
  the document back and returns EngineError::Internal; a panicking tool is
  reset; the MCP server answers with an internal error and keeps serving; the
  UI frame and each control request are guarded.
- APIs that hid failures now return them: Rendered::to_png/to_jpeg/to_webp
  return Result (JPEG/WebP errors used to write empty files),
  FontDb::face returns Option, Region::top returns Option.
- Fuzzing: engine/tests/import_fuzz.rs feeds garbage, hostile and mutated SVG
  and PDF through import → render → export (30k cases locally, no panics).
- Docs: AGENTS.md/CLAUDE.md rule, docs/development.md "Robustness" section,
  README pointer and a PR template checklist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 06:28:59 +07:00
bflatasticandClaude Opus 5.5 b4ba4ecf0a M3.70: Expand Appearance turns fills, strokes, effects and brushes into objects
effect.expandAppearance now expands the whole appearance: each visible fill becomes a
path of its own and each stroke its outline (a brushed stroke its brush art), grouped
in paint order under the object's id and transparency; geometry effects are baked and
raster effects become an embedded image (shadows below the art, blur/feather/inner glow
replacing it). Type with effects or its own fills is outlined, and a group's or layer's
own fills and strokes are expanded among its members. The command is enabled whenever
an appearance isn't basic. Builds on bake_leaf (effects::expand_leaf / expand_art) and
shares the raster-effect image code with PDF export.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 02:16:02 +07:00
bflatasticandClaude Opus 5.5 8a837fd4b9 M3.68: groups, layers and type have their own fills, strokes and effects, with Contents and Characters rows
A group's or layer's own fills and strokes paint every member's geometry, below or above the
members as the new contents slot (Appearance.contents_index) says; its geometry effects reshape
the members as one piece and its raster effects apply to the composite (one combined shadow),
respecting knockout groups. Type's own fills and strokes paint under or over its characters.
Render, SVG/PDF (via bake) and Expand Appearance evaluate them alike.

Commands: appearance.* / effect.* take target: "object"|"contents" and layer ids;
appearance.moveItem moves the Contents slot (from: "contents") or an item across it
(contents); appearance.targetContents selects a group's members. Graphic styles applied to a
group now style the group itself. The Appearance panel shows Contents/Characters rows that
drag, and double-click to target the members or edit the characters' paint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 00:59:34 +07:00
Brandon ThomasandClaude Opus 5.5 1c1fd0f139 M9.3: Effect → Pathfinder (Add, Intersect, Exclude, Subtract, Minus Back, Divide, Trim, Merge, Crop, Outline) as live effects on groups/layers; rendered via the live cache, baked by Expand Appearance
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:57:14 -04:00