The Battle for Wesnoth  1.19.25+dev
utils.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 "color_range.hpp"
19 #include "color.hpp"
20 #include "sdl/surface.hpp"
21 #include "utils/math.hpp"
22 #include "game_version.hpp"
23 
24 #include <string>
25 
26 struct rect;
27 
28 namespace sdl
29 {
30 
31 /** Returns the runtime SDL version. */
33 
34 /**
35  * Returns true if the runtime SDL version is at or greater than the
36  * specified version, false otherwise.
37  */
38 bool runtime_at_least(uint8_t major, uint8_t minor = 0, uint8_t patch = 0);
39 
40 } // namespace sdl
41 
42 
43 inline void sdl_blit(const surface& src, const SDL_Rect* src_rect, surface& dst, SDL_Rect* dst_rect){
44  // Note: this is incorrect when both src and dst combine transparent pixels.
45  // The correct equation is, per-pixel:
46  // outA = srcA + dstA * (1 - srcA)
47  // outRGB = (srcRGB * srcA + dstRGB * dstA * (1 - srcA)) / outA
48  // When outA is 0, outRGB can of course be anything.
49  // TODO: implement proper transparent blending using the above formula
50  SDL_BlitSurface(src, src_rect, dst, dst_rect);
51 }
52 
53 /** Scale a surface using xBRZ algorithm
54  * @param surf The source surface
55  * @param z The scaling factor. Should be an integer 2-5 (1 is tolerated).
56  * @return The scaled surface
57  */
58 surface scale_surface_xbrz(const surface & surf, std::size_t z);
59 
60 /** Scale a surface using alpha-weighted modified bilinear filtering
61  * Note: causes artifacts with alpha gradients, for example in some portraits
62  * @param surf The source surface.
63  * @param w The width of the resulting surface.
64  * @param h The height of the resulting surface.
65  * @return A surface containing the scaled version of the source.
66  * @retval 0 Returned upon error.
67  * @retval surf Returned if w == surf->w and h == surf->h.
68  */
69 surface scale_surface(const surface &surf, int w, int h);
70 
71 /** Scale a surface using simple bilinear filtering (discarding rgb from source
72  * pixels with 0 alpha)
73  * @param surf The source surface.
74  * @param w The width of the resulting surface.
75  * @param h The height of the resulting surface.
76  * @return A surface containing the scaled version of the source.
77  * @retval 0 Returned upon error.
78  * @retval surf Returned if w == surf->w and h == surf->h.
79  */
80 surface scale_surface_legacy(const surface &surf, int w, int h);
81 
82 /** Scale a surface using modified nearest neighbour algorithm. Use only if
83  * preserving sharp edges is a priority (e.g. minimap).
84  * @param surf The source surface.
85  * @param w The width of the resulting surface.
86  * @param h The height of the resulting surface.
87  * @return A surface containing the scaled version of the source.
88  * @retval 0 Returned upon error.
89  * @retval surf Returned if w == surf->w and h == surf->h.
90  */
91 surface scale_surface_sharp(const surface& surf, int w, int h);
92 
93 void adjust_surface_color(surface& surf, int r, int g, int b);
95 void monochrome_image(surface& surf, const int threshold);
96 void sepia_image(surface& surf);
97 void negative_image(surface& surf, const int thresholdR, const int thresholdG, const int thresholdB);
99 void wipe_alpha(surface& surf);
100 /** create an heavy shadow of the image, by blurring, increasing alpha and darkening */
101 void shadow_image(surface& surf, int scale = 1);
102 
103 enum channel { RED, GREEN, BLUE, ALPHA };
105 
106 /**
107  * Applies an opacity modification to a surface.
108  * @param surf The surface to modify.
109  * @param opacity The new opacity (0.0 to 1.0).
110  */
111 void apply_surface_opacity(surface& surf, float opacity);
112 
113 /**
114  * Recolors a surface using a map with source and converted palette values.
115  * This is most often used for team-coloring.
116  * @param surf The source surface.
117  * @param map_rgb Map of color values, with the keys corresponding to the
118  * source palette, and the values to the recolored palette.
119  */
120 void recolor_image(surface& surf, const color_mapping& map_rgb);
121 
122 void brighten_image(surface& surf, int32_t amount);
123 
124 /** Get a portion of the screen.
125  * Send nullptr if the portion is outside of the screen.
126  * @param surf The source surface.
127  * @param rect The portion of the source surface to copy.
128  * @return A surface containing the portion of the source.
129  * No RLE or Alpha bits are set.
130  * @retval 0 if error or the portion is outside of the surface.
131  */
133 
134 void adjust_surface_alpha(surface& surf, uint8_t alpha_mod);
135 void adjust_surface_alpha_add(surface& surf, int amount);
136 
137 /**
138  * Applies a mask to the source surface by calculating the minimum alpha channel
139  * value for every corresponding pixel. This operation ensures that the resulting
140  * surface is only visible where BOTH the original surface AND the mask were visible.
141  * Mostly used to remove any pixels outside a hex shape.
142  * @param surf The surface to be modified (the destination).
143  * @param mask The mask surface (read-only).
144  * if the resulting surface contains no visible pixels (i.e., is fully transparent).
145  * @param filename Optional string for logging purposes.
146  */
147 bool mask_surface(surface& surf, const surface& mask, const std::string& filename = std::string());
148 
149 /**
150  * Checks if the source surface is entirely covered by the visible area of the mask.
151  * If a visible pixel is found outside the mask's visible area, the function immediately
152  * returns false. Mostly used to see if an image has all visable pixels within a hex shape.
153  * @param surf The source surface (whose visibility is being checked).
154  * @param mask The mask surface (whose visible area defines the boundary).
155  * @return true if all visible pixels of @p surf are contained within the non-transparent
156  * area of @p mask (i.e., the surface is fully covered). Returns false otherwise.
157  */
158 bool in_mask_surface(const surface& surf, const surface& mask);
159 
160 /**
161  * Light surf using lightmap
162  * @param surf The source surface.
163  * @param lightmap add/subtract this color to surf
164  * but RGB values are converted to (X-128)*2
165  * to cover the full (-256,256) spectrum.
166  * Should already be neutral
167 */
168 void light_surface(surface& surf, const surface &lightmap);
169 
170 /**
171  * Cross-fades a surface in place.
172  *
173  * @param surf The surface to blur, must have 32 bits per pixel.
174  * @param rect The part of the surface to blur.
175  * @param depth The depth of the blurring.
176  */
177 void blur_surface(surface& surf, rect rect, int depth = 1);
178 
179 /**
180  * Cross-fades a surface with alpha channel.
181  *
182  * @param surf The source surface.
183  * @param depth The depth of the blurring.
184  */
185 void blur_alpha_surface(surface& surf, int depth = 1);
186 
187 /** Cuts a rectangle from a surface. */
188 surface cut_surface(const surface &surf, const rect& r);
189 
190 /**
191  * Blends a surface with a color.
192  *
193  * Every pixel in the surface will be blended with the @p color given. The
194  * final color of a pixel is amount * @p color + (1 - amount) * original.
195  *
196  * @param surf The surface to blend.
197  * @param amount The amount of the new color is determined by
198  * @p color. Must be a number in the range
199  * [0, 1].
200  * @param color The color to blend width, note its alpha
201  * channel is ignored.
202  */
203 void blend_surface(surface& surf, const double amount, const color_t color);
204 
205 /**
206  * Rotates a surface by any degrees.
207  *
208  * @pre @p zoom >= @p offset Otherwise @return will have empty pixels.
209  * @pre @p offset > 0 Otherwise the procedure will not return.
210  *
211  * @param surf The surface to rotate.
212  * @param angle The angle of rotation.
213  * @param zoom Which zoom level to use for calculating the result.
214  * @param offset Pixel offset when scanning the zoomed source.
215  *
216  * @return The rotated surface.
217  */
218 surface rotate_any_surface(const surface& surf, float angle, int zoom, int offset);
219 
220 /**
221  * Rotates a surface 180 degrees.
222  *
223  * @param surf The surface to rotate.
224  *
225  * @return The rotated surface.
226  */
228 
229 /**
230  * Rotates a surface 90 degrees.
231  *
232  * @param surf The surface to rotate.
233  * @param clockwise Whether the rotation should be clockwise (true)
234  * or counter-clockwise (false).
235  *
236  * @return The rotated surface.
237  */
238 surface rotate_90_surface(const surface& surf, bool clockwise);
239 
240 void flip_surface(surface& surf);
241 void flop_surface(surface& surf);
242 
double g
Definition: astarsearch.cpp:63
Represents version numbers.
std::unordered_map< color_t, color_t > color_mapping
Definition: color_range.hpp:24
Interfaces for manipulating version numbers of engine, add-ons, etc.
General math utility functions.
version_info get_version()
Returns the runtime SDL version.
Definition: utils.cpp:42
bool runtime_at_least(uint8_t major, uint8_t minor=0, uint8_t patch=0)
Returns true if the runtime SDL version is at or greater than the specified version,...
Definition: utils.cpp:48
void scale(size_t factor, const uint32_t *src, uint32_t *trg, int srcWidth, int srcHeight, ColorFormat colFmt, const ScalerCfg &cfg=ScalerCfg(), int yFirst=0, int yLast=std::numeric_limits< int >::max())
Definition: xbrz.cpp:1175
int w
Definition: pathfind.cpp:188
rect dst
Location on the final composed sheet.
surface surf
Image.
rect src
Non-transparent portion of the surface to compose.
std::string filename
Filename.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:51
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:49
void blend_surface(surface &surf, const double amount, const color_t color)
Blends a surface with a color.
Definition: utils.cpp:1153
void sepia_image(surface &surf)
Definition: utils.cpp:464
void flip_surface(surface &surf)
Definition: utils.cpp:1317
void blur_surface(surface &surf, rect rect, int depth=1)
Cross-fades a surface in place.
Definition: utils.cpp:838
void recolor_image(surface &surf, const color_mapping &map_rgb)
Recolors a surface using a map with source and converted palette values.
Definition: utils.cpp:636
surface get_surface_portion(const surface &surf, rect &rect)
Get a portion of the screen.
Definition: utils.cpp:1356
surface scale_surface_legacy(const surface &surf, int w, int h)
Scale a surface using simple bilinear filtering (discarding rgb from source pixels with 0 alpha)
Definition: utils.cpp:225
void wipe_alpha(surface &surf)
Definition: utils.cpp:517
void brighten_image(surface &surf, int32_t amount)
Definition: utils.cpp:667
surface cut_surface(const surface &surf, const rect &r)
Cuts a rectangle from a surface.
Definition: utils.cpp:1092
void greyscale_image(surface &surf)
Definition: utils.cpp:424
void adjust_surface_alpha(surface &surf, uint8_t alpha_mod)
Definition: utils.cpp:685
void swap_channels_image(surface &surf, channel r, channel g, channel b, channel a)
Definition: utils.cpp:554
void blur_alpha_surface(surface &surf, int depth=1)
Cross-fades a surface with alpha channel.
Definition: utils.cpp:954
void negative_image(surface &surf, const int thresholdR, const int thresholdG, const int thresholdB)
Definition: utils.cpp:483
void adjust_surface_color(surface &surf, int r, int g, int b)
Definition: utils.cpp:405
void alpha_to_greyscale(surface &surf)
Definition: utils.cpp:504
rect get_non_transparent_portion(const surface &surf)
Definition: utils.cpp:1440
void shadow_image(surface &surf, int scale=1)
create an heavy shadow of the image, by blurring, increasing alpha and darkening
Definition: utils.cpp:529
bool mask_surface(surface &surf, const surface &mask, const std::string &filename=std::string())
Applies a mask to the source surface by calculating the minimum alpha channel value for every corresp...
Definition: utils.cpp:708
void sdl_blit(const surface &src, const SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
Definition: utils.hpp:43
void monochrome_image(surface &surf, const int threshold)
Definition: utils.cpp:446
void light_surface(surface &surf, const surface &lightmap)
Light surf using lightmap.
Definition: utils.cpp:790
void flop_surface(surface &surf)
Definition: utils.cpp:1340
surface scale_surface_xbrz(const surface &surf, std::size_t z)
Scale a surface using xBRZ algorithm.
Definition: utils.cpp:61
surface scale_surface_sharp(const surface &surf, int w, int h)
Scale a surface using modified nearest neighbour algorithm.
Definition: utils.cpp:358
void adjust_surface_alpha_add(surface &surf, int amount)
Definition: utils.cpp:694
void apply_surface_opacity(surface &surf, float opacity)
Applies an opacity modification to a surface.
Definition: utils.cpp:1392
surface rotate_90_surface(const surface &surf, bool clockwise)
Rotates a surface 90 degrees.
Definition: utils.cpp:1283
surface rotate_180_surface(const surface &surf)
Rotates a surface 180 degrees.
Definition: utils.cpp:1243
surface scale_surface(const surface &surf, int w, int h)
Scale a surface using alpha-weighted modified bilinear filtering Note: causes artifacts with alpha gr...
Definition: utils.cpp:99
surface rotate_any_surface(const surface &surf, float angle, int zoom, int offset)
Rotates a surface by any degrees.
Definition: utils.cpp:1181
channel
Definition: utils.hpp:103
@ BLUE
Definition: utils.hpp:103
@ ALPHA
Definition: utils.hpp:103
@ GREEN
Definition: utils.hpp:103
@ RED
Definition: utils.hpp:103
bool in_mask_surface(const surface &surf, const surface &mask)
Checks if the source surface is entirely covered by the visible area of the mask.
Definition: utils.cpp:756
#define h
#define b