1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "../../SDL_internal.h"
22
23#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED
24
25#include "SDL_draw.h"
26#include "SDL_blendline.h"
27#include "SDL_blendpoint.h"
28
29
30static void
31SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2,
32 SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
33 SDL_bool draw_end)
34{
35 const SDL_PixelFormat *fmt = dst->format;
36 unsigned r, g, b, a, inva;
37
38 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
39 r = DRAW_MUL(_r, _a);
40 g = DRAW_MUL(_g, _a);
41 b = DRAW_MUL(_b, _a);
42 a = _a;
43 } else {
44 r = _r;
45 g = _g;
46 b = _b;
47 a = _a;
48 }
49 inva = (a ^ 0xff);
50
51 if (y1 == y2) {
52 switch (blendMode) {
53 case SDL_BLENDMODE_BLEND:
54 HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
55 break;
56 case SDL_BLENDMODE_ADD:
57 HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
58 break;
59 case SDL_BLENDMODE_MOD:
60 HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
61 break;
62 case SDL_BLENDMODE_MUL:
63 HLINE(Uint16, DRAW_SETPIXEL_MUL_RGB, draw_end);
64 break;
65 default:
66 HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
67 break;
68 }
69 } else if (x1 == x2) {
70 switch (blendMode) {
71 case SDL_BLENDMODE_BLEND:
72 VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
73 break;
74 case SDL_BLENDMODE_ADD:
75 VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
76 break;
77 case SDL_BLENDMODE_MOD:
78 VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
79 break;
80 case SDL_BLENDMODE_MUL:
81 VLINE(Uint16, DRAW_SETPIXEL_MUL_RGB, draw_end);
82 break;
83 default:
84 VLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
85 break;
86 }
87 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
88 switch (blendMode) {
89 case SDL_BLENDMODE_BLEND:
90 DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
91 break;
92 case SDL_BLENDMODE_ADD:
93 DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
94 break;
95 case SDL_BLENDMODE_MOD:
96 DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
97 break;
98 case SDL_BLENDMODE_MUL:
99 DLINE(Uint16, DRAW_SETPIXEL_MUL_RGB, draw_end);
100 break;
101 default:
102 DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
103 break;
104 }
105 } else {
106 switch (blendMode) {
107 case SDL_BLENDMODE_BLEND:
108 AALINE(x1, y1, x2, y2,
109 DRAW_SETPIXELXY2_BLEND_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
110 draw_end);
111 break;
112 case SDL_BLENDMODE_ADD:
113 AALINE(x1, y1, x2, y2,
114 DRAW_SETPIXELXY2_ADD_RGB, DRAW_SETPIXELXY2_ADD_RGB,
115 draw_end);
116 break;
117 case SDL_BLENDMODE_MOD:
118 AALINE(x1, y1, x2, y2,
119 DRAW_SETPIXELXY2_MOD_RGB, DRAW_SETPIXELXY2_MOD_RGB,
120 draw_end);
121 break;
122 case SDL_BLENDMODE_MUL:
123 AALINE(x1, y1, x2, y2,
124 DRAW_SETPIXELXY2_MUL_RGB, DRAW_SETPIXELXY2_MUL_RGB,
125 draw_end);
126 break;
127 default:
128 AALINE(x1, y1, x2, y2,
129 DRAW_SETPIXELXY2_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
130 draw_end);
131 break;
132 }
133 }
134}
135
136static void
137SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2,
138 SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
139 SDL_bool draw_end)
140{
141 unsigned r, g, b, a, inva;
142
143 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
144 r = DRAW_MUL(_r, _a);
145 g = DRAW_MUL(_g, _a);
146 b = DRAW_MUL(_b, _a);
147 a = _a;
148 } else {
149 r = _r;
150 g = _g;
151 b = _b;
152 a = _a;
153 }
154 inva = (a ^ 0xff);
155
156 if (y1 == y2) {
157 switch (blendMode) {
158 case SDL_BLENDMODE_BLEND:
159 HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
160 break;
161 case SDL_BLENDMODE_ADD:
162 HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
163 break;
164 case SDL_BLENDMODE_MOD:
165 HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
166 break;
167 case SDL_BLENDMODE_MUL:
168 HLINE(Uint16, DRAW_SETPIXEL_MUL_RGB555, draw_end);
169 break;
170 default:
171 HLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
172 break;
173 }
174 } else if (x1 == x2) {
175 switch (blendMode) {
176 case SDL_BLENDMODE_BLEND:
177 VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
178 break;
179 case SDL_BLENDMODE_ADD:
180 VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
181 break;
182 case SDL_BLENDMODE_MOD:
183 VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
184 break;
185 case SDL_BLENDMODE_MUL:
186 VLINE(Uint16, DRAW_SETPIXEL_MUL_RGB555, draw_end);
187 break;
188 default:
189 VLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
190 break;
191 }
192 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
193 switch (blendMode) {
194 case SDL_BLENDMODE_BLEND:
195 DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
196 break;
197 case SDL_BLENDMODE_ADD:
198 DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
199 break;
200 case SDL_BLENDMODE_MOD:
201 DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
202 break;
203 case SDL_BLENDMODE_MUL:
204 DLINE(Uint16, DRAW_SETPIXEL_MUL_RGB555, draw_end);
205 break;
206 default:
207 DLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
208 break;
209 }
210 } else {
211 switch (blendMode) {
212 case SDL_BLENDMODE_BLEND:
213 AALINE(x1, y1, x2, y2,
214 DRAW_SETPIXELXY_BLEND_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
215 draw_end);
216 break;
217 case SDL_BLENDMODE_ADD:
218 AALINE(x1, y1, x2, y2,
219 DRAW_SETPIXELXY_ADD_RGB555, DRAW_SETPIXELXY_ADD_RGB555,
220 draw_end);
221 break;
222 case SDL_BLENDMODE_MOD:
223 AALINE(x1, y1, x2, y2,
224 DRAW_SETPIXELXY_MOD_RGB555, DRAW_SETPIXELXY_MOD_RGB555,
225 draw_end);
226 break;
227 case SDL_BLENDMODE_MUL:
228 AALINE(x1, y1, x2, y2,
229 DRAW_SETPIXELXY_MUL_RGB555, DRAW_SETPIXELXY_MUL_RGB555,
230 draw_end);
231 break;
232 default:
233 AALINE(x1, y1, x2, y2,
234 DRAW_SETPIXELXY_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
235 draw_end);
236 break;
237 }
238 }
239}
240
241static void
242SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2,
243 SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
244 SDL_bool draw_end)
245{
246 unsigned r, g, b, a, inva;
247
248 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
249 r = DRAW_MUL(_r, _a);
250 g = DRAW_MUL(_g, _a);
251 b = DRAW_MUL(_b, _a);
252 a = _a;
253 } else {
254 r = _r;
255 g = _g;
256 b = _b;
257 a = _a;
258 }
259 inva = (a ^ 0xff);
260
261 if (y1 == y2) {
262 switch (blendMode) {
263 case SDL_BLENDMODE_BLEND:
264 HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
265 break;
266 case SDL_BLENDMODE_ADD:
267 HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
268 break;
269 case SDL_BLENDMODE_MOD:
270 HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
271 break;
272 case SDL_BLENDMODE_MUL:
273 HLINE(Uint16, DRAW_SETPIXEL_MUL_RGB565, draw_end);
274 break;
275 default:
276 HLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
277 break;
278 }
279 } else if (x1 == x2) {
280 switch (blendMode) {
281 case SDL_BLENDMODE_BLEND:
282 VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
283 break;
284 case SDL_BLENDMODE_ADD:
285 VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
286 break;
287 case SDL_BLENDMODE_MOD:
288 VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
289 break;
290 case SDL_BLENDMODE_MUL:
291 VLINE(Uint16, DRAW_SETPIXEL_MUL_RGB565, draw_end);
292 break;
293 default:
294 VLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
295 break;
296 }
297 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
298 switch (blendMode) {
299 case SDL_BLENDMODE_BLEND:
300 DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
301 break;
302 case SDL_BLENDMODE_ADD:
303 DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
304 break;
305 case SDL_BLENDMODE_MOD:
306 DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
307 break;
308 case SDL_BLENDMODE_MUL:
309 DLINE(Uint16, DRAW_SETPIXEL_MUL_RGB565, draw_end);
310 break;
311 default:
312 DLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
313 break;
314 }
315 } else {
316 switch (blendMode) {
317 case SDL_BLENDMODE_BLEND:
318 AALINE(x1, y1, x2, y2,
319 DRAW_SETPIXELXY_BLEND_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
320 draw_end);
321 break;
322 case SDL_BLENDMODE_ADD:
323 AALINE(x1, y1, x2, y2,
324 DRAW_SETPIXELXY_ADD_RGB565, DRAW_SETPIXELXY_ADD_RGB565,
325 draw_end);
326 break;
327 case SDL_BLENDMODE_MOD:
328 AALINE(x1, y1, x2, y2,
329 DRAW_SETPIXELXY_MOD_RGB565, DRAW_SETPIXELXY_MOD_RGB565,
330 draw_end);
331 break;
332 case SDL_BLENDMODE_MUL:
333 AALINE(x1, y1, x2, y2,
334 DRAW_SETPIXELXY_MUL_RGB565, DRAW_SETPIXELXY_MUL_RGB565,
335 draw_end);
336 break;
337 default:
338 AALINE(x1, y1, x2, y2,
339 DRAW_SETPIXELXY_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
340 draw_end);
341 break;
342 }
343 }
344}
345
346static void
347SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
348 SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
349 SDL_bool draw_end)
350{
351 const SDL_PixelFormat *fmt = dst->format;
352 unsigned r, g, b, a, inva;
353
354 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
355 r = DRAW_MUL(_r, _a);
356 g = DRAW_MUL(_g, _a);
357 b = DRAW_MUL(_b, _a);
358 a = _a;
359 } else {
360 r = _r;
361 g = _g;
362 b = _b;
363 a = _a;
364 }
365 inva = (a ^ 0xff);
366
367 if (y1 == y2) {
368 switch (blendMode) {
369 case SDL_BLENDMODE_BLEND:
370 HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
371 break;
372 case SDL_BLENDMODE_ADD:
373 HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
374 break;
375 case SDL_BLENDMODE_MOD:
376 HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
377 break;
378 case SDL_BLENDMODE_MUL:
379 HLINE(Uint32, DRAW_SETPIXEL_MUL_RGB, draw_end);
380 break;
381 default:
382 HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
383 break;
384 }
385 } else if (x1 == x2) {
386 switch (blendMode) {
387 case SDL_BLENDMODE_BLEND:
388 VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
389 break;
390 case SDL_BLENDMODE_ADD:
391 VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
392 break;
393 case SDL_BLENDMODE_MOD:
394 VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
395 break;
396 case SDL_BLENDMODE_MUL:
397 VLINE(Uint32, DRAW_SETPIXEL_MUL_RGB, draw_end);
398 break;
399 default:
400 VLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
401 break;
402 }
403 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
404 switch (blendMode) {
405 case SDL_BLENDMODE_BLEND:
406 DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
407 break;
408 case SDL_BLENDMODE_ADD:
409 DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
410 break;
411 case SDL_BLENDMODE_MOD:
412 DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
413 break;
414 case SDL_BLENDMODE_MUL:
415 DLINE(Uint32, DRAW_SETPIXEL_MUL_RGB, draw_end);
416 break;
417 default:
418 DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
419 break;
420 }
421 } else {
422 switch (blendMode) {
423 case SDL_BLENDMODE_BLEND:
424 AALINE(x1, y1, x2, y2,
425 DRAW_SETPIXELXY4_BLEND_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
426 draw_end);
427 break;
428 case SDL_BLENDMODE_ADD:
429 AALINE(x1, y1, x2, y2,
430 DRAW_SETPIXELXY4_ADD_RGB, DRAW_SETPIXELXY4_ADD_RGB,
431 draw_end);
432 break;
433 case SDL_BLENDMODE_MOD:
434 AALINE(x1, y1, x2, y2,
435 DRAW_SETPIXELXY4_MOD_RGB, DRAW_SETPIXELXY4_MOD_RGB,
436 draw_end);
437 break;
438 case SDL_BLENDMODE_MUL:
439 AALINE(x1, y1, x2, y2,
440 DRAW_SETPIXELXY4_MUL_RGB, DRAW_SETPIXELXY4_MUL_RGB,
441 draw_end);
442 break;
443 default:
444 AALINE(x1, y1, x2, y2,
445 DRAW_SETPIXELXY4_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
446 draw_end);
447 break;
448 }
449 }
450}
451
452static void
453SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
454 SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
455 SDL_bool draw_end)
456{
457 const SDL_PixelFormat *fmt = dst->format;
458 unsigned r, g, b, a, inva;
459
460 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
461 r = DRAW_MUL(_r, _a);
462 g = DRAW_MUL(_g, _a);
463 b = DRAW_MUL(_b, _a);
464 a = _a;
465 } else {
466 r = _r;
467 g = _g;
468 b = _b;
469 a = _a;
470 }
471 inva = (a ^ 0xff);
472
473 if (y1 == y2) {
474 switch (blendMode) {
475 case SDL_BLENDMODE_BLEND:
476 HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
477 break;
478 case SDL_BLENDMODE_ADD:
479 HLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
480 break;
481 case SDL_BLENDMODE_MOD:
482 HLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
483 break;
484 case SDL_BLENDMODE_MUL:
485 HLINE(Uint32, DRAW_SETPIXEL_MUL_RGBA, draw_end);
486 break;
487 default:
488 HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
489 break;
490 }
491 } else if (x1 == x2) {
492 switch (blendMode) {
493 case SDL_BLENDMODE_BLEND:
494 VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
495 break;
496 case SDL_BLENDMODE_ADD:
497 VLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
498 break;
499 case SDL_BLENDMODE_MOD:
500 VLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
501 break;
502 case SDL_BLENDMODE_MUL:
503 VLINE(Uint32, DRAW_SETPIXEL_MUL_RGBA, draw_end);
504 break;
505 default:
506 VLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
507 break;
508 }
509 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
510 switch (blendMode) {
511 case SDL_BLENDMODE_BLEND:
512 DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
513 break;
514 case SDL_BLENDMODE_ADD:
515 DLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
516 break;
517 case SDL_BLENDMODE_MOD:
518 DLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
519 break;
520 case SDL_BLENDMODE_MUL:
521 DLINE(Uint32, DRAW_SETPIXEL_MUL_RGBA, draw_end);
522 break;
523 default:
524 DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
525 break;
526 }
527 } else {
528 switch (blendMode) {
529 case SDL_BLENDMODE_BLEND:
530 AALINE(x1, y1, x2, y2,
531 DRAW_SETPIXELXY4_BLEND_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
532 draw_end);
533 break;
534 case SDL_BLENDMODE_ADD:
535 AALINE(x1, y1, x2, y2,
536 DRAW_SETPIXELXY4_ADD_RGBA, DRAW_SETPIXELXY4_ADD_RGBA,
537 draw_end);
538 break;
539 case SDL_BLENDMODE_MOD:
540 AALINE(x1, y1, x2, y2,
541 DRAW_SETPIXELXY4_MOD_RGBA, DRAW_SETPIXELXY4_MOD_RGBA,
542 draw_end);
543 break;
544 case SDL_BLENDMODE_MUL:
545 AALINE(x1, y1, x2, y2,
546 DRAW_SETPIXELXY4_MUL_RGBA, DRAW_SETPIXELXY4_MUL_RGBA,
547 draw_end);
548 break;
549 default:
550 AALINE(x1, y1, x2, y2,
551 DRAW_SETPIXELXY4_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
552 draw_end);
553 break;
554 }
555 }
556}
557
558static void
559SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
560 SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
561 SDL_bool draw_end)
562{
563 unsigned r, g, b, a, inva;
564
565 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
566 r = DRAW_MUL(_r, _a);
567 g = DRAW_MUL(_g, _a);
568 b = DRAW_MUL(_b, _a);
569 a = _a;
570 } else {
571 r = _r;
572 g = _g;
573 b = _b;
574 a = _a;
575 }
576 inva = (a ^ 0xff);
577
578 if (y1 == y2) {
579 switch (blendMode) {
580 case SDL_BLENDMODE_BLEND:
581 HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end);
582 break;
583 case SDL_BLENDMODE_ADD:
584 HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end);
585 break;
586 case SDL_BLENDMODE_MOD:
587 HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end);
588 break;
589 case SDL_BLENDMODE_MUL:
590 HLINE(Uint32, DRAW_SETPIXEL_MUL_RGB888, draw_end);
591 break;
592 default:
593 HLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
594 break;
595 }
596 } else if (x1 == x2) {
597 switch (blendMode) {
598 case SDL_BLENDMODE_BLEND:
599 VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end);
600 break;
601 case SDL_BLENDMODE_ADD:
602 VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end);
603 break;
604 case SDL_BLENDMODE_MOD:
605 VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end);
606 break;
607 case SDL_BLENDMODE_MUL:
608 VLINE(Uint32, DRAW_SETPIXEL_MUL_RGB888, draw_end);
609 break;
610 default:
611 VLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
612 break;
613 }
614 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
615 switch (blendMode) {
616 case SDL_BLENDMODE_BLEND:
617 DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end);
618 break;
619 case SDL_BLENDMODE_ADD:
620 DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end);
621 break;
622 case SDL_BLENDMODE_MOD:
623 DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end);
624 break;
625 case SDL_BLENDMODE_MUL:
626 DLINE(Uint32, DRAW_SETPIXEL_MUL_RGB888, draw_end);
627 break;
628 default:
629 DLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end);
630 break;
631 }
632 } else {
633 switch (blendMode) {
634 case SDL_BLENDMODE_BLEND:
635 AALINE(x1, y1, x2, y2,
636 DRAW_SETPIXELXY_BLEND_RGB888, DRAW_SETPIXELXY_BLEND_RGB888,
637 draw_end);
638 break;
639 case SDL_BLENDMODE_ADD:
640 AALINE(x1, y1, x2, y2,
641 DRAW_SETPIXELXY_ADD_RGB888, DRAW_SETPIXELXY_ADD_RGB888,
642 draw_end);
643 break;
644 case SDL_BLENDMODE_MOD:
645 AALINE(x1, y1, x2, y2,
646 DRAW_SETPIXELXY_MOD_RGB888, DRAW_SETPIXELXY_MOD_RGB888,
647 draw_end);
648 break;
649 case SDL_BLENDMODE_MUL:
650 AALINE(x1, y1, x2, y2,
651 DRAW_SETPIXELXY_MUL_RGB888, DRAW_SETPIXELXY_MUL_RGB888,
652 draw_end);
653 break;
654 default:
655 AALINE(x1, y1, x2, y2,
656 DRAW_SETPIXELXY_RGB888, DRAW_SETPIXELXY_BLEND_RGB888,
657 draw_end);
658 break;
659 }
660 }
661}
662
663static void
664SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
665 SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
666 SDL_bool draw_end)
667{
668 unsigned r, g, b, a, inva;
669
670 if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
671 r = DRAW_MUL(_r, _a);
672 g = DRAW_MUL(_g, _a);
673 b = DRAW_MUL(_b, _a);
674 a = _a;
675 } else {
676 r = _r;
677 g = _g;
678 b = _b;
679 a = _a;
680 }
681 inva = (a ^ 0xff);
682
683 if (y1 == y2) {
684 switch (blendMode) {
685 case SDL_BLENDMODE_BLEND:
686 HLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
687 break;
688 case SDL_BLENDMODE_ADD:
689 HLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
690 break;
691 case SDL_BLENDMODE_MOD:
692 HLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
693 break;
694 case SDL_BLENDMODE_MUL:
695 HLINE(Uint32, DRAW_SETPIXEL_MUL_ARGB8888, draw_end);
696 break;
697 default:
698 HLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
699 break;
700 }
701 } else if (x1 == x2) {
702 switch (blendMode) {
703 case SDL_BLENDMODE_BLEND:
704 VLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
705 break;
706 case SDL_BLENDMODE_ADD:
707 VLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
708 break;
709 case SDL_BLENDMODE_MOD:
710 VLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
711 break;
712 case SDL_BLENDMODE_MUL:
713 VLINE(Uint32, DRAW_SETPIXEL_MUL_ARGB8888, draw_end);
714 break;
715 default:
716 VLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
717 break;
718 }
719 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
720 switch (blendMode) {
721 case SDL_BLENDMODE_BLEND:
722 DLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
723 break;
724 case SDL_BLENDMODE_ADD:
725 DLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
726 break;
727 case SDL_BLENDMODE_MOD:
728 DLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
729 break;
730 case SDL_BLENDMODE_MUL:
731 DLINE(Uint32, DRAW_SETPIXEL_MUL_ARGB8888, draw_end);
732 break;
733 default:
734 DLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
735 break;
736 }
737 } else {
738 switch (blendMode) {
739 case SDL_BLENDMODE_BLEND:
740 AALINE(x1, y1, x2, y2,
741 DRAW_SETPIXELXY_BLEND_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
742 draw_end);
743 break;
744 case SDL_BLENDMODE_ADD:
745 AALINE(x1, y1, x2, y2,
746 DRAW_SETPIXELXY_ADD_ARGB8888, DRAW_SETPIXELXY_ADD_ARGB8888,
747 draw_end);
748 break;
749 case SDL_BLENDMODE_MOD:
750 AALINE(x1, y1, x2, y2,
751 DRAW_SETPIXELXY_MOD_ARGB8888, DRAW_SETPIXELXY_MOD_ARGB8888,
752 draw_end);
753 break;
754 case SDL_BLENDMODE_MUL:
755 AALINE(x1, y1, x2, y2,
756 DRAW_SETPIXELXY_MUL_ARGB8888, DRAW_SETPIXELXY_MUL_ARGB8888,
757 draw_end);
758 break;
759 default:
760 AALINE(x1, y1, x2, y2,
761 DRAW_SETPIXELXY_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
762 draw_end);
763 break;
764 }
765 }
766}
767
768typedef void (*BlendLineFunc) (SDL_Surface * dst,
769 int x1, int y1, int x2, int y2,
770 SDL_BlendMode blendMode,
771 Uint8 r, Uint8 g, Uint8 b, Uint8 a,
772 SDL_bool draw_end);
773
774static BlendLineFunc
775SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt)
776{
777 switch (fmt->BytesPerPixel) {
778 case 2:
779 if (fmt->Rmask == 0x7C00) {
780 return SDL_BlendLine_RGB555;
781 } else if (fmt->Rmask == 0xF800) {
782 return SDL_BlendLine_RGB565;
783 } else {
784 return SDL_BlendLine_RGB2;
785 }
786 /* break; -Wunreachable-code-break */
787 case 4:
788 if (fmt->Rmask == 0x00FF0000) {
789 if (fmt->Amask) {
790 return SDL_BlendLine_ARGB8888;
791 } else {
792 return SDL_BlendLine_RGB888;
793 }
794 } else {
795 if (fmt->Amask) {
796 return SDL_BlendLine_RGBA4;
797 } else {
798 return SDL_BlendLine_RGB4;
799 }
800 }
801 }
802 return NULL;
803}
804
805int
806SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
807 SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
808{
809 BlendLineFunc func;
810
811 if (!dst) {
812 return SDL_SetError("SDL_BlendLine(): Passed NULL destination surface");
813 }
814
815 func = SDL_CalculateBlendLineFunc(dst->format);
816 if (!func) {
817 return SDL_SetError("SDL_BlendLine(): Unsupported surface format");
818 }
819
820 /* Perform clipping */
821 /* FIXME: We don't actually want to clip, as it may change line slope */
822 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
823 return 0;
824 }
825
826 func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_TRUE);
827 return 0;
828}
829
830int
831SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count,
832 SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
833{
834 int i;
835 int x1, y1;
836 int x2, y2;
837 SDL_bool draw_end;
838 BlendLineFunc func;
839
840 if (!dst) {
841 return SDL_SetError("SDL_BlendLines(): Passed NULL destination surface");
842 }
843
844 func = SDL_CalculateBlendLineFunc(dst->format);
845 if (!func) {
846 return SDL_SetError("SDL_BlendLines(): Unsupported surface format");
847 }
848
849 for (i = 1; i < count; ++i) {
850 x1 = points[i-1].x;
851 y1 = points[i-1].y;
852 x2 = points[i].x;
853 y2 = points[i].y;
854
855 /* Perform clipping */
856 /* FIXME: We don't actually want to clip, as it may change line slope */
857 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
858 continue;
859 }
860
861 /* Draw the end if it was clipped */
862 draw_end = (x2 != points[i].x || y2 != points[i].y);
863
864 func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end);
865 }
866 if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
867 SDL_BlendPoint(dst, points[count-1].x, points[count-1].y,
868 blendMode, r, g, b, a);
869 }
870 return 0;
871}
872
873#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */
874
875/* vi: set ts=4 sw=4 expandtab: */
876