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