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