Mercurial > sdl-ios-xcode
comparison src/video/SDL_blendline.c @ 3596:f638ded38b8a
Added SDL_RenderClear() as a fast method of clearing the screen to the drawing color.
Renamed SDL_RenderPoint() and SDL_RenderLine() to SDL_RenderDrawPoint() and SDL_RenderDrawLine().
Added API for rectangle drawing (as opposed to filling)
Added placeholder API functions for circles and ellipses ... I'm not sure whether these will stay.
Optimized software line drawing quite a bit.
Added support for Wu's anti-aliased line drawing, currently disabled by default.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 23 Dec 2009 01:55:00 +0000 |
parents | c8bed77b0386 |
children | f7b03b6838cb |
comparison
equal
deleted
inserted
replaced
3595:b7c6828d4039 | 3596:f638ded38b8a |
---|---|
21 */ | 21 */ |
22 #include "SDL_config.h" | 22 #include "SDL_config.h" |
23 | 23 |
24 #include "SDL_draw.h" | 24 #include "SDL_draw.h" |
25 | 25 |
26 static int | 26 |
27 static void | |
28 SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2, | |
29 int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, | |
30 SDL_bool draw_end) | |
31 { | |
32 const SDL_PixelFormat *fmt = dst->format; | |
33 unsigned r, g, b, a, inva; | |
34 | |
35 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { | |
36 r = DRAW_MUL(_r, _a); | |
37 g = DRAW_MUL(_g, _a); | |
38 b = DRAW_MUL(_b, _a); | |
39 a = _a; | |
40 } else { | |
41 r = _r; | |
42 g = _g; | |
43 b = _b; | |
44 a = _a; | |
45 } | |
46 inva = (a ^ 0xff); | |
47 | |
48 if (y1 == y2) { | |
49 switch (blendMode) { | |
50 case SDL_BLENDMODE_BLEND: | |
51 HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end); | |
52 break; | |
53 case SDL_BLENDMODE_ADD: | |
54 HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end); | |
55 break; | |
56 case SDL_BLENDMODE_MOD: | |
57 HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end); | |
58 break; | |
59 default: | |
60 HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end); | |
61 break; | |
62 } | |
63 } else if (x1 == x2) { | |
64 switch (blendMode) { | |
65 case SDL_BLENDMODE_BLEND: | |
66 VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end); | |
67 break; | |
68 case SDL_BLENDMODE_ADD: | |
69 VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end); | |
70 break; | |
71 case SDL_BLENDMODE_MOD: | |
72 VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end); | |
73 break; | |
74 default: | |
75 VLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end); | |
76 break; | |
77 } | |
78 } else if (ABS(x1 - x2) == ABS(y1 - y2)) { | |
79 switch (blendMode) { | |
80 case SDL_BLENDMODE_BLEND: | |
81 DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end); | |
82 break; | |
83 case SDL_BLENDMODE_ADD: | |
84 DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end); | |
85 break; | |
86 case SDL_BLENDMODE_MOD: | |
87 DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end); | |
88 break; | |
89 default: | |
90 DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end); | |
91 break; | |
92 } | |
93 } else { | |
94 switch (blendMode) { | |
95 case SDL_BLENDMODE_BLEND: | |
96 AALINE(x1, y1, x2, y2, | |
97 DRAW_SETPIXELXY2_BLEND_RGB, DRAW_SETPIXELXY2_BLEND_RGB, | |
98 draw_end); | |
99 break; | |
100 case SDL_BLENDMODE_ADD: | |
101 AALINE(x1, y1, x2, y2, | |
102 DRAW_SETPIXELXY2_ADD_RGB, DRAW_SETPIXELXY2_ADD_RGB, | |
103 draw_end); | |
104 break; | |
105 case SDL_BLENDMODE_MOD: | |
106 AALINE(x1, y1, x2, y2, | |
107 DRAW_SETPIXELXY2_MOD_RGB, DRAW_SETPIXELXY2_MOD_RGB, | |
108 draw_end); | |
109 break; | |
110 default: | |
111 AALINE(x1, y1, x2, y2, | |
112 DRAW_SETPIXELXY2_RGB, DRAW_SETPIXELXY2_BLEND_RGB, | |
113 draw_end); | |
114 break; | |
115 } | |
116 } | |
117 } | |
118 | |
119 static void | |
27 SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2, | 120 SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2, |
28 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, | 121 int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, |
29 SDL_bool draw_end) | 122 SDL_bool draw_end) |
30 { | 123 { |
31 unsigned inva = 0xff - a; | 124 const SDL_PixelFormat *fmt = dst->format; |
32 | 125 unsigned r, g, b, a, inva; |
33 switch (blendMode) { | 126 |
34 case SDL_BLENDMODE_BLEND: | 127 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { |
35 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB555, draw_end); | 128 r = DRAW_MUL(_r, _a); |
36 break; | 129 g = DRAW_MUL(_g, _a); |
37 case SDL_BLENDMODE_ADD: | 130 b = DRAW_MUL(_b, _a); |
38 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB555, draw_end); | 131 a = _a; |
39 break; | 132 } else { |
40 case SDL_BLENDMODE_MOD: | 133 r = _r; |
41 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB555, draw_end); | 134 g = _g; |
42 break; | 135 b = _b; |
43 default: | 136 a = _a; |
44 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB555, draw_end); | 137 } |
45 break; | 138 inva = (a ^ 0xff); |
46 } | 139 |
47 return 0; | 140 if (y1 == y2) { |
48 } | 141 switch (blendMode) { |
49 | 142 case SDL_BLENDMODE_BLEND: |
50 static int | 143 HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end); |
144 break; | |
145 case SDL_BLENDMODE_ADD: | |
146 HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end); | |
147 break; | |
148 case SDL_BLENDMODE_MOD: | |
149 HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end); | |
150 break; | |
151 default: | |
152 HLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end); | |
153 break; | |
154 } | |
155 } else if (x1 == x2) { | |
156 switch (blendMode) { | |
157 case SDL_BLENDMODE_BLEND: | |
158 VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end); | |
159 break; | |
160 case SDL_BLENDMODE_ADD: | |
161 VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end); | |
162 break; | |
163 case SDL_BLENDMODE_MOD: | |
164 VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end); | |
165 break; | |
166 default: | |
167 VLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end); | |
168 break; | |
169 } | |
170 } else if (ABS(x1 - x2) == ABS(y1 - y2)) { | |
171 switch (blendMode) { | |
172 case SDL_BLENDMODE_BLEND: | |
173 DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end); | |
174 break; | |
175 case SDL_BLENDMODE_ADD: | |
176 DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end); | |
177 break; | |
178 case SDL_BLENDMODE_MOD: | |
179 DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end); | |
180 break; | |
181 default: | |
182 DLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end); | |
183 break; | |
184 } | |
185 } else { | |
186 switch (blendMode) { | |
187 case SDL_BLENDMODE_BLEND: | |
188 AALINE(x1, y1, x2, y2, | |
189 DRAW_SETPIXELXY_BLEND_RGB555, DRAW_SETPIXELXY_BLEND_RGB555, | |
190 draw_end); | |
191 break; | |
192 case SDL_BLENDMODE_ADD: | |
193 AALINE(x1, y1, x2, y2, | |
194 DRAW_SETPIXELXY_ADD_RGB555, DRAW_SETPIXELXY_ADD_RGB555, | |
195 draw_end); | |
196 break; | |
197 case SDL_BLENDMODE_MOD: | |
198 AALINE(x1, y1, x2, y2, | |
199 DRAW_SETPIXELXY_MOD_RGB555, DRAW_SETPIXELXY_MOD_RGB555, | |
200 draw_end); | |
201 break; | |
202 default: | |
203 AALINE(x1, y1, x2, y2, | |
204 DRAW_SETPIXELXY_RGB555, DRAW_SETPIXELXY_BLEND_RGB555, | |
205 draw_end); | |
206 break; | |
207 } | |
208 } | |
209 } | |
210 | |
211 static void | |
51 SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2, | 212 SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2, |
52 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, | 213 int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, |
53 SDL_bool draw_end) | 214 SDL_bool draw_end) |
54 { | 215 { |
55 unsigned inva = 0xff - a; | 216 const SDL_PixelFormat *fmt = dst->format; |
56 | 217 unsigned r, g, b, a, inva; |
57 switch (blendMode) { | 218 |
58 case SDL_BLENDMODE_BLEND: | 219 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { |
59 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB565, draw_end); | 220 r = DRAW_MUL(_r, _a); |
60 break; | 221 g = DRAW_MUL(_g, _a); |
61 case SDL_BLENDMODE_ADD: | 222 b = DRAW_MUL(_b, _a); |
62 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB565, draw_end); | 223 a = _a; |
63 break; | 224 } else { |
64 case SDL_BLENDMODE_MOD: | 225 r = _r; |
65 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB565, draw_end); | 226 g = _g; |
66 break; | 227 b = _b; |
67 default: | 228 a = _a; |
68 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB565, draw_end); | 229 } |
69 break; | 230 inva = (a ^ 0xff); |
70 } | 231 |
71 return 0; | 232 if (y1 == y2) { |
72 } | 233 switch (blendMode) { |
73 | 234 case SDL_BLENDMODE_BLEND: |
74 static int | 235 HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end); |
236 break; | |
237 case SDL_BLENDMODE_ADD: | |
238 HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end); | |
239 break; | |
240 case SDL_BLENDMODE_MOD: | |
241 HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end); | |
242 break; | |
243 default: | |
244 HLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end); | |
245 break; | |
246 } | |
247 } else if (x1 == x2) { | |
248 switch (blendMode) { | |
249 case SDL_BLENDMODE_BLEND: | |
250 VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end); | |
251 break; | |
252 case SDL_BLENDMODE_ADD: | |
253 VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end); | |
254 break; | |
255 case SDL_BLENDMODE_MOD: | |
256 VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end); | |
257 break; | |
258 default: | |
259 VLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end); | |
260 break; | |
261 } | |
262 } else if (ABS(x1 - x2) == ABS(y1 - y2)) { | |
263 switch (blendMode) { | |
264 case SDL_BLENDMODE_BLEND: | |
265 DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end); | |
266 break; | |
267 case SDL_BLENDMODE_ADD: | |
268 DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end); | |
269 break; | |
270 case SDL_BLENDMODE_MOD: | |
271 DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end); | |
272 break; | |
273 default: | |
274 DLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end); | |
275 break; | |
276 } | |
277 } else { | |
278 switch (blendMode) { | |
279 case SDL_BLENDMODE_BLEND: | |
280 AALINE(x1, y1, x2, y2, | |
281 DRAW_SETPIXELXY_BLEND_RGB565, DRAW_SETPIXELXY_BLEND_RGB565, | |
282 draw_end); | |
283 break; | |
284 case SDL_BLENDMODE_ADD: | |
285 AALINE(x1, y1, x2, y2, | |
286 DRAW_SETPIXELXY_ADD_RGB565, DRAW_SETPIXELXY_ADD_RGB565, | |
287 draw_end); | |
288 break; | |
289 case SDL_BLENDMODE_MOD: | |
290 AALINE(x1, y1, x2, y2, | |
291 DRAW_SETPIXELXY_MOD_RGB565, DRAW_SETPIXELXY_MOD_RGB565, | |
292 draw_end); | |
293 break; | |
294 default: | |
295 AALINE(x1, y1, x2, y2, | |
296 DRAW_SETPIXELXY_RGB565, DRAW_SETPIXELXY_BLEND_RGB565, | |
297 draw_end); | |
298 break; | |
299 } | |
300 } | |
301 } | |
302 | |
303 static void | |
304 SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2, | |
305 int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, | |
306 SDL_bool draw_end) | |
307 { | |
308 const SDL_PixelFormat *fmt = dst->format; | |
309 unsigned r, g, b, a, inva; | |
310 | |
311 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { | |
312 r = DRAW_MUL(_r, _a); | |
313 g = DRAW_MUL(_g, _a); | |
314 b = DRAW_MUL(_b, _a); | |
315 a = _a; | |
316 } else { | |
317 r = _r; | |
318 g = _g; | |
319 b = _b; | |
320 a = _a; | |
321 } | |
322 inva = (a ^ 0xff); | |
323 | |
324 if (y1 == y2) { | |
325 switch (blendMode) { | |
326 case SDL_BLENDMODE_BLEND: | |
327 HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end); | |
328 break; | |
329 case SDL_BLENDMODE_ADD: | |
330 HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end); | |
331 break; | |
332 case SDL_BLENDMODE_MOD: | |
333 HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end); | |
334 break; | |
335 default: | |
336 HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end); | |
337 break; | |
338 } | |
339 } else if (x1 == x2) { | |
340 switch (blendMode) { | |
341 case SDL_BLENDMODE_BLEND: | |
342 VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end); | |
343 break; | |
344 case SDL_BLENDMODE_ADD: | |
345 VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end); | |
346 break; | |
347 case SDL_BLENDMODE_MOD: | |
348 VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end); | |
349 break; | |
350 default: | |
351 VLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end); | |
352 break; | |
353 } | |
354 } else if (ABS(x1 - x2) == ABS(y1 - y2)) { | |
355 switch (blendMode) { | |
356 case SDL_BLENDMODE_BLEND: | |
357 DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end); | |
358 break; | |
359 case SDL_BLENDMODE_ADD: | |
360 DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end); | |
361 break; | |
362 case SDL_BLENDMODE_MOD: | |
363 DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end); | |
364 break; | |
365 default: | |
366 DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end); | |
367 break; | |
368 } | |
369 } else { | |
370 switch (blendMode) { | |
371 case SDL_BLENDMODE_BLEND: | |
372 AALINE(x1, y1, x2, y2, | |
373 DRAW_SETPIXELXY4_BLEND_RGB, DRAW_SETPIXELXY4_BLEND_RGB, | |
374 draw_end); | |
375 break; | |
376 case SDL_BLENDMODE_ADD: | |
377 AALINE(x1, y1, x2, y2, | |
378 DRAW_SETPIXELXY4_ADD_RGB, DRAW_SETPIXELXY4_ADD_RGB, | |
379 draw_end); | |
380 break; | |
381 case SDL_BLENDMODE_MOD: | |
382 AALINE(x1, y1, x2, y2, | |
383 DRAW_SETPIXELXY4_MOD_RGB, DRAW_SETPIXELXY4_MOD_RGB, | |
384 draw_end); | |
385 break; | |
386 default: | |
387 AALINE(x1, y1, x2, y2, | |
388 DRAW_SETPIXELXY4_RGB, DRAW_SETPIXELXY4_BLEND_RGB, | |
389 draw_end); | |
390 break; | |
391 } | |
392 } | |
393 } | |
394 | |
395 static void | |
396 SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2, | |
397 int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, | |
398 SDL_bool draw_end) | |
399 { | |
400 const SDL_PixelFormat *fmt = dst->format; | |
401 unsigned r, g, b, a, inva; | |
402 | |
403 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { | |
404 r = DRAW_MUL(_r, _a); | |
405 g = DRAW_MUL(_g, _a); | |
406 b = DRAW_MUL(_b, _a); | |
407 a = _a; | |
408 } else { | |
409 r = _r; | |
410 g = _g; | |
411 b = _b; | |
412 a = _a; | |
413 } | |
414 inva = (a ^ 0xff); | |
415 | |
416 if (y1 == y2) { | |
417 switch (blendMode) { | |
418 case SDL_BLENDMODE_BLEND: | |
419 HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end); | |
420 break; | |
421 case SDL_BLENDMODE_ADD: | |
422 HLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end); | |
423 break; | |
424 case SDL_BLENDMODE_MOD: | |
425 HLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end); | |
426 break; | |
427 default: | |
428 HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end); | |
429 break; | |
430 } | |
431 } else if (x1 == x2) { | |
432 switch (blendMode) { | |
433 case SDL_BLENDMODE_BLEND: | |
434 VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end); | |
435 break; | |
436 case SDL_BLENDMODE_ADD: | |
437 VLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end); | |
438 break; | |
439 case SDL_BLENDMODE_MOD: | |
440 VLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end); | |
441 break; | |
442 default: | |
443 VLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end); | |
444 break; | |
445 } | |
446 } else if (ABS(x1 - x2) == ABS(y1 - y2)) { | |
447 switch (blendMode) { | |
448 case SDL_BLENDMODE_BLEND: | |
449 DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end); | |
450 break; | |
451 case SDL_BLENDMODE_ADD: | |
452 DLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end); | |
453 break; | |
454 case SDL_BLENDMODE_MOD: | |
455 DLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end); | |
456 break; | |
457 default: | |
458 DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end); | |
459 break; | |
460 } | |
461 } else { | |
462 switch (blendMode) { | |
463 case SDL_BLENDMODE_BLEND: | |
464 AALINE(x1, y1, x2, y2, | |
465 DRAW_SETPIXELXY4_BLEND_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA, | |
466 draw_end); | |
467 break; | |
468 case SDL_BLENDMODE_ADD: | |
469 AALINE(x1, y1, x2, y2, | |
470 DRAW_SETPIXELXY4_ADD_RGBA, DRAW_SETPIXELXY4_ADD_RGBA, | |
471 draw_end); | |
472 break; | |
473 case SDL_BLENDMODE_MOD: | |
474 AALINE(x1, y1, x2, y2, | |
475 DRAW_SETPIXELXY4_MOD_RGBA, DRAW_SETPIXELXY4_MOD_RGBA, | |
476 draw_end); | |
477 break; | |
478 default: | |
479 AALINE(x1, y1, x2, y2, | |
480 DRAW_SETPIXELXY4_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA, | |
481 draw_end); | |
482 break; | |
483 } | |
484 } | |
485 } | |
486 | |
487 static void | |
75 SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2, | 488 SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2, |
76 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, | 489 int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, |
77 SDL_bool draw_end) | 490 SDL_bool draw_end) |
78 { | 491 { |
79 unsigned inva = 0xff - a; | 492 const SDL_PixelFormat *fmt = dst->format; |
80 | 493 unsigned r, g, b, a, inva; |
81 switch (blendMode) { | 494 |
82 case SDL_BLENDMODE_BLEND: | 495 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { |
83 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB888, draw_end); | 496 r = DRAW_MUL(_r, _a); |
84 break; | 497 g = DRAW_MUL(_g, _a); |
85 case SDL_BLENDMODE_ADD: | 498 b = DRAW_MUL(_b, _a); |
86 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB888, draw_end); | 499 a = _a; |
87 break; | 500 } else { |
88 case SDL_BLENDMODE_MOD: | 501 r = _r; |
89 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB888, draw_end); | 502 g = _g; |
90 break; | 503 b = _b; |
91 default: | 504 a = _a; |
92 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB888, draw_end); | 505 } |
93 break; | 506 inva = (a ^ 0xff); |
94 } | 507 |
95 return 0; | 508 if (y1 == y2) { |
96 } | 509 switch (blendMode) { |
97 | 510 case SDL_BLENDMODE_BLEND: |
98 static int | 511 HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end); |
512 break; | |
513 case SDL_BLENDMODE_ADD: | |
514 HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end); | |
515 break; | |
516 case SDL_BLENDMODE_MOD: | |
517 HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end); | |
518 break; | |
519 default: | |
520 HLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end); | |
521 break; | |
522 } | |
523 } else if (x1 == x2) { | |
524 switch (blendMode) { | |
525 case SDL_BLENDMODE_BLEND: | |
526 VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end); | |
527 break; | |
528 case SDL_BLENDMODE_ADD: | |
529 VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end); | |
530 break; | |
531 case SDL_BLENDMODE_MOD: | |
532 VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end); | |
533 break; | |
534 default: | |
535 VLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end); | |
536 break; | |
537 } | |
538 } else if (ABS(x1 - x2) == ABS(y1 - y2)) { | |
539 switch (blendMode) { | |
540 case SDL_BLENDMODE_BLEND: | |
541 DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end); | |
542 break; | |
543 case SDL_BLENDMODE_ADD: | |
544 DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end); | |
545 break; | |
546 case SDL_BLENDMODE_MOD: | |
547 DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end); | |
548 break; | |
549 default: | |
550 DLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end); | |
551 break; | |
552 } | |
553 } else { | |
554 switch (blendMode) { | |
555 case SDL_BLENDMODE_BLEND: | |
556 AALINE(x1, y1, x2, y2, | |
557 DRAW_SETPIXELXY_BLEND_RGB888, DRAW_SETPIXELXY_BLEND_RGB888, | |
558 draw_end); | |
559 break; | |
560 case SDL_BLENDMODE_ADD: | |
561 AALINE(x1, y1, x2, y2, | |
562 DRAW_SETPIXELXY_ADD_RGB888, DRAW_SETPIXELXY_ADD_RGB888, | |
563 draw_end); | |
564 break; | |
565 case SDL_BLENDMODE_MOD: | |
566 AALINE(x1, y1, x2, y2, | |
567 DRAW_SETPIXELXY_MOD_RGB888, DRAW_SETPIXELXY_MOD_RGB888, | |
568 draw_end); | |
569 break; | |
570 default: | |
571 AALINE(x1, y1, x2, y2, | |
572 DRAW_SETPIXELXY_RGB888, DRAW_SETPIXELXY_BLEND_RGB888, | |
573 draw_end); | |
574 break; | |
575 } | |
576 } | |
577 } | |
578 | |
579 static void | |
99 SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2, | 580 SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2, |
100 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, | 581 int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, |
101 SDL_bool draw_end) | 582 SDL_bool draw_end) |
102 { | 583 { |
103 unsigned inva = 0xff - a; | 584 const SDL_PixelFormat *fmt = dst->format; |
104 | 585 unsigned r, g, b, a, inva; |
105 switch (blendMode) { | 586 |
106 case SDL_BLENDMODE_BLEND: | 587 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { |
107 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_ARGB8888, draw_end); | 588 r = DRAW_MUL(_r, _a); |
108 break; | 589 g = DRAW_MUL(_g, _a); |
109 case SDL_BLENDMODE_ADD: | 590 b = DRAW_MUL(_b, _a); |
110 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_ARGB8888, draw_end); | 591 a = _a; |
111 break; | 592 } else { |
112 case SDL_BLENDMODE_MOD: | 593 r = _r; |
113 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_ARGB8888, draw_end); | 594 g = _g; |
114 break; | 595 b = _b; |
115 default: | 596 a = _a; |
116 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ARGB8888, draw_end); | 597 } |
117 break; | 598 inva = (a ^ 0xff); |
118 } | 599 |
119 return 0; | 600 if (y1 == y2) { |
120 } | 601 switch (blendMode) { |
121 | 602 case SDL_BLENDMODE_BLEND: |
122 static int | 603 HLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); |
123 SDL_BlendLine_RGB(SDL_Surface * dst, int x1, int y1, int x2, int y2, | 604 break; |
124 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, | 605 case SDL_BLENDMODE_ADD: |
125 SDL_bool draw_end) | 606 HLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end); |
126 { | 607 break; |
127 SDL_PixelFormat *fmt = dst->format; | 608 case SDL_BLENDMODE_MOD: |
128 unsigned inva = 0xff - a; | 609 HLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end); |
129 | 610 break; |
611 default: | |
612 HLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end); | |
613 break; | |
614 } | |
615 } else if (x1 == x2) { | |
616 switch (blendMode) { | |
617 case SDL_BLENDMODE_BLEND: | |
618 VLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); | |
619 break; | |
620 case SDL_BLENDMODE_ADD: | |
621 VLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end); | |
622 break; | |
623 case SDL_BLENDMODE_MOD: | |
624 VLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end); | |
625 break; | |
626 default: | |
627 VLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end); | |
628 break; | |
629 } | |
630 } else if (ABS(x1 - x2) == ABS(y1 - y2)) { | |
631 switch (blendMode) { | |
632 case SDL_BLENDMODE_BLEND: | |
633 DLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); | |
634 break; | |
635 case SDL_BLENDMODE_ADD: | |
636 DLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end); | |
637 break; | |
638 case SDL_BLENDMODE_MOD: | |
639 DLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end); | |
640 break; | |
641 default: | |
642 DLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end); | |
643 break; | |
644 } | |
645 } else { | |
646 switch (blendMode) { | |
647 case SDL_BLENDMODE_BLEND: | |
648 AALINE(x1, y1, x2, y2, | |
649 DRAW_SETPIXELXY_BLEND_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888, | |
650 draw_end); | |
651 break; | |
652 case SDL_BLENDMODE_ADD: | |
653 AALINE(x1, y1, x2, y2, | |
654 DRAW_SETPIXELXY_ADD_ARGB8888, DRAW_SETPIXELXY_ADD_ARGB8888, | |
655 draw_end); | |
656 break; | |
657 case SDL_BLENDMODE_MOD: | |
658 AALINE(x1, y1, x2, y2, | |
659 DRAW_SETPIXELXY_MOD_ARGB8888, DRAW_SETPIXELXY_MOD_ARGB8888, | |
660 draw_end); | |
661 break; | |
662 default: | |
663 AALINE(x1, y1, x2, y2, | |
664 DRAW_SETPIXELXY_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888, | |
665 draw_end); | |
666 break; | |
667 } | |
668 } | |
669 } | |
670 | |
671 typedef void (*BlendLineFunc) (SDL_Surface * dst, | |
672 int x1, int y1, int x2, int y2, | |
673 int blendMode, | |
674 Uint8 r, Uint8 g, Uint8 b, Uint8 a, | |
675 SDL_bool draw_end); | |
676 | |
677 static BlendLineFunc | |
678 SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt) | |
679 { | |
130 switch (fmt->BytesPerPixel) { | 680 switch (fmt->BytesPerPixel) { |
131 case 2: | 681 case 2: |
132 switch (blendMode) { | 682 if (fmt->Rmask == 0x7C00) { |
133 case SDL_BLENDMODE_BLEND: | 683 return SDL_BlendLine_RGB555; |
134 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_BLEND_RGB, draw_end); | 684 } else if (fmt->Rmask == 0xF800) { |
135 break; | 685 return SDL_BlendLine_RGB565; |
136 case SDL_BLENDMODE_ADD: | 686 } else { |
137 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_ADD_RGB, draw_end); | 687 return SDL_BlendLine_RGB2; |
138 break; | 688 } |
139 case SDL_BLENDMODE_MOD: | 689 break; |
140 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_MOD_RGB, draw_end); | |
141 break; | |
142 default: | |
143 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_RGB, draw_end); | |
144 break; | |
145 } | |
146 return 0; | |
147 case 4: | 690 case 4: |
148 switch (blendMode) { | 691 if (fmt->Rmask == 0x00FF0000) { |
149 case SDL_BLENDMODE_BLEND: | 692 if (fmt->Amask) { |
150 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGB, draw_end); | 693 return SDL_BlendLine_ARGB8888; |
151 break; | 694 } else { |
152 case SDL_BLENDMODE_ADD: | 695 return SDL_BlendLine_RGB888; |
153 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGB, draw_end); | 696 } |
154 break; | 697 } else { |
155 case SDL_BLENDMODE_MOD: | 698 if (fmt->Amask) { |
156 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGB, draw_end); | 699 return SDL_BlendLine_RGBA4; |
157 break; | 700 } else { |
158 default: | 701 return SDL_BlendLine_RGB4; |
159 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGB, draw_end); | 702 } |
160 break; | 703 } |
161 } | 704 } |
162 return 0; | 705 return NULL; |
163 default: | |
164 SDL_Unsupported(); | |
165 return -1; | |
166 } | |
167 } | |
168 | |
169 static int | |
170 SDL_BlendLine_RGBA(SDL_Surface * dst, int x1, int y1, int x2, int y2, | |
171 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, | |
172 SDL_bool draw_end) | |
173 { | |
174 SDL_PixelFormat *fmt = dst->format; | |
175 unsigned inva = 0xff - a; | |
176 | |
177 switch (fmt->BytesPerPixel) { | |
178 case 4: | |
179 switch (blendMode) { | |
180 case SDL_BLENDMODE_BLEND: | |
181 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGBA, draw_end); | |
182 break; | |
183 case SDL_BLENDMODE_ADD: | |
184 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGBA, draw_end); | |
185 break; | |
186 case SDL_BLENDMODE_MOD: | |
187 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGBA, draw_end); | |
188 break; | |
189 default: | |
190 DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGBA, draw_end); | |
191 break; | |
192 } | |
193 return 0; | |
194 default: | |
195 SDL_Unsupported(); | |
196 return -1; | |
197 } | |
198 } | 706 } |
199 | 707 |
200 int | 708 int |
201 SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, | 709 SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, |
202 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) | 710 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) |
203 { | 711 { |
204 /* This function doesn't work on surfaces < 8 bpp */ | 712 BlendLineFunc func; |
205 if (dst->format->BitsPerPixel < 8) { | 713 |
714 if (!dst) { | |
715 SDL_SetError("SDL_BlendLine(): Passed NULL destination surface"); | |
716 return -1; | |
717 } | |
718 | |
719 func = SDL_CalculateBlendLineFunc(dst->format); | |
720 if (!func) { | |
206 SDL_SetError("SDL_BlendLine(): Unsupported surface format"); | 721 SDL_SetError("SDL_BlendLine(): Unsupported surface format"); |
207 return (-1); | 722 return -1; |
208 } | 723 } |
209 | 724 |
210 /* Perform clipping */ | 725 /* Perform clipping */ |
726 /* FIXME: We don't actually want to clip, as it may change line slope */ | |
211 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { | 727 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { |
212 return (0); | 728 return 0; |
213 } | 729 } |
214 | 730 |
215 | 731 func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_TRUE); |
216 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { | 732 return 0; |
217 r = DRAW_MUL(r, a); | |
218 g = DRAW_MUL(g, a); | |
219 b = DRAW_MUL(b, a); | |
220 } | |
221 | |
222 switch (dst->format->BitsPerPixel) { | |
223 case 15: | |
224 switch (dst->format->Rmask) { | |
225 case 0x7C00: | |
226 return SDL_BlendLine_RGB555(dst, x1, y1, x2, y2, blendMode, r, g, | |
227 b, a, SDL_TRUE); | |
228 } | |
229 break; | |
230 case 16: | |
231 switch (dst->format->Rmask) { | |
232 case 0xF800: | |
233 return SDL_BlendLine_RGB565(dst, x1, y1, x2, y2, blendMode, r, g, | |
234 b, a, SDL_TRUE); | |
235 } | |
236 break; | |
237 case 32: | |
238 switch (dst->format->Rmask) { | |
239 case 0x00FF0000: | |
240 if (!dst->format->Amask) { | |
241 return SDL_BlendLine_RGB888(dst, x1, y1, x2, y2, blendMode, r, | |
242 g, b, a, SDL_TRUE); | |
243 } else { | |
244 return SDL_BlendLine_ARGB8888(dst, x1, y1, x2, y2, blendMode, | |
245 r, g, b, a, SDL_TRUE); | |
246 } | |
247 break; | |
248 } | |
249 break; | |
250 default: | |
251 break; | |
252 } | |
253 | |
254 if (!dst->format->Amask) { | |
255 return SDL_BlendLine_RGB(dst, x1, y1, x2, y2, blendMode, | |
256 r, g, b, a, SDL_TRUE); | |
257 } else { | |
258 return SDL_BlendLine_RGBA(dst, x1, y1, x2, y2, blendMode, | |
259 r, g, b, a, SDL_TRUE); | |
260 } | |
261 } | 733 } |
262 | 734 |
263 int | 735 int |
264 SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, | 736 SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, |
265 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) | 737 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) |
266 { | 738 { |
267 int i; | 739 int i; |
268 int x1, y1; | 740 int x1, y1; |
269 int x2, y2; | 741 int x2, y2; |
270 int (*func)(SDL_Surface * dst, int x1, int y1, int x2, int y2, | 742 SDL_bool draw_end; |
271 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, | 743 BlendLineFunc func; |
272 SDL_bool draw_end) = NULL; | |
273 int status = 0; | |
274 | 744 |
275 if (!dst) { | 745 if (!dst) { |
276 SDL_SetError("Passed NULL destination surface"); | 746 SDL_SetError("SDL_BlendLines(): Passed NULL destination surface"); |
277 return -1; | 747 return -1; |
278 } | 748 } |
279 | 749 |
280 /* This function doesn't work on surfaces < 8 bpp */ | 750 func = SDL_CalculateBlendLineFunc(dst->format); |
281 if (dst->format->BitsPerPixel < 8) { | 751 if (!func) { |
282 SDL_SetError("SDL_BlendLines(): Unsupported surface format"); | 752 SDL_SetError("SDL_BlendLines(): Unsupported surface format"); |
283 return -1; | 753 return -1; |
284 } | |
285 | |
286 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { | |
287 r = DRAW_MUL(r, a); | |
288 g = DRAW_MUL(g, a); | |
289 b = DRAW_MUL(b, a); | |
290 } | |
291 | |
292 /* FIXME: Does this function pointer slow things down significantly? */ | |
293 switch (dst->format->BitsPerPixel) { | |
294 case 15: | |
295 switch (dst->format->Rmask) { | |
296 case 0x7C00: | |
297 func = SDL_BlendLine_RGB555; | |
298 } | |
299 break; | |
300 case 16: | |
301 switch (dst->format->Rmask) { | |
302 case 0xF800: | |
303 func = SDL_BlendLine_RGB565; | |
304 } | |
305 break; | |
306 case 32: | |
307 switch (dst->format->Rmask) { | |
308 case 0x00FF0000: | |
309 if (!dst->format->Amask) { | |
310 func = SDL_BlendLine_RGB888; | |
311 } else { | |
312 func = SDL_BlendLine_ARGB8888; | |
313 } | |
314 break; | |
315 } | |
316 default: | |
317 break; | |
318 } | |
319 | |
320 if (!func) { | |
321 if (!dst->format->Amask) { | |
322 func = SDL_BlendLine_RGB; | |
323 } else { | |
324 func = SDL_BlendLine_RGBA; | |
325 } | |
326 } | 754 } |
327 | 755 |
328 for (i = 1; i < count; ++i) { | 756 for (i = 1; i < count; ++i) { |
329 x1 = points[i-1].x; | 757 x1 = points[i-1].x; |
330 y1 = points[i-1].y; | 758 y1 = points[i-1].y; |
335 /* FIXME: We don't actually want to clip, as it may change line slope */ | 763 /* FIXME: We don't actually want to clip, as it may change line slope */ |
336 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { | 764 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { |
337 continue; | 765 continue; |
338 } | 766 } |
339 | 767 |
340 status = func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_FALSE); | 768 /* Draw the end if it was clipped */ |
769 draw_end = (x2 != points[i].x || y2 != points[i].y); | |
770 | |
771 func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end); | |
341 } | 772 } |
342 if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { | 773 if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { |
343 SDL_BlendPoint(dst, points[count-1].x, points[count-1].y, r, g, b, a); | 774 SDL_BlendPoint(dst, points[count-1].x, points[count-1].y, |
344 } | 775 blendMode, r, g, b, a); |
345 return status; | 776 } |
777 return 0; | |
346 } | 778 } |
347 | 779 |
348 /* vi: set ts=4 sw=4 expandtab: */ | 780 /* vi: set ts=4 sw=4 expandtab: */ |