/pidgin/main: 3cbfaaacaec3: Luminanosity Contrast Check

Jerin Philip <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: 3cbfaaacaec3867f1260d9d36e96a33f166121a2
Author:	 Jerin Philip <[email protected]>
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;
 }
 

_______________________________________________
Commits mailing list
[email protected]
https://pidgin.im/cgi-bin/mailman/listinfo/commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.