From ca4f4fc8d1be9e2bebc3c1c68ea5ba112035b9fa Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Mon, 5 Jun 2017 13:15:43 -0700 Subject: [PATCH] Make the Brightness estimator public (#10508) --- .../flutter/lib/src/material/theme_data.dart | 61 ++++++++++--------- .../test/material/theme_data_test.dart | 15 ++++- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/packages/flutter/lib/src/material/theme_data.dart b/packages/flutter/lib/src/material/theme_data.dart index cc134fbb1c..591e9edcaf 100644 --- a/packages/flutter/lib/src/material/theme_data.dart +++ b/packages/flutter/lib/src/material/theme_data.dart @@ -43,32 +43,6 @@ const Color _kLightThemeSplashColor = const Color(0x66C8C8C8); const Color _kDarkThemeHighlightColor = const Color(0x40CCCCCC); const Color _kDarkThemeSplashColor = const Color(0x40CCCCCC); -// See -double _linearizeColorComponent(double component) { - if (component <= 0.03928) - return component / 12.92; - return math.pow((component + 0.055) / 1.055, 2.4); -} - -Brightness _estimateBrightnessForColor(Color color) { - // See - final double R = _linearizeColorComponent(color.red / 0xFF); - final double G = _linearizeColorComponent(color.green / 0xFF); - final double B = _linearizeColorComponent(color.blue / 0xFF); - final double L = 0.2126 * R + 0.7152 * G + 0.0722 * B; - - // See - // The spec says to use kThreshold=0.0525, but Material Design appears to bias - // more towards using light text than WCAG20 recommends. Material Design spec - // doesn't say what value to use, but 0.15 seemed close to what the Material - // Design spec shows for its color palette on - // . - const double kThreshold = 0.15; - if ((L + 0.05) * (L + 0.05) > kThreshold ) - return Brightness.light; - return Brightness.dark; -} - /// Holds the color and typography values for a material design theme. /// /// Use this class to configure a [Theme] widget. @@ -134,10 +108,10 @@ class ThemeData { final bool isDark = brightness == Brightness.dark; primarySwatch ??= Colors.blue; primaryColor ??= isDark ? Colors.grey[900] : primarySwatch[500]; - primaryColorBrightness ??= _estimateBrightnessForColor(primaryColor); + primaryColorBrightness ??= estimateBrightnessForColor(primaryColor); final bool primaryIsDark = primaryColorBrightness == Brightness.dark; accentColor ??= isDark ? Colors.tealAccent[200] : primarySwatch[500]; - accentColorBrightness ??= _estimateBrightnessForColor(accentColor); + accentColorBrightness ??= estimateBrightnessForColor(accentColor); final bool accentIsDark = accentColorBrightness == Brightness.dark; canvasColor ??= isDark ? Colors.grey[850] : Colors.grey[50]; scaffoldBackgroundColor ??= canvasColor; @@ -467,6 +441,37 @@ class ThemeData { ); } + // See + static double _linearizeColorComponent(double component) { + if (component <= 0.03928) + return component / 12.92; + return math.pow((component + 0.055) / 1.055, 2.4); + } + + /// Determines whether the given [Color] is [Brightness.light] or + /// [Brightness.dark]. + /// + /// This compares the luminosity of the given color to a threshold value that + /// matches the material design specification. + static Brightness estimateBrightnessForColor(Color color) { + // See + final double R = _linearizeColorComponent(color.red / 0xFF); + final double G = _linearizeColorComponent(color.green / 0xFF); + final double B = _linearizeColorComponent(color.blue / 0xFF); + final double L = 0.2126 * R + 0.7152 * G + 0.0722 * B; + + // See + // The spec says to use kThreshold=0.0525, but Material Design appears to bias + // more towards using light text than WCAG20 recommends. Material Design spec + // doesn't say what value to use, but 0.15 seemed close to what the Material + // Design spec shows for its color palette on + // . + const double kThreshold = 0.15; + if ((L + 0.05) * (L + 0.05) > kThreshold ) + return Brightness.light; + return Brightness.dark; + } + /// Linearly interpolate between two themes. /// /// The arguments must not be null. diff --git a/packages/flutter/test/material/theme_data_test.dart b/packages/flutter/test/material/theme_data_test.dart index 57ea08665c..33b4f307c3 100644 --- a/packages/flutter/test/material/theme_data_test.dart +++ b/packages/flutter/test/material/theme_data_test.dart @@ -90,7 +90,20 @@ void main() { expect(themeData.accentTextTheme.display4.fontFamily, equals('Ahem')); }); - test('Can estimate brightness', () { + test('Can estimate brightness - directly', () { + expect(ThemeData.estimateBrightnessForColor(Colors.white), equals(Brightness.light)); + expect(ThemeData.estimateBrightnessForColor(Colors.black), equals(Brightness.dark)); + expect(ThemeData.estimateBrightnessForColor(Colors.blue), equals(Brightness.dark)); + expect(ThemeData.estimateBrightnessForColor(Colors.yellow), equals(Brightness.light)); + expect(ThemeData.estimateBrightnessForColor(Colors.deepOrange), equals(Brightness.dark)); + expect(ThemeData.estimateBrightnessForColor(Colors.orange), equals(Brightness.light)); + expect(ThemeData.estimateBrightnessForColor(Colors.lime), equals(Brightness.light)); + expect(ThemeData.estimateBrightnessForColor(Colors.grey), equals(Brightness.light)); + expect(ThemeData.estimateBrightnessForColor(Colors.teal), equals(Brightness.dark)); + expect(ThemeData.estimateBrightnessForColor(Colors.indigo), equals(Brightness.dark)); + }); + + test('Can estimate brightness - indirectly', () { expect(new ThemeData(primaryColor: Colors.white).primaryColorBrightness, equals(Brightness.light)); expect(new ThemeData(primaryColor: Colors.black).primaryColorBrightness, equals(Brightness.dark)); expect(new ThemeData(primaryColor: Colors.blue).primaryColorBrightness, equals(Brightness.dark));