mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add support for linear gradients, implemented as skia shaders.
I had to complicate the IDL bindings generation to allow passing an array of colors. Without these changes, we'd try to convert the dart object to Vector<SkColor>, which C++ thinks is Vector<unsigned>, and we'd use the wrong converter. So I added some template grease to force it to use a Vector<CanvasColor> converter. R=eseidel@chromium.org Review URL: https://codereview.chromium.org/1152963009
This commit is contained in:
parent
2384779263
commit
edd0d6e16a
@ -366,13 +366,12 @@ DART_TO_CPP_VALUE = {
|
||||
# Pass-by-value types.
|
||||
'Color': pass_by_value_format('CanvasColor'),
|
||||
'Float32List': pass_by_value_format('Float32List'),
|
||||
'Point': pass_by_value_format('{implemented_as}'),
|
||||
'Rect': pass_by_value_format('{implemented_as}'),
|
||||
'Point': pass_by_value_format('Point'),
|
||||
'Rect': pass_by_value_format('Rect'),
|
||||
'TransferMode': pass_by_value_format('TransferMode'),
|
||||
'PaintingStyle': pass_by_value_format('PaintingStyle'),
|
||||
}
|
||||
|
||||
|
||||
def dart_value_to_cpp_value(idl_type, extended_attributes, variable_name,
|
||||
null_check, has_type_checking_interface,
|
||||
index, auto_scope=True):
|
||||
@ -428,12 +427,19 @@ def dart_value_to_cpp_value(idl_type, extended_attributes, variable_name,
|
||||
auto_scope=DartUtilities.bool_to_cpp(auto_scope))
|
||||
|
||||
|
||||
# Special mappings for arrays of types.
|
||||
INNER_TYPE_FOR_ARRAY = {
|
||||
'SkColor': 'CanvasColor'
|
||||
}
|
||||
|
||||
def dart_value_to_cpp_value_array_or_sequence(native_array_element_type, variable_name, index):
|
||||
# Index is None for setters, index (starting at 0) for method arguments,
|
||||
# and is used to provide a human-readable exception message
|
||||
if index is None:
|
||||
index = 0 # special case, meaning "setter"
|
||||
this_cpp_type = native_array_element_type.cpp_type
|
||||
if this_cpp_type in INNER_TYPE_FOR_ARRAY:
|
||||
this_cpp_type = INNER_TYPE_FOR_ARRAY[this_cpp_type]
|
||||
expression_format = '{variable_name} = DartConverter<Vector<{cpp_type}>>::FromArguments(args, {index}, exception)'
|
||||
expression = expression_format.format(native_array_element_type=native_array_element_type.name,
|
||||
cpp_type=this_cpp_type, index=index,
|
||||
|
||||
@ -852,6 +852,8 @@ sky_core_files = [
|
||||
"painting/DrawLooperAddLayerCallback.h",
|
||||
"painting/DrawLooperLayerInfo.cpp",
|
||||
"painting/DrawLooperLayerInfo.h",
|
||||
"painting/CanvasGradient.cpp",
|
||||
"painting/CanvasGradient.h",
|
||||
"painting/LayerDrawLooperBuilder.cpp",
|
||||
"painting/LayerDrawLooperBuilder.h",
|
||||
"painting/LayoutRoot.cpp",
|
||||
@ -878,6 +880,8 @@ sky_core_files = [
|
||||
"painting/Rect.h",
|
||||
"painting/RRect.cpp",
|
||||
"painting/RRect.h",
|
||||
"painting/Shader.cpp",
|
||||
"painting/Shader.h",
|
||||
"painting/TransferMode.cpp",
|
||||
"painting/TransferMode.h",
|
||||
"rendering/BidiRun.h",
|
||||
@ -1145,6 +1149,7 @@ core_idl_files = get_path_info([
|
||||
"painting/DrawLooper.idl",
|
||||
"painting/DrawLooperAddLayerCallback.idl",
|
||||
"painting/DrawLooperLayerInfo.idl",
|
||||
"painting/Gradient.idl",
|
||||
"painting/Image.idl",
|
||||
"painting/LayerDrawLooperBuilder.idl",
|
||||
"painting/LayoutRoot.idl",
|
||||
@ -1156,6 +1161,7 @@ core_idl_files = get_path_info([
|
||||
"painting/Picture.idl",
|
||||
"painting/PictureRecorder.idl",
|
||||
"painting/RRect.idl",
|
||||
"painting/Shader.idl",
|
||||
"view/BeginFrameCallback.idl",
|
||||
"view/EventCallback.idl",
|
||||
"view/View.idl",
|
||||
|
||||
@ -12,16 +12,7 @@
|
||||
|
||||
namespace blink {
|
||||
|
||||
// Convert dart_color => SkColor.
|
||||
SkColor DartConverter<CanvasColor>::FromArgumentsWithNullCheck(
|
||||
Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception) {
|
||||
SkColor result;
|
||||
|
||||
Dart_Handle dart_color = Dart_GetNativeArgument(args, index);
|
||||
DCHECK(!LogIfError(dart_color));
|
||||
|
||||
SkColor DartConverter<CanvasColor>::FromDart(Dart_Handle dart_color) {
|
||||
Dart_Handle value =
|
||||
Dart_GetField(dart_color, DOMDartState::Current()->value_handle());
|
||||
|
||||
@ -30,8 +21,16 @@ SkColor DartConverter<CanvasColor>::FromArgumentsWithNullCheck(
|
||||
DCHECK(!LogIfError(rv));
|
||||
DCHECK(color <= 0xffffffff);
|
||||
|
||||
result = static_cast<SkColor>(color);
|
||||
return result;
|
||||
return static_cast<SkColor>(color);
|
||||
}
|
||||
|
||||
SkColor DartConverter<CanvasColor>::FromArgumentsWithNullCheck(
|
||||
Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception) {
|
||||
Dart_Handle dart_color = Dart_GetNativeArgument(args, index);
|
||||
DCHECK(!LogIfError(dart_color));
|
||||
return FromDart(dart_color);
|
||||
}
|
||||
|
||||
void DartConverter<CanvasColor>::SetReturnValue(Dart_NativeArguments args,
|
||||
|
||||
@ -15,8 +15,15 @@ namespace blink {
|
||||
|
||||
class CanvasColor {};
|
||||
|
||||
template <>
|
||||
struct DartConverterTypes<CanvasColor> {
|
||||
using ConverterType = CanvasColor;
|
||||
using ValueType = SkColor;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct DartConverter<CanvasColor> {
|
||||
static SkColor FromDart(Dart_Handle handle);
|
||||
static SkColor FromArgumentsWithNullCheck(Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception);
|
||||
|
||||
40
engine/core/painting/CanvasGradient.cpp
Normal file
40
engine/core/painting/CanvasGradient.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2015 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/core/painting/CanvasGradient.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "sky/engine/core/painting/Picture.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
PassRefPtr<CanvasGradient> CanvasGradient::create(
|
||||
int type,
|
||||
const Vector<Point>& end_points,
|
||||
const Vector<SkColor>& colors,
|
||||
const Vector<float>& color_stops) {
|
||||
ASSERT(type == 0); // Only 1 supported type so far.
|
||||
ASSERT(end_points.size() == 2);
|
||||
ASSERT(colors.size() == color_stops.size() || color_stops.data() == nullptr);
|
||||
SkPoint sk_end_points[2];
|
||||
for (int i = 0; i < 2; ++i)
|
||||
sk_end_points[i] = end_points[i].sk_point;
|
||||
|
||||
SkShader* shader = SkGradientShader::CreateLinear(
|
||||
sk_end_points, colors.data(), color_stops.data(), colors.size(),
|
||||
SkShader::kClamp_TileMode);
|
||||
return adoptRef(new CanvasGradient(adoptRef(shader)));
|
||||
}
|
||||
|
||||
CanvasGradient::CanvasGradient(PassRefPtr<SkShader> shader)
|
||||
: Shader(shader)
|
||||
{
|
||||
}
|
||||
|
||||
CanvasGradient::~CanvasGradient()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
31
engine/core/painting/CanvasGradient.h
Normal file
31
engine/core/painting/CanvasGradient.h
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SKY_ENGINE_CORE_PAINTING_CANVASGRADIENT_H_
|
||||
#define SKY_ENGINE_CORE_PAINTING_CANVASGRADIENT_H_
|
||||
|
||||
#include "sky/engine/core/painting/CanvasColor.h"
|
||||
#include "sky/engine/core/painting/Point.h"
|
||||
#include "sky/engine/core/painting/Shader.h"
|
||||
#include "sky/engine/tonic/dart_wrappable.h"
|
||||
#include "third_party/skia/include/effects/SkGradientShader.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class CanvasGradient : public Shader {
|
||||
DEFINE_WRAPPERTYPEINFO();
|
||||
public:
|
||||
~CanvasGradient() override;
|
||||
static PassRefPtr<CanvasGradient> create(int type,
|
||||
const Vector<Point>& end_points,
|
||||
const Vector<SkColor>& colors,
|
||||
const Vector<float>& color_stops);
|
||||
|
||||
private:
|
||||
CanvasGradient(PassRefPtr<SkShader> shader);
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_CORE_PAINTING_CANVASGRADIENT_H_
|
||||
23
engine/core/painting/Gradient.dart
Normal file
23
engine/core/painting/Gradient.dart
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Extends the generated _Gradient interface via the CustomDart attribute.
|
||||
|
||||
class Gradient extends _Gradient {
|
||||
// TODO(mpcomplete): Support other gradient types.
|
||||
// TODO(mpcomplete): Maybe pass a list of (color, colorStop) pairs instead?
|
||||
Gradient.Linear(List<Point> endPoints,
|
||||
List<Color> colors,
|
||||
List<double> colorStops)
|
||||
: super(0, endPoints, colors, _validate(colorStops, colors));
|
||||
|
||||
// TODO(mpcomplete): Figure out a good way to validate arguments.
|
||||
static List<double> _validate(colorStops, colors) {
|
||||
if (colorStops != null && colors.length != colorStops.length) {
|
||||
throw new ArgumentError(
|
||||
"[colors] and [colorStops] parameters must be equal length.");
|
||||
}
|
||||
return colorStops;
|
||||
}
|
||||
}
|
||||
10
engine/core/painting/Gradient.idl
Normal file
10
engine/core/painting/Gradient.idl
Normal file
@ -0,0 +1,10 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
[
|
||||
ImplementedAs=CanvasGradient,
|
||||
CustomDart,
|
||||
Constructor(unsigned long gradientType, Point[] endPoints, Color[] colors, float[] colorStops)
|
||||
] interface Gradient : Shader {
|
||||
};
|
||||
@ -8,6 +8,7 @@
|
||||
#include "sky/engine/core/painting/ColorFilter.h"
|
||||
#include "sky/engine/core/painting/DrawLooper.h"
|
||||
#include "sky/engine/core/painting/MaskFilter.h"
|
||||
#include "sky/engine/core/painting/Shader.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
@ -37,6 +38,12 @@ void Paint::setMaskFilter(MaskFilter* filter)
|
||||
m_paint.setMaskFilter(filter->filter());
|
||||
}
|
||||
|
||||
void Paint::setShader(Shader* shader)
|
||||
{
|
||||
ASSERT(shader);
|
||||
m_paint.setShader(shader->shader());
|
||||
}
|
||||
|
||||
void Paint::setStyle(SkPaint::Style style)
|
||||
{
|
||||
m_paint.setStyle(style);
|
||||
|
||||
@ -18,6 +18,7 @@ namespace blink {
|
||||
class DrawLooper;
|
||||
class ColorFilter;
|
||||
class MaskFilter;
|
||||
class Shader;
|
||||
|
||||
class Paint : public RefCounted<Paint>, public DartWrappable {
|
||||
DEFINE_WRAPPERTYPEINFO();
|
||||
@ -44,6 +45,7 @@ public:
|
||||
void setDrawLooper(DrawLooper* looper);
|
||||
void setColorFilter(ColorFilter* filter);
|
||||
void setMaskFilter(MaskFilter* filter);
|
||||
void setShader(Shader* shader);
|
||||
void setStyle(SkPaint::Style style);
|
||||
void setTransferMode(SkXfermode::Mode transfer_mode);
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
void setDrawLooper(DrawLooper looper);
|
||||
void setColorFilter(ColorFilter filter);
|
||||
void setMaskFilter(MaskFilter filter);
|
||||
void setShader(Shader shader);
|
||||
void setStyle(PaintingStyle style);
|
||||
void setTransferMode(TransferMode transferMode);
|
||||
};
|
||||
|
||||
@ -11,21 +11,17 @@
|
||||
|
||||
namespace blink {
|
||||
|
||||
// Convert dartPoint.x,y ==> SkPoint.
|
||||
Point DartConverter<Point>::FromArgumentsWithNullCheck(
|
||||
Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception) {
|
||||
// Convert handle.x,y ==> SkPoint.
|
||||
Point DartConverter<Point>::FromDart(Dart_Handle handle) {
|
||||
Point result;
|
||||
result.is_null = true;
|
||||
|
||||
Dart_Handle dartPoint = Dart_GetNativeArgument(args, index);
|
||||
DCHECK(!LogIfError(dartPoint));
|
||||
DCHECK(!LogIfError(handle));
|
||||
|
||||
Dart_Handle x_value =
|
||||
Dart_GetField(dartPoint, DOMDartState::Current()->x_handle());
|
||||
Dart_GetField(handle, DOMDartState::Current()->x_handle());
|
||||
Dart_Handle y_value =
|
||||
Dart_GetField(dartPoint, DOMDartState::Current()->y_handle());
|
||||
Dart_GetField(handle, DOMDartState::Current()->y_handle());
|
||||
|
||||
double x = 0.0, y = 0.0;
|
||||
Dart_Handle err = Dart_DoubleValue(x_value, &x);
|
||||
@ -37,4 +33,11 @@ Point DartConverter<Point>::FromArgumentsWithNullCheck(
|
||||
return result;
|
||||
}
|
||||
|
||||
Point DartConverter<Point>::FromArgumentsWithNullCheck(
|
||||
Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception) {
|
||||
return FromDart(Dart_GetNativeArgument(args, index));
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
|
||||
@ -19,6 +19,7 @@ class Point {
|
||||
|
||||
template <>
|
||||
struct DartConverter<Point> {
|
||||
static Point FromDart(Dart_Handle handle);
|
||||
static Point FromArgumentsWithNullCheck(Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception);
|
||||
|
||||
17
engine/core/painting/Shader.cpp
Normal file
17
engine/core/painting/Shader.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2015 The Chromium 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 "sky/engine/config.h"
|
||||
#include "sky/engine/core/painting/Shader.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
Shader::Shader(PassRefPtr<SkShader> shader)
|
||||
: shader_(shader) {
|
||||
}
|
||||
|
||||
Shader::~Shader() {
|
||||
}
|
||||
|
||||
} // namespace blink
|
||||
31
engine/core/painting/Shader.h
Normal file
31
engine/core/painting/Shader.h
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SKY_ENGINE_CORE_PAINTING_SHADER_H_
|
||||
#define SKY_ENGINE_CORE_PAINTING_SHADER_H_
|
||||
|
||||
#include "sky/engine/tonic/dart_wrappable.h"
|
||||
#include "sky/engine/wtf/PassRefPtr.h"
|
||||
#include "sky/engine/wtf/RefCounted.h"
|
||||
#include "third_party/skia/include/core/SkShader.h"
|
||||
|
||||
namespace blink {
|
||||
|
||||
class Shader : public RefCounted<Shader>, public DartWrappable {
|
||||
DEFINE_WRAPPERTYPEINFO();
|
||||
public:
|
||||
~Shader() override;
|
||||
|
||||
SkShader* shader() { return shader_.get(); }
|
||||
|
||||
protected:
|
||||
Shader(PassRefPtr<SkShader> shader);
|
||||
|
||||
private:
|
||||
RefPtr<SkShader> shader_;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // SKY_ENGINE_CORE_PAINTING_SHADER_H_
|
||||
6
engine/core/painting/Shader.idl
Normal file
6
engine/core/painting/Shader.idl
Normal file
@ -0,0 +1,6 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
interface Shader {
|
||||
};
|
||||
@ -18,7 +18,24 @@ namespace blink {
|
||||
// DartConvert converts types back and forth from Sky to Dart. The template
|
||||
// parameter |T| determines what kind of type conversion to perform.
|
||||
template <typename T, typename Enable = void>
|
||||
struct DartConverter {};
|
||||
struct DartConverter {
|
||||
};
|
||||
|
||||
// This is to work around the fact that typedefs do not create new types. If you
|
||||
// have a typedef, and want it to use a different converter, specialize this
|
||||
// template and override the types here.
|
||||
// Ex:
|
||||
// typedef int ColorType; // Want to use a different converter.
|
||||
// class ColorConverterType {}; // Dummy type.
|
||||
// template<> struct DartConvertType<ColorConverterType> {
|
||||
// using ConverterType = ColorConverterType;
|
||||
// using ValueType = ColorType;
|
||||
// };
|
||||
template <typename T>
|
||||
struct DartConverterTypes {
|
||||
using ConverterType = T;
|
||||
using ValueType = T;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Boolean
|
||||
@ -227,21 +244,25 @@ struct DartConverter<AtomicString> {
|
||||
|
||||
template <typename T>
|
||||
struct DartConverter<Vector<T>> {
|
||||
static Dart_Handle ToDart(const Vector<T>& val) {
|
||||
using ValueType = typename DartConverterTypes<T>::ValueType;
|
||||
using ConverterType = typename DartConverterTypes<T>::ConverterType;
|
||||
|
||||
static Dart_Handle ToDart(const Vector<ValueType>& val) {
|
||||
Dart_Handle list = Dart_NewList(val.size());
|
||||
if (Dart_IsError(list))
|
||||
return list;
|
||||
for (size_t i = 0; i < val.size(); i++) {
|
||||
Dart_Handle result =
|
||||
Dart_ListSetAt(list, i, DartConverter<T>::ToDart(val[i]));
|
||||
Dart_ListSetAt(list, i,
|
||||
DartConverter<ConverterType>::ToDart(val[i]));
|
||||
if (Dart_IsError(result))
|
||||
return result;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static Vector<T> FromDart(Dart_Handle handle) {
|
||||
Vector<T> result;
|
||||
static Vector<ValueType> FromDart(Dart_Handle handle) {
|
||||
Vector<ValueType> result;
|
||||
if (!Dart_IsList(handle))
|
||||
return result;
|
||||
intptr_t length = 0;
|
||||
@ -251,15 +272,15 @@ struct DartConverter<Vector<T>> {
|
||||
Dart_Handle item = Dart_ListGetAt(handle, i);
|
||||
DCHECK(!Dart_IsError(item));
|
||||
DCHECK(item);
|
||||
result.append(DartConverter<T>::FromDart(item));
|
||||
result.append(DartConverter<ConverterType>::FromDart(item));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static Vector<T> FromArguments(Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception,
|
||||
bool auto_scope = true) {
|
||||
static Vector<ValueType> FromArguments(Dart_NativeArguments args,
|
||||
int index,
|
||||
Dart_Handle& exception,
|
||||
bool auto_scope = true) {
|
||||
// TODO(abarth): What should we do with auto_scope?
|
||||
return FromDart(Dart_GetNativeArgument(args, index));
|
||||
}
|
||||
|
||||
@ -26,8 +26,12 @@ void main() {
|
||||
paint.color = const Color.fromARGB(128, 255, 0, 255);
|
||||
context.rotateDegrees(45.0);
|
||||
|
||||
Gradient yellowBlue = new Gradient.Linear(
|
||||
[new Point(-radius, -radius), new Point(0.0, 0.0)],
|
||||
[const Color(0xFFFFFF00), const Color(0xFF0000FF)],
|
||||
null);
|
||||
context.drawRect(new Rect.fromLTRB(-radius, -radius, radius, radius),
|
||||
paint);
|
||||
new Paint()..setShader(yellowBlue));
|
||||
|
||||
// Scale x and y by 0.5.
|
||||
var scaleMatrix = new Float32List.fromList([
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user