src/render/software/SDL_blendfillrect.c
author Sam Lantinga
Fri, 08 Apr 2011 13:03:26 -0700
changeset 5535 96594ac5fd1a
parent 5297 1800dc39b74c
child 6138 4c64952a58fb
permissions -rw-r--r--
SDL 1.3 is now under the zlib license.
slouken@5163
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@5535
     3
  Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
slouken@5163
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@5163
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@5163
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@5163
    20
*/
slouken@5163
    21
#include "SDL_config.h"
slouken@5163
    22
slouken@5226
    23
#if !SDL_RENDER_DISABLED
slouken@5226
    24
slouken@5163
    25
#include "SDL_draw.h"
slouken@5163
    26
#include "SDL_blendfillrect.h"
slouken@5163
    27
slouken@5163
    28
slouken@5163
    29
static int
slouken@5163
    30
SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
    31
                         SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
    32
{
slouken@5163
    33
    unsigned inva = 0xff - a;
slouken@5163
    34
slouken@5163
    35
    switch (blendMode) {
slouken@5163
    36
    case SDL_BLENDMODE_BLEND:
slouken@5163
    37
        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
slouken@5163
    38
        break;
slouken@5163
    39
    case SDL_BLENDMODE_ADD:
slouken@5163
    40
        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
slouken@5163
    41
        break;
slouken@5184
    42
    case SDL_BLENDMODE_MOD:
slouken@5184
    43
        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
slouken@5184
    44
        break;
slouken@5163
    45
    default:
slouken@5163
    46
        FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
slouken@5163
    47
        break;
slouken@5163
    48
    }
slouken@5163
    49
    return 0;
slouken@5163
    50
}
slouken@5163
    51
slouken@5163
    52
static int
slouken@5163
    53
SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
    54
                         SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
    55
{
slouken@5163
    56
    unsigned inva = 0xff - a;
slouken@5163
    57
slouken@5163
    58
    switch (blendMode) {
slouken@5163
    59
    case SDL_BLENDMODE_BLEND:
slouken@5163
    60
        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
slouken@5163
    61
        break;
slouken@5163
    62
    case SDL_BLENDMODE_ADD:
slouken@5163
    63
        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
slouken@5163
    64
        break;
slouken@5184
    65
    case SDL_BLENDMODE_MOD:
slouken@5184
    66
        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
slouken@5184
    67
        break;
slouken@5163
    68
    default:
slouken@5163
    69
        FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
slouken@5163
    70
        break;
slouken@5163
    71
    }
slouken@5163
    72
    return 0;
slouken@5163
    73
}
slouken@5163
    74
slouken@5163
    75
static int
slouken@5163
    76
SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
    77
                         SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
    78
{
slouken@5163
    79
    unsigned inva = 0xff - a;
slouken@5163
    80
slouken@5163
    81
    switch (blendMode) {
slouken@5163
    82
    case SDL_BLENDMODE_BLEND:
slouken@5163
    83
        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888);
slouken@5163
    84
        break;
slouken@5163
    85
    case SDL_BLENDMODE_ADD:
slouken@5163
    86
        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888);
slouken@5163
    87
        break;
slouken@5184
    88
    case SDL_BLENDMODE_MOD:
slouken@5184
    89
        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
slouken@5184
    90
        break;
slouken@5163
    91
    default:
slouken@5163
    92
        FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
slouken@5163
    93
        break;
slouken@5163
    94
    }
slouken@5163
    95
    return 0;
slouken@5163
    96
}
slouken@5163
    97
slouken@5163
    98
static int
slouken@5163
    99
SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   100
                           SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   101
{
slouken@5163
   102
    unsigned inva = 0xff - a;
slouken@5163
   103
slouken@5163
   104
    switch (blendMode) {
slouken@5163
   105
    case SDL_BLENDMODE_BLEND:
slouken@5163
   106
        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
slouken@5163
   107
        break;
slouken@5163
   108
    case SDL_BLENDMODE_ADD:
slouken@5163
   109
        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
slouken@5163
   110
        break;
slouken@5184
   111
    case SDL_BLENDMODE_MOD:
slouken@5184
   112
        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
slouken@5184
   113
        break;
slouken@5163
   114
    default:
slouken@5163
   115
        FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
slouken@5163
   116
        break;
slouken@5163
   117
    }
slouken@5163
   118
    return 0;
slouken@5163
   119
}
slouken@5163
   120
slouken@5163
   121
static int
slouken@5163
   122
SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   123
                      SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   124
{
slouken@5163
   125
    SDL_PixelFormat *fmt = dst->format;
slouken@5163
   126
    unsigned inva = 0xff - a;
slouken@5163
   127
slouken@5163
   128
    switch (fmt->BytesPerPixel) {
slouken@5163
   129
    case 2:
slouken@5163
   130
        switch (blendMode) {
slouken@5163
   131
        case SDL_BLENDMODE_BLEND:
slouken@5163
   132
            FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
slouken@5163
   133
            break;
slouken@5163
   134
        case SDL_BLENDMODE_ADD:
slouken@5163
   135
            FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
slouken@5163
   136
            break;
slouken@5184
   137
        case SDL_BLENDMODE_MOD:
slouken@5184
   138
            FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
slouken@5184
   139
            break;
slouken@5163
   140
        default:
slouken@5163
   141
            FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
slouken@5163
   142
            break;
slouken@5163
   143
        }
slouken@5163
   144
        return 0;
slouken@5163
   145
    case 4:
slouken@5163
   146
        switch (blendMode) {
slouken@5163
   147
        case SDL_BLENDMODE_BLEND:
slouken@5163
   148
            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
slouken@5163
   149
            break;
slouken@5163
   150
        case SDL_BLENDMODE_ADD:
slouken@5163
   151
            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
slouken@5163
   152
            break;
slouken@5184
   153
        case SDL_BLENDMODE_MOD:
slouken@5184
   154
            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
slouken@5184
   155
            break;
slouken@5163
   156
        default:
slouken@5163
   157
            FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
slouken@5163
   158
            break;
slouken@5163
   159
        }
slouken@5163
   160
        return 0;
slouken@5163
   161
    default:
slouken@5163
   162
        SDL_Unsupported();
slouken@5163
   163
        return -1;
slouken@5163
   164
    }
slouken@5163
   165
}
slouken@5163
   166
slouken@5163
   167
static int
slouken@5163
   168
SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   169
                       SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   170
{
slouken@5163
   171
    SDL_PixelFormat *fmt = dst->format;
slouken@5163
   172
    unsigned inva = 0xff - a;
slouken@5163
   173
slouken@5163
   174
    switch (fmt->BytesPerPixel) {
slouken@5163
   175
    case 4:
slouken@5163
   176
        switch (blendMode) {
slouken@5163
   177
        case SDL_BLENDMODE_BLEND:
slouken@5163
   178
            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
slouken@5163
   179
            break;
slouken@5163
   180
        case SDL_BLENDMODE_ADD:
slouken@5163
   181
            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
slouken@5163
   182
            break;
slouken@5184
   183
        case SDL_BLENDMODE_MOD:
slouken@5184
   184
            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
slouken@5184
   185
            break;
slouken@5163
   186
        default:
slouken@5163
   187
            FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
slouken@5163
   188
            break;
slouken@5163
   189
        }
slouken@5163
   190
        return 0;
slouken@5163
   191
    default:
slouken@5163
   192
        SDL_Unsupported();
slouken@5163
   193
        return -1;
slouken@5163
   194
    }
slouken@5163
   195
}
slouken@5163
   196
slouken@5163
   197
int
slouken@5163
   198
SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   199
                  SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   200
{
slouken@5163
   201
    SDL_Rect clipped;
slouken@5163
   202
slouken@5163
   203
    if (!dst) {
slouken@5163
   204
        SDL_SetError("Passed NULL destination surface");
slouken@5163
   205
        return -1;
slouken@5163
   206
    }
slouken@5163
   207
slouken@5163
   208
    /* This function doesn't work on surfaces < 8 bpp */
slouken@5163
   209
    if (dst->format->BitsPerPixel < 8) {
slouken@5163
   210
        SDL_SetError("SDL_BlendFillRect(): Unsupported surface format");
slouken@5163
   211
        return -1;
slouken@5163
   212
    }
slouken@5163
   213
slouken@5163
   214
    /* If 'rect' == NULL, then fill the whole surface */
slouken@5163
   215
    if (rect) {
slouken@5163
   216
        /* Perform clipping */
slouken@5163
   217
        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
slouken@5163
   218
            return 0;
slouken@5163
   219
        }
slouken@5163
   220
        rect = &clipped;
slouken@5163
   221
    } else {
slouken@5163
   222
        rect = &dst->clip_rect;
slouken@5163
   223
    }
slouken@5163
   224
slouken@5163
   225
    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
slouken@5163
   226
        r = DRAW_MUL(r, a);
slouken@5163
   227
        g = DRAW_MUL(g, a);
slouken@5163
   228
        b = DRAW_MUL(b, a);
slouken@5163
   229
    }
slouken@5163
   230
slouken@5163
   231
    switch (dst->format->BitsPerPixel) {
slouken@5163
   232
    case 15:
slouken@5163
   233
        switch (dst->format->Rmask) {
slouken@5163
   234
        case 0x7C00:
slouken@5163
   235
            return SDL_BlendFillRect_RGB555(dst, rect, blendMode, r, g, b, a);
slouken@5163
   236
        }
slouken@5163
   237
        break;
slouken@5163
   238
    case 16:
slouken@5163
   239
        switch (dst->format->Rmask) {
slouken@5163
   240
        case 0xF800:
slouken@5163
   241
            return SDL_BlendFillRect_RGB565(dst, rect, blendMode, r, g, b, a);
slouken@5163
   242
        }
slouken@5163
   243
        break;
slouken@5163
   244
    case 32:
slouken@5163
   245
        switch (dst->format->Rmask) {
slouken@5163
   246
        case 0x00FF0000:
slouken@5163
   247
            if (!dst->format->Amask) {
slouken@5163
   248
                return SDL_BlendFillRect_RGB888(dst, rect, blendMode, r, g, b, a);
slouken@5163
   249
            } else {
slouken@5163
   250
                return SDL_BlendFillRect_ARGB8888(dst, rect, blendMode, r, g, b, a);
slouken@5163
   251
            }
slouken@5163
   252
            break;
slouken@5163
   253
        }
slouken@5163
   254
        break;
slouken@5163
   255
    default:
slouken@5163
   256
        break;
slouken@5163
   257
    }
