Author: jtn
Date: Sat Dec 19 11:10:13 2015
New Revision: 31098

URL: http://svn.gna.org/viewcvs/freeciv?rev=31098&view=rev
Log:
In the city full bar on the main map, draw city size text as white or
black depending on the background (nation) colour.

GUIs must implement a new function color_brightness_score(); in
principle this could take advantage of GUI-specific colourspace
functions, but all current implementations use a platform-independent
utility rgbcolor_brightness_score().

Invisibility of city size on yellow background in Qt client reported by
mir3x@gna.

See gna bug #24120.

Modified:
    branches/S2_5/client/colors_common.c
    branches/S2_5/client/colors_common.h
    branches/S2_5/client/gui-gtk-2.0/canvas.c
    branches/S2_5/client/gui-gtk-2.0/colors.c
    branches/S2_5/client/gui-gtk-3.0/canvas.c
    branches/S2_5/client/gui-gtk-3.0/colors.c
    branches/S2_5/client/gui-qt/colors.cpp
    branches/S2_5/client/gui-sdl/colors.c
    branches/S2_5/client/gui-stub/colors.c
    branches/S2_5/client/gui-xaw/colors.c
    branches/S2_5/client/gui-xaw/mapview.c
    branches/S2_5/client/include/colors_g.h
    branches/S2_5/client/mapview_common.c
    branches/S2_5/common/rgbcolor.c
    branches/S2_5/common/rgbcolor.h
    branches/S2_5/utility/shared.h

Modified: branches/S2_5/client/colors_common.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/colors_common.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/colors_common.c        (original)
+++ branches/S2_5/client/colors_common.c        Sat Dec 19 11:10:13 2015
@@ -128,3 +128,30 @@
 
   return ensure_color(pterrain->rgb);
 }
+
+/****************************************************************************
+  Find the colour from 'candidates' with the best perceptual contrast from
+  'subject'.
+****************************************************************************/
+struct color *color_best_contrast(struct color *subject,
+                                  struct color **candidates, int ncandidates)
+{
+  int sbright = color_brightness_score(subject), bestdiff = 0;
+  int i;
+  struct color *best = NULL;
+
+  fc_assert_ret_val(candidates != NULL, NULL);
+  fc_assert_ret_val(ncandidates > 0, NULL);
+
+  for (i = 0; i < ncandidates; i++) {
+    int cbright = color_brightness_score(candidates[i]);
+    int diff = ABS(sbright - cbright);
+
+    if (best == NULL || diff > bestdiff) {
+      best = candidates[i];
+      bestdiff = diff;
+    }
+  }
+
+  return best;
+}

Modified: branches/S2_5/client/colors_common.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/colors_common.h?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/colors_common.h        (original)
+++ branches/S2_5/client/colors_common.h        Sat Dec 19 11:10:13 2015
@@ -125,6 +125,10 @@
 struct color_system *color_system_read(struct section_file *file);
 void color_system_free(struct color_system *colors);
 
+/* Utilities for color values */
+struct color *color_best_contrast(struct color *subject,
+                                  struct color **candidates, int ncandidates);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: branches/S2_5/client/gui-gtk-2.0/canvas.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/gui-gtk-2.0/canvas.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/gui-gtk-2.0/canvas.c   (original)
+++ branches/S2_5/client/gui-gtk-2.0/canvas.c   Sat Dec 19 11:10:13 2015
@@ -415,7 +415,10 @@
   pango_layout_set_text(layout, text, -1);
 
   pango_layout_get_pixel_extents(layout, &rect, NULL);
