diff --git a/engine/bindings/scripts/dart_types.py b/engine/bindings/scripts/dart_types.py index 11f10578c9176d6fd1a7f076d27799bfecf03cce..85f194261c37aa5ebc281051e8b55b19d8bf88dc 100644 --- a/engine/bindings/scripts/dart_types.py +++ b/engine/bindings/scripts/dart_types.py @@ -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>::FromArguments(args, {index}, exception)' expression = expression_format.format(native_array_element_type=native_array_element_type.name, cpp_type=this_cpp_type, index=index, diff --git a/engine/core/core.gni b/engine/core/core.gni index 73d0f19d2517fbe51e09fa8571be937444d21227..4e624bf99406f84be5b62ba091c27879f4e27ea8 100644 --- a/engine/core/core.gni +++ b/engine/core/core.gni @@ -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", diff --git a/engine/core/painting/CanvasColor.cpp b/engine/core/painting/CanvasColor.cpp index 7153a488d830b351700dd38b3e9acc00e89c043c..34e63712b589c68588f54f1055856b9346e65fa5 100644 --- a/engine/core/painting/CanvasColor.cpp +++ b/engine/core/painting/CanvasColor.cpp @@ -12,16 +12,7 @@ namespace blink { -// Convert dart_color => SkColor. -SkColor DartConverter::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::FromDart(Dart_Handle dart_color) { Dart_Handle value = Dart_GetField(dart_color, DOMDartState::Current()->value_handle()); @@ -30,8 +21,16 @@ SkColor DartConverter::FromArgumentsWithNullCheck( DCHECK(!LogIfError(rv)); DCHECK(color <= 0xffffffff); - result = static_cast(color); - return result; + return static_cast(color); +} + +SkColor DartConverter::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::SetReturnValue(Dart_NativeArguments args, diff --git a/engine/core/painting/CanvasColor.h b/engine/core/painting/CanvasColor.h index 04205f6e4927ed29005a7dfba7ef31da35f90206..0e727ea0416bf552f06a662684a3f533ca894516 100644 --- a/engine/core/painting/CanvasColor.h +++ b/engine/core/painting/CanvasColor.h @@ -15,8 +15,15 @@ namespace blink { class CanvasColor {}; +template <> +struct DartConverterTypes { + using ConverterType = CanvasColor; + using ValueType = SkColor; +}; + template <> struct DartConverter { + static SkColor FromDart(Dart_Handle handle); static SkColor FromArgumentsWithNullCheck(Dart_NativeArguments args, int index, Dart_Handle& exception); diff --git a/engine/core/painting/CanvasGradient.cpp b/engine/core/painting/CanvasGradient.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5e356ef03b0820c8b9dd2e0f4508698e824622ed --- /dev/null +++ b/engine/core/painting/CanvasGradient.cpp @@ -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::create( + int type, + const Vector& end_points, + const Vector& colors, + const Vector& 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 shader) + : Shader(shader) +{ +} + +CanvasGradient::~CanvasGradient() +{ +} + +} // namespace blink diff --git a/engine/core/painting/CanvasGradient.h b/engine/core/painting/CanvasGradient.h new file mode 100644 index 0000000000000000000000000000000000000000..7d8ea19843df30095e17edb91504301822e69689 --- /dev/null +++ b/engine/core/painting/CanvasGradient.h @@ -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 create(int type, + const Vector& end_points, + const Vector& colors, + const Vector& color_stops); + + private: + CanvasGradient(PassRefPtr shader); +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_PAINTING_CANVASGRADIENT_H_ diff --git a/engine/core/painting/Gradient.dart b/engine/core/painting/Gradient.dart new file mode 100644 index 0000000000000000000000000000000000000000..be919951e11128fbf240bcb4363d0a28acd31031 --- /dev/null +++ b/engine/core/painting/Gradient.dart @@ -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 endPoints, + List colors, + List colorStops) + : super(0, endPoints, colors, _validate(colorStops, colors)); + + // TODO(mpcomplete): Figure out a good way to validate arguments. + static List _validate(colorStops, colors) { + if (colorStops != null && colors.length != colorStops.length) { + throw new ArgumentError( + "[colors] and [colorStops] parameters must be equal length."); + } + return colorStops; + } +} diff --git a/engine/core/painting/Gradient.idl b/engine/core/painting/Gradient.idl new file mode 100644 index 0000000000000000000000000000000000000000..aeea5b71d89f1e1faa939a9a9e1c866fbfd92817 --- /dev/null +++ b/engine/core/painting/Gradient.idl @@ -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 { +}; diff --git a/engine/core/painting/Paint.cpp b/engine/core/painting/Paint.cpp index c11fa674d96c24e0b00b536af867af4103777dfa..8728d013cfb70647074e5504449988f9cc90fa06 100644 --- a/engine/core/painting/Paint.cpp +++ b/engine/core/painting/Paint.cpp @@ -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); diff --git a/engine/core/painting/Paint.h b/engine/core/painting/Paint.h index ceda34f9b3f7a608635b7f264e5407475c52e3d1..f5df044016934cc0539f84dcdc664d9d9fd7bce6 100644 --- a/engine/core/painting/Paint.h +++ b/engine/core/painting/Paint.h @@ -18,6 +18,7 @@ namespace blink { class DrawLooper; class ColorFilter; class MaskFilter; +class Shader; class Paint : public RefCounted, 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); diff --git a/engine/core/painting/Paint.idl b/engine/core/painting/Paint.idl index ae8f662c748ceb3040a0b63b960637a2bd87c1d2..2f239df4561758dc7fa55af9e29064c02ad2c2d3 100644 --- a/engine/core/painting/Paint.idl +++ b/engine/core/painting/Paint.idl @@ -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); }; diff --git a/engine/core/painting/Point.cpp b/engine/core/painting/Point.cpp index 6df54fe7e97b2a0d9c4fdc42791a749f9b153222..e7e29c62d82ba315fac8ecb061a7890418147ac8 100644 --- a/engine/core/painting/Point.cpp +++ b/engine/core/painting/Point.cpp @@ -11,21 +11,17 @@ namespace blink { -// Convert dartPoint.x,y ==> SkPoint. -Point DartConverter::FromArgumentsWithNullCheck( - Dart_NativeArguments args, - int index, - Dart_Handle& exception) { +// Convert handle.x,y ==> SkPoint. +Point DartConverter::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::FromArgumentsWithNullCheck( return result; } +Point DartConverter::FromArgumentsWithNullCheck( + Dart_NativeArguments args, + int index, + Dart_Handle& exception) { + return FromDart(Dart_GetNativeArgument(args, index)); +} + } // namespace blink diff --git a/engine/core/painting/Point.h b/engine/core/painting/Point.h index e3b80f7a4c6e5838019a2884190d6fa8e4a6819e..c08c48e72d939ea7fb761595c774204c52d14dca 100644 --- a/engine/core/painting/Point.h +++ b/engine/core/painting/Point.h @@ -19,6 +19,7 @@ class Point { template <> struct DartConverter { + static Point FromDart(Dart_Handle handle); static Point FromArgumentsWithNullCheck(Dart_NativeArguments args, int index, Dart_Handle& exception); diff --git a/engine/core/painting/Shader.cpp b/engine/core/painting/Shader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..332dc24504141ab4e398a0596099d69f2a3e2402 --- /dev/null +++ b/engine/core/painting/Shader.cpp @@ -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 shader) + : shader_(shader) { +} + +Shader::~Shader() { +} + +} // namespace blink diff --git a/engine/core/painting/Shader.h b/engine/core/painting/Shader.h new file mode 100644 index 0000000000000000000000000000000000000000..3a29f9e2d6ec2c8541018e515f54d7cbb4023b43 --- /dev/null +++ b/engine/core/painting/Shader.h @@ -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, public DartWrappable { + DEFINE_WRAPPERTYPEINFO(); + public: + ~Shader() override; + + SkShader* shader() { return shader_.get(); } + + protected: + Shader(PassRefPtr shader); + + private: + RefPtr shader_; +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_PAINTING_SHADER_H_ diff --git a/engine/core/painting/Shader.idl b/engine/core/painting/Shader.idl new file mode 100644 index 0000000000000000000000000000000000000000..d29440d5fce72be5227edfd890d32f2473494ae6 --- /dev/null +++ b/engine/core/painting/Shader.idl @@ -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 { +}; diff --git a/engine/tonic/dart_converter.h b/engine/tonic/dart_converter.h index c40fe5383dc69a0dd30bdf9df9d937c742430342..055a82b7efa3e5f1203147a6245cda59570658f3 100644 --- a/engine/tonic/dart_converter.h +++ b/engine/tonic/dart_converter.h @@ -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 -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 { +// using ConverterType = ColorConverterType; +// using ValueType = ColorType; +// }; +template +struct DartConverterTypes { + using ConverterType = T; + using ValueType = T; +}; //////////////////////////////////////////////////////////////////////////////// // Boolean @@ -227,21 +244,25 @@ struct DartConverter { template struct DartConverter> { - static Dart_Handle ToDart(const Vector& val) { + using ValueType = typename DartConverterTypes::ValueType; + using ConverterType = typename DartConverterTypes::ConverterType; + + static Dart_Handle ToDart(const Vector& 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::ToDart(val[i])); + Dart_ListSetAt(list, i, + DartConverter::ToDart(val[i])); if (Dart_IsError(result)) return result; } return list; } - static Vector FromDart(Dart_Handle handle) { - Vector result; + static Vector FromDart(Dart_Handle handle) { + Vector result; if (!Dart_IsList(handle)) return result; intptr_t length = 0; @@ -251,15 +272,15 @@ struct DartConverter> { Dart_Handle item = Dart_ListGetAt(handle, i); DCHECK(!Dart_IsError(item)); DCHECK(item); - result.append(DartConverter::FromDart(item)); + result.append(DartConverter::FromDart(item)); } return result; } - static Vector FromArguments(Dart_NativeArguments args, - int index, - Dart_Handle& exception, - bool auto_scope = true) { + static Vector 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)); } diff --git a/examples/raw/painting.sky b/examples/raw/painting.sky index 075867a8c6e0cd0ede15c1360c0dca42de0f1405..b0731a95594e355902cbb00aa228826bebc1e952 100644 --- a/examples/raw/painting.sky +++ b/examples/raw/painting.sky @@ -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([