1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2018 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 
30 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)31 SDL_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         default:
63             HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
64             break;
65         }
66     } else if (x1 == x2) {
67         switch (blendMode) {
68         case SDL_BLENDMODE_BLEND:
69             VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
70             break;
71         case SDL_BLENDMODE_ADD:
72             VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
73             break;
74         case SDL_BLENDMODE_MOD:
75             VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
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) {
83         case SDL_BLENDMODE_BLEND:
84             DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
85             break;
86         case SDL_BLENDMODE_ADD:
87             DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
88             break;
89         case SDL_BLENDMODE_MOD:
90             DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
91             break;
92         default:
93             DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
94             break;
95         }
96     } else {
97         switch (blendMode) {
98         case SDL_BLENDMODE_BLEND:
99             AALINE(x1, y1, x2, y2,
100                    DRAW_SETPIXELXY2_BLEND_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
101                    draw_end);
102             break;
103         case SDL_BLENDMODE_ADD:
104             AALINE(x1, y1, x2, y2,
105                    DRAW_SETPIXELXY2_ADD_RGB, DRAW_SETPIXELXY2_ADD_RGB,
106                    draw_end);
107             break;
108         case SDL_BLENDMODE_MOD:
109             AALINE(x1, y1, x2, y2,
110                    DRAW_SETPIXELXY2_MOD_RGB, DRAW_SETPIXELXY2_MOD_RGB,
111                    draw_end);
112             break;
113         default:
114             AALINE(x1, y1, x2, y2,
115                    DRAW_SETPIXELXY2_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
116                    draw_end);
117             break;
118         }
119     }
120 }
121 
122 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)123 SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2,
124                      SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
125                      SDL_bool draw_end)
126 {
127     unsigned r, g, b, a, inva;
128 
129     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
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) {
144         case SDL_BLENDMODE_BLEND:
145             HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
146             break;
147         case SDL_BLENDMODE_ADD:
148             HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
149             break;
150         case SDL_BLENDMODE_MOD:
151             HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
152             break;
153         default:
154             HLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
155             break;
156         }
157     } else if (x1 == x2) {
158         switch (blendMode) {
159         case SDL_BLENDMODE_BLEND:
160             VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
161             break;
162         case SDL_BLENDMODE_ADD:
163             VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
164             break;
165         case SDL_BLENDMODE_MOD:
166             VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
167             break;
168         default:
169             VLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
170             break;
171         }
172     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
173         switch (blendMode) {
174         case SDL_BLENDMODE_BLEND:
175             DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
176             break;
177         case SDL_BLENDMODE_ADD:
178             DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
179             break;
180         case SDL_BLENDMODE_MOD:
181             DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
182             break;
183         default:
184             DLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
185             break;
186         }
187     } else {
188         switch (blendMode) {
189         case SDL_BLENDMODE_BLEND:
190             AALINE(x1, y1, x2, y2,
191                    DRAW_SETPIXELXY_BLEND_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
192                    draw_end);
193             break;
194         case SDL_BLENDMODE_ADD:
195             AALINE(x1, y1, x2, y2,
196                    DRAW_SETPIXELXY_ADD_RGB555, DRAW_SETPIXELXY_ADD_RGB555,
197                    draw_end);
198             break;
199         case SDL_BLENDMODE_MOD:
200             AALINE(x1, y1, x2, y2,
201                    DRAW_SETPIXELXY_MOD_RGB555, DRAW_SETPIXELXY_MOD_RGB555,
202                    draw_end);
203             break;
204         default:
205             AALINE(x1, y1, x2, y2,
206                    DRAW_SETPIXELXY_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
207                    draw_end);
208             break;
209         }
210     }
211 }
212 
213 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)214 SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2,
215                      SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
216                      SDL_bool draw_end)
217 {
218     unsigned r, g, b, a, inva;
219 
220     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
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) {
235         case SDL_BLENDMODE_BLEND:
236             HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
237             break;
238         case SDL_BLENDMODE_ADD:
239             HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
240             break;
241         case SDL_BLENDMODE_MOD:
242             HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
243             break;
244         default:
245             HLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
246             break;
247         }
248     } else if (x1 == x2) {
249         switch (blendMode) {
250         case SDL_BLENDMODE_BLEND:
251             VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
252             break;
253         case SDL_BLENDMODE_ADD:
254             VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
255             break;
256         case SDL_BLENDMODE_MOD:
257             VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
258             break;
259         default:
260             VLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
261             break;
262         }
263     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
264         switch (blendMode) {
265         case SDL_BLENDMODE_BLEND:
266             DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
267             break;
268         case SDL_BLENDMODE_ADD:
269             DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
270             break;
271         case SDL_BLENDMODE_MOD:
272             DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
273             break;
274         default:
275             DLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
276             break;
277         }
278     } else {
279         switch (blendMode) {
280         case SDL_BLENDMODE_BLEND:
281             AALINE(x1, y1, x2, y2,
282                    DRAW_SETPIXELXY_BLEND_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
283                    draw_end);
284             break;
285         case SDL_BLENDMODE_ADD:
286             AALINE(x1, y1, x2, y2,
287                    DRAW_SETPIXELXY_ADD_RGB565, DRAW_SETPIXELXY_ADD_RGB565,
288                    draw_end);
289             break;
290         case SDL_BLENDMODE_MOD:
291             AALINE(x1, y1, x2, y2,
292                    DRAW_SETPIXELXY_MOD_RGB565, DRAW_SETPIXELXY_MOD_RGB565,
293                    draw_end);
294             break;
295         default:
296             AALINE(x1, y1, x2, y2,
297                    DRAW_SETPIXELXY_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
298                    draw_end);
299             break;
300         }
301     }
302 }
303 
304 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)305 SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
306                    SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
307                    SDL_bool draw_end)
308 {
309     const SDL_PixelFormat *fmt = dst->format;
310     unsigned r, g, b, a, inva;
311 
312     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
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) {
327         case SDL_BLENDMODE_BLEND:
328             HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
329             break;
330         case SDL_BLENDMODE_ADD:
331             HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
332             break;
333         case SDL_BLENDMODE_MOD:
334             HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
335             break;
336         default:
337             HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
338             break;
339         }
340     } else if (x1 == x2) {
341         switch (blendMode) {
342         case SDL_BLENDMODE_BLEND:
343             VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
344             break;
345         case SDL_BLENDMODE_ADD:
346             VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
347             break;
348         case SDL_BLENDMODE_MOD:
349             VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
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) {
357         case SDL_BLENDMODE_BLEND:
358             DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
359             break;
360         case SDL_BLENDMODE_ADD:
361             DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
362             break;
363         case SDL_BLENDMODE_MOD:
364             DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
365             break;
366         default:
367             DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
368             break;
369         }
370     } else {
371         switch (blendMode) {
372         case SDL_BLENDMODE_BLEND:
373             AALINE(x1, y1, x2, y2,
374                    DRAW_SETPIXELXY4_BLEND_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
375                    draw_end);
376             break;
377         case SDL_BLENDMODE_ADD:
378             AALINE(x1, y1, x2, y2,
379                    DRAW_SETPIXELXY4_ADD_RGB, DRAW_SETPIXELXY4_ADD_RGB,
380                    draw_end);
381             break;
382         case SDL_BLENDMODE_MOD:
383             AALINE(x1, y1, x2, y2,
384                    DRAW_SETPIXELXY4_MOD_RGB, DRAW_SETPIXELXY4_MOD_RGB,
385                    draw_end);
386             break;
387         default:
388             AALINE(x1, y1, x2, y2,
389                    DRAW_SETPIXELXY4_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
390                    draw_end);
391             break;
392         }
393     }
394 }
395 
396 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)397 SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2,
398                     SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
399                     SDL_bool draw_end)
400 {
401     const SDL_PixelFormat *fmt = dst->format;
402     unsigned r, g, b, a, inva;
403 
404     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
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) {
419         case SDL_BLENDMODE_BLEND:
420             HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
421             break;
422         case SDL_BLENDMODE_ADD:
423             HLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
424             break;
425         case SDL_BLENDMODE_MOD:
426             HLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
427             break;
428         default:
429             HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
430             break;
431         }
432     } else if (x1 == x2) {
433         switch (blendMode) {
434         case SDL_BLENDMODE_BLEND:
435             VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
436             break;
437         case SDL_BLENDMODE_ADD:
438             VLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
439             break;
440         case SDL_BLENDMODE_MOD:
441             VLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
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) {
449         case SDL_BLENDMODE_BLEND:
450             DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
451             break;
452         case SDL_BLENDMODE_ADD:
453             DLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
454             break;
455         case SDL_BLENDMODE_MOD:
456             DLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
457             break;
458         default:
459             DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
460             break;
461         }
462     } else {
463         switch (blendMode) {
464         case SDL_BLENDMODE_BLEND:
465             AALINE(x1, y1, x2, y2,
466                    DRAW_SETPIXELXY4_BLEND_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
467                    draw_end);
468             break;
469         case SDL_BLENDMODE_ADD:
470             AALINE(x1, y1, x2, y2,
471                    DRAW_SETPIXELXY4_ADD_RGBA, DRAW_SETPIXELXY4_ADD_RGBA,
472                    draw_end);
473             break;
474         case SDL_BLENDMODE_MOD:
475             AALINE(x1, y1, x2, y2,
476                    DRAW_SETPIXELXY4_MOD_RGBA, DRAW_SETPIXELXY4_MOD_RGBA,
477                    draw_end);
478             break;
479         default:
480             AALINE(x1, y1, x2, y2,
481                    DRAW_SETPIXELXY4_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
482                    draw_end);
483             break;
484         }
485     }
486 }
487 
488 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)489 SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
490                      SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
491                      SDL_bool draw_end)
492 {
493     unsigned r, g, b, a, inva;
494 
495     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
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) {
510         case SDL_BLENDMODE_BLEND:
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
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)580 SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
581                        SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
582                        SDL_bool draw_end)
583 {
584     unsigned r, g, b, a, inva;
585 
586     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
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) {
601         case SDL_BLENDMODE_BLEND:
602             HLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
603             break;
604         case SDL_BLENDMODE_ADD:
605             HLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
606             break;
607         case SDL_BLENDMODE_MOD:
608             HLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
609             break;
610         default:
611             HLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
612             break;
613         }
614     } else if (x1 == x2) {
615         switch (blendMode) {
616         case SDL_BLENDMODE_BLEND:
617             VLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
618             break;
619         case SDL_BLENDMODE_ADD:
620             VLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
621             break;
622         case SDL_BLENDMODE_MOD:
623             VLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
624             break;
625         default:
626             VLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
627             break;
628         }
629     } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
630         switch (blendMode) {
631         case SDL_BLENDMODE_BLEND:
632             DLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
633             break;
634         case SDL_BLENDMODE_ADD:
635             DLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
636             break;
637         case SDL_BLENDMODE_MOD:
638             DLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
639             break;
640         default:
641             DLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
642             break;
643         }
644     } else {
645         switch (blendMode) {
646         case SDL_BLENDMODE_BLEND:
647             AALINE(x1, y1, x2, y2,
648                    DRAW_SETPIXELXY_BLEND_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
649                    draw_end);
650             break;
651         case SDL_BLENDMODE_ADD:
652             AALINE(x1, y1, x2, y2,
653                    DRAW_SETPIXELXY_ADD_ARGB8888, DRAW_SETPIXELXY_ADD_ARGB8888,
654                    draw_end);
655             break;
656         case SDL_BLENDMODE_MOD:
657             AALINE(x1, y1, x2, y2,
658                    DRAW_SETPIXELXY_MOD_ARGB8888, DRAW_SETPIXELXY_MOD_ARGB8888,
659                    draw_end);
660             break;
661         default:
662             AALINE(x1, y1, x2, y2,
663                    DRAW_SETPIXELXY_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
664                    draw_end);
665             break;
666         }
667     }
668 }
669 
670 typedef void (*BlendLineFunc) (SDL_Surface * dst,
671                                int x1, int y1, int x2, int y2,
672                                SDL_BlendMode blendMode,
673                                Uint8 r, Uint8 g, Uint8 b, Uint8 a,
674                                SDL_bool draw_end);
675 
676 static BlendLineFunc
SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt)677 SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt)
678 {
679     switch (fmt->BytesPerPixel) {
680     case 2:
681         if (fmt->Rmask == 0x7C00) {
682             return SDL_BlendLine_RGB555;
683         } else if (fmt->Rmask == 0xF800) {
684             return SDL_BlendLine_RGB565;
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) {
692                 return SDL_BlendLine_ARGB8888;
693             } else {
694                 return SDL_BlendLine_RGB888;
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 
707 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)708 SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
709               SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
710 {
711     BlendLineFunc func;
712 
713     if (!dst) {
714         return SDL_SetError("SDL_BlendLine(): Passed NULL destination surface");
715     }
716 
717     func = SDL_CalculateBlendLineFunc(dst->format);
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 
732 int
SDL_BlendLines(SDL_Surface * dst,const SDL_Point * points,int count,SDL_BlendMode blendMode,Uint8 r,Uint8 g,Uint8 b,Uint8 a)733 SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count,
734                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
735 {
736     int i;
737     int x1, y1;
738     int x2, y2;
739     SDL_bool draw_end;
740     BlendLineFunc func;
741 
742     if (!dst) {
743         return SDL_SetError("SDL_BlendLines(): Passed NULL destination surface");
744     }
745 
746     func = SDL_CalculateBlendLineFunc(dst->format);
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) {
769         SDL_BlendPoint(dst, points[count-1].x, 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: */
778