forked from firka/flutter
Enable sweep gradients (flutter/engine#4950)
* Enable sweep gradients * Use _matrix4IsValid * Add assert for startAngle < endAngle * Use radians for startAngle and endAngle * Update AUTHORS * Better assert on matrix4IsValid
This commit is contained in:
committed by
Ian Hickson
parent
5defa98d3a
commit
3d2ae063e9
@@ -8,3 +8,4 @@ Jim Simon <jim.j.simon@gmail.com>
|
||||
Ali Bitek <alibitek@protonmail.ch>
|
||||
Jacob Greenfield <jacob.greenfield.256@gmail.com>
|
||||
Dan Field <dfield@gmail.com>
|
||||
Victor Choueiri <victor@ctrlanddev.com>
|
||||
|
||||
@@ -2231,8 +2231,8 @@ Float32List _encodeTwoPoints(Offset pointA, Offset pointB) {
|
||||
|
||||
/// A shader (as used by [Paint.shader]) that renders a color gradient.
|
||||
///
|
||||
/// There are two useful types of gradients, created by [new Gradient.linear]
|
||||
/// and [new Gradient.radial].
|
||||
/// There are several types of gradients, represented by the various constructors
|
||||
/// on this class.
|
||||
class Gradient extends Shader {
|
||||
|
||||
void _constructor() native 'Gradient_constructor';
|
||||
@@ -2306,9 +2306,8 @@ class Gradient extends Shader {
|
||||
]) : assert(_offsetIsValid(center)),
|
||||
assert(colors != null),
|
||||
assert(tileMode != null),
|
||||
assert(matrix4 == null || _matrix4IsValid(matrix4)),
|
||||
super._() {
|
||||
if (matrix4 != null && matrix4.length != 16)
|
||||
throw new ArgumentError('"matrix4" must have 16 entries.');
|
||||
_validateColorStops(colors, colorStops);
|
||||
final Int32List colorsBuffer = _encodeColorList(colors);
|
||||
final Float32List colorStopsBuffer = colorStops == null ? null : new Float32List.fromList(colorStops);
|
||||
@@ -2317,6 +2316,56 @@ class Gradient extends Shader {
|
||||
}
|
||||
void _initRadial(double centerX, double centerY, double radius, Int32List colors, Float32List colorStops, int tileMode, Float64List matrix4) native 'Gradient_initRadial';
|
||||
|
||||
/// Creates a sweep gradient centered at `center` that starts at `startAngle`
|
||||
/// and ends at `endAngle`.
|
||||
///
|
||||
/// `startAngle` and `endAngle` should be provided in radians, with zero
|
||||
/// radians being the horizontal line to the right of the `center` and with
|
||||
/// positive angles going clockwise around the `center`.
|
||||
///
|
||||
/// If `colorStops` is provided, `colorStops[i]` is a number from 0.0 to 1.0
|
||||
/// that specifies where `color[i]` begins in the gradient. If `colorStops` is
|
||||
/// not provided, then only two stops, at 0.0 and 1.0, are implied (and
|
||||
/// `color` must therefore only have two entries).
|
||||
///
|
||||
/// The behavior before `startAngle` and after `endAngle` is described by the
|
||||
/// `tileMode` argument. For details, see the [TileMode] enum.
|
||||
///
|
||||
/// 
|
||||
/// 
|
||||
/// 
|
||||
///
|
||||
/// If `center`, `colors`, `tileMode`, `startAngle`, or `endAngle` are null,
|
||||
/// or if `colors` or `colorStops` contain null values, this constructor will
|
||||
/// throw a [NoSuchMethodError].
|
||||
///
|
||||
/// If `matrix4` is provided, the gradient fill will be transformed by the
|
||||
/// specified 4x4 matrix relative to the local coordinate system. `matrix4` must
|
||||
/// be a column-major matrix packed into a list of 16 values.
|
||||
Gradient.sweep(
|
||||
Offset center,
|
||||
List<Color> colors, [
|
||||
List<double> colorStops,
|
||||
TileMode tileMode = TileMode.clamp,
|
||||
double startAngle = 0.0,
|
||||
double endAngle = math.pi * 2,
|
||||
Float64List matrix4,
|
||||
]) : assert(_offsetIsValid(center)),
|
||||
assert(colors != null),
|
||||
assert(tileMode != null),
|
||||
assert(startAngle != null),
|
||||
assert(endAngle != null),
|
||||
assert(startAngle < endAngle),
|
||||
assert(matrix4 == null || _matrix4IsValid(matrix4)),
|
||||
super._() {
|
||||
_validateColorStops(colors, colorStops);
|
||||
final Int32List colorsBuffer = _encodeColorList(colors);
|
||||
final Float32List colorStopsBuffer = colorStops == null ? null : new Float32List.fromList(colorStops);
|
||||
_constructor();
|
||||
_initSweep(center.dx, center.dy, colorsBuffer, colorStopsBuffer, tileMode.index, startAngle, endAngle, matrix4);
|
||||
}
|
||||
void _initSweep(double centerX, double centerY, Int32List colors, Float32List colorStops, int tileMode, double startAngle, double endAngle, Float64List matrix) native 'Gradient_initSweep';
|
||||
|
||||
static void _validateColorStops(List<Color> colors, List<double> colorStops) {
|
||||
if (colorStops == null) {
|
||||
if (colors.length != 2)
|
||||
|
||||
@@ -22,7 +22,8 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Gradient);
|
||||
|
||||
#define FOR_EACH_BINDING(V) \
|
||||
V(Gradient, initLinear) \
|
||||
V(Gradient, initRadial)
|
||||
V(Gradient, initRadial) \
|
||||
V(Gradient, initSweep)
|
||||
|
||||
FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
|
||||
|
||||
@@ -79,6 +80,33 @@ void CanvasGradient::initRadial(double center_x,
|
||||
colors.num_elements(), tile_mode, 0, has_matrix ? &sk_matrix : nullptr)));
|
||||
}
|
||||
|
||||
void CanvasGradient::initSweep(double center_x,
|
||||
double center_y,
|
||||
const tonic::Int32List& colors,
|
||||
const tonic::Float32List& color_stops,
|
||||
SkShader::TileMode tile_mode,
|
||||
double start_angle,
|
||||
double end_angle,
|
||||
const tonic::Float64List& matrix4) {
|
||||
FXL_DCHECK(colors.num_elements() == color_stops.num_elements() ||
|
||||
color_stops.data() == nullptr);
|
||||
|
||||
static_assert(sizeof(SkColor) == sizeof(int32_t),
|
||||
"SkColor doesn't use int32_t.");
|
||||
|
||||
SkMatrix sk_matrix;
|
||||
bool has_matrix = matrix4.data() != nullptr;
|
||||
if (has_matrix) {
|
||||
sk_matrix = ToSkMatrix(matrix4);
|
||||
}
|
||||
|
||||
set_shader(SkGradientShader::MakeSweep(
|
||||
center_x, center_y, reinterpret_cast<const SkColor*>(colors.data()),
|
||||
color_stops.data(), colors.num_elements(), tile_mode,
|
||||
start_angle * 180.0 / M_PI, end_angle * 180.0 / M_PI, 0,
|
||||
has_matrix ? &sk_matrix : nullptr));
|
||||
}
|
||||
|
||||
CanvasGradient::CanvasGradient() = default;
|
||||
|
||||
CanvasGradient::~CanvasGradient() = default;
|
||||
|
||||
@@ -43,6 +43,15 @@ class CanvasGradient : public Shader {
|
||||
SkShader::TileMode tile_mode,
|
||||
const tonic::Float64List& matrix4);
|
||||
|
||||
void initSweep(double center_x,
|
||||
double center_y,
|
||||
const tonic::Int32List& colors,
|
||||
const tonic::Float32List& color_stops,
|
||||
SkShader::TileMode tile_mode,
|
||||
double start_angle,
|
||||
double end_angle,
|
||||
const tonic::Float64List& matrix4);
|
||||
|
||||
static void RegisterNatives(tonic::DartLibraryNatives* natives);
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user