GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/resources/image/subimage.cpp Lines: 32 64 50.0 %
Date: 2021-03-17 Branches: 6 20 30.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2004-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2019  The ManaPlus Developers
6
 *  Copyright (C) 2019-2021  Andrei Karas
7
 *
8
 *  This file is part of The ManaPlus Client.
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
#include "resources/image/subimage.h"
25
26
#include "utils/cast.h"
27
28
#ifdef DEBUG_IMAGES
29
#include "logger.h"
30
#endif  // DEBUG_IMAGES
31
32
#include "debug.h"
33
34
#ifdef USE_SDL2
35
SubImage::SubImage(Image *const parent,
36
                   SDL_Texture *const image,
37
                   const int x, const int y,
38
                   const int width, const int height) :
39
    Image(image, width, height),
40
    mInternalBounds(),
41
    mParent(parent)
42
{
43
    if (mParent)
44
    {
45
        mParent->incRef();
46
        mParent->SDLTerminateAlphaCache();
47
        mHasAlphaChannel = mParent->hasAlphaChannel();
48
        mIsAlphaVisible = mHasAlphaChannel;
49
        mAlphaChannel = mParent->SDLgetAlphaChannel();
50
        mSource = parent->mIdPath;
51
#ifdef DEBUG_IMAGES
52
        logger->log("set name2 %p, %s",
53
            static_cast<void*>(this),
54
            mSource.c_str());
55
#endif  // DEBUG_IMAGES
56
#ifdef DEBUG_BIND_TEXTURE
57
        mIdPath = parent->mIdPath;
58
#endif  // DEBUG_BIND_TEXTURE
59
    }
60
    else
61
    {
62
        mHasAlphaChannel = false;
63
        mIsAlphaVisible = false;
64
        mAlphaChannel = nullptr;
65
    }
66
67
    // Set up the rectangle.
68
    mBounds.x = CAST_S16(x);
69
    mBounds.y = CAST_S16(y);
70
    mBounds.w = CAST_U16(width);
71
    mBounds.h = CAST_U16(height);
72
    if (mParent)
73
    {
74
        mInternalBounds.x = mParent->mBounds.x;
75
        mInternalBounds.y = mParent->mBounds.y;
76
        mInternalBounds.w = mParent->mBounds.w;
77
        mInternalBounds.h = mParent->mBounds.h;
78
    }
79
    else
80
    {
81
        mInternalBounds.x = 0;
82
        mInternalBounds.y = 0;
83
        mInternalBounds.w = 1;
84
        mInternalBounds.h = 1;
85
    }
86
    mUseAlphaCache = false;
87
}
88
#endif  // USE_SDL2
89
90
29006
SubImage::SubImage(Image *const parent,
91
                   SDL_Surface *const image,
92
                   const int x, const int y,
93
29006
                   const int width, const int height) :
94
    Image(image, false, nullptr),
95
    mInternalBounds(),
96
29006
    mParent(parent)
97
{
98
29006
    if (mParent != nullptr)
99
    {
100
29006
        mParent->incRef();
101
29006
        mParent->SDLTerminateAlphaCache();
102
29006
        mHasAlphaChannel = mParent->hasAlphaChannel();
103
29006
        mIsAlphaVisible = mHasAlphaChannel;
104
58012
        mAlphaChannel = mParent->SDLgetAlphaChannel();
105
29006
        mSource = parent->mIdPath;
106
#ifdef DEBUG_IMAGES
107
        logger->log("set name2 %p, %s", static_cast<void*>(this),
108
            mSource.c_str());
109
#endif  // DEBUG_IMAGES
110
#ifdef DEBUG_BIND_TEXTURE
111
        mIdPath = parent->mIdPath;
112
#endif  // DEBUG_BIND_TEXTURE
113
    }
114
    else
115
    {
116
        mHasAlphaChannel = false;
117
        mIsAlphaVisible = false;
118
        mAlphaChannel = nullptr;
119
    }
120
121
    // Set up the rectangle.
122
29006
    mBounds.x = CAST_S16(x);
123
29006
    mBounds.y = CAST_S16(y);
124
29006
    mBounds.w = CAST_U16(width);
125
29006
    mBounds.h = CAST_U16(height);
126
29006
    if (mParent != nullptr)
127
    {
128
29006
        mInternalBounds.x = mParent->mBounds.x;
129
29006
        mInternalBounds.y = mParent->mBounds.y;
130
29006
        mInternalBounds.w = mParent->mBounds.w;
131
29006
        mInternalBounds.h = mParent->mBounds.h;
132
    }
133
    else
134
    {
135
        mInternalBounds.x = 0;
136
        mInternalBounds.y = 0;
137
        mInternalBounds.w = 1;
138
        mInternalBounds.h = 1;
139
    }
140
29006
    mUseAlphaCache = false;
141
29006
}
142
143
#ifdef USE_OPENGL
144
SubImage::SubImage(Image *const parent,
145
                   const GLuint image,
146
                   const int x, const int y,
147
                   const int width, const int height,
148
                   const int texWidth, const int texHeight) :
