Commit Graph

214 Commits

Author SHA1 Message Date
Timon
c6d6f9f8be Use cargo workspace to remove duplicated version, license, and author fields (#4226)
Use cargo workspace to remove dublicated version, license and author fields
2026-09-15 10:36:17 +00:00
Keavon Chambers
1940e430dc Replace the 'Luminance' node with a 'Desaturate' node with a better selection of desaturation methods (#4529)
* Remove the 'Threshold' node's luminance calculation dropdown so it always compares the Rec. 601 luma

* Find the HSL lightness extremes before encoding and drop a stale luminance TODO
2026-09-14 14:34:55 -07:00
Keavon Chambers
645d346565 Ease the Smooth gradient interpolation into the ends of an open ramp (#4521) 2026-09-12 16:26:03 -07:00
Keavon Chambers
3e51b757db Add the Curves adjustment node with a Transfer Curve type and editor widget (#4520)
* Add the Curves adjustment node with a Transfer Curve type and editor widget

* Address review feedback on the Transfer Curve widget's edge cases
2026-09-12 13:03:12 -07:00
Dennis Kobert
944d00cac5 Switch the Color struct back to storing unassociated alpha (#4518)
* Switch Color struct back to storing unassociated alpha

* Address review feedback

* Update the Invert node and legacy image migration for straight alpha and add round-trip tests

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2026-09-12 08:22:54 +00:00
Keavon Chambers
5612b63633 Extend open paths from endpoints with the Freehand tool and skip hidden layers in path edits (#4508)
* Let the Freehand tool continue a selected open path from its endpoint and show endpoint overlays in the Freehand and Spline tools

* Share the closest-point search with the open path endpoint lookup, tally endpoint connections in a single pass, and rename the endpoint overlay function

* Skip hidden layers and use the feeds-aware transform in path point searches, path overlays, and Freehand point placement

* Map the Spline tool's merge goal with the feeds-aware transform so it matches the endpoint candidates

* Highlight the hovered open path endpoint in the Freehand and Spline tools
2026-09-06 20:37:49 -07:00
Timon
c7a64fff0c Add the 'Basic Brush' node and replace the legacy Brush tool implementation with it (#4469)
* Draw raster images with pad extension instead of repeat

* Add the GPU basic brush renderer

* Rework the brush tool around the GPU basic brush

* Remove the CPU brush implementation
2026-08-27 15:19:02 +00:00
Timon
fd31f2d89b Add caching infrastructure for the GPU brush nodes (#4468)
Add the per-brush texture cache value type
2026-08-27 15:19:01 +00:00
Timon
10256dd22c Introduce the new brush stroke data types (#4467)
* Add the brush stroke format types

* Route brush strokes through the node graph

* Store brush style as per-item attributes instead of a struct
2026-08-27 15:19:01 +00:00
Timon
96cc520c4b Improve texture caching by allowing weak refs and more formats (#4447)
* Destroy GPU textures when the last reference drops

* Request pooled textures synchronously

* Pool cached textures by format

* Add the owned GPU buffer type

* Route the remaining GPU allocations through the executor

* Add weak texture parking to the texture cache

* Raise the texture cache budget to 1GB for native and 512MB for wasm
2026-08-27 15:19:00 +00:00
Timon
8c48d5acce Fix Vello-related GPU out-of-memory issues (#4446)
* Update vello

* Reuse vello image atlas slots across frames
2026-08-27 15:19:00 +00:00
Keavon Chambers
c8667edacc Make Data panel scalars selectable inline, denoise float display, and standardize breadcrumb string truncation (#4470)
* Make Data panel scalars selectable inline, denoise float display, and move breadcrumb truncation to Rust

* Code review fixes

* Remove denoising from f32
2026-08-22 01:28:23 -07:00
Keavon Chambers
2fa6b743fe Reintroduce improved logic for mesh interior region fill determination (#4464)
* Decide branching mesh fill insideness by winding, normalizing drawn direction at the Path node

* Fix dead connector click targets by explicitly closing the kurbo ellipse port paths

* Fix hole subtraction when a hole vertex is snapped exactly onto its covering contour

* Classify embedded negative space by its single surrounding face so fully enclosed mesh cells still fill
2026-08-19 00:59:40 -07:00
Keavon Chambers
daa8b6a5a4 Delete the vestigial region domain, reverting to naive logic for mesh region fill determination (#4463)
Delete the vestigial region domain, reverting the face fill decision to the bare branching test
2026-08-18 23:50:16 -07:00
Keavon Chambers
39425ca7ea Delete the dead StrokeId and FillId attributes from the Vector segment and region domains (#4461) 2026-08-18 17:51:29 -07:00
Keavon Chambers
c19f79977b Dedupe code for BezPath emission, epsilon constants, and Polynomial internals (#4459)
* Collapse duplicated BezPath emission, constants, and Polynomial surface across the vector algorithms

* Fix the quadratic segment length lower bound using a control leg instead of the chord
2026-08-18 16:24:12 -07:00
Keavon Chambers
5c580f9dac Clean up the Vector struct implementations by privatizing and deleting unused APIs (#4458)
Trim the Vector API surface by privatizing and deleting caller-less items
2026-08-18 15:54:55 -07:00
Keavon Chambers
e3b968f7e2 Port all remaining Subpath producers to BezPath and delete the legacy subpath module (#4457)
* Port all remaining Subpath producers to BezPath and delete the legacy subpath module

* Reset contour state at each MoveTo so an open contour's segments don't leak into the next region

* Give the polygon and star constructors a true center and radius instead of compensated arguments
2026-08-18 15:28:58 -07:00
Keavon Chambers
8f1b2bed5f Collapse ClickTargetType to a single multi-contour BezPath variant (#4456)
* Collapse ClickTargetType to a single multi-contour BezPath variant

* Restrict no-stroke point hits to a path's closed contours
2026-08-18 14:31:52 -07:00
Keavon Chambers
c111308c67 Replace the legacy Bezier struct with kurbo::PathSeg throughout (#4455) 2026-08-18 13:08:28 -07:00
Keavon Chambers
20af96c1d9 Remove remnant dead code across the Subpath, Vector, and editor geometry API surfaces (#4454) 2026-08-18 12:34:34 -07:00
Keavon Chambers
656daa26bc Render a paint from its Graphic directly instead of a single-element List wrapper (#4450)
* Render a paint from its Graphic directly instead of a single-element List wrapper

* Fix a stale doc comment reference to the moved paint render implementation
2026-08-17 21:26:13 -07:00
Keavon Chambers
e9e7ef54f6 Fix color and gradient list paints not rendering as stacks (#4439)
Stack every item of a color or gradient paint instead of painting only the first
2026-08-17 20:52:55 -07:00
Keavon Chambers
51662a5fe8 Fix the blend mode formulas for the Overlay, whole-color, and alpha-only modes (#4449)
* Fix the Overlay, whole-color, and alpha-only blend mode formulas

* Add unit tests covering the blend mode formula fixes
2026-08-17 20:28:17 -07:00
Keavon Chambers
35a98a2975 Move the color blending helpers down beside Color and BlendMode in no-std-types (#4448) 2026-08-17 19:33:28 -07:00
Keavon Chambers
ef6d430f97 Replace the IntoPaint trait with direct Graphic-typed node inputs (#4442)
* Let the Fill and Stroke paint inputs take Item<Graphic>, replacing the IntoPaint trait

* Rename the FIll node's "fill" input to "paint"

* Let the graphic-consuming nodes take List<Graphic> directly, relying on the embedding adapters

* Remove outdated todo comments

* Re-save the demo art
2026-08-17 03:10:02 -07:00
Keavon Chambers
d63362718f Split 'To Graphic' and 'Wrap Graphic' into the 'As Graphic' type assertion and 'Into Group' reducer nodes (#4441)
* Split 'To Graphic' and 'Wrap Graphic' into the 'As Graphic' type assertion and 'Into Group' reducer nodes

* Make 'Into Group' reduce List<DVec2> not Item<DVec2>

* Reset the Merge definition for every legacy alias of its coercion nodes

* Improve test
2026-08-17 02:19:59 -07:00
Keavon Chambers
104b8b71e6 Support embedding whole items into Graphic variants so their attributes survive the conversion (#4440)
Add embedding conversion adapters that move a whole ranked value inside a Graphic variant
2026-08-16 19:51:58 -07:00
Keavon Chambers
f635c56eab Fix color and gradient paints not rendering with their opacity attributes (#4438)
Fade color and gradient paints by their own opacity attributes
2026-08-16 15:52:27 -07:00
Keavon Chambers
c507b35645 Add rank-0 Item leaf variants to the Graphic enum alongside its List variants (#4437)
* Add the rank-0 Item leaf variants to the Graphic enum, rendering leaves and list rows through shared per-row logic

* Traverse the rank-0 Graphic leaf variants in the vector node helpers and flattening

* Reach rank-0 vector graphics from the styling and gradient-fitting helpers

* Two code review fixes

* Fix comment
2026-08-16 02:24:15 -07:00
Keavon Chambers
ba7cbd83bc Store an appearance's paint as a bare Graphic rather than a single-element List<Graphic> (#4435)
Rank the coverage's paint attribute down from List<Graphic> to Graphic
2026-08-14 22:13:00 -07:00
Keavon Chambers
69585b25e3 Rename the Graphic enum wrapper variants with a "List" suffix (#4434)
* Make the Artboard and Gradient newtype fields public to match the other list newtypes

* Rename the Graphic enum's self-named Graphic::Graphic variant to Graphic::GraphicList

* Rename the Graphic::Vector variant to Graphic::VectorList

* Rename the Graphic::RasterCPU variant to Graphic::RasterCPUList

* Rename the Graphic::RasterGPU variant to Graphic::RasterGPUList

* Rename the Graphic::Color variant to Graphic::ColorList

* Rename the Graphic::Gradient variant to Graphic::GradientList

* Rename the Graphic::Text variant to Graphic::TextList

* Restore the SVG group tag comment that the variant rename sweep clobbered
2026-08-14 18:55:07 -07:00
Keavon Chambers
d117c3eace Adopt the cascading "appearance" attribute in place of Vector::stroke and the "fill"/"paint" attributes (#4433)
* Add the appearance model types and attribute constants

* Dual-write the appearance attribute alongside the fill/stroke pair in all paint-writing nodes

* Read paint from the appearance attribute in the renderer, analysis, metadata, and editor, cascading from ancestors

* Retire the fill/stroke attribute pair and the Vector stroke field in favor of the appearance attribute

* Replace the Stroke node's paint order input with the relative chain order of the Fill and Stroke nodes

* Code review fixes

* Re-save demo art

* Stamp coverages in place and fuse the renderer's per-item appearance reads into single walks

* Treat an empty appearance as the undeclared state so padded rows inherit instead of blocking the cascade

* Update demo art

* Treat padded appearance rows as undeclared in the boolean flatten's group recursion
2026-08-14 13:25:23 -07:00
Keavon Chambers
9a129ecf5c Fix clipping masks, click targets, and bounds when rendering Vector[] and flattened graphic wrappers (#4429)
* Honor clipping masks when rendering Vector[] lists, not just Graphic[] groups

* Keep per-layer click targets when a Vector[] round-trips through a Graphic[] wrapper

* Skip the rebuild and the merged-layers snapshot when flattening a lone anonymous graphic wrapper

* Fix a group's bounds excluding its raster children and stretching to the origin

* Fix SVG clipping masks landing in the wrong space when sibling layers differ in transform
2026-08-11 13:31:48 -07:00
Keavon Chambers
ceb2de51fb New nodes: 'Gradient Reverse', 'Gradient Shift', and 'Gradient Stretch' nodes for rearranging a ramp's stops (#4424)
* New nodes: 'Gradient Reverse', 'Gradient Shift', and 'Gradient Stretch' nodes for rearranging a ramp's stops

* Clip a lone out-of-range stop into the bake, and correct the docs that still promised edge-held stops
2026-08-08 03:09:06 -07:00
Keavon Chambers
6b1e9912ef Fix Vello rendering incompatibility with its gradients using premultiplied alpha instead of SVG's straight (#4419)
* Upgrade Vello to a git main revision that honors the brush's interpolation alpha space

* Interpolate Vello gradients with straight alpha, matching the SVG renderer

* Draw the gradient picker strip and fill swatches as SVG so transparency previews with straight alpha

* Keep gradient stop handles opaque so a transparent stop's RGB stays visible

* Paint a stopless gradient's picker strip and swatch black rather than transparent
2026-08-07 18:45:12 -07:00
Keavon Chambers
681b4033f5 Add a gradient interpolation attribute with Stepped, Linear (existing), and Smooth modes (#4418)
* Delete dead code function

* Add a Gradient Interpolation axis with Stepped, Linear, and Smooth paths through the stops

* Keep the gradient interpolation attached when dragging stops in the picker

* Give the gradient popover's dropdowns the same tooltips as their row labels

* Order the gradient popover with Intrp. above Space

* Hold gradient stops in place when the cyclic flag is toggled

* Fix wrong Smooth gradient colors around stops sitting on the ramp boundaries

* Consolidate gradient settings plumbing and fix bugs

* Bundle whole-ramp gradient settings into GradientSettings across the editor plumbing

* Name the Smooth gradient interpolation's spline type in its tooltip

* Linearize the gamma hex stop colors recovered from imported Graphite SVGs

* Code review

* Aim the Smooth bake's seam subdivision at the copied boundary color

* Add GradientEvaluator to build gradient sampling state once per loop instead of per sample

* Correct the gradient evaluator's documented setup cost to O(n log n)
2026-08-07 16:43:36 -07:00
Keavon Chambers
4b01abe36d Add a "Cyclic" gradient option that closes the ramp into a seamless loop (#4416)
* Add a Cyclic gradient attribute that wraps the stop list through the 1|0 boundary back to the first stop

* Show the wrap segment's midpoint diamond in the color picker spectrum strip when cyclic

* Keep the wrap midpoint diamond tracking the pointer by a wrapped strip width when dragged past the ends

* Give the Gradient tool's viewport overlay the same cyclic wrap midpoint diamond and drag behavior

* Correct the docs claiming the final stop's midpoint is always ignored now that cyclic uses it

* Move the gradient cyclic toggle onto the Ends row as a Link icon checkbox

* Update labels

* Register GradientHueDirection with the Data panel so its attribute column renders

* Reword wrap segment to wrapped interval and stray segment usages to interval

* Clean up comments

* Fix the color picker write-back losing default position elision and the blend path guessing the cyclic flag
2026-08-06 18:52:00 -07:00
Keavon Chambers
461ddbc872 Add the "Perceptual" and "Classic" families of gradient spaces with OkLab as the new default (#4415)
* Add an OkLab gradient interpolation space and make it the new default

* Fix the Properties panel fill row resetting the gradient interpolation space to the default

* Add OkLch, Lab, LCh, and HSL gradient interpolation spaces

* Add a hue direction attribute and picker choice for polar gradient interpolation spaces

* Add an HSV gradient interpolation space

* Rename the sRGB Linear and sRGB Gamma gradient spaces to RGB Linear and RGB Gamma

* Divide the gradient interpolation dropdown between absolute and relative color spaces

* Rename the OkLch gradient interpolation space to OkLCh for channel-notation capitalization

* Shorten the color picker popover's hue direction row label to Arc

* Call the Gradient Interpolation node's parameter Space and extend the picker tooltip title to match

* Rename the gradient interpolation attribute and type family to gradient space

* Rename the gradient tool's gradient space transform to gradient to viewport transform

* Add serde aliases and a node replacement covering the gradient space renames

* Give the gradient space choices artist-facing labels and reorder the dropdown sections

* Add a Gradient Hue Direction node and its attribute read node

* Say interpolate instead of blend for gradient stop color traversal in docs and tooltips

* Label the polar perceptual gradient spaces as Perceptual Hue and group the dropdown sections by geometry

* Add a migration alias covering the gradient space attribute reader rename

* Carry the gradient hue direction attribute through boolean operations

* Register GradientHueDirection wire types in the node registry
2026-08-06 02:40:25 -07:00
Keavon Chambers
3f082c881f Make gradient evaluation follow the ramp's interpolation space attribute (#4414) 2026-08-05 19:32:51 -07:00
Keavon Chambers
faed7f81bf Give whole-expanse gradient layers a transform cage based on the gradient line (#4413) 2026-08-05 17:47:54 -07:00
Keavon Chambers
fd01d66070 Add a gradient interpolation space attribute with sRGB Gamma (existing) and sRGB Linear (new) (#4412)
* Build dropdown menu entries from choice type metadata

* Add a gradient interpolation color space attribute, blending stops in linear light by default

* Add a Space interpolation dropdown to the color picker popover

* Stamp legacy gradient ramps with their implicit gamma interpolation during deserialization

* Resolve color-interpolation from SVG style blocks and fix cascade order among repeated declarations
2026-08-05 15:58:25 -07:00
Keavon Chambers
7762ab2e4c Add a Clear gradient spread that cuts off to transparency beyond the ends (#4410) 2026-08-05 00:27:18 -07:00
Keavon Chambers
7c8b189c71 Build radio widget entries from choice type metadata so variants display their icons (#4408)
* Build radio widget entries from choice type metadata so variants display their icons

* Route the node properties enum radio through the shared choice type entry builder
2026-08-04 21:16:14 -07:00
Keavon Chambers
788fe227c6 Rename gradient type to gradient form (#4405)
* Rename gradient type to gradient form

* Update the demo art for the gradient form rename

* Say form not type in the Gradient Form node's doc comment
2026-08-04 05:51:10 -07:00
Keavon Chambers
ca44dbaf55 Rename spread method to gradient spread so it matches the other gradient attribute names (#4404)
* Rename spread method to gradient spread so it matches the other gradient attribute names

* Keep the legacy gradient struct's spread method field name matching its on-disk key
2026-08-04 05:15:21 -07:00
Keavon Chambers
b2265be88f Move the gradient spread method into GradientRamp and the color picker popover (#4402)
* Add a spread method field to GradientRamp, carried at runtime as the gradient item's attribute

* Retire the Fill node's spread method input, folding its value into the gradient ramps on document upgrade

* Add an Ends spread method radio to the color picker popover, replacing the Gradient tool's control bar radio

* Update the demo art
2026-08-04 04:08:21 -07:00
Keavon Chambers
79136c95be Wrap serialized gradient stops in a new GradientRamp struct and unify FillChoice (#4400)
* Introduce the GradientRamp exchange struct as the serialized TaggedValue::Gradient payload

* Unify FillChoice and FillChoiceUI into one enum generic over color format, carrying GradientRamp stops

* Rename the TaggedValue::Gradient variant to GradientRamp to match its payload

* Move the Color variant into the tagged_value macro list since its stored and wire forms match
2026-08-03 23:23:41 -07:00
Keavon Chambers
2f24459344 Rework Gradient into a newtype of List<Color> with optional position and midpoint attributes (#4397)
* Rework Gradient into a newtype of List<Color> with optional position and midpoint attributes

* Fix Vello stopless-gradient fallback coverage, empty legacy gradient tables, the node docs gradient swatch, NaN position elision, and wired setter input overwrites
2026-08-03 04:05:02 -07:00
Keavon Chambers
e52a442504 Remove custom (de)serializers from the DashPattern and BoxCorners TaggedValue variants (#4394)
Replace the DashPattern and BoxCorners custom serde impls with storage-shaped Vec<f64> TaggedValue payloads
2026-08-02 01:00:46 -07:00