[web] Cupertino dynamic color fix. (#13296)

* Fix cupertino theme rendering issues due to Color subclassing
Fixes flutter/flutter#41257
This commit is contained in:
Ferhat 2019-10-22 16:46:38 -07:00 committed by GitHub
parent e57c058cea
commit 227e44d9e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 22 deletions

View File

@ -43,11 +43,11 @@ class Color {
/// Bits 16-23 are the red value.
/// Bits 8-15 are the green value.
/// Bits 0-7 are the blue value.
const Color(int value) : _value = value & 0xFFFFFFFF;
const Color(int value) : this.value = value & 0xFFFFFFFF;
/// Construct a color from the lower 8 bits of four integers.
const Color.fromARGB(int a, int r, int g, int b)
: _value = (((a & 0xff) << 24) |
: value = (((a & 0xff) << 24) |
((r & 0xff) << 16) |
((g & 0xff) << 8) |
((b & 0xff) << 0)) &
@ -65,7 +65,7 @@ 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) |
: value = ((((opacity * 0xff ~/ 1) & 0xff) << 24) |
((r & 0xff) << 16) |
((g & 0xff) << 8) |
((b & 0xff) << 0)) &
@ -77,23 +77,22 @@ class Color {
/// Bits 16-23 are the red value.
/// Bits 8-15 are the green value.
/// Bits 0-7 are the blue value.
int get value => _value;
final int _value;
final int value;
/// The alpha channel of this color in an 8 bit value.
int get alpha => (0xff000000 & _value) >> 24;
int get alpha => (0xff000000 & value) >> 24;
/// The alpha channel of this color as a double.
double get opacity => alpha / 0xFF;
/// The red channel of this color in an 8 bit value.
int get red => (0x00ff0000 & _value) >> 16;
int get red => (0x00ff0000 & value) >> 16;
/// The green channel of this color in an 8 bit value.
int get green => (0x0000ff00 & _value) >> 8;
int get green => (0x0000ff00 & value) >> 8;
/// The blue channel of this color in an 8 bit value.
int get blue => (0x000000ff & _value) >> 0;
int get blue => (0x000000ff & value) >> 0;
/// Returns a new color that matches this color with the alpha channel
/// replaced with a (which ranges from 0 to 255).
@ -240,22 +239,22 @@ class Color {
}
@override
int get hashCode => _value.hashCode;
int get hashCode => value.hashCode;
/// Converts color to a css compatible attribute value.
// webOnly
String toCssString() {
if ((0xff000000 & _value) == 0xff000000) {
if ((0xff000000 & value) == 0xff000000) {
return toCssStringRgbOnly();
} else {
final double alpha = ((_value >> 24) & 0xFF) / 255.0;
final double alpha = ((value >> 24) & 0xFF) / 255.0;
final StringBuffer sb = StringBuffer();
sb.write('rgba(');
sb.write(((_value >> 16) & 0xFF).toString());
sb.write(((value >> 16) & 0xFF).toString());
sb.write(',');
sb.write(((_value >> 8) & 0xFF).toString());
sb.write(((value >> 8) & 0xFF).toString());
sb.write(',');
sb.write((_value & 0xFF).toString());
sb.write((value & 0xFF).toString());
sb.write(',');
sb.write(alpha.toString());
sb.write(')');
@ -269,7 +268,7 @@ class Color {
/// with the paint opacity.
// webOnly
String toCssStringRgbOnly() {
final String paddedValue = '00000${_value.toRadixString(16)}';
final String paddedValue = '00000${value.toRadixString(16)}';
return '#${paddedValue.substring(paddedValue.length - 6)}';
}
@ -1396,7 +1395,8 @@ abstract class ColorFilter {
/// The output of this filter is then composited into the background according
/// to the [Paint.blendMode], using the output of this filter as the source
/// and the background as the destination.
const factory ColorFilter.mode(Color color, BlendMode blendMode) = engine.EngineColorFilter.mode;
const factory ColorFilter.mode(Color color, BlendMode blendMode) =
engine.EngineColorFilter.mode;
/// Construct a color filter that transforms a color by a 4x5 matrix.
///
@ -1456,22 +1456,25 @@ abstract class ColorFilter {
/// 0, 0, 0, 1, 0,
/// ]);
/// ```
const factory ColorFilter.matrix(List<double> matrix) = engine.EngineColorFilter.matrix;
const factory ColorFilter.matrix(List<double> matrix) =
engine.EngineColorFilter.matrix;
/// Construct a color filter that applies the sRGB gamma curve to the RGB
/// channels.
const factory ColorFilter.linearToSrgbGamma() = engine.EngineColorFilter.linearToSrgbGamma;
const factory ColorFilter.linearToSrgbGamma() =
engine.EngineColorFilter.linearToSrgbGamma;
/// Creates a color filter that applies the inverse of the sRGB gamma curve
/// to the RGB channels.
const factory ColorFilter.srgbToLinearGamma() = engine.EngineColorFilter.srgbToLinearGamma;
const factory ColorFilter.srgbToLinearGamma() =
engine.EngineColorFilter.srgbToLinearGamma;
List<dynamic> webOnlySerializeToCssPaint() {
throw UnsupportedError('ColorFilter for CSS paint not yet supported');
}
@override
bool operator==(dynamic other);
bool operator ==(dynamic other);
@override
int get hashCode;
@ -1743,7 +1746,8 @@ class Codec {
///
/// The returned future can complete with an error if the image decoding has
/// failed.
Future<Codec> instantiateImageCodec(Uint8List list, {
Future<Codec> instantiateImageCodec(
Uint8List list, {
int targetWidth,
int targetHeight,
}) {

View File

@ -137,4 +137,21 @@ void main() {
// 0.0722 * ((0.18823529411 + 0.055) / 1.055) ^ 2.4
expect(brightRed.computeLuminance(), equals(0.24601329637099723));
});
// Regression test for https://github.com/flutter/flutter/issues/41257
// CupertinoDynamicColor was overriding base class and calling super(0).
test('subclass of Color can override value', () {
final DynamicColorClass color = DynamicColorClass(0xF0E0D0C0);
expect(color.value, 0xF0E0D0C0);
// Call base class member, make sure it uses overridden value.
expect(color.red, 0xE0);
});
}
class DynamicColorClass extends Color {
const DynamicColorClass(int newValue) : _newValue = newValue, super(0);
final int _newValue;
int get value => _newValue;
}