149
    Image(image, width, height, texWidth, texHeight),
150
    mInternalBounds(),
151
    mParent(parent)
152
{
153
    if (mParent != nullptr)
154
        mParent->incRef();
155
156
    // Set up the rectangle.
157
    mBounds.x = CAST_S16(x);
158
    mBounds.y = CAST_S16(y);
159
    mBounds.w = CAST_U16(width);
160
    mBounds.h = CAST_U16(height);
161
    if (mParent != nullptr)
162
    {
163
        mInternalBounds.x = mParent->mBounds.x;
164
        mInternalBounds.y = mParent->mBounds.y;
165
        mInternalBounds.w = mParent->mBounds.w;
166
        mInternalBounds.h = mParent->mBounds.h;
167
        mSource = parent->mIdPath;
168
#ifdef DEBUG_IMAGES
169
        logger->log("set name2 %p, %s", static_cast<void*>(this),
170
            mSource.c_str());
171
#endif  // DEBUG_IMAGES
172
#ifdef DEBUG_BIND_TEXTURE
173
        mIdPath = parent->mIdPath;
174
#endif  // DEBUG_BIND_TEXTURE
175
    }
176
    else
177
    {
178
        mInternalBounds.x = 0;
179
        mInternalBounds.y = 0;
180
        mInternalBounds.w = 1;
181
        mInternalBounds.h = 1;
182
    }
183
    mIsAlphaVisible = mHasAlphaChannel;
184
}
185
#endif  // USE_OPENGL
186
187
87018
SubImage::~SubImage()
188
{
189
#ifdef DEBUG_IMAGES
190
    logger->log("delete subimage: %p", static_cast<void*>(this));
191
    logger->log("  %s, %s", mIdPath.c_str(), mSource.c_str());
192
#endif  // DEBUG_IMAGES
193
    // Avoid destruction of the image
194
29006
    mSDLSurface = nullptr;
195
    // Avoid possible destruction of its alpha channel
196
29006
    mAlphaChannel = nullptr;
197
#ifdef USE_SDL2
198
    // Avoid destruction of texture
199
    mTexture = nullptr;
200
#endif  // USE_SDL2
201
#ifdef USE_OPENGL
202
29006
    mGLImage = 0;
203
#endif  // USE_OPENGL
204
29006
    if (mParent != nullptr)
205
    {
206
#ifdef DEBUG_IMAGES
207
        logger->log("decref from subminage: %p, parent: %p",
208
            static_cast<void*>(this), static_cast<void*>(mParent));
209
#endif  // DEBUG_IMAGES
210
211
29006
        mParent->decRef();
212
29006
        mParent = nullptr;
213
    }
214
58012
}
215
216
Image *SubImage::getSubImage(const int x, const int y,
217
                             const int w, const int h)
218
{
219
    if (mParent != nullptr)
220
        return mParent->getSubImage(mBounds.x + x, mBounds.y + y, w, h);
221
    return nullptr;
222
}
223
224
#ifdef USE_OPENGL
225
6636
void SubImage::decRef()
226
{
227
6636
    Resource::decRef();
228
6636
}
229
#endif  // USE_OPENGL
230
231
int SubImage::calcMemoryLocal() const
232
{
233
    return static_cast<int>(sizeof(SubImage) +
234
        sizeof(std::map<float, SDL_Surface*>)) +
235
        Image::calcMemoryLocal();
236
}