diff --git a/widget/nsNativeTheme.cpp b/widget/nsNativeTheme.cpp index 3c53d84e965d..6044a0e1068b 100644 --- a/widget/nsNativeTheme.cpp +++ b/widget/nsNativeTheme.cpp @@ -30,6 +30,7 @@ #include "mozilla/PresShell.h" #include "mozilla/StaticPrefs_layout.h" #include "mozilla/dom/DocumentInlines.h" +#include "mozilla/RelativeLuminanceUtils.h" #include 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 there diff --git a/widget/nsNativeTheme.h b/widget/nsNativeTheme.h index d565c839016a..d7f6bcef4fd9 100644 --- a/widget/nsNativeTheme.h +++ b/widget/nsNativeTheme.h @@ -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);