slouken@5163
   258
slouken@5163
   259
    if (!dst->format->Amask) {
slouken@5163
   260
        return SDL_BlendFillRect_RGB(dst, rect, blendMode, r, g, b, a);
slouken@5163
   261
    } else {
slouken@5163
   262
        return SDL_BlendFillRect_RGBA(dst, rect, blendMode, r, g, b, a);
slouken@5163
   263
    }
slouken@5163
   264
}
slouken@5163
   265
slouken@5163
   266
int
slouken@5297
   267
SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
slouken@5163
   268
                   SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@5163
   269
{
slouken@5297
   270
    SDL_Rect rect;
slouken@5163
   271
    int i;
slouken@5163
   272
    int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
slouken@5163
   273
                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
slouken@5163
   274
    int status = 0;
slouken@5163
   275
slouken@5163
   276
    if (!dst) {
slouken@5163
   277
        SDL_SetError("Passed NULL destination surface");
slouken@5163
   278
        return -1;
slouken@5163
   279
    }
slouken@5163
   280
slouken@5163
   281
    /* This function doesn't work on surfaces < 8 bpp */
slouken@5163
   282
    if (dst->format->BitsPerPixel < 8) {
slouken@5163
   283
        SDL_SetError("SDL_BlendFillRects(): Unsupported surface format");
slouken@5163
   284
        return -1;
slouken@5163
   285
    }
slouken@5163
   286
slouken@5163
   287
    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
slouken@5163
   288
        r = DRAW_MUL(r, a);
slouken@5163
   289
        g = DRAW_MUL(g, a);
slouken@5163
   290
        b = DRAW_MUL(b, a);
slouken@5163
   291
    }
slouken@5163
   292
slouken@5163
   293
    /* FIXME: Does this function pointer slow things down significantly? */
slouken@5163
   294
    switch (dst->format->BitsPerPixel) {
slouken@5163
   295
    case 15:
slouken@5163
   296
        switch (dst->format->Rmask) {
slouken@5163
   297
        case 0x7C00:
slouken@5163
   298
            func = SDL_BlendFillRect_RGB555;
slouken@5163
   299
        }
slouken@5163
   300
        break;
slouken@5163
   301
    case 16:
slouken@5163
   302
        switch (dst->format->Rmask) {
slouken@5163
   303
        case 0xF800:
slouken@5163
   304
            func = SDL_BlendFillRect_RGB565;
slouken@5163
   305
        }
slouken@5163
   306
        break;
slouken@5163
   307
    case 32:
slouken@5163
   308
        switch (dst->format->Rmask) {
slouken@5163
   309
        case 0x00FF0000:
slouken@5163
   310
            if (!dst->format->Amask) {
slouken@5163
   311
                func = SDL_BlendFillRect_RGB888;
slouken@5163
   312
            } else {
slouken@5163
   313
                func = SDL_BlendFillRect_ARGB8888;
slouken@5163
   314
            }
slouken@5163
   315
            break;
slouken@5163
   316
        }
slouken@5163
   317
        break;
slouken@5163
   318
    default:
slouken@5163
   319
        break;
slouken@5163
   320
    }
slouken@5163
   321
slouken@5163
   322
    if (!func) {
slouken@5163
   323
        if (!dst->format->Amask) {
slouken@5163
   324
            func = SDL_BlendFillRect_RGB;
slouken@5163
   325
        } else {
slouken@5163
   326
            func = SDL_BlendFillRect_RGBA;
slouken@5163
   327
        }
slouken@5163
   328
    }
slouken@5163
   329
slouken@5163
   330
    for (i = 0; i < count; ++i) {
slouken@5297
   331
        /* Perform clipping */
slouken@5297
   332
        if (!SDL_IntersectRect(&rects[i], &dst->clip_rect, &rect)) {
slouken@5297
   333
            continue;
slouken@5163
   334
        }
slouken@5297
   335
        status = func(dst, &rect, blendMode, r, g, b, a);
slouken@5163
   336
    }
slouken@5163
   337
    return status;
slouken@5163
   338
}
slouken@5163
   339
slouken@5226
   340
#endif /* !SDL_RENDER_DISABLED */
slouken@5226
   341
slouken@5163
   342
/* vi: set ts=4 sw=4 expandtab: */