提交 edd0d6e1 编写于 作者: M Matt Perry

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
上级 23847792
......@@ -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);
......
// 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
// 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_
// 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;
}
}
// 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);
......
// 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
// 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_
// 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([
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册