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