/pidgin/main: 3cbfaaacaec3: Luminanosity Contrast Check
Jerin Philip
jerin.philip at students.iiit.ac.in
Sat Feb 13 18:05:31 EST 2016
Changeset: 3cbfaaacaec3867f1260d9d36e96a33f166121a2
Author: Jerin Philip <jerin.philip at students.iiit.ac.in>
Date: 2016-02-11 23:54 +0530
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/3cbfaaacaec3
Description:
Luminanosity Contrast Check
Replace existing brightness-color contrast check with luminosity contrast to get better colors.
Ref: https://developer.pidgin.im/ticket/15745
diffstat:
pidgin/gtkconv.c | 105 ++++++++++++++++++++++++++++++++----------------------
1 files changed, 62 insertions(+), 43 deletions(-)
diffs (151 lines):
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -142,12 +142,7 @@ enum {
#define LUMINANCE(c) (float)((0.3*(c.red))+(0.59*(c.green))+(0.11*(c.blue)))
-/* From http://www.w3.org/TR/AERT#color-contrast
- * Range for color difference is 500
- * Range for brightness is 125
- */
-#define MIN_BRIGHTNESS_CONTRAST 85
-#define MIN_COLOR_CONTRAST 250
+#define MIN_LUMINANCE_CONTRAST_RATIO 4.5
#define NICK_COLOR_GENERATE_COUNT 220
static GArray *generated_nick_colors = NULL;
@@ -210,7 +205,8 @@ static void update_typing_icon(PidginCon
static void update_typing_message(PidginConversation *gtkconv, const char *message);
gboolean pidgin_conv_has_focus(PurpleConversation *conv);
static GArray* generate_nick_colors(guint numcolors, GdkColor background);
-static gboolean color_is_visible(GdkColor foreground, GdkColor background, guint color_contrast, guint brightness_contrast);
+gfloat luminance(GdkColor color);
+static gboolean color_is_visible(GdkColor foreground, GdkColor background, gfloat min_contrast_ratio);
static GtkTextTag *get_buddy_tag(PurpleChatConversation *chat, const char *who, PurpleMessageFlags flag, gboolean create);
static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
static void focus_out_from_menubar(GtkWidget *wid, PidginConvWindow *win);
@@ -11113,37 +11109,54 @@ pidgin_conv_is_hidden(PidginConversation
}
-/* Algorithm from http://www.w3.org/TR/AERT#color-contrast */
+gfloat luminance(GdkColor color)
+{
+ gfloat r, g, b;
+ gfloat rr, gg, bb;
+ gint ir, ig, ib;
+ gfloat cutoff = 0.03928, scale = 12.92,
+ a = 0.055, d = 1.055, p = 2.2;
+ gfloat sRGBScale = 255.0;
+
+ ir = color.red >> 8;
+ ig = color.green >> 8;
+ ib = color.blue >> 8;
+
+ rr = (float)(ir)/sRGBScale;
+ gg = (float)(ig)/sRGBScale;
+ bb = (float)(ib)/sRGBScale;
+
+ r = (rr > cutoff) ? pow((rr+a)/d, p) : rr/scale;
+ g = (gg > cutoff) ? pow((gg+a)/d, p) : gg/scale;
+ b = (bb > cutoff) ? pow((bb+a)/d, p) : bb/scale;
+
+ return (r*0.2126 + g*0.7152 + b*0.0722);
+}
+
+/* Algorithm from https://www.w3.org/TR/2008/REC-WCAG20-20081211/relative-luminance.xml */
static gboolean
-color_is_visible(GdkColor foreground, GdkColor background, guint color_contrast, guint brightness_contrast)
-{
- gulong fg_brightness;
- gulong bg_brightness;
- gulong br_diff;
- gulong col_diff;
- int fred, fgreen, fblue, bred, bgreen, bblue;
-
- /* this algorithm expects colors between 0 and 255 for each of red green and blue.
- * GTK on the other hand has values between 0 and 65535
- * Err suggested I >> 8, which grabbed the high bits.
- */
-
- fred = foreground.red >> 8 ;
- fgreen = foreground.green >> 8 ;
- fblue = foreground.blue >> 8 ;
-
-
- bred = background.red >> 8 ;
- bgreen = background.green >> 8 ;
- bblue = background.blue >> 8 ;
-
- fg_brightness = (fred * 299 + fgreen * 587 + fblue * 114) / 1000;
- bg_brightness = (bred * 299 + bgreen * 587 + bblue * 114) / 1000;
- br_diff = abs(fg_brightness - bg_brightness);
-
- col_diff = abs(fred - bred) + abs(fgreen - bgreen) + abs(fblue - bblue);
-
- return ((col_diff > color_contrast) && (br_diff > brightness_contrast));
+color_is_visible(GdkColor foreground, GdkColor background, gfloat min_contrast_ratio)
+{
+ gfloat lfg, lbg, lmin, lmax;
+ gfloat luminosity_ratio;
+
+ lfg = luminance(foreground);
+ lbg = luminance(background);
+
+ if (lfg > lbg)
+ lmax = lfg, lmin = lbg;
+ else
+ lmax = lbg, lmin = lfg;
+
+ gfloat nr, dr;
+ nr = lmax + 0.05, dr = lmin - 0.05;
+ if ( dr == 0 )
+ dr += 0.01;
+
+ luminosity_ratio = nr/dr;
+ if ( luminosity_ratio < 0)
+ luminosity_ratio *= -1.0;
+ return (luminosity_ratio > min_contrast_ratio);
}
@@ -11171,9 +11184,9 @@ generate_nick_colors(guint numcolors, Gd
{
GdkColor color = nick_seed_colors[j];
- if (color_is_visible(color, background, MIN_COLOR_CONTRAST, MIN_BRIGHTNESS_CONTRAST) &&
- color_is_visible(color, nick_highlight, MIN_COLOR_CONTRAST / 2, 0) &&
- color_is_visible(color, send_color, MIN_COLOR_CONTRAST / 4, 0))
+ if (color_is_visible(color, background, MIN_LUMINANCE_CONTRAST_RATIO) &&
+ color_is_visible(color, nick_highlight, MIN_LUMINANCE_CONTRAST_RATIO) &&
+ color_is_visible(color, send_color, MIN_LUMINANCE_CONTRAST_RATIO))
{
g_array_append_val(colors, color);
i++;
@@ -11190,9 +11203,9 @@ generate_nick_colors(guint numcolors, Gd
{
GdkColor color = { 0, rand() % 65536, rand() % 65536, rand() % 65536 };
- if (color_is_visible(color, background, MIN_COLOR_CONTRAST, MIN_BRIGHTNESS_CONTRAST) &&
- color_is_visible(color, nick_highlight, MIN_COLOR_CONTRAST / 2, 0) &&
- color_is_visible(color, send_color, MIN_COLOR_CONTRAST / 4, 0))
+ if (color_is_visible(color, background, MIN_LUMINANCE_CONTRAST_RATIO) &&
+ color_is_visible(color, nick_highlight, MIN_LUMINANCE_CONTRAST_RATIO) &&
+ color_is_visible(color, send_color, MIN_LUMINANCE_CONTRAST_RATIO))
{
g_array_append_val(colors, color);
i++;
@@ -11203,6 +11216,12 @@ generate_nick_colors(guint numcolors, Gd
purple_debug_warning("gtkconv", "Unable to generate enough random colors before timeout. %u colors found.\n", i);
}
+ if( i == 0 ) {
+ /* To remove errors caused by an empty array. */
+ GdkColor color = {0, 32768, 32768, 32768};
+ g_array_append_val(colors, color);
+ }
+
return colors;
}
More information about the Commits
mailing list