Freeciv21
Develop your civilization from humble roots to a global empire
colors_common.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2023 Freeciv21 and Freeciv contributors. This file
3  is part of Freeciv21. Freeciv21 is free software:
4 |\_/|,,_____,~~` you can redistribute it and/or modify it under the
5 (.".)~~ )`~}} terms of the GNU General Public License as published
6  \o/\ /---~\\ ~}} by the Free Software Foundation, either version 3 of
7  _// _// ~} the License, or (at your option) any later version.
8  You should have received a copy of the GNU General
9  Public License along with Freeciv21. If not, see
10  https://www.gnu.org/licenses/.
11  */
12 
13 // utility
14 #include "log.h"
15 #include "shared.h"
16 
17 // common
18 #include "player.h"
19 #include "rgbcolor.h"
20 #include "terrain.h"
21 
22 /* client/include */
23 #include "colors_g.h"
24 
25 // client
26 #include "tileset/tilespec.h"
27 
28 #include "colors_common.h"
29 
30 struct color_system {
31  struct rgbcolor **stdcolors;
32 };
33 
41 {
42  struct color_system *colors = new color_system;
43  enum color_std stdcolor;
44 
45  colors->stdcolors = new rgbcolor *[COLOR_LAST]();
46 
47  for (stdcolor = color_std_begin(); stdcolor != color_std_end();
48  stdcolor = color_std_next(stdcolor)) {
49  struct rgbcolor *prgbcolor = nullptr;
50 
51  if (rgbcolor_load(file, &prgbcolor, "colors.%s0",
52  color_std_name(stdcolor))) {
53  *(colors->stdcolors + stdcolor) = prgbcolor;
54  } else {
55  qCritical("Color %s: %s", color_std_name(stdcolor), secfile_error());
56  *(colors->stdcolors + stdcolor) = rgbcolor_new(0, 0, 0);
57  }
58  }
59 
60  return colors;
61 }
62 
67 {
68  enum color_std stdcolor;
69 
70  for (stdcolor = color_std_begin(); stdcolor != color_std_end();
71  stdcolor = color_std_next(stdcolor)) {
72  rgbcolor_destroy(*(colors->stdcolors + stdcolor));
73  }
74 
75  delete[] colors->stdcolors;
76  delete colors;
77 }
78 
82 QColor get_color(const struct tileset *t, enum color_std stdcolor)
83 {
85 
86  fc_assert_ret_val(colors != nullptr, Qt::black);
87 
88  auto &color = *(colors->stdcolors + stdcolor);
89  return QColor(color->r, color->g, color->b);
90 }
91 
96 bool player_has_color(const struct tileset *t, const struct player *pplayer)
97 {
98  Q_UNUSED(t)
99  fc_assert_ret_val(pplayer != nullptr, false);
100 
101  return pplayer->rgb != nullptr;
102 }
103 
109 QColor get_player_color(const struct tileset *t,
110  const struct player *pplayer)
111 {
112  Q_UNUSED(t)
113  fc_assert_ret_val(pplayer != nullptr, Qt::black);
114  fc_assert_ret_val(pplayer->rgb != nullptr, Qt::black);
115 
116  return QColor(pplayer->rgb->r, pplayer->rgb->g, pplayer->rgb->b);
117 }
118 
122 QColor get_terrain_color(const struct tileset *t,
123  const struct terrain *pterrain)
124 {
125  Q_UNUSED(t)
126  fc_assert_ret_val(pterrain != nullptr, Qt::black);
127  fc_assert_ret_val(pterrain->rgb != nullptr, Qt::black);
128 
129  return QColor(pterrain->rgb->r, pterrain->rgb->g, pterrain->rgb->b);
130 }
131 
136 QColor color_best_contrast(const QColor &subject, const QColor *candidates,
137  int ncandidates)
138 {
139  int sbright = color_brightness_score(subject), bestdiff = 0;
140 
141  fc_assert_ret_val(candidates != nullptr, Qt::black);
142  fc_assert_ret_val(ncandidates > 0, Qt::black);
143 
144  QColor best;
145  for (int i = 0; i < ncandidates; i++) {
146  int cbright = color_brightness_score(candidates[i]);
147  int diff = ABS(sbright - cbright);
148 
149  if (i == 0 || diff > bestdiff) {
150  best = candidates[i];
151  bestdiff = diff;
152  }
153  }
154 
155  return best;
156 }
157 
162 int color_brightness_score(const QColor &color)
163 {
164  /* QColor has color space conversions, but nothing giving a perceptually
165  * even color space */
166  rgbcolor prgb{color.red(), color.green(), color.blue()};
167  return rgbcolor_brightness_score(&prgb);
168 }
void color_system_free(struct color_system *colors)
Called when the client first starts to free any allocated colors.
QColor color_best_contrast(const QColor &subject, const QColor *candidates, int ncandidates)
Find the colour from 'candidates' with the best perceptual contrast from 'subject'.
QColor get_color(const struct tileset *t, enum color_std stdcolor)
Return a pointer to the given "standard" color.
QColor get_terrain_color(const struct tileset *t, const struct terrain *pterrain)
Return a pointer to the given "terrain" color.
struct color_system * color_system_read(struct section_file *file)
Called when the client first starts to allocate the default colors.
bool player_has_color(const struct tileset *t, const struct player *pplayer)
Return whether the player has a color assigned yet.
QColor get_player_color(const struct tileset *t, const struct player *pplayer)
Return the color of the player.
int color_brightness_score(const QColor &color)
Return a number indicating the perceptual brightness of this color relative to others (larger is brig...
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
Colors.
const char * secfile_error()
Returns the last error which occurred in a string.
void rgbcolor_destroy(struct rgbcolor *prgbcolor)
Free rgbcolor structure.
Definition: rgbcolor.cpp:65
bool rgbcolor_load(struct section_file *file, struct rgbcolor **prgbcolor, const char *path,...)
Lookup an RGB color definition ([colorpath].red, [colorpath].green and [colorpath]....
Definition: rgbcolor.cpp:78
struct rgbcolor * rgbcolor_new(int r, int g, int b)
Allocate new rgbcolor structure.
Definition: rgbcolor.cpp:25
int rgbcolor_brightness_score(struct rgbcolor *prgbcolor)
Return a number indicating the perceptual brightness of this color relative to others (larger is brig...
Definition: rgbcolor.cpp:185
#define ABS(x)
Definition: shared.h:55
struct rgbcolor ** stdcolors
Definition: player.h:231
struct rgbcolor * rgb
Definition: player.h:293
int g
Definition: rgbcolor.h:27
int b
Definition: rgbcolor.h:27
int r
Definition: rgbcolor.h:27
struct rgbcolor * rgb
Definition: terrain.h:240
struct color_system * get_color_system(const struct tileset *t)
Return the tileset's color system.
Definition: tilespec.cpp:3622