diff --git a/lib/stub_ui/lib/src/ui/painting.dart b/lib/stub_ui/lib/src/ui/painting.dart index fdabd8bff7a3c..fe6c8e8938cdf 100644 --- a/lib/stub_ui/lib/src/ui/painting.dart +++ b/lib/stub_ui/lib/src/ui/painting.dart @@ -1213,6 +1213,7 @@ abstract class Gradient extends Shader { List colors, [ List colorStops, TileMode tileMode = TileMode.clamp, + Float64List matrix4, // TODO(yjbanov): Implement this https://github.com/flutter/flutter/issues/32819 ]) => _GradientLinear(from, to, colors, colorStops, tileMode); diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index e79b2436a5bb2..f59964bfc7a74 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -2722,25 +2722,31 @@ class Gradient extends Shader { /// If `from`, `to`, `colors`, or `tileMode` 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.linear( Offset from, Offset to, List colors, [ List colorStops, TileMode tileMode = TileMode.clamp, + Float64List matrix4, ]) : assert(_offsetIsValid(from)), assert(_offsetIsValid(to)), assert(colors != null), assert(tileMode != null), + assert(matrix4 == null || _matrix4IsValid(matrix4)), super._() { _validateColorStops(colors, colorStops); final Float32List endPointsBuffer = _encodeTwoPoints(from, to); final Int32List colorsBuffer = _encodeColorList(colors); final Float32List colorStopsBuffer = colorStops == null ? null : Float32List.fromList(colorStops); _constructor(); - _initLinear(endPointsBuffer, colorsBuffer, colorStopsBuffer, tileMode.index); + _initLinear(endPointsBuffer, colorsBuffer, colorStopsBuffer, tileMode.index, matrix4); } - void _initLinear(Float32List endPoints, Int32List colors, Float32List colorStops, int tileMode) native 'Gradient_initLinear'; + void _initLinear(Float32List endPoints, Int32List colors, Float32List colorStops, int tileMode, Float64List matrix4) native 'Gradient_initLinear'; /// Creates a radial gradient centered at `center` that ends at `radius` /// distance from the center. diff --git a/lib/ui/painting/gradient.cc b/lib/ui/painting/gradient.cc index 72cb4f8ca6922..c46df8f67bbcd 100644 --- a/lib/ui/painting/gradient.cc +++ b/lib/ui/painting/gradient.cc @@ -42,7 +42,8 @@ fml::RefPtr CanvasGradient::Create() { void CanvasGradient::initLinear(const tonic::Float32List& end_points, const tonic::Int32List& colors, const tonic::Float32List& color_stops, - SkTileMode tile_mode) { + SkTileMode tile_mode, + const tonic::Float64List& matrix4) { FML_DCHECK(end_points.num_elements() == 4); FML_DCHECK(colors.num_elements() == color_stops.num_elements() || color_stops.data() == nullptr); @@ -52,10 +53,16 @@ void CanvasGradient::initLinear(const tonic::Float32List& end_points, 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(UIDartState::CreateGPUObject(SkGradientShader::MakeLinear( reinterpret_cast(end_points.data()), reinterpret_cast(colors.data()), color_stops.data(), - colors.num_elements(), tile_mode))); + colors.num_elements(), tile_mode, 0, has_matrix ? &sk_matrix : nullptr))); } void CanvasGradient::initRadial(double center_x, diff --git a/lib/ui/painting/gradient.h b/lib/ui/painting/gradient.h index 0a817dda0b402..a0d142a5adab4 100644 --- a/lib/ui/painting/gradient.h +++ b/lib/ui/painting/gradient.h @@ -31,7 +31,8 @@ class CanvasGradient : public Shader { void initLinear(const tonic::Float32List& end_points, const tonic::Int32List& colors, const tonic::Float32List& color_stops, - SkTileMode tile_mode); + SkTileMode tile_mode, + const tonic::Float64List& matrix4); void initRadial(double center_x, double center_y,