cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

SDL_draw.h (18301B)


      1/*
      2  Simple DirectMedia Layer
      3  Copyright (C) 1997-2014 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) \
     47do { \
     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) \
     53do { \
     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) \
     64do { \
     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) \
     74do { \
     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) \
     84do { \
     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) \
    556do { \
    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: */