New nodes: 'Gradient Type' and 'Spread Method', and add Gradient tool support for controlling these nodes (#4084)

* Use 'Transform', 'Gradient Type', and 'Spread Method' nodes for table gradients

* Add gradient widget to the tool's control bar and update where the two swap buttons go

* Fix gradient rendering

* Format

* Code review
This commit is contained in:
Keavon Chambers
2026-04-29 19:27:44 -07:00
committed by GitHub
parent e686ee9f42
commit 4b2430290c
13 changed files with 584 additions and 224 deletions

View File

@@ -230,11 +230,17 @@ async fn render<'a: 'n>(ctx: impl Ctx + ExtractFootprint + ExtractVarArgs, edito
scene.append(child, Some(footprint_transform_vello));
// We now replace all transforms which are supposed to be infinite with a transform which covers the entire viewport
// See <https://xi.zulipchat.com/#narrow/channel/197075-vello/topic/Full.20screen.20color.2Fgradients/near/538435044> for more detail
// We now replace all transforms which are supposed to be infinite with a transform which covers the entire viewport.
// See <https://xi.zulipchat.com/#narrow/channel/197075-vello/topic/Full.20screen.20color.2Fgradients/near/538435044> for more detail.
//
// `!is_finite()` rather than `== f32::INFINITY`: `scene.append` composes the child's `Affine::scale(INFINITY)` with
// the viewport rotation, leaving `matrix[0] = cos(θ) * INFINITY`. In the (90°, 270°) tilt range cos is negative so
// the result is `-INFINITY`, which the old equality check missed; Vello then rasterized a unit rect with non-finite
// vertices, dropping the gradient and tanking performance. `!is_finite()` also covers NaN as a guard against future
// code paths where `matrix[0]` could land on `0 * INFINITY`.
let scaled_infinite_transform = vello::kurbo::Affine::scale_non_uniform(physical_resolution.x as f64, physical_resolution.y as f64);
for transform in scene.encoding_mut().transforms.iter_mut() {
if transform.matrix[0] == f32::INFINITY {
if !transform.matrix[0].is_finite() {
*transform = vello_encoding::Transform::from_kurbo(&scaled_infinite_transform);
}
}