SDL 2.0
SDL_blendline.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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_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,
33 SDL_bool draw_end)
34{
35 const SDL_PixelFormat *fmt = dst->format;
36 unsigned r, g, b, a, inva;
37
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) {
55 break;
58 break;
61 break;
62 default:
63 HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
64 break;
65 }
66 } else if (x1 == x2) {
67 switch (blendMode) {
70 break;
73 break;
76 break;
77 default:
78 VLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
79 break;
80 }
81 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
82 switch (blendMode) {
85 break;
88 break;
91 break;
92 default:
93 DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
94 break;
95 }
96 } else {
97 switch (blendMode) {
99 AALINE(x1, y1, x2, y2,
101 draw_end);
102 break;
104 AALINE(x1, y1, x2, y2,
106 draw_end);
107 break;
109 AALINE(x1, y1, x2, y2,
111 draw_end);
112 break;
113 default:
114 AALINE(x1, y1, x2, y2,
116 draw_end);
117 break;
118 }
119 }
120}
121
122static void
125 SDL_bool draw_end)
126{
127 unsigned r, g, b, a, inva;
128
130 r = DRAW_MUL(_r, _a);
131 g = DRAW_MUL(_g, _a);
132 b = DRAW_MUL(_b, _a);
133 a = _a;
134 } else {
135 r = _r;
136 g = _g;
137 b = _b;
138 a = _a;
139 }
140 inva = (a ^ 0xff);
141
142 if (y1 == y2) {
143 switch (blendMode) {
146 break;
149 break;
152 break;
153 default:
155 break;
156 }
157 } else if (x1 == x2) {
158 switch (blendMode) {
161 break;
164 break;
167 break;
168 default:
170 break;
171 }
172 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
173 switch (blendMode) {
176 break;
179 break;
182 break;
183 default:
185 break;
186 }
187 } else {
188 switch (blendMode) {
190 AALINE(x1, y1, x2, y2,
192 draw_end);
193 break;
195 AALINE(x1, y1, x2, y2,
197 draw_end);
198 break;
200 AALINE(x1, y1, x2, y2,
202 draw_end);
203 break;
204 default:
205 AALINE(x1, y1, x2, y2,
207 draw_end);
208 break;
209 }
210 }
211}
212
213static void
216 SDL_bool draw_end)
217{
218 unsigned r, g, b, a, inva;
219
221 r = DRAW_MUL(_r, _a);
222 g = DRAW_MUL(_g, _a);
223 b = DRAW_MUL(_b, _a);
224 a = _a;
225 } else {
226 r = _r;
227 g = _g;
228 b = _b;
229 a = _a;
230 }
231 inva = (a ^ 0xff);
232
233 if (y1 == y2) {
234 switch (blendMode) {
237 break;
240 break;
243 break;
244 default:
246 break;
247 }
248 } else if (x1 == x2) {
249 switch (blendMode) {
252 break;
255 break;
258 break;
259 default:
261 break;
262 }
263 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
264 switch (blendMode) {
267 break;
270 break;
273 break;
274 default:
276 break;
277 }
278 } else {
279 switch (blendMode) {
281 AALINE(x1, y1, x2, y2,
283 draw_end);
284 break;
286 AALINE(x1, y1, x2, y2,
288 draw_end);
289 break;
291 AALINE(x1, y1, x2, y2,
293 draw_end);
294 break;
295 default:
296 AALINE(x1, y1, x2, y2,
298 draw_end);
299 break;
300 }
301 }
302}
303
304static void
307 SDL_bool draw_end)
308{
309 const SDL_PixelFormat *fmt = dst->format;
310 unsigned r, g, b, a, inva;
311
313 r = DRAW_MUL(_r, _a);
314 g = DRAW_MUL(_g, _a);
315 b = DRAW_MUL(_b, _a);
316 a = _a;
317 } else {
318 r = _r;
319 g = _g;
320 b = _b;
321 a = _a;
322 }
323 inva = (a ^ 0xff);
324
325 if (y1 == y2) {
326 switch (blendMode) {
329 break;
332 break;
335 break;
336 default:
337 HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
338 break;
339 }
340 } else if (x1 == x2) {
341 switch (blendMode) {
344 break;
347 break;
350 break;
351 default:
352 VLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
353 break;
354 }
355 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
356 switch (blendMode) {
359 break;
362 break;
365 break;
366 default:
367 DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
368 break;
369 }
370 } else {
371 switch (blendMode) {
373 AALINE(x1, y1, x2, y2,
375 draw_end);
376 break;
378 AALINE(x1, y1, x2, y2,
380 draw_end);
381 break;
383 AALINE(x1, y1, x2, y2,
385 draw_end);
386 break;
387 default:
388 AALINE(x1, y1, x2, y2,
390 draw_end);
391 break;
392 }
393 }
394}
395
396static void
399 SDL_bool draw_end)
400{
401 const SDL_PixelFormat *fmt = dst->format;
402 unsigned r, g, b, a, inva;
403
405 r = DRAW_MUL(_r, _a);
406 g = DRAW_MUL(_g, _a);
407 b = DRAW_MUL(_b, _a);
408 a = _a;
409 } else {
410 r = _r;
411 g = _g;
412 b = _b;
413 a = _a;
414 }
415 inva = (a ^ 0xff);
416
417 if (y1 == y2) {
418 switch (blendMode) {
421 break;
424 break;
427 break;
428 default:
429 HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
430 break;
431 }
432 } else if (x1 == x2) {
433 switch (blendMode) {
436 break;
439 break;
442 break;
443 default:
444 VLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
445 break;
446 }
447 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
448 switch (blendMode) {
451 break;
454 break;
457 break;
458 default:
459 DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
460 break;
461 }
462 } else {
463 switch (blendMode) {
465 AALINE(x1, y1, x2, y2,
467 draw_end);
468 break;
470 AALINE(x1, y1, x2, y2,
472 draw_end);
473 break;
475 AALINE(x1, y1, x2, y2,
477 draw_end);
478 break;
479 default:
480 AALINE(x1, y1, x2, y2,
482 draw_end);
483 break;
484 }
485 }
486}
487
488static void
491 SDL_bool draw_end)
492{
493 unsigned r, g, b, a, inva;
494
496 r = DRAW_MUL(_r, _a);
497 g = DRAW_MUL(_g, _a);
498 b = DRAW_MUL(_b, _a);
499 a = _a;
500 } else {
501 r = _r;
502 g = _g;
503 b = _b;
504 a = _a;
505 }
506 inva = (a ^ 0xff);
507
508 if (y1 == y2) {
509 switch (blendMode) {
512 break;
515 break;
518 break;
519 default:
521 break;
522 }
523 } else if (x1 == x2) {
524 switch (blendMode) {
527 break;
530 break;
533 break;
534 default:
536 break;
537 }
538 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
539 switch (blendMode) {
542 break;
545 break;
548 break;
549 default:
551 break;
552 }
553 } else {
554 switch (blendMode) {
556 AALINE(x1, y1, x2, y2,
558 draw_end);
559 break;
561 AALINE(x1, y1, x2, y2,
563 draw_end);
564 break;
566 AALINE(x1, y1, x2, y2,
568 draw_end);
569 break;
570 default:
571 AALINE(x1, y1, x2, y2,
573 draw_end);
574 break;
575 }
576 }
577}
578
579static void
582 SDL_bool draw_end)
583{
584 unsigned r, g, b, a, inva;
585
587 r = DRAW_MUL(_r, _a);
588 g = DRAW_MUL(_g, _a);
589 b = DRAW_MUL(_b, _a);
590 a = _a;
591 } else {
592 r = _r;
593 g = _g;
594 b = _b;
595 a = _a;
596 }
597 inva = (a ^ 0xff);
598
599 if (y1 == y2) {
600 switch (blendMode) {
603 break;
606 break;
609 break;
610 default:
612 break;
613 }
614 } else if (x1 == x2) {
615 switch (blendMode) {
618 break;
621 break;
624 break;
625 default:
627 break;
628 }
629 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
630 switch (blendMode) {
633 break;
636 break;
639 break;
640 default:
642 break;
643 }
644 } else {
645 switch (blendMode) {
647 AALINE(x1, y1, x2, y2,
649 draw_end);
650 break;
652 AALINE(x1, y1, x2, y2,
654 draw_end);
655 break;
657 AALINE(x1, y1, x2, y2,
659 draw_end);
660 break;
661 default:
662 AALINE(x1, y1, x2, y2,
664 draw_end);
665 break;
666 }
667 }
668}
669
671 int x1, int y1, int x2, int y2,
673 Uint8 r, Uint8 g, Uint8 b, Uint8 a,
674 SDL_bool draw_end);
675
676static BlendLineFunc
678{
679 switch (fmt->BytesPerPixel) {
680 case 2:
681 if (fmt->Rmask == 0x7C00) {
683 } else if (fmt->Rmask == 0xF800) {
685 } else {
686 return SDL_BlendLine_RGB2;
687 }
688 /* break; -Wunreachable-code-break */
689 case 4:
690 if (fmt->Rmask == 0x00FF0000) {
691 if (fmt->Amask) {
693 } else {
695 }
696 } else {
697 if (fmt->Amask) {
698 return SDL_BlendLine_RGBA4;
699 } else {
700 return SDL_BlendLine_RGB4;
701 }
702 }
703 }
704 return NULL;
705}
706
707int
708SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
710{
712
713 if (!dst) {
714 return SDL_SetError("SDL_BlendLine(): Passed NULL destination surface");
715 }
716
718 if (!func) {
719 return SDL_SetError("SDL_BlendLine(): Unsupported surface format");
720 }
721
722 /* Perform clipping */
723 /* FIXME: We don't actually want to clip, as it may change line slope */
724 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
725 return 0;
726 }
727
728 func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_TRUE);
729 return 0;
730}
731
732int
735{
736 int i;
737 int x1, y1;
738 int x2, y2;
739 SDL_bool draw_end;
741
742 if (!dst) {
743 return SDL_SetError("SDL_BlendLines(): Passed NULL destination surface");
744 }
745
747 if (!func) {
748 return SDL_SetError("SDL_BlendLines(): Unsupported surface format");
749 }
750
751 for (i = 1; i < count; ++i) {
752 x1 = points[i-1].x;
753 y1 = points[i-1].y;
754 x2 = points[i].x;
755 y2 = points[i].y;
756
757 /* Perform clipping */
758 /* FIXME: We don't actually want to clip, as it may change line slope */
759 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
760 continue;
761 }
762
763 /* Draw the end if it was clipped */
764 draw_end = (x2 != points[i].x || y2 != points[i].y);
765
766 func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end);
767 }
768 if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
770 blendMode, r, g, b, a);
771 }
772 return 0;
773}
774
775#endif /* !SDL_RENDER_DISABLED */
776
777/* vi: set ts=4 sw=4 expandtab: */
static void SDL_BlendLine_RGB4(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, SDL_bool draw_end)
static void SDL_BlendLine_RGBA4(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, SDL_bool draw_end)
static void SDL_BlendLine_ARGB8888(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, SDL_bool draw_end)
int SDL_BlendLines(SDL_Surface *dst, const SDL_Point *points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
static void SDL_BlendLine_RGB555(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, SDL_bool draw_end)
void(* BlendLineFunc)(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_bool draw_end)
static void SDL_BlendLine_RGB565(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, SDL_bool draw_end)
static void SDL_BlendLine_RGB888(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, SDL_bool draw_end)
static void SDL_BlendLine_RGB2(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, SDL_bool draw_end)
Definition: SDL_blendline.c:31
static BlendLineFunc SDL_CalculateBlendLineFunc(const SDL_PixelFormat *fmt)
int SDL_BlendLine(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:41
@ SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
@ SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
@ SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
int SDL_BlendPoint(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
#define DRAW_SETPIXELXY_RGB565(x, y)
Definition: SDL_draw.h:140
#define DRAW_SETPIXELXY4_MOD_RGB(x, y)
Definition: SDL_draw.h:254
#define HLINE(type, op, draw_end)
Definition: SDL_draw.h:296
#define DRAW_SETPIXELXY_MOD_RGB888(x, y)
Definition: SDL_draw.h:180
#define DRAW_SETPIXELXY_MOD_RGB555(x, y)
Definition: SDL_draw.h:118
#define DRAW_SETPIXELXY4_ADD_RGB(x, y)
Definition: SDL_draw.h:248
#define DRAW_SETPIXELXY_ADD_RGB888(x, y)
Definition: SDL_draw.h:177
#define DRAW_SETPIXELXY_ADD_RGB565(x, y)
Definition: SDL_draw.h:146
#define DRAW_SETPIXELXY_RGB888(x, y)
Definition: SDL_draw.h:171
#define DRAW_SETPIXEL_RGB888
Definition: SDL_draw.h:156
#define DRAW_SETPIXELXY4_RGB(x, y)
Definition: SDL_draw.h:236
#define DRAW_SETPIXEL_ARGB8888
Definition: SDL_draw.h:187
#define DRAW_SETPIXELXY_BLEND_RGB888(x, y)
Definition: SDL_draw.h:174
#define DRAW_SETPIXELXY2_BLEND_RGB(x, y)
Definition: SDL_draw.h:239
#define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end)
Definition: SDL_draw.h:537
#define DRAW_SETPIXELXY_RGB555(x, y)
Definition: SDL_draw.h:109
#define DRAW_SETPIXELXY_ADD_RGB555(x, y)
Definition: SDL_draw.h:115
#define ABS(_x)
Definition: SDL_draw.h:293
#define DRAW_SETPIXEL_RGB565
Definition: SDL_draw.h:125
#define DRAW_SETPIXEL_MOD_RGB565
Definition: SDL_draw.h:136
#define DRAW_SETPIXELXY_ARGB8888(x, y)
Definition: SDL_draw.h:202
#define DRAW_SETPIXEL_BLEND_RGB
Definition: SDL_draw.h:221
#define DRAW_SETPIXELXY_MOD_RGB565(x, y)
Definition: SDL_draw.h:149
#define DRAW_SETPIXELXY_BLEND_RGB565(x, y)
Definition: SDL_draw.h:143
#define DLINE(type, op, draw_end)
Definition: SDL_draw.h:340
#define DRAW_SETPIXELXY2_ADD_RGB(x, y)
Definition: SDL_draw.h:245
#define DRAW_SETPIXEL_ADD_ARGB8888
Definition: SDL_draw.h:194
#define DRAW_MUL(_a, _b)
Definition: SDL_draw.h:29
#define DRAW_SETPIXEL_RGB
Definition: SDL_draw.h:218
#define DRAW_SETPIXEL_MOD_RGBA
Definition: SDL_draw.h:273
#define DRAW_SETPIXELXY_BLEND_RGB555(x, y)
Definition: SDL_draw.h:112
#define DRAW_SETPIXELXY_BLEND_ARGB8888(x, y)
Definition: SDL_draw.h:205
#define DRAW_SETPIXEL_MOD_ARGB8888
Definition: SDL_draw.h:198
#define DRAW_SETPIXEL_BLEND_RGB565
Definition: SDL_draw.h:128
#define DRAW_SETPIXELXY4_ADD_RGBA(x, y)
Definition: SDL_draw.h:283
#define DRAW_SETPIXEL_ADD_RGB888
Definition: SDL_draw.h:163
#define DRAW_SETPIXEL_BLEND_ARGB8888
Definition: SDL_draw.h:190
#define DRAW_SETPIXEL_ADD_RGB555
Definition: SDL_draw.h:101
#define DRAW_SETPIXELXY_ADD_ARGB8888(x, y)
Definition: SDL_draw.h:208
#define DRAW_SETPIXEL_RGB555
Definition: SDL_draw.h:94
#define DRAW_SETPIXELXY_MOD_ARGB8888(x, y)
Definition: SDL_draw.h:211
#define DRAW_SETPIXEL_MOD_RGB
Definition: SDL_draw.h:229
#define DRAW_SETPIXELXY4_BLEND_RGBA(x, y)
Definition: SDL_draw.h:280
#define DRAW_SETPIXEL_MOD_RGB888
Definition: SDL_draw.h:167
#define DRAW_SETPIXEL_RGBA
Definition: SDL_draw.h:262
#define DRAW_SETPIXEL_BLEND_RGB888
Definition: SDL_draw.h:159
#define DRAW_SETPIXELXY4_BLEND_RGB(x, y)
Definition: SDL_draw.h:242
#define DRAW_SETPIXEL_BLEND_RGBA
Definition: SDL_draw.h:265
#define DRAW_SETPIXELXY2_MOD_RGB(x, y)
Definition: SDL_draw.h:251
#define DRAW_SETPIXEL_MOD_RGB555
Definition: SDL_draw.h:105
#define DRAW_SETPIXEL_BLEND_RGB555
Definition: SDL_draw.h:97
#define DRAW_SETPIXELXY4_MOD_RGBA(x, y)
Definition: SDL_draw.h:286
#define DRAW_SETPIXELXY2_RGB(x, y)
Definition: SDL_draw.h:233
#define DRAW_SETPIXEL_ADD_RGBA
Definition: SDL_draw.h:269
#define DRAW_SETPIXELXY4_RGBA(x, y)
Definition: SDL_draw.h:277
#define VLINE(type, op, draw_end)
Definition: SDL_draw.h:318
#define DRAW_SETPIXEL_ADD_RGB
Definition: SDL_draw.h:225
#define DRAW_SETPIXEL_ADD_RGB565
Definition: SDL_draw.h:132
#define SDL_SetError
#define SDL_IntersectRectAndLine
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLboolean GLboolean GLboolean b
GLfixed GLfixed GLint GLint GLfixed points
GLenum func
GLfixed GLfixed GLfixed y2
GLfixed y1
GLuint GLfloat GLfloat GLfloat x1
GLboolean GLboolean GLboolean GLboolean a
GLfixed GLfixed x2
GLenum GLenum dst
GLboolean GLboolean g
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
uint32_t Uint32
Definition: SDL_stdinc.h:203
uint16_t Uint16
Definition: SDL_stdinc.h:191
uint8_t Uint8
Definition: SDL_stdinc.h:179
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:167
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
The structure that defines a point (integer)
Definition: SDL_rect.h:49
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
static SDL_BlendMode blendMode
Definition: testdraw2.c:34