The Battle for Wesnoth  1.17.10+dev
picture.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2022
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "map/location.hpp"
19 #include "terrain/translation.hpp"
20 
21 #include <unordered_map>
22 
23 class surface;
24 class texture;
25 struct point;
26 
27 /**
28  * Functions to load and save images from/to disk.
29  *
30  * image::get_image() and other loading functions implement a pseudo-functional
31  * syntax to apply transformations to image files by including them as a suffix
32  * to the path (Image Path Functions). They also offer the option to choose
33  * between different rendering formats for a single image path according to the
34  * display intent -- unscaled, masked to hex, rescaled to zoom, etc.
35  *
36  * @code
37  * surface surf = image::get_image("units/elves-wood/shyde.png~TC(4,magenta)~FL()",
38  * image::UNSCALED);
39  * @endcode
40  *
41  * Internally, all loading functions utilize a cache to avoid reading
42  * individual images from disk more than once, or wasting valuable CPU time
43  * applying potentially expensive transforms every time (e.g. team colors on
44  * animated units). The cache can be manually invalidated using
45  * image::flush_cache(). Certain functions will invalidate parts of the cache
46  * as needed when relevant configuration parameters change in a way that would
47  * be expected to alter the output (e.g. Time of Day-tinted images).
48  */
49 namespace image {
50 
51 template<typename T>
52 class cache_type;
53 
54 /**
55  * Generic locator abstracting the location of an image.
56  *
57  * Constructing locators is somewhat slow, while accessing images through
58  * locators is fast. The general idea is that callers should store locators
59  * and not strings to construct new ones. (The latter will still work, of
60  * course, even if it is slower.)
61  */
62 class locator
63 {
64 public:
65  enum type { NONE, FILE, SUB_FILE };
66 
67  locator();
68  locator(const locator& a, const std::string& mods = "");
69  locator(const char* filename);
70  locator(const std::string& filename);
71  locator(const char* filename, const char* modifications);
72  locator(const std::string& filename, const std::string& modifications);
73  locator(const std::string& filename, const map_location& loc, int center_x, int center_y, const std::string& modifications = "");
74 
75  locator& operator=(const locator& a);
76 
77  bool operator==(const locator& a) const { return index_ == a.index_; }
78  bool operator!=(const locator& a) const { return index_ != a.index_; }
79  bool operator<(const locator& a) const { return index_ < a.index_; }
80 
81  const std::string& get_filename() const { return val_.filename_; }
82  bool is_data_uri() const { return val_.is_data_uri_; }
83  const map_location& get_loc() const { return val_.loc_ ; }
84  int get_center_x() const { return val_.center_x_; }
85  int get_center_y() const { return val_.center_y_; }
86  const std::string& get_modifications() const {return val_.modifications_;}
87  type get_type() const { return val_.type_; }
88  // const int get_index() const { return index_; };
89 
90  /**
91  * Returns @a true if the locator does not correspond to an actual image.
92  */
93  bool is_void() const { return val_.type_ == NONE; }
94 
95  /**
96  * Tests whether the file the locator points at exists.
97  *
98  * is_void does not work before the image is loaded, and also a placeholder
99  * is returned instead in debug mode. Thus it's not possible to test for
100  * the existence of an actual file without this function.
101  *
102  * @note This does not test whether the image is valid or not.
103  *
104  * @return Whether or not the file exists.
105  */
106  bool file_exists() const;
107 
108  template<typename T>
109  bool in_cache(cache_type<T>& cache) const;
110 
111  template<typename T>
112  T& access_in_cache(cache_type<T>& cache) const;
113 
114  template<typename T>
115  const T& locate_in_cache(cache_type<T>& cache) const;
116 
117  template<typename T>
118  void add_to_cache(cache_type<T>& cache, const T& data) const;
119 
120 private:
121  // Called by each constructor after actual construction to
122  // initialize the index_ field
123  void init_index();
124  void parse_arguments();
125 
126  struct value
127  {
128  value();
129  value(const char *filename);
130  value(const std::string& filename);
131  value(const char *filename, const char* modifications);
132  value(const std::string& filename, const std::string& modifications);
133  value(const std::string& filename, const map_location& loc, int center_x, int center_y, const std::string& modifications);
134 
135  bool operator==(const value& a) const;
136  bool operator<(const value& a) const;
137 
140  std::string filename_;
142  std::string modifications_;
145  };
146 
147 public:
148  typedef std::unordered_map<value, int> locator_finder_t;
149 
150 private:
151  friend struct std::hash<value>;
152 
153  int index_;
155 };
156 
157 // write a readable representation of a locator, mostly for debugging
158 std::ostream& operator<<(std::ostream&, const locator&);
159 
163 
164 typedef std::map<t_translation::terrain_code, surface> mini_terrain_cache_map;
165 
166 extern mini_terrain_cache_map mini_terrain_cache;
167 extern mini_terrain_cache_map mini_fogged_terrain_cache;
168 extern mini_terrain_cache_map mini_highlighted_terrain_cache;
169 
170 /**
171  * Type used to store color information of central and adjacent hexes.
172  *
173  * The structure is one or several 4-char blocks: [L,R,G,B]
174  * The R, G, B values represent the color, and L the lightmap to use:
175  *
176  * -1: none
177  * 0: full hex
178  * 1-6: concave corners
179  * 7-12: convex half-corners 1
180  * 13-19: convex half-corners 2
181  */
182 typedef std::basic_string<signed char> light_string;
183 
184 /** Type used to pair light possibilities with the corresponding lit surface. */
185 typedef std::map<light_string, surface> lit_surface_variants;
186 typedef std::map<light_string, texture> lit_texture_variants;
187 
188 /** Lit variants for each locator. */
191 
192 /**
193  * Returns the light_string for one light operation.
194  *
195  * See light_string for more information.
196  */
197 light_string get_light_string(int op, int r, int g, int b);
198 
199 /**
200  * Purges all image caches.
201  */
202 void flush_cache();
203 
204 /**
205  * Image cache manager.
206  *
207  * This class is responsible for setting up and flushing the image cache. No
208  * more than one instance of it should exist at a time.
209  */
210 struct manager
211 {
212  manager();
213  ~manager();
214 };
215 
216 /**
217  * Changes Time of Day color tint for all applicable image types.
218  *
219  * In particular this affects TOD_COLORED images, as well as
220  * images with lightmaps applied. Changing the previous values automatically
221  * invalidates all cached images of those types.
222  */
223 void set_color_adjustment(int r, int g, int b);
224 
225 /**
226  * Used to specify the rendering format of images.
227  */
228 enum TYPE
229 {
230  /** Unmodified original-size image. */
232  /** Standard hexagonal tile mask applied, removing portions that don't fit. */
234  /** Same as HEXED, but with Time of Day color tint applied. */
236  NUM_TYPES // Equal to the number of types specified above
237 };
238 
239 enum class scale_quality { nearest, linear };
240 
241 /**
242  * [DEPRECATED] Caches and returns an image.
243  *
244  * This function is deprecated. Use get_texture or get_surface in stead.
245  *
246  * @param i_locator Image path.
247  * @param type Rendering format.
248  */
249 surface get_image(const locator& i_locator, TYPE type = UNSCALED);
250 
251 /**
252  * Returns an image surface suitable for software manipulation.
253  *
254  * The equivalent get_texture() function should generally be preferred.
255  *
256  * Surfaces will be cached for repeat access, unless skip_cache is set.
257  *
258  * @param i_locator Image path.
259  * @param type Rendering format.
260  * @param skip_cache Skip adding the result to the surface cache.
261  */
262 surface get_surface(const locator& i_locator, TYPE type = UNSCALED,
263  bool skip_cache = false);
264 
265 /**
266  * Returns an image texture suitable for hardware-accelerated rendering.
267  *
268  * Texture pointers are not unique, and will be cached and retained
269  * until no longer needed. Users of the returned texture do not have to
270  * worry about texture management.
271  *
272  * If caching is disabled via @a skip_cache, texture memory will be
273  * automatically freed once the returned object and all other linked
274  * textures (if any) are destroyed.
275  *
276  * @param i_locator Image path.
277  * @param type Rendering format.
278  * @param skip_cache Skip adding the result to the surface cache.
279  */
280 texture get_texture(const locator& i_locator, TYPE type = UNSCALED,
281  bool skip_cache = false);
282 
283 texture get_texture(const image::locator& i_locator, scale_quality quality,
284  TYPE type = UNSCALED, bool skip_cache = false);
285 
286 /**
287  * Caches and returns an image with a lightmap applied to it.
288  *
289  * Images will always be HEXED type.
290  *
291  * @param i_locator Image path.
292  * @param ls Light map to apply to the image.
293  */
294 surface get_lighted_image(const image::locator& i_locator, const light_string& ls);
295 texture get_lighted_texture(const image::locator& i_locator, const light_string& ls);
296 
297 /**
298  * Retrieves the standard hexagonal tile mask.
299  */
301 
302 /**
303  * Returns the width and height of an image.
304  *
305  * If the image is not yet in the surface cache, it will be loaded and cached
306  * unless skip_cache is explicitly set.
307  *
308  * @param i_locator Image path.
309  * @param skip_cache If true, do not cache the image if loaded.
310  */
311 point get_size(const locator& i_locator, bool skip_cache = false);
312 
313 /**
314  * Checks if an image fits into a single hex.
315  */
316 bool is_in_hex(const locator& i_locator);
317 
318 /**
319  * Checks if an image is empty after hex masking.
320  *
321  * This should be only used on terrain images, and it will automatically cache
322  * the hex-masked version if necessary.
323  */
324 bool is_empty_hex(const locator& i_locator);
325 
326 /**
327  * Returns @a true if the given image actually exists, without loading it.
328  */
329 bool exists(const locator& i_locator);
330 
331 /**
332  * Precache the existence of files in a binary path subdirectory (e.g. "terrain/").
333  */
334 void precache_file_existence(const std::string& subdir = "");
335 
336 bool precached_file_exists(const std::string& file);
337 
338 enum class save_result
339 {
340  success,
342  save_failed,
343  no_image
344 };
345 
346 save_result save_image(const locator& i_locator, const std::string& outfile);
347 save_result save_image(const surface& surf, const std::string& outfile);
348 
349 }
TYPE
Used to specify the rendering format of images.
Definition: picture.hpp:228
surface get_image(const image::locator &i_locator, TYPE type)
[DEPRECATED] Caches and returns an image.
Definition: picture.cpp:887
const std::string & get_modifications() const
Definition: picture.hpp:86
int get_center_y() const
Definition: picture.hpp:85
void precache_file_existence(const std::string &subdir)
Precache the existence of files in a binary path subdirectory (e.g.
Definition: picture.cpp:1073
bool operator!=(const locator &a) const
Definition: picture.hpp:78
map_location loc_
Definition: picture.hpp:141
void add_to_cache(cache_type< T > &cache, const T &data) const
Definition: picture.cpp:149
std::string filename_
Definition: picture.hpp:140
void init_index()
Definition: picture.cpp:259
bool operator==(const locator &a) const
Definition: picture.hpp:77
cache_type< texture > texture_cache
Definition: picture.hpp:161
cache_type< lit_surface_variants > lit_surface_cache
Lit variants for each locator.
Definition: picture.hpp:189
bool precached_file_exists(const std::string &file)
Definition: picture.cpp:1082
save_result
Definition: picture.hpp:338
#define a
surface get_surface(const image::locator &i_locator, TYPE type, bool skip_cache)
Returns an image surface suitable for software manipulation.
Definition: picture.cpp:824
mini_terrain_cache_map mini_fogged_terrain_cache
Definition: picture.cpp:229
scale_quality
Definition: picture.hpp:239
std::string_view data
Definition: picture.cpp:206
std::map< light_string, surface > lit_surface_variants
Type used to pair light possibilities with the corresponding lit surface.
Definition: picture.hpp:185
save_result save_image(const locator &i_locator, const std::string &filename)
Definition: picture.cpp:1092
T & access_in_cache(cache_type< T > &cache) const
Definition: picture.cpp:142
void parse_arguments()
Definition: picture.cpp:271
std::map< t_translation::terrain_code, surface > mini_terrain_cache_map
Definition: picture.hpp:164
cache_type< surface > surface_cache
Definition: picture.hpp:160
type get_type() const
Definition: picture.hpp:87
Standard hexagonal tile mask applied, removing portions that don&#39;t fit.
Definition: picture.hpp:233
point get_size(const locator &i_locator, bool skip_cache)
Returns the width and height of an image.
Definition: picture.cpp:970
Same as HEXED, but with Time of Day color tint applied.
Definition: picture.hpp:235
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:32
void flush_cache()
Purges all image caches.
Definition: picture.cpp:234
#define b
bool exists(const image::locator &i_locator)
Returns true if the given image actually exists, without loading it.
Definition: picture.cpp:1022
const T & locate_in_cache(cache_type< T > &cache) const
Definition: picture.cpp:135
light_string get_light_string(int op, int r, int g, int b)
Returns the light_string for one light operation.
Definition: picture.cpp:649
std::string modifications_
Definition: picture.hpp:142
std::ostream & operator<<(std::ostream &s, const locator &l)
Definition: picture.cpp:367
std::unordered_map< value, int > locator_finder_t
Definition: picture.hpp:148
std::map< light_string, texture > lit_texture_variants
Definition: picture.hpp:186
bool operator<(const locator &a) const
Definition: picture.hpp:79
Generic locator abstracting the location of an image.
Definition: picture.hpp:62
void set_color_adjustment(int r, int g, int b)
Changes Time of Day color tint for all applicable image types.
Definition: picture.cpp:747
Encapsulates the map of the game.
Definition: location.hpp:38
surface get_lighted_image(const image::locator &i_locator, const light_string &ls)
Caches and returns an image with a lightmap applied to it.
Definition: picture.cpp:892
cache_type< bool > bool_cache
Definition: picture.hpp:162
locator & operator=(const locator &a)
Definition: picture.cpp:359
double g
Definition: astarsearch.cpp:65
surface get_hexmask()
Retrieves the standard hexagonal tile mask.
Definition: picture.cpp:964
std::basic_string< signed char > light_string
Type used to store color information of central and adjacent hexes.
Definition: picture.hpp:182
Holds a 2D point.
Definition: point.hpp:24
mini_terrain_cache_map mini_highlighted_terrain_cache
Definition: picture.cpp:230
int get_center_x() const
Definition: picture.hpp:84
Image cache manager.
Definition: picture.hpp:210
const std::string & get_filename() const
Definition: picture.hpp:81
bool is_in_hex(const locator &i_locator)
Checks if an image fits into a single hex.
Definition: picture.cpp:980
bool is_data_uri() const
Definition: picture.hpp:82
bool operator<(const value &a) const
Definition: picture.cpp:463
mini_terrain_cache_map mini_terrain_cache
Definition: picture.cpp:228
const std::vector< std::string > & modifications(bool mp)
Definition: game.cpp:712
texture get_lighted_texture(const image::locator &i_locator, const light_string &ls)
Definition: picture.cpp:928
const map_location & get_loc() const
Definition: picture.hpp:83
bool is_empty_hex(const locator &i_locator)
Checks if an image is empty after hex masking.
Definition: picture.cpp:1003
Functions to load and save images from/to disk.
bool operator==(const value &a) const
Definition: picture.cpp:449
bool is_void() const
Returns true if the locator does not correspond to an actual image.
Definition: picture.hpp:93
texture get_texture(const image::locator &i_locator, TYPE type, bool skip_cache)
Returns an image texture suitable for hardware-accelerated rendering.
Definition: picture.cpp:1128
bool in_cache(cache_type< T > &cache) const
Definition: picture.cpp:129
Unmodified original-size image.
Definition: picture.hpp:231
bool file_exists() const
Tests whether the file the locator points at exists.
Definition: picture.cpp:715
cache_type< lit_texture_variants > lit_texture_cache
Definition: picture.hpp:190