This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_blendfillrect.c
347 lines (313 loc) · 9.3 KB
1
2
/*
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2010 Sam Lantinga
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#include "SDL_video.h"
25
#include "SDL_draw.h"
26
27
static int
28
29
SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
30
{
31
32
33
34
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
35
FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
36
37
break;
case SDL_BLENDMODE_ADD:
38
FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
39
40
break;
case SDL_BLENDMODE_MOD:
41
FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
42
43
break;
default:
44
FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
45
break;
46
}
47
48
return 0;
}
49
50
static int
51
52
SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
53
54
55
56
57
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
58
FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
59
60
break;
case SDL_BLENDMODE_ADD:
61
FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
62
63
break;
case SDL_BLENDMODE_MOD:
64
FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
65
66
break;
default:
67
FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
68
break;
69
}
70
71
return 0;
}
72
73
static int
74
75
SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
76
77
78
79
80
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
81
FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888);
82
83
break;
case SDL_BLENDMODE_ADD:
84
FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888);
85
86
break;
case SDL_BLENDMODE_MOD:
87
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
88
89
break;
default:
90
FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
91
break;
92
}
93
94
95
return 0;
}
96
static int
97
98
SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
99
100
101
102
103
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
104
FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
105
106
break;
case SDL_BLENDMODE_ADD:
107
FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
108
109
break;
case SDL_BLENDMODE_MOD:
110
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
111
112
break;
default:
113
FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
114
115
116
117
118
break;
}
return 0;
}
119
static int
120
121
SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
122
123
124
125
126
127
{
SDL_PixelFormat *fmt = dst->format;
unsigned inva = 0xff - a;
switch (fmt->BytesPerPixel) {
case 2:
128
129
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
130
FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
131
132
break;
case SDL_BLENDMODE_ADD:
133
FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
134
135
break;
case SDL_BLENDMODE_MOD:
136
FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
137
138
break;
default:
139
FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
140
141
break;
}
142
143
return 0;
case 4:
144
145
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
146
FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
147
148
break;
case SDL_BLENDMODE_ADD:
149
FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
150
151
break;
case SDL_BLENDMODE_MOD:
152
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
153
154
break;
default:
155
FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
156
157
break;
}
158
159
160
161
162
163
164
165
return 0;
default:
SDL_Unsupported();
return -1;
}
}
static int
166
167
SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
168
169
170
171
172
173
{
SDL_PixelFormat *fmt = dst->format;
unsigned inva = 0xff - a;
switch (fmt->BytesPerPixel) {
case 4:
174
175
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
176
FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
177
178
break;
case SDL_BLENDMODE_ADD:
179
FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
180
181
break;
case SDL_BLENDMODE_MOD:
182
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
183
184
break;
default:
185
FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
186
187
break;
}
188
return 0;
189
190
191
192
default:
SDL_Unsupported();
return -1;
}
193
194
195
}
int
196
197
SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
198
{
199
200
201
202
203
204
SDL_Rect clipped;
if (!dst) {
SDL_SetError("Passed NULL destination surface");
return -1;
}
205
206
/* This function doesn't work on surfaces < 8 bpp */
207
if (dst->format->BitsPerPixel < 8) {
208
SDL_SetError("SDL_BlendFillRect(): Unsupported surface format");
209
return -1;
210
211
}
212
213
/* If 'rect' == NULL, then fill the whole surface */
if (rect) {
214
/* Perform clipping */
215
216
if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
return 0;
217
}
218
rect = &clipped;
219
} else {
220
rect = &dst->clip_rect;
221
222
}
223
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
224
225
226
227
228
r = DRAW_MUL(r, a);
g = DRAW_MUL(g, a);
b = DRAW_MUL(b, a);
}
229
switch (dst->format->BitsPerPixel) {
230
case 15:
231
switch (dst->format->Rmask) {
232
case 0x7C00:
233
return SDL_BlendFillRect_RGB555(dst, rect, blendMode, r, g, b, a);
234
235
236
}
break;
case 16:
237
switch (dst->format->Rmask) {
238
case 0xF800:
239
return SDL_BlendFillRect_RGB565(dst, rect, blendMode, r, g, b, a);
240
241
242
}
break;
case 32:
243
switch (dst->format->Rmask) {
244
case 0x00FF0000:
245
if (!dst->format->Amask) {
246
return SDL_BlendFillRect_RGB888(dst, rect, blendMode, r, g, b, a);
247
} else {
248
return SDL_BlendFillRect_ARGB8888(dst, rect, blendMode, r, g, b, a);
249
250
251
}
break;
}
252
break;
253
254
255
256
default:
break;
}
257
if (!dst->format->Amask) {
258
return SDL_BlendFillRect_RGB(dst, rect, blendMode, r, g, b, a);
259
} else {
260
return SDL_BlendFillRect_RGBA(dst, rect, blendMode, r, g, b, a);
261
262
263
264
}
}
int
265
266
SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
267
268
269
270
271
272
273
274
275
276
277
278
279
280
{
SDL_Rect clipped;
int i;
int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
int status = 0;
if (!dst) {
SDL_SetError("Passed NULL destination surface");
return -1;
}
/* This function doesn't work on surfaces < 8 bpp */
if (dst->format->BitsPerPixel < 8) {
281
SDL_SetError("SDL_BlendFillRects(): Unsupported surface format");
282
283
284
285
286
287
288
289
290
291
292
293
294
295
return -1;
}
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(r, a);
g = DRAW_MUL(g, a);
b = DRAW_MUL(b, a);
}
/* FIXME: Does this function pointer slow things down significantly? */
switch (dst->format->BitsPerPixel) {
case 15:
switch (dst->format->Rmask) {
case 0x7C00:
296
func = SDL_BlendFillRect_RGB555;
297
298
299
300
301
}
break;
case 16:
switch (dst->format->Rmask) {
case 0xF800:
302
func = SDL_BlendFillRect_RGB565;
303
304
305
306
307
308
}
break;
case 32:
switch (dst->format->Rmask) {
case 0x00FF0000:
if (!dst->format->Amask) {
309
func = SDL_BlendFillRect_RGB888;
310
} else {
311
func = SDL_BlendFillRect_ARGB8888;
312
313
314
315
316
317
318
319
320
321
}
break;
}
break;
default:
break;
}
if (!func) {
if (!dst->format->Amask) {
322
func = SDL_BlendFillRect_RGB;
323
} else {
324
func = SDL_BlendFillRect_RGBA;
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
}
}
for (i = 0; i < count; ++i) {
const SDL_Rect * rect = rects[i];
/* If 'rect' == NULL, then fill the whole surface */
if (rect) {
/* Perform clipping */
if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
continue;
}
rect = &clipped;
} else {
rect = &dst->clip_rect;
}
status = func(dst, rect, blendMode, r, g, b, a);
343
}
344
return status;
345
346
347
}
/* vi: set ts=4 sw=4 expandtab: */