Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Support for TwoPointConical gradients #5275

Merged
merged 1 commit into from
May 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions lib/ui/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2296,25 +2296,44 @@ class Gradient extends Shader {
/// 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.
///
/// If `focal` is provided and not equal to `center` or `focalRadius` is
/// provided and not equal to 0.0, the generated shader will be a two point
/// conical radial gradient, with `focal` being the center of the focal
/// circle and `focalRadius` being the radius of that circle. If `focal` is
/// provided and not equal to `center`, at least one of the two offsets must
/// not be equal to [Offset.zero].
Gradient.radial(
Offset center,
double radius,
List<Color> colors, [
List<double> colorStops,
TileMode tileMode = TileMode.clamp,
Float64List matrix4
Float64List matrix4,
Offset focal,
double focalRadius
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh man, we should have used named arguments. this has become sad.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah :( but that'd be a a breaking change. I suppose it could be another method and deprecate this one....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could do another method, but as you point out in the commit message, that's got its own problems.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's just do a good job of the framework wrapper, then this particular method won't matter much.

]) : assert(_offsetIsValid(center)),
assert(colors != null),
assert(tileMode != null),
assert(matrix4 == null || _matrix4IsValid(matrix4)),
super._() {
focal ??= center;
focalRadius ??= 0.0;
_validateColorStops(colors, colorStops);
final Int32List colorsBuffer = _encodeColorList(colors);
final Float32List colorStopsBuffer = colorStops == null ? null : new Float32List.fromList(colorStops);
_constructor();
_initRadial(center.dx, center.dy, radius, colorsBuffer, colorStopsBuffer, tileMode.index, matrix4);

if (center == focal && focalRadius != 0.0) {
_constructor();
_initRadial(center.dx, center.dy, radius, colorsBuffer, colorStopsBuffer, tileMode.index, matrix4);
} else {
assert(center != Offset.zero || focal != Offset.zero); // will result in nullptr in Skia side
_constructor();
_initConical(focal.dx, focal.dy, focalRadius, center.dx, center.dy, radius, colorsBuffer, colorStopsBuffer, tileMode.index, matrix4);
}
}
void _initRadial(double centerX, double centerY, double radius, Int32List colors, Float32List colorStops, int tileMode, Float64List matrix4) native 'Gradient_initRadial';
void _initConical(double startX, double startY, double startRadius, double endX, double endY, double endRadius, Int32List colors, Float32List colorStops, int tileMode, Float64List matrix4) native 'Gradient_initTwoPointConical';

/// Creates a sweep gradient centered at `center` that starts at `startAngle`
/// and ends at `endAngle`.
Expand Down
32 changes: 31 additions & 1 deletion lib/ui/painting/gradient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, Gradient);
#define FOR_EACH_BINDING(V) \
V(Gradient, initLinear) \
V(Gradient, initRadial) \
V(Gradient, initSweep)
V(Gradient, initSweep) \
V(Gradient, initTwoPointConical)

FOR_EACH_BINDING(DART_NATIVE_CALLBACK)

Expand Down Expand Up @@ -109,6 +110,35 @@ void CanvasGradient::initSweep(double center_x,
has_matrix ? &sk_matrix : nullptr)));
}

void CanvasGradient::initTwoPointConical(double start_x,
double start_y,
double start_radius,
double end_x,
double end_y,
double end_radius,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
SkShader::TileMode tile_mode,
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(UIDartState::CreateGPUObject(SkGradientShader::MakeTwoPointConical(
SkPoint::Make(start_x, start_y), start_radius,
SkPoint::Make(end_x, end_y), end_radius,
reinterpret_cast<const SkColor*>(colors.data()), color_stops.data(),
colors.num_elements(), tile_mode, 0, has_matrix ? &sk_matrix : nullptr)));
}

CanvasGradient::CanvasGradient() = default;

CanvasGradient::~CanvasGradient() = default;
Expand Down
11 changes: 11 additions & 0 deletions lib/ui/painting/gradient.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ class CanvasGradient : public Shader {
double end_angle,
const tonic::Float64List& matrix4);

void initTwoPointConical(double start_x,
double start_y,
double start_radius,
double end_x,
double end_y,
double end_radius,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
SkShader::TileMode tile_mode,
const tonic::Float64List& matrix4);

static void RegisterNatives(tonic::DartLibraryNatives* natives);

private:
Expand Down