The Battle for Wesnoth  1.19.11+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 <cstdlib>
25 #include <string>
26 
27 struct rect;
28 
29 namespace sdl
30 {
31 
32 /** Returns the runtime SDL version. */
34 
35 /**
36  * Returns true if the runtime SDL version is at or greater than the
37  * specified version, false otherwise.
38  */
39 bool runtime_at_least(uint8_t major, uint8_t minor = 0, uint8_t patch = 0);
40 
41 } // namespace sdl
42 
43 
44 inline void sdl_blit(const surface& src, const SDL_Rect* src_rect, surface& dst, SDL_Rect* dst_rect){
45  // Note: this is incorrect when both src and dst combine transparent pixels.
46  // The correct equation is, per-pixel:
47  // outA = srcA + dstA * (1 - srcA)
48  // outRGB = (srcRGB * srcA + dstRGB * dstA * (1 - srcA)) / outA
49  // When outA is 0, outRGB can of course be anything.
50  // TODO: implement proper transparent blending using the above formula
51  SDL_BlitSurface(src, src_rect, dst, dst_rect);
52 }
53 
54 /** Scale a surface using xBRZ algorithm
55  * @param surf The source surface
56  * @param z The scaling factor. Should be an integer 2-5 (1 is tolerated).
57  * @return The scaled surface
58  */
59 surface scale_surface_xbrz(const surface & surf, std::size_t z);
60 
61 /** Scale a surface using alpha-weighted modified bilinear filtering
62  * Note: causes artifacts with alpha gradients, for example in some portraits
63  * @param surf The source surface.
64  * @param w The width of the resulting surface.
65  * @param h The height of the resulting surface.
66  * @return A surface containing the scaled version of the source.
67  * @retval 0 Returned upon error.
68  * @retval surf Returned if w == surf->w and h == surf->h.
69  */
70 surface scale_surface(const surface &surf, int w, int h);
71 
72 /** Scale a surface using simple bilinear filtering (discarding rgb from source
73  * pixels with 0 alpha)
74  * @param surf The source surface.
75  * @param w The width of the resulting surface.
76  * @param h The height of the resulting surface.
77  * @return A surface containing the scaled version of the source.
78  * @retval 0 Returned upon error.
79  * @retval surf Returned if w == surf->w and h == surf->h.
80  */
81 surface scale_surface_legacy(const surface &surf, int w, int h);
82 
83 /** Scale a surface using modified nearest neighbour algorithm. Use only if
84  * preserving sharp edges is a priority (e.g. minimap).
85  * @param surf The source surface.
86  * @param w The width of the resulting surface.
87  * @param h The height of the resulting surface.
88  * @return A surface containing the scaled version of the source.
89  * @retval 0 Returned upon error.
90  * @retval surf Returned if w == surf->w and h == surf->h.
91  */
92 surface scale_surface_sharp(const surface& surf, int w, int h);
93 
94 void adjust_surface_color(surface& surf, int r, int g, int b);
96 void monochrome_image(surface& surf, const int threshold);
97 void sepia_image(surface& surf);
98 void negative_image(surface& surf, const int thresholdR, const int thresholdG, const int thresholdB);
100 void wipe_alpha(surface& surf);
101 /** create an heavy shadow of the image, by blurring, increasing alpha and darkening */
102 void shadow_image(surface& surf, int scale = 1);
103 
104 enum channel { RED, GREEN, BLUE, ALPHA };
106 
107 /**
108  * Recolors a surface using a map with source and converted palette values.
109  * This is most often used for team-coloring.
110  *
111  * @param surf The source surface.
112  * @param map_rgb Map of color values, with the keys corresponding to the
113  * source palette, and the values to the recolored palette.
114  */
115 void recolor_image(surface& surf, const color_range_map& map_rgb);
116 
117 void brighten_image(surface& surf, int32_t amount);
118 
119 /** Get a portion of the screen.
120  * Send nullptr if the portion is outside of the screen.
121  * @param surf The source surface.
122  * @param rect The portion of the source surface to copy.
123  * @return A surface containing the portion of the source.
124  * No RLE or Alpha bits are set.
125  * @retval 0 if error or the portion is outside of the surface.
126  */
127 surface get_surface_portion(const surface &surf, SDL_Rect &rect);
128 
129 void adjust_surface_alpha(surface& surf, uint8_t alpha_mod);
130 void adjust_surface_alpha_add(surface& surf, int amount);
131 
132 /** Applies a mask on a surface. */
133 void mask_surface(surface& surf, const surface& mask, bool* empty_result = nullptr, const std::string& filename = std::string());
134 
135 /** Check if a surface fit into a mask */
136 bool in_mask_surface(const surface& surf, const surface& mask);
137 
138 /**
139  * Light surf using lightmap
140  * @param surf The source surface.
141  * @param lightmap add/subtract this color to surf
142  * but RGB values are converted to (X-128)*2
143  * to cover the full (-256,256) spectrum.
144  * Should already be neutral
145 */
146 void light_surface(surface& surf, const surface &lightmap);
147 
148 /**
149  * Cross-fades a surface in place.
150  *
151  * @param surf The surface to blur, must have 32 bits per pixel.
152  * @param rect The part of the surface to blur.
153  * @param depth The depth of the blurring.
154  */
155 void blur_surface(surface& surf, SDL_Rect rect, int depth = 1);
156 
157 /**
158  * Cross-fades a surface with alpha channel.
159  *
160  * @param surf The source surface.
161  * @param depth The depth of the blurring.
162  */
163 void blur_alpha_surface(surface& surf, int depth = 1);
164 
165 /** Cuts a rectangle from a surface. */
166 surface cut_surface(const surface &surf, const SDL_Rect& r);
167 
168 /**
169  * Blends a surface with a color.
170  *
171  * Every pixel in the surface will be blended with the @p color given. The
172  * final color of a pixel is amount * @p color + (1 - amount) * original.
173  *
174  * @param surf The surface to blend.
175  * @param amount The amount of the new color is determined by
176  * @p color. Must be a number in the range
177  * [0, 1].
178  * @param color The color to blend width, note its alpha
179  * channel is ignored.
180  */
181 void blend_surface(surface& surf, const double amount, const color_t color);
182 
183 /**
184  * Rotates a surface by any degrees.
185  *
186  * @pre @p zoom >= @p offset Otherwise @return will have empty pixels.
187  * @pre @p offset > 0 Otherwise the procedure will not return.
188  *
189  * @param surf The surface to rotate.
190  * @param angle The angle of rotation.
191  * @param zoom Which zoom level to use for calculating the result.
192  * @param offset Pixel offset when scanning the zoomed source.
193  *
194  * @return The rotated surface.
195  */
196 surface rotate_any_surface(const surface& surf, float angle, int zoom, int offset);
197 
198 /**
199  * Rotates a surface 180 degrees.
200  *
201  * @param surf The surface to rotate.
202  *
203  * @return The rotated surface.
204  */
206 
207 /**
208  * Rotates a surface 90 degrees.
209  *
210  * @param surf The surface to rotate.
211  * @param clockwise Whether the rotation should be clockwise (true)
212  * or counter-clockwise (false).
213  *
214  * @return The rotated surface.
215  */
216 surface rotate_90_surface(const surface& surf, bool clockwise);
217 
218 void flip_surface(surface& surf);
219 void flop_surface(surface& surf);
220 
double g
Definition: astarsearch.cpp:63
Represents version numbers.
std::unordered_map< color_t, color_t > color_range_map
Definition: color_range.hpp:30
int w
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:40
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:47
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:1170
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:61
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:49
void mask_surface(surface &surf, const surface &mask, bool *empty_result=nullptr, const std::string &filename=std::string())
Applies a mask on a surface.
Definition: utils.cpp:706
void blend_surface(surface &surf, const double amount, const color_t color)
Blends a surface with a color.
Definition: utils.cpp:1159
void sepia_image(surface &surf)
Definition: utils.cpp:462
void flip_surface(surface &surf)
Definition: utils.cpp:1323
void recolor_image(surface &surf, const color_range_map &map_rgb)
Recolors a surface using a map with source and converted palette values.
Definition: utils.cpp:634
surface get_surface_portion(const surface &surf, SDL_Rect &rect)
Get a portion of the screen.
Definition: utils.cpp:1355
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:515
void brighten_image(surface &surf, int32_t amount)
Definition: utils.cpp:665
void greyscale_image(surface &surf)
Definition: utils.cpp:422
void adjust_surface_alpha(surface &surf, uint8_t alpha_mod)
Definition: utils.cpp:683
void swap_channels_image(surface &surf, channel r, channel g, channel b, channel a)
Definition: utils.cpp:552
void blur_alpha_surface(surface &surf, int depth=1)
Cross-fades a surface with alpha channel.
Definition: utils.cpp:962
void negative_image(surface &surf, const int thresholdR, const int thresholdG, const int thresholdB)
Definition: utils.cpp:481
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:502
rect get_non_transparent_portion(const surface &surf)
Definition: utils.cpp:1399
void shadow_image(surface &surf, int scale=1)
create an heavy shadow of the image, by blurring, increasing alpha and darkening
Definition: utils.cpp:527
void sdl_blit(const surface &src, const SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
Definition: utils.hpp:44
void monochrome_image(surface &surf, const int threshold)
Definition: utils.cpp:444
surface cut_surface(const surface &surf, const SDL_Rect &r)
Cuts a rectangle from a surface.
Definition: utils.cpp:1100
void light_surface(surface &surf, const surface &lightmap)
Light surf using lightmap.
Definition: utils.cpp:798
void flop_surface(surface &surf)
Definition: utils.cpp:1339
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:692
surface rotate_90_surface(const surface &surf, bool clockwise)
Rotates a surface 90 degrees.
Definition: utils.cpp:1289
surface rotate_180_surface(const surface &surf)
Rotates a surface 180 degrees.
Definition: utils.cpp:1249
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:1187
void blur_surface(surface &surf, SDL_Rect rect, int depth=1)
Cross-fades a surface in place.
Definition: utils.cpp:846
channel
Definition: utils.hpp:104
@ BLUE
Definition: utils.hpp:104
@ ALPHA
Definition: utils.hpp:104
@ GREEN
Definition: utils.hpp:104
@ RED
Definition: utils.hpp:104
bool in_mask_surface(const surface &surf, const surface &mask)
Check if a surface fit into a mask.
Definition: utils.cpp:760
#define h
#define b