@@ -25,7 +25,11 @@ abstract class Gradient {
2525 const Gradient ();
2626
2727 /// Creates a [Shader] for this gradient to fill the given rect.
28- Shader createShader (Rect rect);
28+ ///
29+ /// If the gradient's configuration is text-direction-dependent, for example
30+ /// it uses [FractionalOffsetDirection] objects instead of [FractionalOffset]
31+ /// objects, then the `textDirection` argument must not be null.
32+ Shader createShader (Rect rect, { TextDirection textDirection });
2933}
3034
3135/// A 2D linear gradient.
@@ -91,21 +95,37 @@ class LinearGradient extends Gradient {
9195 assert (colors != null ),
9296 assert (tileMode != null );
9397
94- /// The offset from coordinate (0.0,0.0) at which stop 0.0 of the
95- /// gradient is placed, in a coordinate space that maps the top left
96- /// of the paint box at (0.0,0.0) and the bottom right at (1.0,1.0).
98+ /// The offset at which stop 0.0 of the gradient is placed.
99+ ///
100+ /// If this is a [FractionalOffset] , then it is expressed as a vector from
101+ /// coordinate (0.0,0.0), in a coordinate space that maps the top left of the
102+ /// paint box at (0.0,0.0) and the bottom right at (1.0,1.0).
97103 ///
98104 /// For example, a begin offset of (0.0,0.5) is half way down the
99105 /// left side of the box.
100- final FractionalOffset begin;
106+ ///
107+ /// It can also be a [FractionalOffsetDirectional] , in which case it is
108+ /// expressed as a vector from the top start corner, where the start is the
109+ /// left in left-to-right contexts and the right in right-to-left contexts. If
110+ /// a text-direction-dependent value is provided here, then the [createShader]
111+ /// method will need to be given a [TextDirection] .
112+ final FractionalOffsetGeometry begin;
101113
102- /// The offset from coordinate (0.0,0.0) at which stop 1.0 of the
103- /// gradient is placed, in a coordinate space that maps the top left
104- /// of the paint box at (0.0,0.0) and the bottom right at (1.0,1.0).
114+ /// The offset at which stop 1.0 of the gradient is placed.
105115 ///
106- /// For example, an end offset of (1.0,0.5) is half way down the
116+ /// If this is a [FractionalOffset] , then it is expressed as a vector from
117+ /// coordinate (0.0,0.0), in a coordinate space that maps the top left of the
118+ /// paint box at (0.0,0.0) and the bottom right at (1.0,1.0).
119+ ///
120+ /// For example, a begin offset of (1.0,0.5) is half way down the
107121 /// right side of the box.
108- final FractionalOffset end;
122+ ///
123+ /// It can also be a [FractionalOffsetDirectional] , in which case it is
124+ /// expressed as a vector from the top start corner, where the start is the
125+ /// left in left-to-right contexts and the right in right-to-left contexts. If
126+ /// a text-direction-dependent value is provided here, then the [createShader]
127+ /// method will need to be given a [TextDirection] .
128+ final FractionalOffsetGeometry end;
109129
110130 /// The colors the gradient should obtain at each of the stops.
111131 ///
@@ -144,16 +164,20 @@ class LinearGradient extends Gradient {
144164 final TileMode tileMode;
145165
146166 @override
147- Shader createShader (Rect rect) {
167+ Shader createShader (Rect rect, { TextDirection textDirection } ) {
148168 return new ui.Gradient .linear (
149- begin.withinRect (rect),
150- end.withinRect (rect),
169+ begin.resolve (textDirection). withinRect (rect),
170+ end.resolve (textDirection). withinRect (rect),
151171 colors, stops, tileMode,
152172 );
153173 }
154174
155- /// Returns a new [LinearGradient] with its properties scaled by the given
156- /// factor.
175+ /// Returns a new [LinearGradient] with its properties (in particular the
176+ /// colors) scaled by the given factor.
177+ ///
178+ /// If the factor is 1.0 or greater, then the gradient is returned unmodified.
179+ /// If the factor is 0.0 or less, then the gradient is fully transparent.
180+ /// Values in between scale the opacity of the colors.
157181 LinearGradient scale (double factor) {
158182 return new LinearGradient (
159183 begin: begin,
@@ -168,7 +192,7 @@ class LinearGradient extends Gradient {
168192 ///
169193 /// If either gradient is null, this function linearly interpolates from a
170194 /// a gradient that matches the other gradient in [begin] , [end] , [stops] and
171- /// [tileMode] and with the same [colors] but transparent.
195+ /// [tileMode] and with the same [colors] but transparent (using [scale] ) .
172196 ///
173197 /// If neither gradient is null, they must have the same number of [colors] .
174198 static LinearGradient lerp (LinearGradient a, LinearGradient b, double t) {
@@ -178,11 +202,7 @@ class LinearGradient extends Gradient {
178202 return b.scale (t);
179203 if (b == null )
180204 return a.scale (1.0 - t);
181- // Interpolation is only possible when the lengths of colors and stops are
182- // the same or stops is null for one.
183- // TODO(xster): lerp unsimilar LinearGradients in the future by scaling
184- // lists of LinearGradients.
185- assert (a.colors.length == b.colors.length);
205+ assert (a.colors.length == b.colors.length, 'Cannot interpolate between two gradients with a different number of colors.' );
186206 assert (a.stops == null || b.stops == null || a.stops.length == b.stops.length);
187207 final List <Color > interpolatedColors = < Color > [];
188208 for (int i = 0 ; i < a.colors.length; i += 1 )
@@ -195,8 +215,8 @@ class LinearGradient extends Gradient {
195215 interpolatedStops = a.stops ?? b.stops;
196216 }
197217 return new LinearGradient (
198- begin: FractionalOffset .lerp (a.begin, b.begin, t),
199- end: FractionalOffset .lerp (a.end, b.end, t),
218+ begin: FractionalOffsetGeometry .lerp (a.begin, b.begin, t),
219+ end: FractionalOffsetGeometry .lerp (a.end, b.end, t),
200220 colors: interpolatedColors,
201221 stops: interpolatedStops,
202222 tileMode: t < 0.5 ? a.tileMode : b.tileMode,
@@ -240,7 +260,7 @@ class LinearGradient extends Gradient {
240260
241261 @override
242262 String toString () {
243- return 'LinearGradient ($begin , $end , $colors , $stops , $tileMode )' ;
263+ return '$ runtimeType ($begin , $end , $colors , $stops , $tileMode )' ;
244264 }
245265}
246266
@@ -319,7 +339,17 @@ class RadialGradient extends Gradient {
319339 ///
320340 /// For example, an offset of (0.5,0.5) will place the radial
321341 /// gradient in the center of the box.
322- final FractionalOffset center;
342+ ///
343+ /// If this is a [FractionalOffset] , then it is expressed as a vector from
344+ /// coordinate (0.0,0.0), in a coordinate space that maps the top left of the
345+ /// paint box at (0.0,0.0) and the bottom right at (1.0,1.0).
346+ ///
347+ /// It can also be a [FractionalOffsetDirectional] , in which case it is
348+ /// expressed as a vector from the top start corner, where the start is the
349+ /// left in left-to-right contexts and the right in right-to-left contexts. If
350+ /// a text-direction-dependent value is provided here, then the [createShader]
351+ /// method will need to be given a [TextDirection] .
352+ final FractionalOffsetGeometry center;
323353
324354 /// The radius of the gradient, as a fraction of the shortest side
325355 /// of the paint box.
@@ -368,11 +398,11 @@ class RadialGradient extends Gradient {
368398 final TileMode tileMode;
369399
370400 @override
371- Shader createShader (Rect rect) {
401+ Shader createShader (Rect rect, { TextDirection textDirection } ) {
372402 return new ui.Gradient .radial (
373- center.withinRect (rect),
403+ center.resolve (textDirection). withinRect (rect),
374404 radius * rect.shortestSide,
375- colors, stops, tileMode
405+ colors, stops, tileMode,
376406 );
377407 }
378408
@@ -413,6 +443,6 @@ class RadialGradient extends Gradient {
413443
414444 @override
415445 String toString () {
416- return 'RadialGradient ($center , $radius , $colors , $stops , $tileMode )' ;
446+ return '$ runtimeType ($center , $radius , $colors , $stops , $tileMode )' ;
417447 }
418448}
0 commit comments