Bug 1721606 - Improve dark-color check to actually account for luminance. r=mstange

See the discussion in https://groups.google.com/a/chromium.org/g/blink-dev/c/WwYkLjbGhoA/m/EftJoLN_AwAJ
for some background.

Differential Revision: https://phabricator.services.mozilla.com/D120471
This commit is contained in:
Emilio Cobos Álvarez 2021-07-22 10:29:52 +00:00
parent add15451cf
commit ae847ec44f
2 changed files with 24 additions and 7 deletions

View File

@ -30,6 +30,7 @@
#include "mozilla/PresShell.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/dom/DocumentInlines.h"
#include "mozilla/RelativeLuminanceUtils.h"
#include <algorithm>
using namespace mozilla;
@ -612,6 +613,28 @@ static nsIFrame* GetBodyFrame(nsIFrame* aCanvasFrame) {
return body->GetPrimaryFrame();
}
bool nsNativeTheme::IsDarkColor(nscolor aColor) {
// Given https://www.w3.org/TR/WCAG20/#contrast-ratiodef, this is the
// threshold that tells us whether contrast is better against white or black.
//
// Contrast ratio against black is: (L + 0.05) / 0.05
// Contrast ratio against white is: 1.05 / (L + 0.05)
//
// So the intersection is:
//
// (L + 0.05) / 0.05 = 1.05 / (L + 0.05)
//
// And the solution to that equation is:
//
// sqrt(1.05 * 0.05) - 0.05
//
// So we consider a color dark if the contrast is below this threshold, and
// it's at least half-opaque.
constexpr float kThreshold = 0.179129;
return NS_GET_A(aColor) > 127 &&
RelativeLuminanceUtils::Compute(aColor) < kThreshold;
}
/* static */
bool nsNativeTheme::IsDarkBackground(nsIFrame* aFrame) {
// Try to find the scrolled frame. Note that for stuff like xul <tree> there

View File

@ -185,13 +185,7 @@ class nsNativeTheme : public nsITimerCallback, public nsINamed {
bool IsRangeHorizontal(nsIFrame* aFrame);
static bool IsDarkBackground(nsIFrame* aFrame);
static bool IsDarkColor(nscolor aColor) {
// Consider a color dark if the sum of the r, g and b values is less than
// 384 in a semi-transparent document. This heuristic matches what WebKit
// does, and we can improve it later if needed.
return NS_GET_A(aColor) > 127 &&
NS_GET_R(aColor) + NS_GET_G(aColor) + NS_GET_B(aColor) < 384;
}
static bool IsDarkColor(nscolor aColor);
static bool IsWidgetScrollbarPart(mozilla::StyleAppearance aAppearance);