/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