Skip to content

Add LinearGradient#850

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

Add LinearGradient#850
Dark-Existed wants to merge 1 commit into
OpenSwiftUIProject: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 related

@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.

@Kyle-Ye Kyle-Ye added area: graphics Color, shape, gradient, image, symbols, and graphics primitives. type: feature New API, behavior, platform support, or user-facing capability. labels May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: graphics Color, shape, gradient, image, symbols, and graphics primitives. type: feature New API, behavior, platform support, or user-facing capability.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants