The Battle for Wesnoth  1.19.11+dev
surface.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2025
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 #include "sdl/surface.hpp"
16 
17 #include "color.hpp"
18 #include "sdl/rect.hpp"
19 
20 #include <utility>
21 
22 namespace
23 {
24 void add_refcount(surface& surf)
25 {
26  if(surf) {
27  ++surf->refcount;
28  }
29 }
30 
31 void free_surface(surface& surf)
32 {
33  if(surf) {
34  SDL_FreeSurface(surf);
35  }
36 }
37 
38 void make_neutral(surface& surf)
39 {
40  if(surf && surf->format->format != SDL_PIXELFORMAT_ARGB8888) {
41  surf = surf.clone();
42  }
43 }
44 
45 } // namespace
46 
47 surface::surface(SDL_Surface* surf)
48  : surface_(surf)
49 {
50  make_neutral(*this); // EXTREMELY IMPORTANT!
51 }
52 
53 surface::surface(int w, int h)
54  : surface_(nullptr)
55 {
56  if (w < 0 || h < 0) {
57  throw std::invalid_argument("Creating surface with negative dimensions");
58  }
59 
60  surface_ = SDL_CreateRGBSurfaceWithFormat(0, w, h, 32, SDL_PIXELFORMAT_ARGB8888);
61 }
62 
64  : surface_(s)
65 {
66  add_refcount(*this);
67 }
68 
70  : surface_(std::exchange(s.surface_, nullptr))
71 {
72 }
73 
75 {
76  free_surface(*this);
77 }
78 
80 {
81  if(this != &s) {
82  free_surface(*this);
83  surface_ = s;
84  add_refcount(*this);
85  }
86 
87  return *this;
88 }
89 
91 {
92  free_surface(*this);
93  surface_ = std::exchange(s.surface_, nullptr);
94  return *this;
95 }
96 
98 {
99  // Use SDL_ConvertSurfaceFormat to make a copy
100  return surface(SDL_ConvertSurfaceFormat(surface_, SDL_PIXELFORMAT_ARGB8888, 0));
101 }
102 
103 std::size_t surface::area() const
104 {
105  return surface_ ? surface_->w * surface_->h : 0;
106 }
107 
108 std::ostream& operator<<(std::ostream& stream, const surface& surf)
109 {
110  if(!surf.get()) {
111  stream << "<null surface>";
112  } else if(!surf->format) {
113  stream << "<invalid surface>";
114  } else {
115  stream << "{ " << surf->w << 'x' << surf->h << '@'
116  << unsigned(surf->format->BitsPerPixel) << "bpp"
117  << (surf->format->palette ? " indexed" : "")
118  << " clip_rect=[" << surf->clip_rect
119  << "] refcount=" << surf->refcount
120  << " }";
121  }
122 
123  return stream;
124 }
~surface()
Definition: surface.cpp:74
surface()=default
surface clone() const
Creates a new, duplicate surface in memory using the 'neutral' pixel format.
Definition: surface.cpp:97
SDL_Surface * surface_
Definition: surface.hpp:59
SDL_Surface * get() const
Definition: surface.hpp:55
std::size_t area() const
Total area of the surface in square pixels.
Definition: surface.cpp:103
surface & operator=(const surface &s)
Definition: surface.cpp:79
int w
Contains the SDL_Rect helper code.
surface surf
Image.
std::ostream & operator<<(std::ostream &stream, const surface &surf)
Definition: surface.cpp:108
static map_location::direction s
#define h