src/render/software/SDL_draw.h
author Sam Lantinga <slouken@libsdl.org>
Sun, 10 Sep 2017 12:54:40 -0700
changeset 11493 93013728e8a3
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Fixed bug 3812 - Fallthrough warnings gcc-7
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2017 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++; /* fallthrough */ \
   566             case 3:        op; pixel++; /* fallthrough */ \
   567             case 2:        op; pixel++; /* fallthrough */ \
   568             case 1:        op; pixel++; /* fallthrough */ \
   569                     } while ( --n > 0 ); \
   570             } \
   571         } \
   572         pixel += skip; \
   573     } \
   574 } while (0)
   575 
   576 /* vi: set ts=4 sw=4 expandtab: */