Stop sharing requirement_unit_state_ereq().
[freeciv.git] / common / rgbcolor.c
blob8f39915c69d37731fc6d2b3c16b8c6ee64cae40b
1 /****************************************************************************
2 Freeciv - Copyright (C) 2010 - The Freeciv Team
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ****************************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <stdarg.h>
20 /* utility */
21 #include "fcintl.h"
22 #include "log.h"
23 #include "registry.h"
25 /* common */
26 #include "fc_interface.h"
27 #include "game.h"
29 #include "rgbcolor.h"
31 /****************************************************************************
32 Allocate new rgbcolor structure.
33 ****************************************************************************/
34 struct rgbcolor *rgbcolor_new(int r, int g, int b)
36 struct rgbcolor *prgbcolor;
38 prgbcolor = fc_calloc(1, sizeof(*prgbcolor));
39 prgbcolor->r = r;
40 prgbcolor->g = g;
41 prgbcolor->b = b;
42 prgbcolor->color = NULL;
44 return prgbcolor;
47 /****************************************************************************
48 Allocate new rgbcolor structure and make it copy of one given as input.
49 Return new one.
50 ****************************************************************************/
51 struct rgbcolor *rgbcolor_copy(const struct rgbcolor *prgbcolor)
53 fc_assert_ret_val(prgbcolor != NULL, NULL);
55 return rgbcolor_new(prgbcolor->r, prgbcolor->g, prgbcolor->b);
58 /****************************************************************************
59 Test whether two rgbcolor structures represent the exact same color value.
60 (Does not attempt to determine whether they are visually distinguishable.)
61 ****************************************************************************/
62 bool rgbcolors_are_equal(const struct rgbcolor *c1, const struct rgbcolor *c2)
64 fc_assert_ret_val(c1 != NULL && c2 != NULL, FALSE);
66 /* No check of cached 'color' member -- if values are equal, it should be
67 * equivalent */
68 return (c1->r == c2->r && c1->g == c2->g && c1->b == c2->b);
71 /****************************************************************************
72 Free rgbcolor structure.
73 ****************************************************************************/
74 void rgbcolor_destroy(struct rgbcolor *prgbcolor)
76 if (!prgbcolor) {
77 return;
80 if (prgbcolor->color) {
81 fc_funcs->gui_color_free(prgbcolor->color);
83 free(prgbcolor);
86 /****************************************************************************
87 Lookup an RGB color definition (<colorpath>.red, <colorpath>.green and
88 <colorpath>.blue). Returns TRUE on success and FALSE on error.
89 ****************************************************************************/
90 bool rgbcolor_load(struct section_file *file, struct rgbcolor **prgbcolor,
91 char *path, ...)
93 int r, g, b;
94 char colorpath[256];
95 va_list args;
97 fc_assert_ret_val(file != NULL, FALSE);
98 fc_assert_ret_val(*prgbcolor == NULL, FALSE);
100 va_start(args, path);
101 fc_vsnprintf(colorpath, sizeof(colorpath), path, args);
102 va_end(args);
104 if (!secfile_lookup_int(file, &r, "%s.r", colorpath)
105 || !secfile_lookup_int(file, &g, "%s.g", colorpath)
106 || !secfile_lookup_int(file, &b, "%s.b", colorpath)) {
107 /* One color value (red, green or blue) is missing. */
108 return FALSE;
111 rgbcolor_check(colorpath, r, g, b);
112 *prgbcolor = rgbcolor_new(r, g, b);
114 return TRUE;
117 /****************************************************************************
118 Save an RGB color definition (<colorpath>.red, <colorpath>.green and
119 <colorpath>.blue).
120 ****************************************************************************/
121 void rgbcolor_save(struct section_file *file,
122 const struct rgbcolor *prgbcolor, char *path, ...)
124 char colorpath[256];
125 va_list args;
127 fc_assert_ret(file != NULL);
128 fc_assert_ret(prgbcolor != NULL);
130 va_start(args, path);
131 fc_vsnprintf(colorpath, sizeof(colorpath), path, args);
132 va_end(args);
134 secfile_insert_int(file, prgbcolor->r, "%s.r", colorpath);
135 secfile_insert_int(file, prgbcolor->g, "%s.g", colorpath);
136 secfile_insert_int(file, prgbcolor->b, "%s.b", colorpath);
139 /****************************************************************************
140 Convert a rgb color to a hex string (like 0xff0000 for red [255, 0, 0]).
141 ****************************************************************************/
142 bool rgbcolor_to_hex(const struct rgbcolor *prgbcolor, char *hex,
143 size_t hex_len)
145 fc_assert_ret_val(prgbcolor != NULL, FALSE);
146 /* Needs a length greater than 7 ('#' + 6 hex digites and '\0'). */
147 fc_assert_ret_val(hex_len > 7, FALSE);
149 fc_assert_ret_val(0 <= prgbcolor->r && prgbcolor->r <= 255, FALSE);
150 fc_assert_ret_val(0 <= prgbcolor->g && prgbcolor->g <= 255, FALSE);
151 fc_assert_ret_val(0 <= prgbcolor->b && prgbcolor->b <= 255, FALSE);
153 fc_snprintf(hex, hex_len, "#%06x",
154 (prgbcolor->r * 256 + prgbcolor->g) * 256 + prgbcolor->b);
156 return TRUE;
159 /****************************************************************************
160 Convert a hex string into a rgb color
161 ****************************************************************************/
162 bool rgbcolor_from_hex(struct rgbcolor **prgbcolor, const char *hex)
164 int rgb, r, g, b;
165 char hex2[16];
167 fc_assert_ret_val(*prgbcolor == NULL, FALSE);
168 fc_assert_ret_val(hex != NULL, FALSE);
170 if (hex[0] == '#') {
171 hex++;
174 if (strlen(hex) != 6) {
175 return FALSE;
178 fc_snprintf(hex2, sizeof(hex2), "0x%s", hex);
179 if (!sscanf(hex2, "%x", &rgb)) {
180 return FALSE;
183 r = rgb / 256 / 256;
184 g = (rgb - r * 256 * 256) / 256;
185 b = rgb % 256;
187 *prgbcolor = rgbcolor_new(r, g, b);
189 return TRUE;
192 /****************************************************************************
193 Return a number indicating the perceptual brightness of this color
194 relative to others (larger is brighter).
195 ****************************************************************************/
196 int rgbcolor_brightness_score(struct rgbcolor *prgbcolor)
198 /* This simple scoring system taken from W3C "Techniques For Accessibility
199 * Evaluation And Repair Tools", http://www.w3.org/TR/AERT#color-contrast
201 * "Color brightness is determined by the following formula:
202 * ((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000
203 * Note: This algorithm is taken from a formula for converting RGB values to
204 * YIQ [NTSC] values [specifically the Y component]. This brightness value
205 * gives a perceived brightness for a color." */
206 return (prgbcolor->r*299 + prgbcolor->g*587 + prgbcolor->b*114) / 1000;