The Battle for Wesnoth  1.17.0-dev
surface.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2021
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 "utils/const_clone.hpp"
18 
19 #include <SDL2/SDL.h>
20 
21 #include <ostream>
22 
23 class CVideo;
24 
25 class surface
26 {
27 public:
28  surface() : surface_(nullptr)
29  {}
30 
31  surface(SDL_Surface* surf);
32 
33  /** Allocates a new surface with the given dimensions. */
34  surface(int w, int h);
35 
36  surface(const surface& s) : surface_(s.get())
37  {
39  }
40 
41  surface(surface&& s) noexcept : surface_(s.get())
42  {
43  s.surface_ = nullptr;
44  }
45 
47  {
48  free_surface();
49  }
50 
52  {
54  return *this;
55  }
56 
57  surface& operator=(surface&& s) noexcept
58  {
59  free_surface();
60  surface_ = s.surface_;
61  s.surface_ = nullptr;
62  return *this;
63  }
64 
65  /**
66  * Check that the surface is neutral bpp 32.
67  *
68  * The surface may have an empty alpha channel.
69  *
70  * @returns The status @c true if neutral, @c false if not.
71  */
72  bool is_neutral() const;
73 
74  /**
75  * Converts this surface to a neutral format if it is not already.
76  *
77  * @returns A reference to this object for chaining convenience.
78  */
80 
81  /**
82  * Makes a copy of this surface. The copy will be in the 'neutral' pixel format.
83  *
84  * Note this is creates a new, duplicate surface in memory. Making a copy of this
85  * 'surface' object will *not* duplicate the surface itself since we only hold a
86  * pointer to the actual surface.
87  */
88  surface clone() const;
89 
90  operator SDL_Surface*() const { return surface_; }
91 
92  SDL_Surface* get() const { return surface_; }
93 
94  SDL_Surface* operator->() const { return surface_; }
95 
96 private:
97  static void add_surface_ref(SDL_Surface* surf)
98  {
99  if(surf) {
100  ++surf->refcount;
101  }
102  }
103 
104  void assign_surface_internal(SDL_Surface* surf);
105 
106  void free_surface();
107 
108  SDL_Surface* surface_;
109 
110  static const SDL_PixelFormat neutral_pixel_format;
111 };
112 
113 bool operator<(const surface& a, const surface& b);
114 
115 std::ostream& operator<<(std::ostream& stream, const surface& surf);
116 
118 {
120  surface_restorer(class CVideo* target, const SDL_Rect& rect);
121  ~surface_restorer();
122 
123  void restore() const;
124  void restore(const SDL_Rect& dst) const;
125  void update();
126  void cancel();
127 
128  const SDL_Rect& area() const { return rect_; }
129 
130 private:
131  class CVideo* target_;
132  SDL_Rect rect_;
134 };
135 
136 /**
137  * Helper class for pinning SDL surfaces into memory.
138  * @note This class should be used only with neutral surfaces, so that
139  * the pointer returned by #pixels is meaningful.
140  */
141 template<typename T>
143 {
144 private:
146 
147 public:
148  surface_locker(T& surf) : surface_(surf), locked_(false)
149  {
150  if(SDL_MUSTLOCK(surface_)) {
151  locked_ = SDL_LockSurface(surface_) == 0;
152  }
153  }
154 
156  {
157  if(locked_) {
158  SDL_UnlockSurface(surface_);
159  }
160  }
161 
162  pixel_t* pixels() const { return reinterpret_cast<pixel_t*>(surface_->pixels); }
163 
164 private:
166  bool locked_;
167 };
168 
171 
173 {
174  // if r is nullptr, clip to the full size of the surface.
175  clip_rect_setter(const surface &surf, const SDL_Rect* r, bool operate = true) : surface_(surf), rect_(), operate_(operate)
176  {
177  if(operate_ && surface_.get()){
178  SDL_GetClipRect(surface_, &rect_);
179  SDL_Rect final_rect = { 0, 0, 0, 0 };
180 
181  if(r) {
182  SDL_IntersectRect(&rect_, r, &final_rect);
183  } else {
184  final_rect.w = surface_->w;
185  final_rect.h = surface_->h;
186  }
187 
188  SDL_SetClipRect(surface_, &final_rect);
189  }
190  }
191 
193  {
194  if(operate_ && surface_.get()) {
195  SDL_SetClipRect(surface_, &rect_);
196  }
197  }
198 
199 private:
201  SDL_Rect rect_;
202  const bool operate_;
203 };
pixel_t * pixels() const
Definition: surface.hpp:162
SDL_Surface * get() const
Definition: surface.hpp:92
void free_surface()
Definition: surface.cpp:77
#define a
Definition: video.hpp:32
surface_locker(T &surf)
Definition: surface.hpp:148
const SDL_Rect & area() const
Definition: surface.hpp:128
static void add_surface_ref(SDL_Surface *surf)
Definition: surface.hpp:97
#define h
surface(const surface &s)
Definition: surface.hpp:36
void assign_surface_internal(SDL_Surface *surf)
Definition: surface.cpp:69
surface & operator=(surface &&s) noexcept
Definition: surface.hpp:57
surface clone() const
Makes a copy of this surface.
Definition: surface.cpp:63
surface surface_
Definition: surface.hpp:133
#define b
surface()
Definition: surface.hpp:28
surface(surface &&s) noexcept
Definition: surface.hpp:41
surface & operator=(const surface &s)
Definition: surface.hpp:51
surface & make_neutral()
Converts this surface to a neutral format if it is not already.
Definition: surface.cpp:49
SDL_Rect rect_
Definition: surface.hpp:132
utils::const_clone_t< uint32_t, T > pixel_t
Definition: surface.hpp:145
SDL_Rect rect_
Definition: surface.hpp:201
const bool operate_
Definition: surface.hpp:202
bool operator<(const surface &a, const surface &b)
Definition: surface.cpp:145
std::ostream & operator<<(std::ostream &stream, const surface &surf)
Definition: surface.cpp:150
class CVideo * target_
Definition: surface.hpp:131
static map_location::DIRECTION s
SDL_Surface * surface_
Definition: surface.hpp:108
Helper class for pinning SDL surfaces into memory.
Definition: surface.hpp:142
SDL_Surface * operator->() const
Definition: surface.hpp:94
int w
surface surface_
Definition: surface.hpp:200
bool is_neutral() const
Check that the surface is neutral bpp 32.
Definition: surface.cpp:40
clip_rect_setter(const surface &surf, const SDL_Rect *r, bool operate=true)
Definition: surface.hpp:175
typename const_clone< D, S >::type const_clone_t
Definition: const_clone.hpp:60
static const SDL_PixelFormat neutral_pixel_format
Definition: surface.hpp:110
~surface()
Definition: surface.hpp:46