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: */