Skip to content

Add LinearGradient#850

Open
Dark-Existed wants to merge 1 commit intoOpenSwiftUIProject:mainfrom
Dark-Existed:feature/linear_gradient
Open

Add LinearGradient#850
Dark-Existed wants to merge 1 commit intoOpenSwiftUIProject:mainfrom
Dark-Existed:feature/linear_gradient

Conversation

@Dark-Existed
Copy link
Copy Markdown
Contributor

@Dark-Existed Dark-Existed commented Apr 12, 2026

Block by OpenSwiftUICore.LinearGradient._Paint swift_dynamicCast

@Dark-Existed Dark-Existed force-pushed the feature/linear_gradient branch 5 times, most recently from 83082a6 to 5d287f6 Compare April 13, 2026 17:27
@Dark-Existed Dark-Existed force-pushed the feature/linear_gradient branch 2 times, most recently from fdd0b16 to 6b32b17 Compare April 19, 2026 16:20
@Dark-Existed Dark-Existed marked this pull request as ready for review April 25, 2026 17:55
@Dark-Existed Dark-Existed requested a review from Kyle-Ye as a code owner April 25, 2026 17:55
@Dark-Existed Dark-Existed force-pushed the feature/linear_gradient branch from 6b32b17 to 2e89d5b Compare April 25, 2026 17:56
@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented Apr 25, 2026

🤖 Augment PR Summary

Summary: This PR introduces first-class gradient infrastructure and a new LinearGradient paint/style implementation.

Changes:

  • Adds Gradient, AnyGradient, and a richer ResolvedGradient model (including color-space conversion and animatable vector support)
  • Introduces a Paint/ResolvedPaint abstraction and an AnchoredResolvedPaint wrapper to carry bounds through resolution/drawing
  • Implements LinearGradient as a Paint + View, drawing via GraphicsContext gradient shading
  • Extends GraphicsContext.ResolvedShading to support gradients (geometry + option set)
  • Updates shape-style packing/rendering to store/animate linear-gradient paints and to resolve gradients from a ShapeStyle
  • Updates AnyShapeStyle to preserve AnyGradient providers
  • Improves Color.Resolved animation data to support perceptual-space interpolation when enabled

Technical Notes: The new gradient pipeline relies on ResolvedPaint visitor/casting for animatable fill reconstruction and on ResolvedGradientVector for gradient interpolation.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 4 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

var colorSpace: ResolvedGradient.ColorSpace

func resolve(in environment: EnvironmentValues) -> ResolvedGradient {
base.resolve(in: environment)
Copy link
Copy Markdown

@augmentcode augmentcode Bot Apr 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sources/OpenSwiftUICore/Graphic/Gradient/GradientColorSpace.swift:51: ColorSpaceGradientProvider.resolve currently returns base.resolve(in:) without applying colorSpace, so calling .colorSpace(_:) has no effect on the resulting ResolvedGradient.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


// MARK: - AnchoredResolvedPaint

package struct AnchoredResolvedPaint<P>: ResolvedPaint where P: ResolvedPaint {
Copy link
Copy Markdown

@augmentcode augmentcode Bot Apr 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sources/OpenSwiftUICore/Graphic/Color/Paint.swift:154: AnchoredResolvedPaint doesn’t override resolvedGradient, so wrapping a gradient paint with bounds makes AnyResolvedPaint.resolvedGradient become nil (and also prevents visitors that cast to LinearGradient._Paint from matching the underlying paint type).

Severity: high

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

private mutating func setColorSpace(_ colorSpace: ResolvedGradient.ColorSpace) {
guard self.colorSpace != colorSpace else { return }
for i in stops.indices {
stops[i].color = colorSpace.convertIn(colorSpace.convertOut(stops[i].color))
Copy link
Copy Markdown

@augmentcode augmentcode Bot Apr 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sources/OpenSwiftUICore/Graphic/Gradient/Gradient.swift:425: ResolvedGradientVector.setColorSpace converts using colorSpace.convertOut(...) on an InterpolatableColor that is still encoded in the previous self.colorSpace, which likely corrupts colors when mixing/animating gradients across different color spaces.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

let li = stops[i].interpolation ?? .linear
let ri = other.stops[i].interpolation ?? .linear
stops[i].interpolation = BezierTimingFunction<Float>(
p1: (li.p1x * scale + ri.p1x, li.p1y * scale + ri.p1y),
Copy link
Copy Markdown

@augmentcode augmentcode Bot Apr 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sources/OpenSwiftUICore/Graphic/Gradient/Gradient.swift:384: In add(_ other:scaledBy:), the Bezier timing-function components apply scale to li (lhs) rather than ri (rhs), so lhs += rhs * scale behaves incorrectly for stop interpolations during animation.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant