@@ -48,8 +48,8 @@ bool _radiusIsValid(Radius radius) {
4848 return true ;
4949}
5050
51- Color _scaleAlpha (Color x , double factor) {
52- return x. withValues (alpha : clampDouble (x.a * factor, 0 , 1 ));
51+ Color _scaleAlpha (Color a , double factor) {
52+ return a. withAlpha ((a.alpha * factor). round (). clamp ( 0 , 255 ));
5353}
5454
5555/// An immutable 32 bit color value in ARGB format.
@@ -310,11 +310,10 @@ class Color {
310310 ///
311311 /// See <https://en.wikipedia.org/wiki/Relative_luminance>.
312312 double computeLuminance () {
313- assert (colorSpace != ColorSpace .extendedSRGB);
314313 // See <https://www.w3.org/TR/WCAG20/#relativeluminancedef>
315- final double R = _linearizeColorComponent (r );
316- final double G = _linearizeColorComponent (g );
317- final double B = _linearizeColorComponent (b );
314+ final double R = _linearizeColorComponent (red / 0xFF );
315+ final double G = _linearizeColorComponent (green / 0xFF );
316+ final double B = _linearizeColorComponent (blue / 0xFF );
318317 return 0.2126 * R + 0.7152 * G + 0.0722 * B ;
319318 }
320319
@@ -340,26 +339,28 @@ class Color {
340339 ///
341340 /// Values for `t` are usually obtained from an [Animation<double>] , such as
342341 /// an [AnimationController] .
343- static Color ? lerp (Color ? x, Color ? y, double t) {
344- assert (x? .colorSpace != ColorSpace .extendedSRGB);
345- assert (y? .colorSpace != ColorSpace .extendedSRGB);
346- if (y == null ) {
347- if (x == null ) {
342+ static Color ? lerp (Color ? a, Color ? b, double t) {
343+ // TODO(gaaclarke): Update math to use floats. This was already attempted
344+ // but it leads to subtle changes that change test results.
345+ assert (a? .colorSpace != ColorSpace .extendedSRGB);
346+ assert (b? .colorSpace != ColorSpace .extendedSRGB);
347+ if (b == null ) {
348+ if (a == null ) {
348349 return null ;
349350 } else {
350- return _scaleAlpha (x , 1.0 - t);
351+ return _scaleAlpha (a , 1.0 - t);
351352 }
352353 } else {
353- if (x == null ) {
354- return _scaleAlpha (y , t);
354+ if (a == null ) {
355+ return _scaleAlpha (b , t);
355356 } else {
356- assert (x .colorSpace == y .colorSpace);
357- return Color .from (
358- alpha : clampDouble ( _lerpDouble (x.a, y.a , t), 0 , 1 ),
359- red : clampDouble ( _lerpDouble (x.r, y.r , t), 0 , 1 ),
360- green : clampDouble ( _lerpDouble (x.g, y.g , t), 0 , 1 ),
361- blue : clampDouble ( _lerpDouble (x.b, y.b , t), 0 , 1 ),
362- colorSpace : x .colorSpace,
357+ assert (a .colorSpace == b .colorSpace);
358+ return Color ._fromARGBC (
359+ _clampInt ( _lerpInt (a.alpha, b.alpha , t). toInt () , 0 , 255 ),
360+ _clampInt ( _lerpInt (a.red, b.red , t). toInt () , 0 , 255 ),
361+ _clampInt ( _lerpInt (a.green, b.green , t). toInt () , 0 , 255 ),
362+ _clampInt ( _lerpInt (a.blue, b.blue , t). toInt () , 0 , 255 ),
363+ a .colorSpace,
363364 );
364365 }
365366 }
@@ -376,30 +377,32 @@ class Color {
376377 static Color alphaBlend (Color foreground, Color background) {
377378 assert (foreground.colorSpace == background.colorSpace);
378379 assert (foreground.colorSpace != ColorSpace .extendedSRGB);
379- final double alpha = foreground.a;
380- if (alpha == 0 ) { // Foreground completely transparent.
380+ // TODO(gaaclarke): Update math to use floats. This was already attempted
381+ // but it leads to subtle changes that change test results.
382+ final int alpha = foreground.alpha;
383+ if (alpha == 0x00 ) { // Foreground completely transparent.
381384 return background;
382385 }
383- final double invAlpha = 1 - alpha;
384- double backAlpha = background.a ;
385- if (backAlpha == 1 ) { // Opaque background case
386- return Color .from (
387- alpha : 1 ,
388- red : alpha * foreground.r + invAlpha * background.r ,
389- green : alpha * foreground.g + invAlpha * background.g ,
390- blue : alpha * foreground.b + invAlpha * background.b ,
391- colorSpace : foreground.colorSpace,
386+ final int invAlpha = 0xff - alpha;
387+ int backAlpha = background.alpha ;
388+ if (backAlpha == 0xff ) { // Opaque background case
389+ return Color ._fromARGBC (
390+ 0xff ,
391+ ( alpha * foreground.red + invAlpha * background.red) ~ / 0xff ,
392+ ( alpha * foreground.green + invAlpha * background.green) ~ / 0xff ,
393+ ( alpha * foreground.blue + invAlpha * background.blue) ~ / 0xff ,
394+ foreground.colorSpace,
392395 );
393396 } else { // General case
394- backAlpha = backAlpha * invAlpha;
395- final double outAlpha = alpha + backAlpha;
396- assert (outAlpha != 0 );
397- return Color .from (
398- alpha : outAlpha,
399- red : (foreground.r * alpha + background.r * backAlpha) / outAlpha,
400- green : (foreground.g * alpha + background.g * backAlpha) / outAlpha,
401- blue : (foreground.b * alpha + background.b * backAlpha) / outAlpha,
402- colorSpace : foreground.colorSpace,
397+ backAlpha = ( backAlpha * invAlpha) ~ / 0xff ;
398+ final int outAlpha = alpha + backAlpha;
399+ assert (outAlpha != 0x00 );
400+ return Color ._fromARGBC (
401+ outAlpha,
402+ (foreground.red * alpha + background.red * backAlpha) ~ / outAlpha,
403+ (foreground.green * alpha + background.green * backAlpha) ~ / outAlpha,
404+ (foreground.blue * alpha + background.blue * backAlpha) ~ / outAlpha,
405+ foreground.colorSpace,
403406 );
404407 }
405408 }
@@ -420,19 +423,16 @@ class Color {
420423 return false ;
421424 }
422425 return other is Color &&
423- other.a == a &&
424- other.r == r &&
425- other.g == g &&
426- other.b == b &&
426+ other.value == value &&
427427 other.colorSpace == colorSpace;
428428 }
429429
430430 @override
431- int get hashCode => Object .hash (a, r, g, b , colorSpace);
431+ int get hashCode => Object .hash (value , colorSpace);
432432
433+ // TODO(gaaclarke): Make toString() print out float values.
433434 @override
434- String toString () =>
435- 'Color(alpha: ${a .toStringAsFixed (4 )}, red: ${r .toStringAsFixed (4 )}, green: ${g .toStringAsFixed (4 )}, blue: ${b .toStringAsFixed (4 )}, colorSpace: $colorSpace )' ;
435+ String toString () => 'Color(0x${value .toRadixString (16 ).padLeft (8 , '0' )})' ;
436436}
437437
438438/// Algorithms to use when painting on the canvas.
0 commit comments