1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 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 #include "../../video/SDL_blit.h"
24 
25 /* This code assumes that r, g, b, a are the source color,
26  * and in the blend and add case, the RGB values are premultiplied by a.
27  */
28 
29 #define DRAW_MUL(_a, _b) (((unsigned)(_a)*(_b))/255)
30 
31 #define DRAW_FASTSETPIXEL(type) \
32     *pixel = (type) color
33 
34 #define DRAW_FASTSETPIXEL1 DRAW_FASTSETPIXEL(Uint8)
35 #define DRAW_FASTSETPIXEL2 DRAW_FASTSETPIXEL(Uint16)
36 #define DRAW_FASTSETPIXEL4 DRAW_FASTSETPIXEL(Uint32)
37 
38 #define DRAW_FASTSETPIXELXY(x, y, type, bpp, color) \
39     *(type *)((Uint8 *)dst->pixels + (y) * dst->pitch \
40                                    + (x) * bpp) = (type) color
41 
42 #define DRAW_FASTSETPIXELXY1(x, y) DRAW_FASTSETPIXELXY(x, y, Uint8, 1, color)
43 #define DRAW_FASTSETPIXELXY2(x, y) DRAW_FASTSETPIXELXY(x, y, Uint16, 2, color)
44 #define DRAW_FASTSETPIXELXY4(x, y) DRAW_FASTSETPIXELXY(x, y, Uint32, 4, color)
45 
46 #define DRAW_SETPIXEL(setpixel) \
47 do { \
48     unsigned sr = r, sg = g, sb = b, sa = a; (void) sa; \
49     setpixel; \
50 } while (0)
51 
52 #define DRAW_SETPIXEL_BLEND(getpixel, setpixel) \
53 do { \
54     unsigned sr, sg, sb, sa = 0xFF; \
55     getpixel; \
56     sr = DRAW_MUL(inva, sr) + r; \
57     sg = DRAW_MUL(inva, sg) + g; \
58     sb = DRAW_MUL(inva, sb) + b; \
59     sa = DRAW_MUL(inva, sa) + a; \
60     setpixel; \
61 } while (0)
62 
63 #define DRAW_SETPIXEL_ADD(getpixel, setpixel) \
64 do { \
65     unsigned sr, sg, sb, sa; (void) sa; \
66     getpixel; \
67     sr += r; if (sr > 0xff) sr = 0xff; \
68     sg += g; if (sg > 0xff) sg = 0xff; \
69     sb += b; if (sb > 0xff) sb = 0xff; \
70     setpixel; \
71 } while (0)
72 
73 #define DRAW_SETPIXEL_MOD(getpixel, setpixel) \
74 do { \
75     unsigned sr, sg, sb, sa; (void) sa; \
76     getpixel; \
77     sr = DRAW_MUL(sr, r); \
78     sg = DRAW_MUL(sg, g); \
79     sb = DRAW_MUL(sb, b); \
80     setpixel; \
81 } while (0)
82 
83 #define DRAW_SETPIXELXY(x, y, type, bpp, op) \
84 do { \
85     type *pixel = (type *)((Uint8 *)dst->pixels + (y) * dst->pitch \
86                                                 + (x) * bpp); \
87     op; \
88 } while (0)
89 
90 /*
91  * Define draw operators for RGB555
92  */
93 
94 #define DRAW_SETPIXEL_RGB555 \
95     DRAW_SETPIXEL(RGB555_FROM_RGB(*pixel, sr, sg, sb))
96 
97 #define DRAW_SETPIXEL_BLEND_RGB555 \
98     DRAW_SETPIXEL_BLEND(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
99                         RGB555_FROM_RGB(*pixel, sr, sg, sb))
100 
101 #define DRAW_SETPIXEL_ADD_RGB555 \
102     DRAW_SETPIXEL_ADD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
103                       RGB555_FROM_RGB(*pixel, sr, sg, sb))
104 
105 #define DRAW_SETPIXEL_MOD_RGB555 \
106     DRAW_SETPIXEL_MOD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
107                       RGB555_FROM_RGB(*pixel, sr, sg, sb))
108 
109 #define DRAW_SETPIXELXY_RGB555(x, y) \
110     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB555)
111 
112 #define DRAW_SETPIXELXY_BLEND_RGB555(x, y) \
113     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB555)
114 
115 #define DRAW_SETPIXELXY_ADD_RGB555(x, y) \
116     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB555)
117 
118 #define DRAW_SETPIXELXY_MOD_RGB555(x, y) \
119     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB555)
120 
121 /*
122  * Define draw operators for RGB565
123  */
124 
125 #define DRAW_SETPIXEL_RGB565 \
126     DRAW_SETPIXEL(RGB565_FROM_RGB(*pixel, sr, sg, sb))
127 
128 #define DRAW_SETPIXEL_BLEND_RGB565 \
129     DRAW_SETPIXEL_BLEND(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
130                         RGB565_FROM_RGB(*pixel, sr, sg, sb))
131 
132 #define DRAW_SETPIXEL_ADD_RGB565 \
133     DRAW_SETPIXEL_ADD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
134                       RGB565_FROM_RGB(*pixel, sr, sg, sb))
135 
136 #define DRAW_SETPIXEL_MOD_RGB565 \
137     DRAW_SETPIXEL_MOD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
138                       RGB565_FROM_RGB(*pixel, sr, sg, sb))
139 
140 #define DRAW_SETPIXELXY_RGB565(x, y) \
141     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB565)
142 
143 #define DRAW_SETPIXELXY_BLEND_RGB565(x, y) \
144     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB565)
145 
146 #define DRAW_SETPIXELXY_ADD_RGB565(x, y) \
147     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB565)
148 
149 #define DRAW_SETPIXELXY_MOD_RGB565(x, y) \
150     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB565)
151 
152 /*
153  * Define draw operators for RGB888
154  */
155 
156 #define DRAW_SETPIXEL_RGB888 \
157     DRAW_SETPIXEL(RGB888_FROM_RGB(*pixel, sr, sg, sb))
158 
159 #define DRAW_SETPIXEL_BLEND_RGB888 \
160     DRAW_SETPIXEL_BLEND(RGB_FROM_RGB888(*pixel, sr, sg, sb), \
161                         RGB888_FROM_RGB(*pixel, sr, sg, sb))
162 
163 #define DRAW_SETPIXEL_ADD_RGB888 \
164     DRAW_SETPIXEL_ADD(RGB_FROM_RGB888(*pixel, sr, sg, sb), \
165                       RGB888_FROM_RGB(*pixel, sr, sg, sb))
166 
167 #define DRAW_SETPIXEL_MOD_RGB888 \
168     DRAW_SETPIXEL_MOD(RGB_FROM_RGB888(*pixel, sr, sg, sb), \
169                       RGB888_FROM_RGB(*pixel, sr, sg, sb))
170 
171 #define DRAW_SETPIXELXY_RGB888(x, y) \
172     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB888)
173 
174 #define DRAW_SETPIXELXY_BLEND_RGB888(x, y) \
175     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGB888)
176 
177 #define DRAW_SETPIXELXY_ADD_RGB888(x, y) \
178     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGB888)
179 
180 #define DRAW_SETPIXELXY_MOD_RGB888(x, y) \
181     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB888)
182 
183 /*
184  * Define draw operators for ARGB8888
185  */
186 
187 #define DRAW_SETPIXEL_ARGB8888 \
188     DRAW_SETPIXEL(ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
189 
190 #define DRAW_SETPIXEL_BLEND_ARGB8888 \
191     DRAW_SETPIXEL_BLEND(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
192                         ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
193 
194 #define DRAW_SETPIXEL_ADD_ARGB8888 \
195     DRAW_SETPIXEL_ADD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
196                       ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
197 
198 #define DRAW_SETPIXEL_MOD_ARGB8888 \
199     DRAW_SETPIXEL_MOD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
200                       ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
201 
202 #define DRAW_SETPIXELXY_ARGB8888(x, y) \
203     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ARGB8888)
204 
205 #define DRAW_SETPIXELXY_BLEND_ARGB8888(x, y) \
206     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_ARGB8888)
207 
208 #define DRAW_SETPIXELXY_ADD_ARGB8888(x, y) \
209     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_ARGB8888)
210 
211 #define DRAW_SETPIXELXY_MOD_ARGB8888(x, y) \
212     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_ARGB8888)
213 
214 /*
215  * Define draw operators for general RGB
216  */
217 
218 #define DRAW_SETPIXEL_RGB \
219     DRAW_SETPIXEL(PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
220 
221 #define DRAW_SETPIXEL_BLEND_RGB \
222     DRAW_SETPIXEL_BLEND(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
223                         PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
224 
225 #define DRAW_SETPIXEL_ADD_RGB \
226     DRAW_SETPIXEL_ADD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
227                       PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
228 
229 #define DRAW_SETPIXEL_MOD_RGB \
230     DRAW_SETPIXEL_MOD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
231                       PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
232 
233 #define DRAW_SETPIXELXY2_RGB(x, y) \
234     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB)
235 
236 #define DRAW_SETPIXELXY4_RGB(x, y) \
237     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB)
238 
239 #define DRAW_SETPIXELXY2_BLEND_RGB(x, y) \
240     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB)
241 
242 #define DRAW_SETPIXELXY4_BLEND_RGB(x, y) \
243     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGB)
244 
245 #define DRAW_SETPIXELXY2_ADD_RGB(x, y) \
246     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB)
247 
248 #define DRAW_SETPIXELXY4_ADD_RGB(x, y) \
249     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGB)
250 
251 #define DRAW_SETPIXELXY2_MOD_RGB(x, y) \
252     DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB)
253 
254 #define DRAW_SETPIXELXY4_MOD_RGB(x, y) \
255     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB)
256 
257 
258 /*
259  * Define draw operators for general RGBA
260  */
261 
262 #define DRAW_SETPIXEL_RGBA \
263     DRAW_SETPIXEL(PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
264 
265 #define DRAW_SETPIXEL_BLEND_RGBA \
266     DRAW_SETPIXEL_BLEND(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
267                         PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
268 
269 #define DRAW_SETPIXEL_ADD_RGBA \
270     DRAW_SETPIXEL_ADD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
271                       PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
272 
273 #define DRAW_SETPIXEL_MOD_RGBA \
274     DRAW_SETPIXEL_MOD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
275                       PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
276 
277 #define DRAW_SETPIXELXY4_RGBA(x, y) \
278     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGBA)
279 
280 #define DRAW_SETPIXELXY4_BLEND_RGBA(x, y) \
281     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGBA)
282 
283 #define DRAW_SETPIXELXY4_ADD_RGBA(x, y) \
284     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGBA)
285 
286 #define DRAW_SETPIXELXY4_MOD_RGBA(x, y) \
287     DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGBA)
288 
289 /*
290  * Define line drawing macro
291  */
292 
293 #define ABS(_x) ((_x) < 0 ? -(_x) : (_x))
294 
295 /* Horizontal line */
296 #define HLINE(type, op, draw_end) \
297 { \
298     int length; \
299     int pitch = (dst->pitch / dst->format->BytesPerPixel); \
300     type *pixel; \
301     if (x1 <= x2) { \
302         pixel = (type *)dst->pixels + y1 * pitch + x1; \
303         length = draw_end ? (x2-x1+1) : (x2-x1); \
304     } else { \
305         pixel = (type *)dst->pixels + y1 * pitch + x2; \
306         if (!draw_end) { \
307             ++pixel; \
308         } \
309         length = draw_end ? (x1-x2+1) : (x1-x2); \
310     } \
311     while (length--) { \
312         op; \
313         ++pixel; \
314     } \
315 }
316 
317 /* Vertical line */
318 #define VLINE(type, op, draw_end) \
319 { \
320     int length; \
321     int pitch = (dst->pitch / dst->format->BytesPerPixel); \
322     type *pixel; \
323     if (y1 <= y2) { \
324         pixel = (type *)dst->pixels + y1 * pitch + x1; \
325         length = draw_end ? (y2-y1+1) : (y2-y1); \
326     } else { \
327         pixel = (type *)dst->pixels + y2 * pitch + x1; \
328         if (!draw_end) { \
329             pixel += pitch; \
330         } \
331         length = draw_end ? (y1-y2+1) : (y1-y2); \
332     } \
333     while (length--) { \
334         op; \
335         pixel += pitch; \
336     } \
337 }
338 
339 /* Diagonal line */
340 #define DLINE(type, op, draw_end) \
341 { \
342     int length; \
343     int pitch = (dst->pitch / dst->format->BytesPerPixel); \
344     type *pixel; \
345     if (y1 <= y2) { \
346         pixel = (type *)dst->pixels + y1 * pitch + x1; \
347         if (x1 <= x2) { \
348             ++pitch; \
349         } else { \
350             --pitch; \
351         } \
352         length = (y2-y1); \
353     } else { \
354         pixel = (type *)dst->pixels + y2 * pitch + x2; \
355         if (x2 <= x1) { \
356             ++pitch; \
357         } else { \
358             --pitch; \
359         } \
360         if (!draw_end) { \
361             pixel += pitch; \
362         } \
363         length = (y1-y2); \
364     } \
365     if (draw_end) { \
366         ++length; \
367     } \
368     while (length--) { \
369         op; \
370         pixel += pitch; \
371     } \
372 }
373 
374 /* Bresenham's line algorithm */
375 #define BLINE(x1, y1, x2, y2, op, draw_end) \
376 { \
377     int i, deltax, deltay, numpixels; \
378     int d, dinc1, dinc2; \
379     int x, xinc1, xinc2; \
380     int y, yinc1, yinc2; \
381  \
382     deltax = ABS(x2 - x1); \
383     deltay = ABS(y2 - y1); \
384  \
385     if (deltax >= deltay) { \
386         numpixels = deltax + 1; \
387         d = (2 * deltay) - deltax; \
388         dinc1 = deltay * 2; \
389         dinc2 = (deltay - deltax) * 2; \
390         xinc1 = 1; \
391         xinc2 = 1; \
392         yinc1 = 0; \
393         yinc2 = 1; \
394     } else { \
395         numpixels = deltay + 1; \
396         d = (2 * deltax) - deltay; \
397         dinc1 = deltax * 2; \
398         dinc2 = (deltax - deltay) * 2; \
399         xinc1 = 0; \
400         xinc2 = 1; \
401         yinc1 = 1; \
402         yinc2 = 1; \
403     } \
404  \
405     if (x1 > x2) { \
406         xinc1 = -xinc1; \
407         xinc2 = -xinc2; \
408     } \
409     if (y1 > y2) { \
410         yinc1 = -yinc1; \
411         yinc2 = -yinc2; \
412     } \
413  \
414     x = x1; \
415     y = y1; \
416  \
417     if (!draw_end) { \
418         --numpixels; \
419     } \
420     for (i = 0; i < numpixels; ++i) { \
421         op(x, y); \
422         if (d < 0) { \
423             d += dinc1; \
424             x += xinc1; \
425             y += yinc1; \
426         } else { \
427             d += dinc2; \
428             x += xinc2; \
429             y += yinc2; \
430         } \
431     } \
432 }
433 
434 /* Xiaolin Wu's line algorithm, based on Michael Abrash's implementation */
435 #define WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \
436 { \
437     Uint16 ErrorAdj, ErrorAcc; \
438     Uint16 ErrorAccTemp, Weighting; \
439     int DeltaX, DeltaY, Temp, XDir; \
440     unsigned r, g, b, a, inva; \
441  \
442     /* Draw the initial pixel, which is always exactly intersected by \
443        the line and so needs no weighting */ \
444     opaque_op(x1, y1); \
445  \
446     /* Draw the final pixel, which is always exactly intersected by the line \
447        and so needs no weighting */ \
448     if (draw_end) { \
449         opaque_op(x2, y2); \
450     } \
451  \
452     /* Make sure the line runs top to bottom */ \
453     if (y1 > y2) { \
454         Temp = y1; y1 = y2; y2 = Temp; \
455         Temp = x1; x1 = x2; x2 = Temp; \
456     } \
457     DeltaY = y2 - y1; \
458  \
459     if ((DeltaX = x2 - x1) >= 0) { \
460         XDir = 1; \
461     } else { \
462         XDir = -1; \
463         DeltaX = -DeltaX; /* make DeltaX positive */ \
464     } \
465  \
466     /* line is not horizontal, diagonal, or vertical */ \
467     ErrorAcc = 0;  /* initialize the line error accumulator to 0 */ \
468  \
469     /* Is this an X-major or Y-major line? */ \
470     if (DeltaY > DeltaX) { \
471         /* Y-major line; calculate 16-bit fixed-point fractional part of a \
472           pixel that X advances each time Y advances 1 pixel, truncating the \
473           result so that we won't overrun the endpoint along the X axis */ \
474         ErrorAdj = ((unsigned long) DeltaX << 16) / (unsigned long) DeltaY; \
475         /* Draw all pixels other than the first and last */ \
476         while (--DeltaY) { \
477             ErrorAccTemp = ErrorAcc;   /* remember currrent accumulated error */ \
478             ErrorAcc += ErrorAdj;      /* calculate error for next pixel */ \
479             if (ErrorAcc <= ErrorAccTemp) { \
480                 /* The error accumulator turned over, so advance the X coord */ \
481                 x1 += XDir; \
482             } \
483             y1++; /* Y-major, so always advance Y */ \
484             /* The IntensityBits most significant bits of ErrorAcc give us the \
485              intensity weighting for this pixel, and the complement of the \
486              weighting for the paired pixel */ \
487             Weighting = ErrorAcc >> 8; \
488             { \
489                 a = DRAW_MUL(_a, (Weighting ^ 255)); \
490                 r = DRAW_MUL(_r, a); \
491                 g = DRAW_MUL(_g, a); \
492                 b = DRAW_MUL(_b, a); \
493                 inva = (a ^ 0xFF); \
494                 blend_op(x1, y1); \
495             } \
496             { \
497                 a = DRAW_MUL(_a, Weighting); \
498                 r = DRAW_MUL(_r, a); \
499                 g = DRAW_MUL(_g, a); \
500                 b = DRAW_MUL(_b, a); \
501                 inva = (a ^ 0xFF); \
502                 blend_op(x1 + XDir, y1); \
503             } \
504         } \
505     } else { \
506         /* X-major line; calculate 16-bit fixed-point fractional part of a \
507            pixel that Y advances each time X advances 1 pixel, truncating the \
508            result to avoid overrunning the endpoint along the X axis */ \
509         ErrorAdj = ((unsigned long) DeltaY << 16) / (unsigned long) DeltaX; \
510         /* Draw all pixels other than the first and last */ \
511         while (--DeltaX) { \
512             ErrorAccTemp = ErrorAcc;   /* remember currrent accumulated error */ \
513             ErrorAcc += ErrorAdj;      /* calculate error for next pixel */ \
514             if (ErrorAcc <= ErrorAccTemp) { \
515                 /* The error accumulator turned over, so advance the Y coord */ \
516                 y1++; \
517             } \
518             x1 += XDir; /* X-major, so always advance X */ \
519             /* The IntensityBits most significant bits of ErrorAcc give us the \
520               intensity weighting for this pixel, and the complement of the \
521               weighting for the paired pixel */ \
522             Weighting = ErrorAcc >> 8; \
523             { \
524                 a = DRAW_MUL(_a, (Weighting ^ 255)); \
525                 r = DRAW_MUL(_r, a); \
526                 g = DRAW_MUL(_g, a); \
527                 b = DRAW_MUL(_b, a); \
528                 inva = (a ^ 0xFF); \
529                 blend_op(x1, y1); \
530             } \
531             { \
532                 a = DRAW_MUL(_a, Weighting); \
533                 r = DRAW_MUL(_r, a); \
534                 g = DRAW_MUL(_g, a); \
535                 b = DRAW_MUL(_b, a); \
536                 inva = (a ^ 0xFF); \
537                 blend_op(x1, y1 + 1); \
538             } \
539         } \
540     } \
541 }
542 
543 #ifdef AA_LINES
544 #define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \
545             WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end)
546 #else
547 #define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \
548             BLINE(x1, y1, x2, y2, opaque_op, draw_end)
549 #endif
550 
551 /*
552  * Define fill rect macro
553  */
554 
555 #define FILLRECT(type, op) \
556 do { \
557     int width = rect->w; \
558     int height = rect->h; \
559     int pitch = (dst->pitch / dst->format->BytesPerPixel); \
560     int skip = pitch - width; \
561     type *pixel = (type *)dst->pixels + rect->y * pitch + rect->x; \
562     while (height--) { \
563         { int n = (width+3)/4; \
564             switch (width & 3) { \
565             case 0: do {   op; pixel++; \
566             case 3:        op; pixel++; \
567             case 2:        op; pixel++; \
568             case 1:        op; pixel++; \
569                     } while ( --n > 0 ); \
570             } \
571         } \
572         pixel += skip; \
573     } \
574 } while (0)
575 
576 /* vi: set ts=4 sw=4 expandtab: */
577