The Battle for Wesnoth  1.15.11+dev
surface.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2018 the Battle for Wesnoth Project https://www.wesnoth.org/
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY.
10 
11  See the COPYING file for more details.
12 */
13 
14 #pragma once
15 
16 #include "utils/const_clone.hpp"
17 
18 #include <SDL2/SDL.h>
19 
20 #include <ostream>
21 
22 class CVideo;
23 
24 class surface
25 {
26 public:
27  surface() : surface_(nullptr)
28  {}
29 
30  surface(SDL_Surface* surf);
31 
32  /** Allocates a new surface with the given dimensions. */
33  surface(int w, int h);
34 
35  surface(const surface& s) : surface_(s.get())
36  {
38  }
39 
40  surface(surface&& s) noexcept : surface_(s.get())
41  {
42  s.surface_ = nullptr;
43  }
44 
46  {
47  free_surface();
48  }
49 
51  {
53  return *this;
54  }
55 
56  surface& operator=(surface&& s) noexcept
57  {
58  free_surface();
59  surface_ = s.surface_;
60  s.surface_ = nullptr;
61  return *this;
62  }
63 
64  // Intended to be used when SDL has already freed the surface
65  void clear_without_free() { surface_ = nullptr; }
66 
67  /**
68  * Check that the surface is neutral bpp 32.
69  *
70  * The surface may have an empty alpha channel.
71  *
72  * @returns The status @c true if neutral, @c false if not.
73  */
74  bool is_neutral() const;
75 
76  /**
77  * Converts this surface to a neutral format if it is not already.
78  *
79  * @returns A reference to this object for chaining convenience.
80  */
82 
83  /**
84  * Makes a copy of this surface. The copy will be in the 'neutral' pixel format.
85  *
86  * Note this is creates a new, duplicate surface in memory. Making a copy of this
87  * 'surface' object will *not* duplicate the surface itself since we only hold a
88  * pointer to the actual surface.
89  */
90  surface clone() const;
91 
92  operator SDL_Surface*() const { return surface_; }
93 
94  SDL_Surface* get() const { return surface_; }
95 
96  SDL_Surface* operator->() const { return surface_; }
97 
98 private:
99  static void add_surface_ref(SDL_Surface* surf)
100  {
101  if(surf) {
102  ++surf->refcount;
103  }
104  }
105 
106  void assign_surface_internal(SDL_Surface* surf);
107 
108  void free_surface();
109 
110  SDL_Surface* surface_;
111 
112  static const SDL_PixelFormat neutral_pixel_format;
113 };
114 
115 bool operator<(const surface& a, const surface& b);
116 
117 std::ostream& operator<<(std::ostream& stream, const surface& surf);
118 
120 {
122  surface_restorer(class CVideo* target, const SDL_Rect& rect);
123  ~surface_restorer();
124 
125  void restore() const;
126  void restore(const SDL_Rect& dst) const;
127  void update();
128  void cancel();
129 
130  const SDL_Rect& area() const { return rect_; }
131 
132 private:
133  class CVideo* target_;
134  SDL_Rect rect_;
136 };
137 
138 /**
139  * Helper class for pinning SDL surfaces into memory.
140  * @note This class should be used only with neutral surfaces, so that
141  * the pointer returned by #pixels is meaningful.
142  */
143 template<typename T>
145 {
146 private:
148 
149 public:
150  surface_locker(T& surf) : surface_(surf), locked_(false)
151  {
152  if(SDL_MUSTLOCK(surface_)) {
153  locked_ = SDL_LockSurface(surface_) == 0;
154  }
155  }
156 
158  {
159  if(locked_) {
160  SDL_UnlockSurface(surface_);
161  }
162  }
163 
164  pixel_t* pixels() const { return reinterpret_cast<pixel_t*>(surface_->pixels); }
165 
166 private:
168  bool locked_;
169 };
170 
173 
175 {
176  // if r is nullptr, clip to the full size of the surface.
177  clip_rect_setter(const surface &surf, const SDL_Rect* r, bool operate = true) : surface_(surf), rect_(), operate_(operate)
178  {
179  if(operate_ && surface_.get()){
180  SDL_GetClipRect(surface_, &rect_);
181  SDL_Rect final_rect = { 0, 0, 0, 0 };
182 
183  if(r) {
184  SDL_IntersectRect(&rect_, r, &final_rect);
185  } else {
186  final_rect.w = surface_->w;
187  final_rect.h = surface_->h;
188  }
189 
190  SDL_SetClipRect(surface_, &final_rect);
191  }
192  }
193 
195  {
196  if(operate_ && surface_.get()) {
197  SDL_SetClipRect(surface_, &rect_);
198  }
199  }
200 
201 private:
203  SDL_Rect rect_;
204  const bool operate_;
205 };
pixel_t * pixels() const
Definition: surface.hpp:164
SDL_Surface * get() const
Definition: surface.hpp:94
void free_surface()
Definition: surface.cpp:89
#define a
Definition: video.hpp:31
surface_locker(T &surf)
Definition: surface.hpp:150
const SDL_Rect & area() const
Definition: surface.hpp:130
static void add_surface_ref(SDL_Surface *surf)
Definition: surface.hpp:99
#define h
surface(const surface &s)
Definition: surface.hpp:35
void assign_surface_internal(SDL_Surface *surf)
Definition: surface.cpp:81
surface & operator=(surface &&s) noexcept
Definition: surface.hpp:56
surface clone() const
Makes a copy of this surface.
Definition: surface.cpp:75
surface surface_
Definition: surface.hpp:135
#define b
surface()
Definition: surface.hpp:27
surface(surface &&s) noexcept
Definition: surface.hpp:40
surface & operator=(const surface &s)
Definition: surface.hpp:50
surface & make_neutral()
Converts this surface to a neutral format if it is not already.
Definition: surface.cpp:61
SDL_Rect rect_
Definition: surface.hpp:134
utils::const_clone_t< uint32_t, T > pixel_t
Definition: surface.hpp:147
SDL_Rect rect_
Definition: surface.hpp:203
const bool operate_
Definition: surface.hpp:204
bool operator<(const surface &a, const surface &b)
Definition: surface.cpp:170
std::ostream & operator<<(std::ostream &stream, const surface &surf)
Definition: surface.cpp:175
class CVideo * target_
Definition: surface.hpp:133
static map_location::DIRECTION s
SDL_Surface * surface_
Definition: surface.hpp:110
Helper class for pinning SDL surfaces into memory.
Definition: surface.hpp:144
SDL_Surface * operator->() const
Definition: surface.hpp:96
int w
surface surface_
Definition: surface.hpp:202
bool is_neutral() const
Check that the surface is neutral bpp 32.
Definition: surface.cpp:52
void clear_without_free()
Definition: surface.hpp:65
clip_rect_setter(const surface &surf, const SDL_Rect *r, bool operate=true)
Definition: surface.hpp:177
typename const_clone< D, S >::type const_clone_t
Definition: const_clone.hpp:59
static const SDL_PixelFormat neutral_pixel_format
Definition: surface.hpp:112
~surface()
Definition: surface.hpp:45