-  if (fonts[font].shadowed) {
+
+  /* Suppress drop shadow for black text */
+  if (fonts[font].shadowed
+      && !gdk_color_equal(&pcolor->color, &toplevel->style->black)) {
     gtk_draw_shadowed_string(pcanvas->v.pixmap,
                             toplevel->style->black_gc, civ_gc,
                             canvas_x,

Modified: branches/S2_5/client/gui-gtk-2.0/colors.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/gui-gtk-2.0/colors.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/gui-gtk-2.0/colors.c   (original)
+++ branches/S2_5/client/gui-gtk-2.0/colors.c   Sat Dec 19 11:10:13 2015
@@ -21,6 +21,8 @@
 
 #include "log.h"
 #include "mem.h"
+
+#include "rgbcolor.h"
 
 #include "gui_main.h"
 
@@ -80,6 +82,21 @@
 }
 
 /****************************************************************************
+  Return a number indicating the perceptual brightness of this color
+  relative to others (larger is brighter).
+****************************************************************************/
+int color_brightness_score(struct color *pcolor)
+{
+  struct rgbcolor *prgb = rgbcolor_new(pcolor->color.red >> 8,
+                                       pcolor->color.green >> 8,
+                                       pcolor->color.blue >> 8);
+  int score = rgbcolor_brightness_score(prgb);
+
+  rgbcolor_destroy(prgb);
+  return score;
+}
+
+/****************************************************************************
   Fill the string with the color in "#rrggbb" mode.  Use it instead of
   gdk_color() which have been included in gtk2.12 version only.
 ****************************************************************************/

Modified: branches/S2_5/client/gui-gtk-3.0/canvas.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/gui-gtk-3.0/canvas.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/gui-gtk-3.0/canvas.c   (original)
+++ branches/S2_5/client/gui-gtk-3.0/canvas.c   Sat Dec 19 11:10:13 2015
@@ -384,9 +384,14 @@
   pango_layout_set_text(layout, text, -1);
 
   if (fonts[font].shadowed) {
-    cairo_set_source_rgb(cr, 0, 0, 0);
-    cairo_move_to(cr, canvas_x + 1, canvas_y + 1);
-    pango_cairo_show_layout (cr, layout);
+    /* Suppress drop shadow for black text */
+    const GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 };
+
+    if (!gdk_rgba_equal(&pcolor->color, &black)) {
+      gdk_cairo_set_source_rgba(cr, &black);
+      cairo_move_to(cr, canvas_x + 1, canvas_y + 1);
+      pango_cairo_show_layout (cr, layout);
+    }
   }
 
   cairo_move_to(cr, canvas_x, canvas_y);

Modified: branches/S2_5/client/gui-gtk-3.0/colors.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/gui-gtk-3.0/colors.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/gui-gtk-3.0/colors.c   (original)
+++ branches/S2_5/client/gui-gtk-3.0/colors.c   Sat Dec 19 11:10:13 2015
@@ -21,6 +21,8 @@
 
 #include "log.h"
 #include "mem.h"
+
+#include "rgbcolor.h"
 
 #include "gui_main.h"
 
@@ -77,3 +79,18 @@
 {
   free(color);
 }
+
+/****************************************************************************
+  Return a number indicating the perceptual brightness of this color
+  relative to others (larger is brighter).
+****************************************************************************/
+int color_brightness_score(struct color *pcolor)
+{
+  struct rgbcolor *prgb = rgbcolor_new(pcolor->color.red * 255,
+                                       pcolor->color.green * 255,
+                                       pcolor->color.blue * 255);
+  int score = rgbcolor_brightness_score(prgb);
+
+  rgbcolor_destroy(prgb);
+  return score;
+}

Modified: branches/S2_5/client/gui-qt/colors.cpp
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/gui-qt/colors.cpp?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/gui-qt/colors.cpp      (original)
+++ branches/S2_5/client/gui-qt/colors.cpp      Sat Dec 19 11:10:13 2015
@@ -43,3 +43,20 @@
 {
   delete pcolor;
 }
+
+/****************************************************************************
+  Return a number indicating the perceptual brightness of this color
+  relative to others (larger is brighter).
+****************************************************************************/
+int color_brightness_score(struct color *pcolor)
+{
+  /* QColor has color space conversions, but nothing giving a perceptually
+   * even color space */
+  struct rgbcolor *prgb = rgbcolor_new(pcolor->qcolor.red(),
+                                       pcolor->qcolor.green(),
+                                       pcolor->qcolor.blue());
+  int score = rgbcolor_brightness_score(prgb);
+
+  rgbcolor_destroy(prgb);
+  return score;
+}

Modified: branches/S2_5/client/gui-sdl/colors.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/gui-sdl/colors.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/gui-sdl/colors.c       (original)
+++ branches/S2_5/client/gui-sdl/colors.c       Sat Dec 19 11:10:13 2015
@@ -99,3 +99,18 @@
   }
   free(pcolor);
 }
