The Battle for Wesnoth  1.17.0-dev
utils.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2021
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 <SDL2/SDL.h>
25 
26 #include <cstdlib>
27 #include <map>
28 #include <string>
29 
31 
32 inline void sdl_blit(const surface& src, SDL_Rect* src_rect, surface& dst, SDL_Rect* dst_rect){
33  SDL_BlitSurface(src, src_rect, dst, dst_rect);
34 }
35 
36 inline void sdl_copy_portion(const surface& screen, SDL_Rect* screen_rect, surface& dst, SDL_Rect* dst_rect){
37  SDL_SetSurfaceBlendMode(screen, SDL_BLENDMODE_NONE);
38  SDL_SetSurfaceBlendMode(dst, SDL_BLENDMODE_NONE);
39  SDL_BlitSurface(screen, screen_rect, dst, dst_rect);
40  SDL_SetSurfaceBlendMode(screen, SDL_BLENDMODE_BLEND);
41 }
42 
43 /**
44  * Stretches a surface in the horizontal direction.
45  *
46  * The stretches a surface it uses the first pixel in the horizontal
47  * direction of the original surface and copies that to the destination.
48  * This means only the first column of the original is used for the destination.
49  * @param surf The source surface.
50  * @param w The width of the resulting surface.
51  *
52  * @return A surface.
53  * returned.
54  * @retval 0 Returned upon error.
55  * @retval surf Returned if w == surf->w.
56  */
58  const surface& surf, const unsigned w);
59 
60 /**
61  * Stretches a surface in the vertical direction.
62  *
63  * The stretches a surface it uses the first pixel in the vertical
64  * direction of the original surface and copies that to the destination.
65  * This means only the first row of the original is used for the destination.
66  * @param surf The source surface.
67  * @param h The height of the resulting surface.
68  *
69  * @return A surface.
70  * returned.
71  *
72  * @retval surf Returned if h == surf->h.
73  */
75  const surface& surf, const unsigned h);
76 
77 /** Scale a surface using xBRZ algorithm
78  * @param surf The source surface
79  * @param z The scaling factor. Should be an integer 2-5 (1 is tolerated).
80  * @return The scaled surface
81  */
82 surface scale_surface_xbrz(const surface & surf, std::size_t z);
83 
84 /** Scale a surface using the nearest neighbor algorithm (provided by xBRZ lib)
85  * @param surf The sources surface
86  * @param w The width of the resulting surface.
87  * @param h The height of the resulting surface.
88  * @return The rescaled surface.
89  */
90 surface scale_surface_nn(const surface & surf, int w, int h);
91 
92 /** Scale a surface using alpha-weighted modified bilinear filtering
93  * Note: causes artifacts with alpha gradients, for example in some portraits
94  * @param surf The source surface.
95  * @param w The width of the resulting surface.
96  * @param h The height of the resulting surface.
97  * @return A surface containing the scaled version of the source.
98  * @retval 0 Returned upon error.
99  * @retval surf Returned if w == surf->w and h == surf->h.
100  */
101 surface scale_surface(const surface &surf, int w, int h);
102 
103 /** Scale a surface using simple bilinear filtering (discarding rgb from source
104  pixels with 0 alpha)
105  * @param surf The source surface.
106  * @param w The width of the resulting surface.
107  * @param h The height of the resulting surface.
108  * @return A surface containing the scaled version of the source.
109  * @retval 0 Returned upon error.
110  * @retval surf Returned if w == surf->w and h == surf->h.
111  */
112 surface scale_surface_legacy(const surface &surf, int w, int h);
113 
114 /** Scale a surface using modified nearest neighbour algorithm. Use only if
115  * preserving sharp edges is a priority (e.g. minimap).
116  * @param surf The source surface.
117  * @param w The width of the resulting surface.
118  * @param h The height of the resulting surface.
119  * @return A surface containing the scaled version of the source.
120  * @retval 0 Returned upon error.
121  * @retval surf Returned if w == surf->w and h == surf->h.
122  */
123 surface scale_surface_sharp(const surface& surf, int w, int h);
124 
125 /** Tile a surface
126  * @param surf The source surface.
127  * @param w The width of the resulting surface.
128  * @param h The height of the resulting surface.
129  * @param centered Whether to tile from the center outwards or from the top left (origin).
130  * @return A surface containing the tiled version of the source.
131  * @retval 0 Returned upon error
132  * @retval surf Returned if w == surf->w and h == surf->h.
133  */
134 surface tile_surface(const surface &surf, int w, int h, bool centered = true);
135 
136 surface adjust_surface_color(const surface &surf, int r, int g, int b);
137 surface greyscale_image(const surface &surf);
138 surface monochrome_image(const surface &surf, const int threshold);
139 surface sepia_image(const surface &surf);
140 surface negative_image(const surface &surf, const int thresholdR, const int thresholdG, const int thresholdB);
141 surface alpha_to_greyscale(const surface & surf);
142 surface wipe_alpha(const surface & surf);
143 /** create an heavy shadow of the image, by blurring, increasing alpha and darkening */
144 surface shadow_image(const surface &surf);
145 
146 enum channel { RED, GREEN, BLUE, ALPHA };
148 
149 /**
150  * Recolors a surface using a map with source and converted palette values.
151  * This is most often used for team-coloring.
152  *
153  * @param surf The source surface.
154  * @param map_rgb Map of color values, with the keys corresponding to the
155  * source palette, and the values to the recolored palette.
156  * @return A recolored surface, or a null surface if there are
157  * problems with the source.
158  */
159 surface recolor_image(surface surf, const color_range_map& map_rgb);
160 
161 surface brighten_image(const surface &surf, fixed_t amount);
162 
163 /** Get a portion of the screen.
164  * Send nullptr if the portion is outside of the screen.
165  * @param surf The source surface.
166  * @param rect The portion of the source surface to copy.
167  * @return A surface containing the portion of the source.
168  * No RLE or Alpha bits are set.
169  * @retval 0 if error or the portion is outside of the surface.
170  */
171 surface get_surface_portion(const surface &surf, SDL_Rect &rect);
172 
173 void adjust_surface_alpha(surface& surf, fixed_t amount);
174 surface adjust_surface_alpha_add(const surface &surf, int amount);
175 
176 /** Applies a mask on a surface. */
177 surface mask_surface(const surface &surf, const surface &mask, bool* empty_result = nullptr, const std::string& filename = std::string());
178 
179 /** Check if a surface fit into a mask */
180 bool in_mask_surface(const surface &surf, const surface &mask);
181 
182 /** Progressively reduce alpha of bottom part of the surface
183  * @param surf The source surface.
184  * @param depth The height of the bottom part in pixels
185  * @param alpha_base The alpha adjustment at the interface
186  * @param alpha_delta The alpha adjustment reduction rate by pixel depth
187 */
188 surface submerge_alpha(const surface &surf, int depth, float alpha_base, float alpha_delta);
189 
190 /**
191  * Light surf using lightmap
192  * @param surf The source surface.
193  * @param lightmap add/subtract this color to surf
194  * but RGB values are converted to (X-128)*2
195  * to cover the full (-256,256) spectrum.
196  * Should already be neutral
197 */
198 surface light_surface(const surface &surf, const surface &lightmap);
199 
200 /**
201  * Cross-fades a surface.
202  *
203  * @param surf The source surface.
204  * @param depth The depth of the blurring.
205  * @return A new, blurred, neutral surface.
206  */
207 surface blur_surface(const surface &surf, int depth = 1);
208 
209 /**
210  * Cross-fades a surface in place.
211  *
212  * @param surf The surface to blur, must have 32 bits per pixel.
213  * @param rect The part of the surface to blur.
214  * @param depth The depth of the blurring.
215  */
216 void blur_surface(surface& surf, SDL_Rect rect, int depth = 1);
217 
218 /**
219  * Cross-fades a surface with alpha channel.
220  *
221  * @param surf The source surface.
222  * @param depth The depth of the blurring.
223  * @return A new, blurred, neutral surface.
224  */
225 surface blur_alpha_surface(const surface &surf, int depth = 1);
226 
227 /** Cuts a rectangle from a surface. */
228 surface cut_surface(const surface &surf, const SDL_Rect& r);
229 
230 /**
231  * Blends a surface with a color.
232  *
233  * Every pixel in the surface will be blended with the @p color given. The
234  * final color of a pixel is amount * @p color + (1 - amount) * original.
235  *
236  * @param surf The surface to blend.
237  * @param amount The amount of the new color is determined by
238  * @p color. Must be a number in the range
239  * [0, 1].
240  * @param color The color to blend width, note its alpha
241  * channel is ignored.
242  *
243  * @return The blended surface.
244  */
246  const surface &surf
247  , const double amount
248  , const color_t color);
249 
250 /**
251  * Rotates a surface by any degrees.
252  *
253  * @pre @p zoom >= @p offset Otherwise @return will have empty pixels.
254  * @pre @p offset > 0 Otherwise the procedure will not return.
255  *
256  * @param surf The surface to rotate.
257  * @param angle The angle of rotation.
258  * @param zoom Which zoom level to use for calculating the result.
259  * @param offset Pixel offset when scanning the zoomed source.
260  *
261  * @return The rotated surface.
262  */
263 surface rotate_any_surface(const surface& surf, float angle,
264  int zoom, int offset);
265 
266 /**
267  * Rotates a surface 180 degrees.
268  *
269  * @param surf The surface to rotate.
270  *
271  * @return The rotated surface.
272  */
273 surface rotate_180_surface(const surface &surf);
274 
275 /**
276  * Rotates a surface 90 degrees.
277  *
278  * @param surf The surface to rotate.
279  * @param clockwise Whether the rotation should be clockwise (true)
280  * or counter-clockwise (false).
281  *
282  * @return The rotated surface.
283  */
284 surface rotate_90_surface(const surface &surf, bool clockwise);
285 
286 surface flip_surface(const surface &surf);
287 surface flop_surface(const surface &surf);
288 
289 /**
290  * Replacement for sdl_blit.
291  *
292  * sdl_blit has problems with blitting partly transparent surfaces so
293  * this is a replacement. It ignores the SDL_SRCALPHA and SDL_SRCCOLORKEY
294  * flags. src and dst will have the SDL_RLEACCEL flag removed.
295  * The return value of SDL_BlistSurface is normally ignored so no return value.
296  * The rectangles are const and will not be modified.
297  *
298  * @pre @p src contains a valid canvas.
299  * @pre @p dst contains a valid neutral canvas.
300  * @pre The caller must make sure the @p src fits on the @p dst.
301  *
302  * @param src The surface to blit.
303  * @param srcrect The region of the surface to blit
304  * @param dst The surface to blit on.
305  * @param dstrect The offset to blit the surface on, only x and y are used.
306  */
307 void blit_surface(const surface& src,
308  const SDL_Rect* srcrect, surface& dst, const SDL_Rect* dstrect);
309 
310 SDL_Rect get_non_transparent_portion(const surface &surf);
311 
312 /**
313  * Helper methods for setting/getting a single pixel in an image.
314  * Lifted from http://sdl.beuc.net/sdl.wiki/Pixel_Access
315  *
316  * @param surf The image to get or receive the pixel from.
317  * @param surf_lock The locked surface to make sure the pointers are valid.
318  * @param x The position in the row of the pixel.
319  * @param y The row of the pixel.
320  * @param pixel The pixel value.
321  */
322 void put_pixel(const surface& surf, surface_lock& surf_lock, int x, int y, uint32_t pixel);
323 uint32_t get_pixel(const surface& surf, const const_surface_lock& surf_lock, int x, int y);
324 
325 // blit the image on the center of the rectangle
326 // and a add a colored background
327 void draw_centered_on_background(surface surf, const SDL_Rect& rect,
328  const color_t& color, surface target);
Definition: utils.hpp:146
surface rotate_any_surface(const surface &surf, float angle, int zoom, int offset)
Rotates a surface by any degrees.
Definition: utils.cpp:1764
surface cut_surface(const surface &surf, const SDL_Rect &r)
Cuts a rectangle from a surface.
Definition: utils.cpp:1659
surface scale_surface_nn(const surface &surf, int w, int h)
Scale a surface using the nearest neighbor algorithm (provided by xBRZ lib)
Definition: utils.cpp:160
Interfaces for manipulating version numbers of engine, add-ons, etc.
surface greyscale_image(const surface &surf)
Definition: utils.cpp:641
void blit_surface(const surface &src, const SDL_Rect *srcrect, surface &dst, const SDL_Rect *dstrect)
Replacement for sdl_blit.
Definition: utils.cpp:2010
surface alpha_to_greyscale(const surface &surf)
Definition: utils.cpp:811
surface monochrome_image(const surface &surf, const int threshold)
Definition: utils.cpp:686
surface stretch_surface_horizontal(const surface &surf, const unsigned w)
Stretches a surface in the horizontal direction.
Definition: utils.cpp:41
#define a
surface flip_surface(const surface &surf)
Definition: utils.cpp:1952
surface rotate_180_surface(const surface &surf)
Rotates a surface 180 degrees.
Definition: utils.cpp:1875
#define h
bool in_mask_surface(const surface &surf, const surface &mask)
Check if a surface fit into a mask.
Definition: utils.cpp:1203
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:197
surface brighten_image(const surface &surf, fixed_t amount)
Definition: utils.cpp:1045
#define b
version_info sdl_get_version()
Definition: utils.cpp:34
surface shadow_image(const surface &surf)
create an heavy shadow of the image, by blurring, increasing alpha and darkening
Definition: utils.cpp:867
void draw_centered_on_background(surface surf, const SDL_Rect &rect, const color_t &color, surface target)
Definition: utils.cpp:2273
surface submerge_alpha(const surface &surf, int depth, float alpha_base, float alpha_delta)
Progressively reduce alpha of bottom part of the surface.
Definition: utils.cpp:1249
Definition: utils.hpp:146
General math utility functions.
surface stretch_surface_vertical(const surface &surf, const unsigned h)
Stretches a surface in the vertical direction.
Definition: utils.cpp:83
void put_pixel(const surface &surf, surface_lock &surf_lock, int x, int y, uint32_t pixel)
Helper methods for setting/getting a single pixel in an image.
Definition: utils.cpp:1821
surface adjust_surface_color(const surface &surf, int r, int g, int b)
Definition: utils.cpp:596
surface mask_surface(const surface &surf, const surface &mask, bool *empty_result=nullptr, const std::string &filename=std::string())
Applies a mask on a surface.
Definition: utils.cpp:1134
surface 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:1006
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:326
surface adjust_surface_alpha_add(const surface &surf, int amount)
Definition: utils.cpp:1096
int32_t fixed_t
Definition: math.hpp:313
std::unordered_map< color_t, color_t > color_range_map
Definition: color_range.hpp:31
Definition: utils.hpp:146
surface tile_surface(const surface &surf, int w, int h, bool centered=true)
Tile a surface.
Definition: utils.cpp:553
surface get_surface_portion(const surface &surf, SDL_Rect &rect)
Get a portion of the screen.
Definition: utils.cpp:2158
double g
Definition: astarsearch.cpp:65
Helper class for pinning SDL surfaces into memory.
Definition: surface.hpp:142
surface wipe_alpha(const surface &surf)
Definition: utils.cpp:839
int w
Definition: utils.hpp:146
uint32_t get_pixel(const surface &surf, const const_surface_lock &surf_lock, int x, int y)
Definition: utils.cpp:1852
Represents version numbers.
surface scale_surface_sharp(const surface &surf, int w, int h)
Scale a surface using modified nearest neighbour algorithm.
Definition: utils.cpp:463
surface scale_surface_xbrz(const surface &surf, std::size_t z)
Scale a surface using xBRZ algorithm.
Definition: utils.cpp:123
surface flop_surface(const surface &surf)
Definition: utils.cpp:1981
void adjust_surface_alpha(surface &surf, fixed_t amount)
Definition: utils.cpp:1087
surface blur_surface(const surface &surf, int depth=1)
Cross-fades a surface.
Definition: utils.cpp:1377
surface light_surface(const surface &surf, const surface &lightmap)
Light surf using lightmap.
Definition: utils.cpp:1311
surface swap_channels_image(const surface &surf, channel r, channel g, channel b, channel a)
Definition: utils.cpp:904
void sdl_copy_portion(const surface &screen, SDL_Rect *screen_rect, surface &dst, SDL_Rect *dst_rect)
Definition: utils.hpp:36
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
Definition: utils.hpp:32
surface blend_surface(const surface &surf, const double amount, const color_t color)
Blends a surface with a color.
Definition: utils.cpp:1717
surface rotate_90_surface(const surface &surf, bool clockwise)
Rotates a surface 90 degrees.
Definition: utils.cpp:1917
SDL_Rect get_non_transparent_portion(const surface &surf)
Definition: utils.cpp:2204
surface blur_alpha_surface(const surface &surf, int depth=1)
Cross-fades a surface with alpha channel.
Definition: utils.cpp:1512
surface negative_image(const surface &surf, const int thresholdR, const int thresholdG, const int thresholdB)
Definition: utils.cpp:768
surface sepia_image(const surface &surf)
Definition: utils.cpp:726
channel
Definition: utils.hpp:146