Improve API for contrast blending functions.
This reduces the number of functions and makes the naming and functionality more
coherent.
Bug: 870384
Change-Id: I67586068ddd32463ad72f0f923540ec6d7bdf737
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1610486
Commit-Queue: Fernando Serboncini <fserb@chromium.org>
Reviewed-by: Fernando Serboncini <fserb@chromium.org>
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: Michael Wasserman <msw@chromium.org>
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#661702}
diff --git a/ash/media/media_notification_background.cc b/ash/media/media_notification_background.cc
index 1a8a2a3..b4e99a15 100644
--- a/ash/media/media_notification_background.cc
+++ b/ash/media/media_notification_background.cc
@@ -343,10 +343,10 @@
}
SkColor MediaNotificationBackground::GetForegroundColor() const {
- return color_utils::GetColorWithMinimumContrast(
- foreground_color_.value_or(views::style::GetColor(
- *owner_, views::style::CONTEXT_LABEL, views::style::STYLE_PRIMARY)),
- GetBackgroundColor());
+ const SkColor foreground = foreground_color_.value_or(views::style::GetColor(
+ *owner_, views::style::CONTEXT_LABEL, views::style::STYLE_PRIMARY));
+ return color_utils::BlendForMinContrast(foreground, GetBackgroundColor())
+ .color;
}
int MediaNotificationBackground::GetArtworkWidth(
diff --git a/ash/public/cpp/default_frame_header.cc b/ash/public/cpp/default_frame_header.cc
index 606c9c9..3a4762a 100644
--- a/ash/public/cpp/default_frame_header.cc
+++ b/ash/public/cpp/default_frame_header.cc
@@ -172,7 +172,7 @@
const SkColor desired_color = color_utils::IsDark(frame_color)
? SK_ColorWHITE
: SkColorSetRGB(40, 40, 40);
- return color_utils::GetColorWithMinimumContrast(desired_color, frame_color);
+ return color_utils::BlendForMinContrast(desired_color, frame_color).color;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/search/ntp_icon_source.cc b/chrome/browser/search/ntp_icon_source.cc
index 2367e2b..fbde10ae 100644
--- a/chrome/browser/search/ntp_icon_source.cc
+++ b/chrome/browser/search/ntp_icon_source.cc
@@ -229,8 +229,10 @@
// If necessary, draw the colored fallback monogram.
if (favicon.empty()) {
- SkColor fallback_color = color_utils::GetColorWithMinimumContrast(
- GetBackgroundColorForUrl(icon_url), kFallbackIconLetterColor);
+ SkColor fallback_color =
+ color_utils::BlendForMinContrast(GetBackgroundColorForUrl(icon_url),
+ kFallbackIconLetterColor)
+ .color;
int offset = (icon_size - fallback_size) / 2;
DrawCircleInCanvas(&canvas, fallback_size, offset, fallback_color);
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc
index 9a72375..dbd7574 100644
--- a/chrome/browser/themes/browser_theme_pack.cc
+++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -812,10 +812,10 @@
frame_text_color = color_utils::GetColorWithMaxContrast(frame_color);
SkColor blend_target =
color_utils::GetColorWithMaxContrast(frame_text_color);
- SkAlpha alpha = color_utils::GetBlendValueWithMinimumContrast(
- frame_color, blend_target, frame_text_color,
- kPreferredReadableContrastRatio);
- frame_color = color_utils::AlphaBlend(blend_target, frame_color, alpha);
+ frame_color = color_utils::BlendForMinContrast(
+ frame_color, frame_text_color, blend_target,
+ kPreferredReadableContrastRatio)
+ .color;
// Generate active tab color so that it has enough contrast with the
// |frame_color| to avoid the isolation line in the tab strip.
@@ -1828,9 +1828,9 @@
}
}
- const SkColor result_color =
- color_utils::GetColorWithMinimumContrast(blend_source_color, bg_color);
- SetColor(text_color_id, result_color);
+ SetColor(
+ text_color_id,
+ color_utils::BlendForMinContrast(blend_source_color, bg_color).color);
}
void BrowserThemePack::GenerateMissingNtpColors() {
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc
index 6dde625..660d6a3 100644
--- a/chrome/browser/themes/theme_service.cc
+++ b/chrome/browser/themes/theme_service.cc
@@ -770,12 +770,13 @@
separator_color = color_utils::GetColorWithMaxContrast(separator_color);
}
- SkAlpha alpha = color_utils::FindBlendValueForContrastRatio(
- frame_color, separator_color, frame_color, kContrastRatio, 0);
- if (color_utils::GetContrastRatio(
- color_utils::AlphaBlend(separator_color, frame_color, alpha),
- frame_color) >= kContrastRatio) {
- return SkColorSetA(separator_color, alpha);
+ {
+ const auto result = color_utils::BlendForMinContrast(
+ frame_color, frame_color, separator_color, kContrastRatio);
+ if (color_utils::GetContrastRatio(result.color, frame_color) >=
+ kContrastRatio) {
+ return SkColorSetA(separator_color, result.alpha);
+ }
}
separator_color = color_utils::GetColorWithMaxContrast(separator_color);
@@ -786,9 +787,9 @@
// dark or very light, just not quite as much so as the frame color. Blend
// towards the opposite separator color, and compute the contrast against the
// tab instead of the frame to ensure both contrasts hit the desired minimum.
- alpha = color_utils::FindBlendValueForContrastRatio(
- frame_color, separator_color, tab_color, kContrastRatio, 0);
- return SkColorSetA(separator_color, alpha);
+ const auto result = color_utils::BlendForMinContrast(
+ frame_color, tab_color, separator_color, kContrastRatio);
+ return SkColorSetA(separator_color, result.alpha);
}
void ThemeService::DoSetTheme(const Extension* extension,
diff --git a/chrome/browser/ui/libgtkui/gtk_ui.cc b/chrome/browser/ui/libgtkui/gtk_ui.cc
index 9d5254b0..26e9fd2 100644
--- a/chrome/browser/ui/libgtkui/gtk_ui.cc
+++ b/chrome/browser/ui/libgtkui/gtk_ui.cc
@@ -920,17 +920,19 @@
color_map[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT] =
background_tab_text_color;
color_map[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO] =
- color_utils::GetColorWithMinimumContrast(
+ color_utils::BlendForMinContrast(
color_utils::HSLShift(background_tab_text_color,
kDefaultTintFrameIncognito),
- frame_color_incognito);
+ frame_color_incognito)
+ .color;
color_map[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT_INACTIVE] =
background_tab_text_color_inactive;
color_map[ThemeProperties::COLOR_BACKGROUND_TAB_TEXT_INCOGNITO_INACTIVE] =
- color_utils::GetColorWithMinimumContrast(
+ color_utils::BlendForMinContrast(
color_utils::HSLShift(background_tab_text_color_inactive,
kDefaultTintFrameIncognito),
- frame_color_incognito_inactive);
+ frame_color_incognito_inactive)
+ .color;
// These colors represent the border drawn around tabs and between
// the tabstrip and toolbar.
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
index ce99958b..93fd77e 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -2028,7 +2028,8 @@
SkColor BookmarkBarView::GetBookmarkBarTextColor() {
const ui::ThemeProvider* theme_provider = GetThemeProvider();
- return color_utils::GetColorWithMinimumContrast(
- theme_provider->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT),
- theme_provider->GetColor(ThemeProperties::COLOR_TOOLBAR));
+ return color_utils::BlendForMinContrast(
+ theme_provider->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT),
+ theme_provider->GetColor(ThemeProperties::COLOR_TOOLBAR))
+ .color;
}
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index 644c4d04..18e9caa 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -1717,8 +1717,8 @@
color_utils::AlphaBlend(default_color, background_color, 0.75f);
}
- return color_utils::GetColorWithMinimumContrast(default_color,
- background_color);
+ return color_utils::BlendForMinContrast(default_color, background_color)
+ .color;
}
// Returns the accessible tab name for the tab.
@@ -2386,14 +2386,14 @@
return;
const SkColor inactive_bg = GetTabBackgroundColor(TAB_INACTIVE);
- const auto get_alpha = [inactive_bg](SkColor target, float contrast) {
- return color_utils::GetBlendValueWithMinimumContrast(inactive_bg, target,
- inactive_bg, contrast);
+ const auto get_blend = [inactive_bg](SkColor target, float contrast) {
+ return color_utils::BlendForMinContrast(inactive_bg, inactive_bg, target,
+ contrast);
};
const SkColor active_bg = GetTabBackgroundColor(TAB_ACTIVE);
- const auto get_hover_opacity = [active_bg, &get_alpha](float contrast) {
- return get_alpha(active_bg, contrast) / 255.0f;
+ const auto get_hover_opacity = [active_bg, &get_blend](float contrast) {
+ return get_blend(active_bg, contrast).alpha / 255.0f;
};
// The contrast ratio for the hover effect on standard-width tabs.
@@ -2414,9 +2414,7 @@
const SkColor inactive_fg = GetTabForegroundColor(TAB_INACTIVE, inactive_bg);
// The contrast ratio for the separator between inactive tabs.
constexpr float kTabSeparatorContrast = 2.5f;
- const SkAlpha separator_alpha = get_alpha(inactive_fg, kTabSeparatorContrast);
- separator_color_ =
- color_utils::AlphaBlend(inactive_fg, inactive_bg, separator_alpha);
+ separator_color_ = get_blend(inactive_fg, kTabSeparatorContrast).color;
}
void TabStrip::ResizeLayoutTabs() {
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc
index ef3ebc4..95bb3d37 100644
--- a/chrome/browser/ui/views/tabs/tab_style_views.cc
+++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -400,20 +400,19 @@
SkColor title_color = tab_->controller()->GetTabForegroundColor(
expected_opacity > 0.5f ? TAB_ACTIVE : TAB_INACTIVE, bg_color);
- title_color = color_utils::GetColorWithMinimumContrast(title_color, bg_color);
+ title_color = color_utils::BlendForMinContrast(title_color, bg_color).color;
const SkColor base_hovered_color = theme_provider->GetColor(
ThemeProperties::COLOR_TAB_CLOSE_BUTTON_BACKGROUND_HOVER);
const SkColor base_pressed_color = theme_provider->GetColor(
ThemeProperties::COLOR_TAB_CLOSE_BUTTON_BACKGROUND_PRESSED);
- const auto get_color_for_contrast_ratio = [](SkColor fg_color,
- SkColor bg_color,
- float contrast_ratio) {
- const SkAlpha blend_alpha = color_utils::GetBlendValueWithMinimumContrast(
- bg_color, fg_color, bg_color, contrast_ratio);
- return color_utils::AlphaBlend(fg_color, bg_color, blend_alpha);
- };
+ const auto get_color_for_contrast_ratio =
+ [](SkColor fg_color, SkColor bg_color, float contrast_ratio) {
+ return color_utils::BlendForMinContrast(bg_color, bg_color, fg_color,
+ contrast_ratio)
+ .color;
+ };
const SkColor generated_icon_color = get_color_for_contrast_ratio(
title_color, bg_color,
@@ -425,11 +424,11 @@
base_pressed_color, bg_color, kMinimumPressedContrastRatio);
const SkColor generated_hovered_icon_color =
- color_utils::GetColorWithMinimumContrast(title_color,
- generated_hovered_color);
+ color_utils::BlendForMinContrast(title_color, generated_hovered_color)
+ .color;
const SkColor generated_pressed_icon_color =
- color_utils::GetColorWithMinimumContrast(title_color,
- generated_pressed_color);
+ color_utils::BlendForMinContrast(title_color, generated_pressed_color)
+ .color;
return {bg_color,
title_color,
@@ -665,9 +664,9 @@
// Tint with group color. With a dark scheme, the tint needs a higher
// contrast to stand out effectively.
const float target_contrast = color_utils::IsDark(color) ? 1.8f : 1.2f;
- const SkAlpha blend_alpha = color_utils::GetBlendValueWithMinimumContrast(
- color, group_color.value(), color, target_contrast);
- color = color_utils::AlphaBlend(group_color.value(), color, blend_alpha);
+ color = color_utils::BlendForMinContrast(
+ color, color, group_color.value(), target_contrast)
+ .color;
}
}
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc
index f7df132..815f670 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_button.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -313,11 +313,10 @@
// Add a fudge factor to the minimum contrast ratio since we'll actually be
// blending with the adjusted color.
- const SkAlpha blend_alpha = color_utils::GetBlendValueWithMinimumContrast(
- contrasting_color, limit, base_color,
- color_utils::kMinimumReadableContrastRatio * 1.05);
-
- return color_utils::AlphaBlend(limit, contrasting_color, blend_alpha);
+ return color_utils::BlendForMinContrast(
+ contrasting_color, base_color, limit,
+ color_utils::kMinimumReadableContrastRatio * 1.05)
+ .color;
}
bool ToolbarButton::ShouldShowMenu() {
diff --git a/ui/gfx/color_utils.cc b/ui/gfx/color_utils.cc
index 92ba1407..c058749 100644
--- a/ui/gfx/color_utils.cc
+++ b/ui/gfx/color_utils.cc
@@ -324,61 +324,40 @@
foreground1 : foreground2;
}
-SkColor GetColorWithMinimumContrast(SkColor default_foreground,
- SkColor background) {
- const SkColor contrasting_color = GetColorWithMaxContrast(background);
- const SkAlpha alpha = GetBlendValueWithMinimumContrast(
- default_foreground, contrasting_color, background,
- kMinimumReadableContrastRatio);
- return AlphaBlend(contrasting_color, default_foreground, alpha);
-}
+BlendResult BlendForMinContrast(
+ SkColor default_foreground,
+ SkColor background,
+ base::Optional<SkColor> high_contrast_foreground,
+ float contrast_ratio) {
+ DCHECK_EQ(SkColorGetA(background), SK_AlphaOPAQUE);
+ default_foreground = GetResultingPaintColor(default_foreground, background);
+ if (GetContrastRatio(default_foreground, background) >= contrast_ratio)
+ return {SK_AlphaTRANSPARENT, default_foreground};
+ const SkColor target_foreground = GetResultingPaintColor(
+ high_contrast_foreground.value_or(GetColorWithMaxContrast(background)),
+ background);
-SkAlpha GetBlendValueWithMinimumContrast(SkColor source,
- SkColor target,
- SkColor base,
- float contrast_ratio) {
- DCHECK_EQ(SkColorGetA(base), SK_AlphaOPAQUE);
+ const float background_luminance = GetRelativeLuminance(background);
- source = GetResultingPaintColor(source, base);
- if (GetContrastRatio(source, base) >= contrast_ratio)
- return 0;
- target = GetResultingPaintColor(target, base);
-
- constexpr int kCloseEnoughAlphaDelta = 0x04;
- return FindBlendValueForContrastRatio(source, target, base, contrast_ratio,
- kCloseEnoughAlphaDelta);
-}
-
-SkAlpha FindBlendValueForContrastRatio(SkColor source,
- SkColor target,
- SkColor base,
- float contrast_ratio,
- int alpha_error_tolerance) {
- DCHECK_EQ(SkColorGetA(source), SK_AlphaOPAQUE);
- DCHECK_EQ(SkColorGetA(target), SK_AlphaOPAQUE);
- DCHECK_EQ(SkColorGetA(base), SK_AlphaOPAQUE);
- DCHECK_GE(alpha_error_tolerance, 0);
-
- const float base_luminance = GetRelativeLuminance(base);
-
+ SkAlpha best_alpha = SK_AlphaOPAQUE;
+ SkColor best_color = target_foreground;
// Use int for inclusive lower bound and exclusive upper bound, reserving
// conversion to SkAlpha for the end (reduces casts).
- int low = SK_AlphaTRANSPARENT;
- int high = SK_AlphaOPAQUE + 1;
- SkAlpha best = SK_AlphaOPAQUE;
- while (low + alpha_error_tolerance < high) {
+ for (int low = SK_AlphaTRANSPARENT, high = SK_AlphaOPAQUE + 1; low < high;) {
const SkAlpha alpha = (low + high) / 2;
- const SkColor blended = AlphaBlend(target, source, alpha);
- const float luminance = GetRelativeLuminance(blended);
- const float contrast = GetContrastRatio(luminance, base_luminance);
+ const SkColor color =
+ AlphaBlend(target_foreground, default_foreground, alpha);
+ const float luminance = GetRelativeLuminance(color);
+ const float contrast = GetContrastRatio(luminance, background_luminance);
if (contrast >= contrast_ratio) {
- best = alpha;
+ best_alpha = alpha;
+ best_color = color;
high = alpha;
} else {
low = alpha + 1;
}
}
- return best;
+ return {best_alpha, best_color};
}
SkColor InvertColor(SkColor color) {
diff --git a/ui/gfx/color_utils.h b/ui/gfx/color_utils.h
index c443749..a0853455 100644
--- a/ui/gfx/color_utils.h
+++ b/ui/gfx/color_utils.h
@@ -8,6 +8,7 @@
#include <string>
#include <tuple>
+#include "base/optional.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/gfx_export.h"
@@ -22,6 +23,13 @@
double l;
};
+// The blend alpha and resulting color when blending to achieve a desired
+// contrast raio.
+struct BlendResult {
+ SkAlpha alpha;
+ SkColor color;
+};
+
// The minimum contrast between text and background that is still readable.
// This value is taken from w3c accessibility guidelines.
constexpr float kMinimumReadableContrastRatio = 4.5f;
@@ -129,37 +137,18 @@
SkColor foreground2,
SkColor background);
-// This function attempts to select a color based on |default_foreground| that
-// will meet the minimum contrast ratio when used as a text color on top of
-// |background|. If |default_foreground| already meets the minimum contrast
-// ratio, this function will simply return it. Otherwise it will blend the color
-// darker/lighter until either the contrast ratio is acceptable or the color
-// cannot become any more extreme. Only use with opaque background.
-GFX_EXPORT SkColor GetColorWithMinimumContrast(SkColor default_foreground,
- SkColor background);
-
-// Attempts to select an alpha value such that blending |target| onto |source|
-// with that alpha produces a color of at least |contrast_ratio| against |base|.
-// If |source| already meets the minimum contrast ratio, this function will
-// simply return 0. Otherwise it will blend the |target| onto |source| until
-// either the contrast ratio is acceptable or the color cannot become any more
-// extreme. |base| must be opaque.
-GFX_EXPORT SkAlpha GetBlendValueWithMinimumContrast(SkColor source,
- SkColor target,
- SkColor base,
- float contrast_ratio);
-
-// Returns the minimum alpha value such that blending |target| onto |source|
-// produces a color that contrasts against |base| with at least |contrast_ratio|
-// unless this is impossible, in which case SK_AlphaOPAQUE is returned.
-// Use only with opaque colors. |alpha_error_tolerance| should normally be 0 for
-// best accuracy, but if performance is critical then it can be a positive value
-// (4 is recommended) to save a few cycles and give "close enough" alpha.
-GFX_EXPORT SkAlpha FindBlendValueForContrastRatio(SkColor source,
- SkColor target,
- SkColor base,
- float contrast_ratio,
- int alpha_error_tolerance);
+// Alpha-blends |default_foreground| toward either |high_contrast_foreground|
+// (if specified) or the color with max contrast with |background| until either
+// the result has a contrast ratio against |background| of at least
+// |contrast_ratio| or the blend can go no further. Returns the blended color
+// and the alpha used to achieve that blend. If |default_foreground| already
+// has sufficient contrast, returns an alpha of 0 and color of
+// |default_foreground|.
+GFX_EXPORT BlendResult BlendForMinContrast(
+ SkColor default_foreground,
+ SkColor background,
+ base::Optional<SkColor> high_contrast_foreground = base::nullopt,
+ float contrast_ratio = kMinimumReadableContrastRatio);
// Invert a color.
GFX_EXPORT SkColor InvertColor(SkColor color);
diff --git a/ui/gfx/color_utils_unittest.cc b/ui/gfx/color_utils_unittest.cc
index 9fcedd3..68c14dd 100644
--- a/ui/gfx/color_utils_unittest.cc
+++ b/ui/gfx/color_utils_unittest.cc
@@ -239,46 +239,49 @@
EXPECT_EQ(old_darkest_color, GetColorWithMaxContrast(SK_ColorWHITE));
}
-TEST(ColorUtils, GetColorWithMinimumContrast_ForegroundAlreadyMeetsMinimum) {
- EXPECT_EQ(SK_ColorBLACK,
- GetColorWithMinimumContrast(SK_ColorBLACK, SK_ColorWHITE));
+TEST(ColorUtils, BlendForMinContrast_ForegroundAlreadyMeetsMinimum) {
+ const auto result = BlendForMinContrast(SK_ColorBLACK, SK_ColorWHITE);
+ EXPECT_EQ(SK_AlphaTRANSPARENT, result.alpha);
+ EXPECT_EQ(SK_ColorBLACK, result.color);
}
-TEST(ColorUtils, GetColorWithMinimumContrast_BlendDarker) {
+TEST(ColorUtils, BlendForMinContrast_BlendDarker) {
const SkColor foreground = SkColorSetRGB(0xAA, 0xAA, 0xAA);
- const SkColor result = GetColorWithMinimumContrast(foreground, SK_ColorWHITE);
- EXPECT_NE(foreground, result);
- EXPECT_GE(GetContrastRatio(result, SK_ColorWHITE),
+ const auto result = BlendForMinContrast(foreground, SK_ColorWHITE);
+ EXPECT_NE(SK_AlphaTRANSPARENT, result.alpha);
+ EXPECT_NE(foreground, result.color);
+ EXPECT_GE(GetContrastRatio(result.color, SK_ColorWHITE),
kMinimumReadableContrastRatio);
}
-TEST(ColorUtils, GetColorWithMinimumContrast_BlendLighter) {
+TEST(ColorUtils, BlendForMinContrast_BlendLighter) {
const SkColor foreground = SkColorSetRGB(0x33, 0x33, 0x33);
- const SkColor result = GetColorWithMinimumContrast(foreground, SK_ColorBLACK);
- EXPECT_NE(foreground, result);
- EXPECT_GE(GetContrastRatio(result, SK_ColorBLACK),
+ const auto result = BlendForMinContrast(foreground, SK_ColorBLACK);
+ EXPECT_NE(SK_AlphaTRANSPARENT, result.alpha);
+ EXPECT_NE(foreground, result.color);
+ EXPECT_GE(GetContrastRatio(result.color, SK_ColorBLACK),
kMinimumReadableContrastRatio);
}
-TEST(ColorUtils, GetColorWithMinimumContrast_StopsAtDarkestColor) {
+TEST(ColorUtils, BlendForMinContrast_StopsAtDarkestColor) {
const SkColor darkest_color = SkColorSetRGB(0x44, 0x44, 0x44);
const SkColor old_darkest_color = SetDarkestColorForTesting(darkest_color);
- EXPECT_EQ(darkest_color,
- GetColorWithMinimumContrast(SkColorSetRGB(0x55, 0x55, 0x55),
- SkColorSetRGB(0xAA, 0xAA, 0xAA)));
+ EXPECT_EQ(darkest_color, BlendForMinContrast(SkColorSetRGB(0x55, 0x55, 0x55),
+ SkColorSetRGB(0xAA, 0xAA, 0xAA))
+ .color);
SetDarkestColorForTesting(old_darkest_color);
}
-TEST(ColorUtils, GetBlendValueWithMinimumContrast_ComputesExpectedOpacities) {
+TEST(ColorUtils, BlendForMinContrast_ComputesExpectedOpacities) {
const SkColor source = SkColorSetRGB(0xDE, 0xE1, 0xE6);
const SkColor target = SkColorSetRGB(0xFF, 0xFF, 0xFF);
const SkColor base = source;
- SkAlpha alpha = GetBlendValueWithMinimumContrast(source, target, base, 1.11f);
+ SkAlpha alpha = BlendForMinContrast(source, base, target, 1.11f).alpha;
EXPECT_NEAR(alpha / 255.0f, 0.4f, 0.03f);
- alpha = GetBlendValueWithMinimumContrast(source, target, base, 1.19f);
+ alpha = BlendForMinContrast(source, base, target, 1.19f).alpha;
EXPECT_NEAR(alpha / 255.0f, 0.65f, 0.03f);
- alpha = GetBlendValueWithMinimumContrast(source, target, base, 1.13728f);
+ alpha = BlendForMinContrast(source, base, target, 1.13728f).alpha;
EXPECT_NEAR(alpha / 255.0f, 0.45f, 0.03f);
}
@@ -304,25 +307,26 @@
}
}
-TEST(ColorUtils, FindBlendValueForContrastRatio_MatchesNaiveImplementation) {
- const SkColor source = SkColorSetRGB(0xDE, 0xE1, 0xE6);
- const SkColor target = SkColorSetRGB(0xFF, 0xFF, 0xFF);
- const SkColor base = source;
- const float contrast_ratio = 1.11f;
- const SkAlpha alpha =
- FindBlendValueForContrastRatio(source, target, base, contrast_ratio, 0);
+TEST(ColorUtils, BlendForMinContrast_MatchesNaiveImplementation) {
+ constexpr SkColor default_foreground = SkColorSetRGB(0xDE, 0xE1, 0xE6);
+ constexpr SkColor high_contrast_foreground = SK_ColorWHITE;
+ constexpr SkColor background = default_foreground;
+ constexpr float kContrastRatio = 1.11f;
+ const auto result = BlendForMinContrast(
+ default_foreground, background, high_contrast_foreground, kContrastRatio);
// Naive implementation is direct translation of function description.
- SkAlpha check = SK_AlphaTRANSPARENT;
- for (SkAlpha alpha = SK_AlphaTRANSPARENT; alpha <= SK_AlphaOPAQUE; ++alpha) {
- const SkColor blended = AlphaBlend(target, source, alpha);
- const float contrast = GetContrastRatio(blended, base);
- check = alpha;
- if (contrast >= contrast_ratio)
+ SkAlpha alpha = SK_AlphaTRANSPARENT;
+ SkColor color = default_foreground;
+ for (int i = SK_AlphaTRANSPARENT; i <= SK_AlphaOPAQUE; ++i) {
+ alpha = SkAlpha{i};
+ color = AlphaBlend(high_contrast_foreground, default_foreground, alpha);
+ if (GetContrastRatio(color, background) >= kContrastRatio)
break;
}
- EXPECT_EQ(check, alpha);
+ EXPECT_EQ(alpha, result.alpha);
+ EXPECT_EQ(color, result.color);
}
} // namespace color_utils
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc
index de56de6..8b42eab 100644
--- a/ui/views/controls/label.cc
+++ b/ui/views/controls/label.cc
@@ -873,7 +873,7 @@
SkColor Label::GetForegroundColor(SkColor foreground,
SkColor background) const {
return (auto_color_readability_ && IsOpaque(background))
- ? color_utils::GetColorWithMinimumContrast(foreground, background)
+ ? color_utils::BlendForMinContrast(foreground, background).color
: foreground;
}
diff --git a/ui/views/controls/label.h b/ui/views/controls/label.h
index f07f285..f21722f 100644
--- a/ui/views/controls/label.h
+++ b/ui/views/controls/label.h
@@ -86,9 +86,9 @@
// Enables or disables auto-color-readability (enabled by default). If this
// is enabled, then calls to set any foreground or background color will
- // trigger an automatic mapper that uses
- // color_utils::GetColorWithMinimumContrast() to ensure that the foreground
- // colors are readable over the background color.
+ // trigger an automatic mapper that uses color_utils::BlendForMinContrast()
+ // to ensure that the foreground colors are readable over the background
+ // color.
void SetAutoColorReadabilityEnabled(bool enabled);
// Sets the color. This will automatically force the color to be readable
diff --git a/ui/views/window/frame_caption_button.cc b/ui/views/window/frame_caption_button.cc
index 25fcf50..2d0e9acb 100644
--- a/ui/views/window/frame_caption_button.cc
+++ b/ui/views/window/frame_caption_button.cc
@@ -75,16 +75,17 @@
// colors) can change between light/dark targets at the same time. It looks
// bad when the title and caption buttons disagree about whether to be light
// or dark.
- const SkColor source = color_utils::IsDark(background_color)
- ? gfx::kGoogleGrey200
- : gfx::kGoogleGrey700;
- const SkColor target = color_utils::GetColorWithMaxContrast(background_color);
+ const SkColor default_foreground = color_utils::IsDark(background_color)
+ ? gfx::kGoogleGrey200
+ : gfx::kGoogleGrey700;
+ const SkColor high_contrast_foreground =
+ color_utils::GetColorWithMaxContrast(background_color);
// Guarantee the caption buttons reach at least contrast ratio 3; this ratio
// matches that used for focus indicators, large text, and other "have to see
// it but perhaps don't have to read fine detail" cases.
- const SkAlpha alpha = color_utils::GetBlendValueWithMinimumContrast(
- source, target, background_color, 3.0f);
- return color_utils::AlphaBlend(target, source, alpha);
+ return color_utils::BlendForMinContrast(default_foreground, background_color,
+ high_contrast_foreground, 3.0f)
+ .color;
}
// static