+
+/****************************************************************************
+  Return a number indicating the perceptual brightness of this color
+  relative to others (larger is brighter).
+****************************************************************************/
+int color_brightness_score(struct color *pcolor)
+{
+  struct rgbcolor *prgb = rgbcolor_new(pcolor->color->r,
+                                       pcolor->color->g,
+                                       pcolor->color->b);
+  int score = rgbcolor_brightness_score(prgb);
+
+  rgbcolor_destroy(prgb);
+  return score;
+}

Modified: branches/S2_5/client/gui-stub/colors.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/gui-stub/colors.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/gui-stub/colors.c      (original)
+++ branches/S2_5/client/gui-stub/colors.c      Sat Dec 19 11:10:13 2015
@@ -17,6 +17,9 @@
 
 /* utility */
 #include "mem.h"
+
+/* common */
+#include "rgbcolor.h"
 
 /* gui main header */
 #include "gui_stub.h"
@@ -47,3 +50,19 @@
   /* PORTME */
   free(color);
 }
+
+/****************************************************************************
+  Return a number indicating the perceptual brightness of this color
+  relative to others (larger is brighter).
+****************************************************************************/
+int color_brightness_score(struct color *pcolor)
+{
+  /* PORTME */
+  /* Can use GUI-specific colorspace functions here. This is a fallback
+   * using platform-independent code */
+  struct rgbcolor *prgb = rgbcolor_new(pcolor->r, pcolor->g, pcolor->b);
+  int score = rgbcolor_brightness_score(prgb);
+
+  rgbcolor_destroy(prgb);
+  return score;
+}

Modified: branches/S2_5/client/gui-xaw/colors.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/gui-xaw/colors.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/gui-xaw/colors.c       (original)
+++ branches/S2_5/client/gui-xaw/colors.c       Sat Dec 19 11:10:13 2015
@@ -28,6 +28,8 @@
 #include "fcintl.h"
 #include "log.h"
 #include "mem.h"
+
+#include "rgbcolor.h"
 
 #include "gui_main.h"
 
@@ -63,7 +65,7 @@
 
   alloc_color_for_colormap(&mycolor);
 
-  color->color.pixel = mycolor.pixel;
+  color->color = mycolor; /* structure copy */
   return color;
 }
 
@@ -225,7 +227,7 @@
         }
 
        XAllocColor(display, cmap, &cells[pixel]);
-        colors[i].pixel = pixel;
+        colors[i] = cells[pixel]; /* structure copy */
       }
 
       /* Unlock the server, since we're done querying it. */
@@ -286,7 +288,7 @@
     }
 
     XAllocColor(display, cmap, &cells[pixel]);
-    color->pixel = pixel;
+    *color = cells[pixel]; /* structure copy */
 
     /* Unlock the server, since we're done querying it. */
     XUngrabServer(display);
@@ -306,3 +308,18 @@
   XFreeColors(display, cmap, pixels, ncols, 0);
 #endif
 }
+
+/****************************************************************************
+  Return a number indicating the perceptual brightness of this color
+  relative to others (larger is brighter).
+****************************************************************************/
+int color_brightness_score(struct color *pcolor)
+{
+  struct rgbcolor *prgb = rgbcolor_new(pcolor->color.red >> 8,
+                                       pcolor->color.green >> 8,
+                                       pcolor->color.blue >> 8);
+  int score = rgbcolor_brightness_score(prgb);
+
+  rgbcolor_destroy(prgb);
+  return score;
+}

Modified: branches/S2_5/client/gui-xaw/mapview.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/gui-xaw/mapview.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/gui-xaw/mapview.c      (original)
+++ branches/S2_5/client/gui-xaw/mapview.c      Sat Dec 19 11:10:13 2015
@@ -687,9 +687,11 @@
 
   y -= XExtentsOfFontSet(fontset)->max_logical_extent.y;
 
