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