diff --git a/engine/src/flutter/.travis.yml b/engine/src/flutter/.travis.yml index 52d948e988b..0e4a765fae4 100644 --- a/engine/src/flutter/.travis.yml +++ b/engine/src/flutter/.travis.yml @@ -8,3 +8,6 @@ script: - ./travis/build.sh - ./travis/test.sh - ./travis/format.sh + +# We don't build the engine or run the tests for the engine on Travis +# See testing/run_tests.sh if that's what you're looking for though. diff --git a/engine/src/flutter/lib/ui/painting.dart b/engine/src/flutter/lib/ui/painting.dart index 25b7c1fefef..c43edf416f2 100644 --- a/engine/src/flutter/lib/ui/painting.dart +++ b/engine/src/flutter/lib/ui/painting.dart @@ -35,7 +35,7 @@ bool _offsetIsValid(Offset offset) { } Color _scaleAlpha(Color a, double factor) { - return a.withAlpha((a.alpha * factor).round()); + return a.withAlpha((a.alpha * factor).round().clamp(0, 255)); } /// An immutable 32 bit color value in ARGB format. @@ -100,10 +100,10 @@ class Color { /// See also [fromARGB], which takes the alpha value as a floating point /// value. const Color.fromARGB(int a, int r, int g, int b) : - value = ((((a & 0xff) << 24) | - ((r & 0xff) << 16) | - ((g & 0xff) << 8) | - ((b & 0xff) << 0)) & 0xFFFFFFFF); + value = (((a & 0xff) << 24) | + ((r & 0xff) << 16) | + ((g & 0xff) << 8) | + ((b & 0xff) << 0)) & 0xFFFFFFFF; /// Create a color from red, green, blue, and opacity, similar to `rgba()` in CSS. /// @@ -117,10 +117,10 @@ class Color { /// /// See also [fromARGB], which takes the opacity as an integer value. const Color.fromRGBO(int r, int g, int b, double opacity) : - value = (((((opacity * 0xff ~/ 1) & 0xff) << 24) | - ((r & 0xff) << 16) | - ((g & 0xff) << 8) | - ((b & 0xff) << 0)) & 0xFFFFFFFF); + value = ((((opacity * 0xff ~/ 1) & 0xff) << 24) | + ((r & 0xff) << 16) | + ((g & 0xff) << 8) | + ((b & 0xff) << 0)) & 0xFFFFFFFF; /// A 32 bit value representing this color. /// @@ -155,31 +155,41 @@ class Color { /// Returns a new color that matches this color with the alpha channel /// replaced with `a` (which ranges from 0 to 255). + /// + /// Out of range values will have unexpected effects. Color withAlpha(int a) { return new Color.fromARGB(a, red, green, blue); } /// Returns a new color that matches this color with the alpha channel /// replaced with the given `opacity` (which ranges from 0.0 to 1.0). + /// + /// Out of range values will have unexpected effects. Color withOpacity(double opacity) { assert(opacity >= 0.0 && opacity <= 1.0); return withAlpha((255.0 * opacity).round()); } /// Returns a new color that matches this color with the red channel replaced - /// with `r`. + /// with `r` (which ranges from 0 to 255). + /// + /// Out of range values will have unexpected effects. Color withRed(int r) { return new Color.fromARGB(alpha, r, green, blue); } /// Returns a new color that matches this color with the green channel - /// replaced with `g`. + /// replaced with `g` (which ranges from 0 to 255). + /// + /// Out of range values will have unexpected effects. Color withGreen(int g) { return new Color.fromARGB(alpha, red, g, blue); } /// Returns a new color that matches this color with the blue channel replaced - /// with `b`. + /// with `b` (which ranges from 0 to 255). + /// + /// Out of range values will have unexpected effects. Color withBlue(int b) { return new Color.fromARGB(alpha, red, green, b); } @@ -188,6 +198,12 @@ class Color { /// /// If either color is null, this function linearly interpolates from a /// transparent instance of the other color. + /// + /// Values of `t` less that 0.0 or greater than 1.0 are supported. Each + /// channel will be clamped to the range 0 to 255. + /// + /// This is intended to be fast but as a result may be ugly. Consider + /// [HSVColor] or writing custom logic for interpolating colors. static Color lerp(Color a, Color b, double t) { if (a == null && b == null) return null; @@ -196,10 +212,10 @@ class Color { if (b == null) return _scaleAlpha(a, 1.0 - t); return new Color.fromARGB( - lerpDouble(a.alpha, b.alpha, t).toInt(), - lerpDouble(a.red, b.red, t).toInt(), - lerpDouble(a.green, b.green, t).toInt(), - lerpDouble(a.blue, b.blue, t).toInt() + lerpDouble(a.alpha, b.alpha, t).toInt().clamp(0, 255), + lerpDouble(a.red, b.red, t).toInt().clamp(0, 255), + lerpDouble(a.green, b.green, t).toInt().clamp(0, 255), + lerpDouble(a.blue, b.blue, t).toInt().clamp(0, 255), ); } diff --git a/engine/src/flutter/testing/dart/color_test.dart b/engine/src/flutter/testing/dart/color_test.dart index 5721c9a5050..33f57e85d45 100644 --- a/engine/src/flutter/testing/dart/color_test.dart +++ b/engine/src/flutter/testing/dart/color_test.dart @@ -11,7 +11,7 @@ class NotAColor extends Color { } void main() { - test("color accessors should work", () { + test('color accessors should work', () { Color foo = const Color(0x12345678); expect(foo.alpha, equals(0x12)); expect(foo.red, equals(0x34)); @@ -19,14 +19,14 @@ void main() { expect(foo.blue, equals(0x78)); }); - test("paint set to black", () { + test('paint set to black', () { Color c = const Color(0x00000000); Paint p = new Paint(); p.color = c; expect(c.toString(), equals('Color(0x00000000)')); }); - test("color created with out of bounds value", () { + test('color created with out of bounds value', () { try { Color c = const Color(0x100 << 24); Paint p = new Paint(); @@ -36,7 +36,7 @@ void main() { } }); - test("color created with wildly out of bounds value", () { + test('color created with wildly out of bounds value', () { try { Color c = const Color(1 << 1000000); Paint p = new Paint(); @@ -46,7 +46,7 @@ void main() { } }); - test("two colors are only == if they have the same runtime type", () { + test('two colors are only == if they have the same runtime type', () { expect(const Color(123), equals(const Color(123))); expect(const Color(123), equals(new Color(123))); expect(const Color(123), isNot(equals(const Color(321)))); @@ -55,4 +55,26 @@ void main() { expect(const NotAColor(123), equals(const NotAColor(123))); }); + test('Color.lerp', () { + expect( + Color.lerp(const Color(0x00000000), const Color(0xFFFFFFFF), 0.0), + const Color(0x00000000), + ); + expect( + Color.lerp(const Color(0x00000000), const Color(0xFFFFFFFF), 0.5), + const Color(0x7F7F7F7F), + ); + expect( + Color.lerp(const Color(0x00000000), const Color(0xFFFFFFFF), 1.0), + const Color(0xFFFFFFFF), + ); + expect( + Color.lerp(const Color(0x00000000), const Color(0xFFFFFFFF), -0.1), + const Color(0x00000000), + ); + expect( + Color.lerp(const Color(0x00000000), const Color(0xFFFFFFFF), 1.1), + const Color(0xFFFFFFFF), + ); + }); }