The Battle for Wesnoth  1.19.11+dev
picture.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2025
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 "utils/optional_fwd.hpp"
22 #include "utils/span.hpp"
23 
24 class surface;
25 class texture;
26 struct point;
27 
28 /**
29  * Functions to load and save images from/to disk.
30  *
31  * image::get_image() and other loading functions implement a pseudo-functional
32  * syntax to apply transformations to image files by including them as a suffix
33  * to the path (Image Path Functions). They also offer the option to choose
34  * between different rendering formats for a single image path according to the
35  * display intent -- unscaled, masked to hex, rescaled to zoom, etc.
36  *
37  * @code
38  * surface surf = image::get_image("units/elves-wood/shyde.png~TC(4,magenta)~FL()",
39  * image::UNSCALED);
40  * @endcode
41  *
42  * Internally, all loading functions utilize a cache to avoid reading
43  * individual images from disk more than once, or wasting valuable CPU time
44  * applying potentially expensive transforms every time (e.g. team colors on
45  * animated units). The cache can be manually invalidated using
46  * image::flush_cache(). Certain functions will invalidate parts of the cache
47  * as needed when relevant configuration parameters change in a way that would
48  * be expected to alter the output (e.g. Time of Day-tinted images).
49  */
50 namespace image {
51 /**
52  * Generic locator abstracting the location of an image.
53  *
54  * Constructing locators is somewhat slow, while accessing images through
55  * locators is fast. The general idea is that callers should store locators
56  * and not strings to construct new ones. (The latter will still work, of
57  * course, even if it is slower.)
58  */
59 class locator
60 {
61 public:
62  enum type { NONE, FILE, SUB_FILE };
63 
64  locator() = default;
65  locator(locator&&) noexcept = default;
66  locator(const locator&) = default;
67 
68  locator(const std::string& filename);
69  locator(const std::string& filename, const std::string& modifications);
70  locator(const std::string& filename, const map_location& loc, int center_x, int center_y, const std::string& modifications = "");
71 
72  locator& operator=(const locator& a) = default;
73  locator& operator=(locator&&) = default;
74 
75  /** Returns a copy of this locator with the given IPF */
76  locator clone(const std::string& mods) const;
77 
78  bool operator==(const locator& a) const;
79  bool operator!=(const locator& a) const { return !operator==(a); }
80 
81  bool operator<(const locator& a) const;
82 
83  const std::string& get_filename() const { return filename_; }
84  bool is_data_uri() const { return is_data_uri_; }
85  const map_location& get_loc() const { return loc_ ; }
86  int get_center_x() const { return center_x_; }
87  int get_center_y() const { return center_y_; }
88  const std::string& get_modifications() const { return modifications_; }
89  type get_type() const { return type_; }
90 
91  /**
92  * Returns @a true if the locator does not correspond to an actual image.
93  */
94  bool is_void() const { return type_ == NONE; }
95 
96 private:
98  bool is_data_uri_ = false;
99  std::string filename_{};
100  std::string modifications_{};
102  int center_x_ = 0;
103  int center_y_ = 0;
104 
105 public:
106  friend struct std::hash<locator>;
107 };
108 
109 // write a readable representation of a locator, mostly for debugging
110 std::ostream& operator<<(std::ostream&, const locator&);
111 
112 /**
113  * Type used to store color information of central and adjacent hexes.
114  *
115  * The structure is one or several 4-char blocks: [L,R,G,B]
116  * The R, G, B values represent the color, and L the lightmap to use:
117  *
118  * -1: none
119  * 0: full hex
120  * 1-6: concave corners
121  * 7-12: convex half-corners 1
122  * 13-19: convex half-corners 2
123  */
125 {
126  light_adjust(int op, int r, int g, int b);
127 
128  int8_t l;
129  int8_t r;
130  int8_t g;
131  int8_t b;
132 };
133 
134 /**
135  * Purges all image caches.
136  */
137 void flush_cache();
138 
139 /**
140  * Image cache manager.
141  *
142  * This class is responsible for setting up and flushing the image cache. No
143  * more than one instance of it should exist at a time.
144  */
145 struct manager
146 {
147  manager();
148  ~manager();
149 };
150 
151 /**
152  * Changes Time of Day color tint for all applicable image types.
153  *
154  * In particular this affects TOD_COLORED images, as well as
155  * images with lightmaps applied. Changing the previous values automatically
156  * invalidates all cached images of those types.
157  */
158 void set_color_adjustment(int r, int g, int b);
159 
160 /**
161  * Used to specify the rendering format of images.
162  */
163 enum TYPE
164 {
165  /** Unmodified original-size image. */
167  /** Standard hexagonal tile mask applied, removing portions that don't fit. */
169  /** Same as HEXED, but with Time of Day color tint applied. */
171  NUM_TYPES // Equal to the number of types specified above
172 };
173 
174 enum class scale_quality { nearest, linear };
175 
176 /**
177  * Returns an image surface suitable for software manipulation.
178  *
179  * The equivalent get_texture() function should generally be preferred.
180  *
181  * Surfaces will be cached for repeat access, unless skip_cache is set.
182  *
183  * @param i_locator Image path.
184  * @param type Rendering format.
185  * @param skip_cache Skip adding the result to the surface cache.
186  */
187 surface get_surface(const locator& i_locator, TYPE type = UNSCALED,
188  bool skip_cache = false);
189 
190 /**
191  * Returns an image texture suitable for hardware-accelerated rendering.
192  *
193  * Texture pointers are not unique, and will be cached and retained
194  * until no longer needed. Users of the returned texture do not have to
195  * worry about texture management.
196  *
197  * If caching is disabled via @a skip_cache, texture memory will be
198  * automatically freed once the returned object and all other linked
199  * textures (if any) are destroyed.
200  *
201  * @param i_locator Image path.
202  * @param type Rendering format.
203  * @param skip_cache Skip adding the result to the surface cache.
204  */
205 texture get_texture(const locator& i_locator, TYPE type = UNSCALED,
206  bool skip_cache = false);
207 
208 texture get_texture(const image::locator& i_locator, scale_quality quality,
209  TYPE type = UNSCALED, bool skip_cache = false);
210 
211 /**
212  * Caches and returns an image with a lightmap applied to it.
213  *
214  * Images will always be HEXED type.
215  *
216  * @param i_locator Image path.
217  * @param ls Light map to apply to the image.
218  */
221 
222 /**
223  * Retrieves the standard hexagonal tile mask.
224  */
226 
227 /**
228  * Returns the width and height of an image.
229  *
230  * If the image is not yet in the surface cache, it will be loaded and cached
231  * unless skip_cache is explicitly set.
232  *
233  * @param i_locator Image path.
234  * @param skip_cache If true, do not cache the image if loaded.
235  */
236 point get_size(const locator& i_locator, bool skip_cache = false);
237 
238 /**
239  * Checks if an image fits into a single hex.
240  */
241 bool is_in_hex(const locator& i_locator);
242 
243 /**
244  * Checks if an image is empty after hex masking.
245  *
246  * This should be only used on terrain images, and it will automatically cache
247  * the hex-masked version if necessary.
248  */
249 bool is_empty_hex(const locator& i_locator);
250 
251 /**
252  * Returns @a true if the given image actually exists, without loading it.
253  */
254 bool exists(const locator& i_locator);
255 
256 /**
257  * Precache the existence of files in a binary path subdirectory (e.g. "terrain/").
258  */
259 void precache_file_existence(const std::string& subdir = "");
260 
261 bool precached_file_exists(const std::string& file);
262 
263 enum class save_result
264 {
265  success,
267  save_failed,
268  no_image
269 };
270 
271 save_result save_image(const locator& i_locator, const std::string& outfile);
272 save_result save_image(const surface& surf, const std::string& outfile);
273 
274 } // namespace image
map_location loc
Definition: move.cpp:172
double g
Definition: astarsearch.cpp:63
Generic locator abstracting the location of an image.
Definition: picture.hpp:60
locator(locator &&) noexcept=default
int get_center_x() const
Definition: picture.hpp:86
bool is_void() const
Returns true if the locator does not correspond to an actual image.
Definition: picture.hpp:94
map_location loc_
Definition: picture.hpp:101
std::string filename_
Definition: picture.hpp:99
const std::string & get_filename() const
Definition: picture.hpp:83
type get_type() const
Definition: picture.hpp:89
bool is_data_uri() const
Definition: picture.hpp:84
const std::string & get_modifications() const
Definition: picture.hpp:88
int get_center_y() const
Definition: picture.hpp:87
bool is_data_uri_
Definition: picture.hpp:98
const map_location & get_loc() const
Definition: picture.hpp:85
locator::type type_
Definition: picture.hpp:97
locator()=default
bool operator<(const locator &a) const
Definition: picture.cpp:303
bool operator==(const locator &a) const
Definition: picture.cpp:289
locator clone(const std::string &mods) const
Returns a copy of this locator with the given IPF.
Definition: picture.cpp:218
std::string modifications_
Definition: picture.hpp:100
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:33
Functions to load and save images from/to disk.
bool is_empty_hex(const locator &i_locator)
Checks if an image is empty after hex masking.
Definition: picture.cpp:811
texture get_lighted_texture(const image::locator &i_locator, utils::span< const light_adjust > ls)
Definition: picture.cpp:759
bool precached_file_exists(const std::string &file)
Definition: picture.cpp:888
save_result
Definition: picture.hpp:264
bool exists(const image::locator &i_locator)
Returns true if the given image actually exists, without loading it.
Definition: picture.cpp:832
void flush_cache()
Purges all image caches.
Definition: picture.cpp:200
surface get_lighted_image(const image::locator &i_locator, utils::span< const light_adjust > ls)
Caches and returns an image with a lightmap applied to it.
Definition: picture.cpp:733
surface get_surface(const image::locator &i_locator, TYPE type, bool skip_cache)
Returns an image surface suitable for software manipulation.
Definition: picture.cpp:665
surface get_hexmask()
Retrieves the standard hexagonal tile mask.
Definition: picture.cpp:785
std::ostream & operator<<(std::ostream &s, const locator &l)
Definition: picture.cpp:229
save_result save_image(const locator &i_locator, const std::string &filename)
Definition: picture.cpp:898
void precache_file_existence(const std::string &subdir)
Precache the existence of files in a binary path subdirectory (e.g.
Definition: picture.cpp:881
TYPE
Used to specify the rendering format of images.
Definition: picture.hpp:164
@ HEXED
Standard hexagonal tile mask applied, removing portions that don't fit.
Definition: picture.hpp:168
@ NUM_TYPES
Definition: picture.hpp:171
@ TOD_COLORED
Same as HEXED, but with Time of Day color tint applied.
Definition: picture.hpp:170
@ UNSCALED
Unmodified original-size image.
Definition: picture.hpp:166
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:934
point get_size(const locator &i_locator, bool skip_cache)
Returns the width and height of an image.
Definition: picture.cpp:791
void set_color_adjustment(int r, int g, int b)
Changes Time of Day color tint for all applicable image types.
Definition: picture.cpp:589
bool is_in_hex(const locator &i_locator)
Checks if an image fits into a single hex.
Definition: picture.cpp:800
scale_quality
Definition: picture.hpp:174
surface surf
Image.
std::string filename
Filename.
Type used to store color information of central and adjacent hexes.
Definition: picture.hpp:125
light_adjust(int op, int r, int g, int b)
Definition: picture.cpp:479
Image cache manager.
Definition: picture.hpp:146
Encapsulates the map of the game.
Definition: location.hpp:45
Holds a 2D point.
Definition: point.hpp:25
#define b