rgb_color: Add new APIs: Contrast(), IsLight(), IsDark()

- Remove perceptual_brightness
- Change implementation of rgb_color::Brightness() to the previous BPrivate::perceptual_brightness()
- Introduce convenience methods Contrast(rgb_color), IsLight() and IsDark()

Change-Id: Id677d4a32ce43d73bffecf9baf8cffaafb01a16d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7399
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
nep
2024-02-26 20:24:25 +00:00
committed by waddlesplash
parent d24476aaf0
commit 9931e8eeee
7 changed files with 39 additions and 44 deletions
+22
View File
@@ -59,6 +59,28 @@ typedef struct rgb_color {
int32 Brightness() const; int32 Brightness() const;
inline bool
IsDark() const
{
return Brightness() <= 127;
}
inline bool
IsLight() const
{
return Brightness() > 127;
}
static inline int32
Contrast(rgb_color colorA, rgb_color colorB)
{
int32 contrast = colorA.Brightness() - colorB.Brightness();
if (contrast < 0)
return -contrast;
return contrast;
}
inline bool inline bool
operator==(const rgb_color& other) const operator==(const rgb_color& other) const
{ {
@@ -65,19 +65,6 @@ private:
}; };
static inline uint8 perceptual_brightness(rgb_color color)
{
// From http://alienryderflex.com/hsp.html
// Useful in particular to decide if the color is "light" or "dark"
// by checking if the perceptual brightness is > 127.
int r = color.red;
int g = color.green;
int b = color.blue;
return (uint8)roundf(sqrtf(
0.299f * r * r + 0.587f * g * g + 0.114 * b * b));
}
} // namespace BPrivate } // namespace BPrivate
#endif #endif
+1 -3
View File
@@ -913,9 +913,7 @@ SysInfoView::_DesktopTextColor(int32 workspace) const
workspace = current_workspace(); workspace = current_workspace();
rgb_color viewColor = screen.DesktopColor(workspace); rgb_color viewColor = screen.DesktopColor(workspace);
int viewBrightness = BPrivate::perceptual_brightness(viewColor); textColor.blue = textColor.green = textColor.red = viewColor.IsLight() ? 0 : 255;
textColor.blue = textColor.green = textColor.red = viewBrightness > 127
? 0 : 255;
textColor.alpha = 255; textColor.alpha = 255;
return textColor; return textColor;
+7 -2
View File
@@ -15,6 +15,7 @@
#include <AppServerLink.h> #include <AppServerLink.h>
#include <ServerProtocol.h> #include <ServerProtocol.h>
#include <math.h>
// patterns // patterns
const pattern B_SOLID_HIGH = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; const pattern B_SOLID_HIGH = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
@@ -36,11 +37,15 @@ const uint32 B_TRANSPARENT_MAGIC_RGBA32_BIG = 0x77747700;
const struct screen_id B_MAIN_SCREEN_ID = {0}; const struct screen_id B_MAIN_SCREEN_ID = {0};
// rgb_color
int32 int32
rgb_color::Brightness() const rgb_color::Brightness() const
{ {
return ((int32)red * 41 + (int32)green * 187 + (int32)blue * 28) >> 8; // From http://alienryderflex.com/hsp.html
// Useful in particular to decide if the color is "light" or "dark"
// by checking if the perceptual brightness is > 127.
return (uint8)roundf(sqrtf(
0.299f * red * red + 0.587f * green * green + 0.114 * blue * blue));
} }
+5 -8
View File
@@ -9158,16 +9158,13 @@ BPoseView::InvertedBackColor() const
{ {
rgb_color background = ui_color(B_DOCUMENT_BACKGROUND_COLOR); rgb_color background = ui_color(B_DOCUMENT_BACKGROUND_COLOR);
rgb_color inverted = invert_color(background); rgb_color inverted = invert_color(background);
int textBrightness = BPrivate::perceptual_brightness(inverted);
int viewBrightness = BPrivate::perceptual_brightness(background);
if (abs(viewBrightness - textBrightness) > 127) { // The colors are different enough, we can use inverted
// The colors are different enough, we can use inverted if (rgb_color::Contrast(background, inverted) > 127)
return inverted; return inverted;
} else {
// use black or white // use black or white
return (viewBrightness > 127 ? kBlack : kWhite); return background.IsLight() ? kBlack : kWhite;
}
} }
+3 -16
View File
@@ -1043,24 +1043,11 @@ BPoseView::DeskTextColor() const
rgb_color textColor = HighColor(); rgb_color textColor = HighColor();
rgb_color viewColor = ViewColor(); rgb_color viewColor = ViewColor();
int textBrightness = BPrivate::perceptual_brightness(textColor); // The colors are different enough, we can use them as is
int viewBrightness = BPrivate::perceptual_brightness(viewColor); if (rgb_color::Contrast(viewColor, textColor) > 127)
if (abs(viewBrightness - textBrightness) > 127) {
// The colors are different enough, we can use them as is
return textColor; return textColor;
} else {
if (viewBrightness > 127) {
textColor.red = 0;
textColor.green = 0;
textColor.blue = 0;
} else {
textColor.red = 255;
textColor.green = 255;
textColor.blue = 255;
}
return textColor; return viewColor.IsLight() ? kBlack : kWhite;
}
} }
+1 -2
View File
@@ -91,8 +91,7 @@ float
ReadOnlyTint(rgb_color base) ReadOnlyTint(rgb_color base)
{ {
// darken tint if read-only (or lighten if dark) // darken tint if read-only (or lighten if dark)
int viewBrightness = BPrivate::perceptual_brightness(base); return base.IsLight() ? B_DARKEN_1_TINT : 0.85;
return viewBrightness > 127 ? B_DARKEN_1_TINT : 0.85;
} }