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