paintFor function
fill as a paint; gradient handles resolve against bounds: the box, never a stroke band.
Implementation
ui.Paint paintFor(Fill fill, ui.Rect bounds) {
final ui.Paint paint = ui.Paint();
switch (fill) {
case SolidFill(:final color):
paint.color = color.toColor();
case LinearGradientFill(:final begin, :final end, :final stops, :final opacity):
assert(stops.length >= 2, 'LinearGradientFill needs at least two stops');
final List<GradientStop> sorted = _sorted(stops);
paint.shader = ui.Gradient.linear(_point(begin, bounds), _point(end, bounds), _colors(sorted, opacity), <double>[
for (final GradientStop s in sorted) s.position / 100,
]);
case RadialGradientFill(:final center, :final end, :final width, :final stops, :final opacity):
assert(stops.length >= 2, 'RadialGradientFill needs at least two stops');
final List<GradientStop> sorted = _sorted(stops);
final ui.Offset origin = _point(center, bounds);
final ui.Offset axisA = _point(end, bounds) - origin;
final ui.Offset axisB = _point(width, bounds) - origin;
// A unit circle mapped so (1, 0) lands on end and (0, 1) on width.
// Collinear axes have no area: use the last stop's color, as SVG does.
if ((axisA.dx * axisB.dy - axisA.dy * axisB.dx).abs() < 1e-9) {
paint.color = _colors(<GradientStop>[sorted.last], opacity).single;
} else {
paint.shader = ui.Gradient.radial(
ui.Offset.zero,
1,
_colors(sorted, opacity),
<double>[for (final GradientStop s in sorted) s.position / 100],
ui.TileMode.clamp,
.fromList(<double>[
axisA.dx,
axisA.dy,
0,
0,
axisB.dx,
axisB.dy,
0,
0,
0,
0,
1,
0,
origin.dx,
origin.dy,
0,
1,
]),
);
}
}
return paint;
}