From 382fd1ea143afd57c1191500d75ac23984e939cf Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Tue, 5 Nov 2024 17:07:20 -0800 Subject: [PATCH] Add and document and explicit `toARGB32`. (#56329) Closes https://github.com/flutter/flutter/issues/157128. --- lib/ui/painting.dart | 22 ++++++++++++++++++++-- lib/web_ui/lib/painting.dart | 5 +++-- testing/dart/color_test.dart | 5 +++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/ui/painting.dart b/lib/ui/painting.dart index cd73c6aaca023..2561fa96e3834 100644 --- a/lib/ui/painting.dart +++ b/lib/ui/painting.dart @@ -197,8 +197,26 @@ class Color { /// * Bits 16-23 are the red value. /// * Bits 8-15 are the green value. /// * Bits 0-7 are the blue value. - @Deprecated('Use component accessors like .r or .g.') - int get value { + @Deprecated('Use component accessors like .r or .g, or toARGB32 for an explicit conversion') + int get value => toARGB32(); + + /// Returns a 32-bit value representing this color. + /// + /// Unlike accessing the floating point equivalent channels individually + /// ([a], [r], [g], [b]), this method is intentionally _lossy_, and scales + /// each channel using `(channel * 255.0).round() & 0xff`. + /// + /// While useful for storing a 32-bit integer value, prefer accessing the + /// individual channels (and storing the double equivalent) where higher + /// precision is required. + /// + /// The bits are assigned as follows: + /// + /// * Bits 24-31 represents the [a] channel as an 8-bit unsigned integer. + /// * Bits 16-23 represents the [r] channel as an 8-bit unsigned integer. + /// * Bits 8-15 represents the [g] channel as an 8-bit unsigned integer. + /// * Bits 0-7 represents the [b] channel as an 8-bit unsigned integer. + int toARGB32() { return _floatToInt8(a) << 24 | _floatToInt8(r) << 16 | _floatToInt8(g) << 8 | diff --git a/lib/web_ui/lib/painting.dart b/lib/web_ui/lib/painting.dart index 82fa3d021f8f5..dce324c9431ca 100644 --- a/lib/web_ui/lib/painting.dart +++ b/lib/web_ui/lib/painting.dart @@ -68,14 +68,15 @@ class Color { return (x * 255.0).round() & 0xff; } - int get value { + int get value => toARGB32(); + + int toARGB32() { return _floatToInt8(a) << 24 | _floatToInt8(r) << 16 | _floatToInt8(g) << 8 | _floatToInt8(b) << 0; } - int get alpha => (0xff000000 & value) >> 24; double get opacity => alpha / 0xFF; diff --git a/testing/dart/color_test.dart b/testing/dart/color_test.dart index 2b45535369e42..a23f485aadeca 100644 --- a/testing/dart/color_test.dart +++ b/testing/dart/color_test.dart @@ -339,6 +339,11 @@ void main() { // Call base class member, make sure it uses overridden value. expect(color.red, 0xE0); }); + + test('toARGB32 converts to a 32-bit integer', () { + const Color color = Color.from(alpha: 0.1, red: 0.2, green: 0.3, blue: 0.4); + expect(color.toARGB32(), equals(0x1a334d66)); + }); } class DynamicColorClass extends Color {