blob: e54f39f41fadd5bffa58f7b83f23df9c4ddc26c7 [file] [log] [blame] [edit]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/lib/ui/painting/gradient.h"
#include "flutter/lib/ui/floating_point.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_args.h"
#include "third_party/tonic/dart_binding_macros.h"
#include "third_party/tonic/dart_library_natives.h"
namespace flutter {
typedef CanvasGradient
Gradient; // Because the C++ name doesn't match the Dart name.
IMPLEMENT_WRAPPERTYPEINFO(ui, Gradient);
void CanvasGradient::Create(Dart_Handle wrapper) {
UIDartState::ThrowIfUIOperationsProhibited();
auto res = fml::MakeRefCounted<CanvasGradient>();
res->AssociateWithDartWrapper(wrapper);
}
void CanvasGradient::initLinear(const tonic::Float32List& end_points,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
DlTileMode 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);
static_assert(sizeof(SkPoint) == sizeof(float) * 2,
"SkPoint doesn't use floats.");
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);
}
SkPoint p0 = SkPoint::Make(end_points[0], end_points[1]);
SkPoint p1 = SkPoint::Make(end_points[2], end_points[3]);
const DlColor* colors_array = reinterpret_cast<const DlColor*>(colors.data());
dl_shader_ = DlColorSource::MakeLinear(
p0, p1, colors.num_elements(), colors_array, color_stops.data(),
tile_mode, has_matrix ? &sk_matrix : nullptr);
// Just a sanity check, all gradient shaders should be thread-safe
FML_DCHECK(dl_shader_->isUIThreadSafe());
}
void CanvasGradient::initRadial(double center_x,
double center_y,
double radius,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
DlTileMode tile_mode,
const tonic::Float64List& matrix4) {
FML_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);
}
const DlColor* colors_array = reinterpret_cast<const DlColor*>(colors.data());
dl_shader_ = DlColorSource::MakeRadial(
SkPoint::Make(SafeNarrow(center_x), SafeNarrow(center_y)),
SafeNarrow(radius), colors.num_elements(), colors_array,
color_stops.data(), tile_mode, has_matrix ? &sk_matrix : nullptr);
// Just a sanity check, all gradient shaders should be thread-safe
FML_DCHECK(dl_shader_->isUIThreadSafe());
}
void CanvasGradient::initSweep(double center_x,
double center_y,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
DlTileMode tile_mode,
double start_angle,
double end_angle,
const tonic::Float64List& matrix4) {
FML_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);
}
const DlColor* colors_array = reinterpret_cast<const DlColor*>(colors.data());
dl_shader_ = DlColorSource::MakeSweep(
SkPoint::Make(SafeNarrow(center_x), SafeNarrow(center_y)),
SafeNarrow(start_angle) * 180.0f / static_cast<float>(M_PI),
SafeNarrow(end_angle) * 180.0f / static_cast<float>(M_PI),
colors.num_elements(), colors_array, color_stops.data(), tile_mode,
has_matrix ? &sk_matrix : nullptr);
// Just a sanity check, all gradient shaders should be thread-safe
FML_DCHECK(dl_shader_->isUIThreadSafe());
}
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,
DlTileMode tile_mode,
const tonic::Float64List& matrix4) {
FML_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);
}
const DlColor* colors_array = reinterpret_cast<const DlColor*>(colors.data());
dl_shader_ = DlColorSource::MakeConical(
SkPoint::Make(SafeNarrow(start_x), SafeNarrow(start_y)),
SafeNarrow(start_radius),
SkPoint::Make(SafeNarrow(end_x), SafeNarrow(end_y)),
SafeNarrow(end_radius), colors.num_elements(), colors_array,
color_stops.data(), tile_mode, has_matrix ? &sk_matrix : nullptr);
// Just a sanity check, all gradient shaders should be thread-safe
FML_DCHECK(dl_shader_->isUIThreadSafe());
}
CanvasGradient::CanvasGradient() = default;
CanvasGradient::~CanvasGradient() = default;
} // namespace flutter