-  XSetForeground(display, font_gc, shadow->color.pixel);
-  XmbDrawString(display, pcanvas->pixmap, fontset, font_gc,
-      x + 1, y + 1, string, len);
+  if (foreground->color.pixel != shadow->color.pixel) {
+    XSetForeground(display, font_gc, shadow->color.pixel);
+    XmbDrawString(display, pcanvas->pixmap, fontset, font_gc,
+                  x + 1, y + 1, string, len);
+  }
 
   XSetForeground(display, font_gc, foreground->color.pixel);
   XmbDrawString(display, pcanvas->pixmap, fontset, font_gc,

Modified: branches/S2_5/client/include/colors_g.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/include/colors_g.h?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/include/colors_g.h     (original)
+++ branches/S2_5/client/include/colors_g.h     Sat Dec 19 11:10:13 2015
@@ -22,4 +22,6 @@
 GUI_FUNC_PROTO(struct color *, color_alloc, int r, int g, int b)
 GUI_FUNC_PROTO(void, color_free, struct color *color)
 
+GUI_FUNC_PROTO(int, color_brightness_score, struct color *color)
+
 #endif  /* FC__COLORS_G_H */

Modified: branches/S2_5/client/mapview_common.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/mapview_common.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/client/mapview_common.c       (original)
+++ branches/S2_5/client/mapview_common.c       Sat Dec 19 11:10:13 2015
@@ -1642,9 +1642,20 @@
     canvas_put_rectangle(pcanvas, owner_color,
                         size_rect.x - border / 2, canvas_y,
                         size_rect.w + border, height1);
-    canvas_put_text(pcanvas, size_rect.x, size_rect.y,
-                   FONT_CITY_NAME,
-                   get_color(tileset, COLOR_MAPVIEW_CITYTEXT), size);
+    {
+      /* Try to pick a color for city size text that contrasts with
+       * player color */
+      struct color *textcolors[2] = {
+        get_color(tileset, COLOR_MAPVIEW_CITYTEXT),
+        /* HACK: this is likely to be black or a dark color */
+        get_color(tileset, COLOR_MAPVIEW_UNKNOWN)
+      };
+
+      canvas_put_text(pcanvas, size_rect.x, size_rect.y,
+                      FONT_CITY_NAME,
+                      color_best_contrast(owner_color, textcolors,
+                                          ARRAY_SIZE(textcolors)), size);
+    }
   }
 
   if (should_draw_lower_bar) {
@@ -2017,8 +2028,6 @@
     return FALSE;
   }
 }
-
-#define ABS(x) (((x) >= 0) ? (x) : -(x))
 
 /****************************************************************************
   Draw a goto line at the given location and direction.  The line goes from

Modified: branches/S2_5/common/rgbcolor.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/rgbcolor.c?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/common/rgbcolor.c     (original)
+++ branches/S2_5/common/rgbcolor.c     Sat Dec 19 11:10:13 2015
@@ -188,3 +188,20 @@
 
   return TRUE;
 }
+
+/****************************************************************************
+  Return a number indicating the perceptual brightness of this color
+  relative to others (larger is brighter).
+****************************************************************************/
+int rgbcolor_brightness_score(struct rgbcolor *prgbcolor)
+{
+  /* This simple scoring system taken from W3C "Techniques For Accessibility
+   * Evaluation And Repair Tools", http://www.w3.org/TR/AERT#color-contrast
+   *
+   * "Color brightness is determined by the following formula:
+   * ((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000
+   * Note: This algorithm is taken from a formula for converting RGB values to
+   * YIQ [NTSC] values [specifically the Y component]. This brightness value
+   * gives a perceived brightness for a color." */
+  return (prgbcolor->r*299 + prgbcolor->g*587 + prgbcolor->b*114) / 1000;
+}

Modified: branches/S2_5/common/rgbcolor.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/common/rgbcolor.h?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/common/rgbcolor.h     (original)
+++ branches/S2_5/common/rgbcolor.h     Sat Dec 19 11:10:13 2015
@@ -79,6 +79,8 @@
                      size_t hex_len);
 bool rgbcolor_from_hex(struct rgbcolor **prgbcolor, const char *hex);
 
+int rgbcolor_brightness_score(struct rgbcolor *prgbcolor);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: branches/S2_5/utility/shared.h
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/utility/shared.h?rev=31098&r1=31097&r2=31098&view=diff
==============================================================================
--- branches/S2_5/utility/shared.h      (original)
+++ branches/S2_5/utility/shared.h      Sat Dec 19 11:10:13 2015
@@ -48,6 +48,10 @@
 #endif
 #define CLIP(lower,current,upper) \
     ((current)<(lower)?(lower):(current)>(upper)?(upper):(current))
+
+#ifndef ABS
+#define ABS(x) (((x) >= 0) ? (x) : -(x))
+#endif
 
 /* Note: Solaris already has a WRAP macro that is completely different. */
 #define FC_WRAP(value, range)                                               \


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to