src/video/SDL_blendrect.c
author Sam Lantinga
Sat, 19 Sep 2009 13:29:40 +0000
changeset 3280 00cace2d9080
parent 2900 3a9636c83849
child 3536 0267b8b1595c
permissions -rw-r--r--
Merged a cleaned up version of Jiang's code changes from Google Summer of Code 2009
slouken@2888
     1
/*
slouken@2888
     2
    SDL - Simple DirectMedia Layer
slouken@2888
     3
    Copyright (C) 1997-2009 Sam Lantinga
slouken@2888
     4
slouken@2888
     5
    This library is free software; you can redistribute it and/or
slouken@2888
     6
    modify it under the terms of the GNU Lesser General Public
slouken@2888
     7
    License as published by the Free Software Foundation; either
slouken@2888
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@2888
     9
slouken@2888
    10
    This library is distributed in the hope that it will be useful,
slouken@2888
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@2888
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@2888
    13
    Lesser General Public License for more details.
slouken@2888
    14
slouken@2888
    15
    You should have received a copy of the GNU Lesser General Public
slouken@2888
    16
    License along with this library; if not, write to the Free Software
slouken@2888
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@2888
    18
slouken@2888
    19
    Sam Lantinga
slouken@2888
    20
    slouken@libsdl.org
slouken@2888
    21
*/
slouken@2888
    22
#include "SDL_config.h"
slouken@2888
    23
slouken@2888
    24
#include "SDL_video.h"
slouken@2898
    25
#include "SDL_draw.h"
slouken@2888
    26
slouken@2898
    27
static int
slouken@2898
    28
SDL_BlendRect_RGB555(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
slouken@2898
    29
                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
    30
{
slouken@2898
    31
    unsigned inva = 0xff - a;
slouken@2896
    32
slouken@2898
    33
    switch (blendMode) {
slouken@2898
    34
    case SDL_BLENDMODE_BLEND:
slouken@2900
    35
        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
slouken@2898
    36
        break;
slouken@2898
    37
    case SDL_BLENDMODE_ADD:
slouken@2900
    38
        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
slouken@2898
    39
        break;
slouken@2898
    40
    case SDL_BLENDMODE_MOD:
slouken@2900
    41
        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
slouken@2898
    42
        break;
slouken@2898
    43
    default:
slouken@2900
    44
        FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
slouken@2898
    45
        break;
slouken@2898
    46
    }
slouken@2898
    47
    return 0;
slouken@2898
    48
}
slouken@2898
    49
slouken@2898
    50
static int
slouken@2898
    51
SDL_BlendRect_RGB565(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
slouken@2898
    52
                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
    53
{
slouken@2898
    54
    unsigned inva = 0xff - a;
slouken@2896
    55
slouken@2898
    56
    switch (blendMode) {
slouken@2898
    57
    case SDL_BLENDMODE_BLEND:
slouken@2900
    58
        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
slouken@2898
    59
        break;
slouken@2898
    60
    case SDL_BLENDMODE_ADD:
slouken@2900
    61
        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
slouken@2898
    62
        break;
slouken@2898
    63
    case SDL_BLENDMODE_MOD:
slouken@2900
    64
        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
slouken@2898
    65
        break;
slouken@2898
    66
    default:
slouken@2900
    67
        FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
slouken@2898
    68
        break;
slouken@2898
    69
    }
slouken@2898
    70
    return 0;
slouken@2898
    71
}
slouken@2896
    72
slouken@2898
    73
static int
slouken@2898
    74
SDL_BlendRect_RGB888(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
slouken@2898
    75
                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
    76
{
slouken@2898
    77
    unsigned inva = 0xff - a;
slouken@2898
    78
slouken@2898
    79
    switch (blendMode) {
slouken@2898
    80
    case SDL_BLENDMODE_BLEND:
slouken@2900
    81
        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888);
slouken@2898
    82
        break;
slouken@2898
    83
    case SDL_BLENDMODE_ADD:
slouken@2900
    84
        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888);
slouken@2898
    85
        break;
slouken@2898
    86
    case SDL_BLENDMODE_MOD:
slouken@2900
    87
        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
slouken@2898
    88
        break;
slouken@2898
    89
    default:
slouken@2900
    90
        FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
slouken@2898
    91
        break;
slouken@2898
    92
    }
slouken@2898
    93
    return 0;
slouken@2898
    94
}
slouken@2896
    95
slouken@2898
    96
static int
slouken@2899
    97
SDL_BlendRect_ARGB8888(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
slouken@2899
    98
                       Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2899
    99
{
slouken@2899
   100
    unsigned inva = 0xff - a;
slouken@2899
   101
slouken@2899
   102
    switch (blendMode) {
slouken@2899
   103
    case SDL_BLENDMODE_BLEND:
slouken@2900
   104
        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
slouken@2899
   105
        break;
slouken@2899
   106
    case SDL_BLENDMODE_ADD:
slouken@2900
   107
        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
slouken@2899
   108
        break;
slouken@2899
   109
    case SDL_BLENDMODE_MOD:
slouken@2900
   110
        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
slouken@2899
   111
        break;
slouken@2899
   112
    default:
slouken@2900
   113
        FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
slouken@2899
   114
        break;
slouken@2899
   115
    }
slouken@2899
   116
    return 0;
slouken@2899
   117
}
slouken@2899
   118
slouken@2899
   119
static int
slouken@2898
   120
SDL_BlendRect_RGB(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
slouken@2898
   121
                  Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
   122
{
slouken@2898
   123
    SDL_PixelFormat *fmt = dst->format;
slouken@2898
   124
    unsigned inva = 0xff - a;
slouken@2896
   125
slouken@2898
   126
    switch (fmt->BytesPerPixel) {
slouken@2898
   127
    case 2:
slouken@2898
   128
        switch (blendMode) {
slouken@2898
   129
        case SDL_BLENDMODE_BLEND:
slouken@2900
   130
            FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
slouken@2898
   131
            break;
slouken@2898
   132
        case SDL_BLENDMODE_ADD:
slouken@2900
   133
            FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
slouken@2898
   134
            break;
slouken@2898
   135
        case SDL_BLENDMODE_MOD:
slouken@2900
   136
            FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
slouken@2898
   137
            break;
slouken@2898
   138
        default:
slouken@2900
   139
            FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
slouken@2898
   140
            break;
slouken@2898
   141
        }
slouken@2898
   142
        return 0;
slouken@2898
   143
    case 4:
slouken@2898
   144
        switch (blendMode) {
slouken@2898
   145
        case SDL_BLENDMODE_BLEND:
slouken@2900
   146
            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
slouken@2898
   147
            break;
slouken@2898
   148
        case SDL_BLENDMODE_ADD:
slouken@2900
   149
            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
slouken@2898
   150
            break;
slouken@2898
   151
        case SDL_BLENDMODE_MOD:
slouken@2900
   152
            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
slouken@2898
   153
            break;
slouken@2898
   154
        default:
slouken@2900
   155
            FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
slouken@2898
   156
            break;
slouken@2898
   157
        }
slouken@2898
   158
        return 0;
slouken@2898
   159
    default:
slouken@2898
   160
        SDL_Unsupported();
slouken@2898
   161
        return -1;
slouken@2898
   162
    }
slouken@2898
   163
}
slouken@2896
   164
slouken@2898
   165
static int
slouken@2898
   166
SDL_BlendRect_RGBA(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
slouken@2898
   167
                   Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
   168
{
slouken@2898
   169
    SDL_PixelFormat *fmt = dst->format;
slouken@2898
   170
    unsigned inva = 0xff - a;
slouken@2898
   171
slouken@2898
   172
    switch (fmt->BytesPerPixel) {
slouken@2898
   173
    case 4:
slouken@2898
   174
        switch (blendMode) {
slouken@2898
   175
        case SDL_BLENDMODE_BLEND:
slouken@2900
   176
            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
slouken@2898
   177
            break;
slouken@2898
   178
        case SDL_BLENDMODE_ADD:
slouken@2900
   179
            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
slouken@2898
   180
            break;
slouken@2898
   181
        case SDL_BLENDMODE_MOD:
slouken@2900
   182
            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
slouken@2898
   183
            break;
slouken@2898
   184
        default:
slouken@2900
   185
            FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
slouken@2898
   186
            break;
slouken@2898
   187
        }
slouken@2898
   188
        return 0;
slouken@2898
   189
    default:
slouken@2898
   190
        SDL_Unsupported();
slouken@2898
   191
        return -1;
slouken@2898
   192
    }
slouken@2898
   193
}
slouken@2888
   194
slouken@2888
   195
int
slouken@2888
   196
SDL_BlendRect(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode, Uint8 r,
slouken@2888
   197
              Uint8 g, Uint8 b, Uint8 a)
slouken@2888
   198
{
slouken@2898
   199
    SDL_PixelFormat *fmt = dst->format;
slouken@2898
   200
slouken@2888
   201
    /* This function doesn't work on surfaces < 8 bpp */
slouken@2898
   202
    if (fmt->BitsPerPixel < 8) {
slouken@2888
   203
        SDL_SetError("SDL_BlendRect(): Unsupported surface format");
slouken@2888
   204
        return (-1);
slouken@2888
   205
    }
slouken@2888
   206
slouken@2888
   207
    /* If 'dstrect' == NULL, then fill the whole surface */
slouken@2888
   208
    if (dstrect) {
slouken@2888
   209
        /* Perform clipping */
slouken@2888
   210
        if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
slouken@2888
   211
            return (0);
slouken@2888
   212
        }
slouken@2888
   213
    } else {
slouken@2888
   214
        dstrect = &dst->clip_rect;
slouken@2888
   215
    }
slouken@2888
   216
slouken@2896
   217
    if ((blendMode == SDL_BLENDMODE_BLEND)
slouken@2896
   218
        || (blendMode == SDL_BLENDMODE_ADD)) {
slouken@2898
   219
        r = DRAW_MUL(r, a);
slouken@2898
   220
        g = DRAW_MUL(g, a);
slouken@2898
   221
        b = DRAW_MUL(b, a);
slouken@2896
   222
    }
slouken@2898
   223
slouken@2898
   224
    switch (fmt->BitsPerPixel) {
slouken@2896
   225
    case 15:
slouken@2898
   226
        switch (fmt->Rmask) {
slouken@2898
   227
        case 0x7C00:
slouken@2898
   228
            return SDL_BlendRect_RGB555(dst, dstrect, blendMode, r, g, b, a);
slouken@2896
   229
        }
slouken@2896
   230
        break;
slouken@2896
   231
    case 16:
slouken@2898
   232
        switch (fmt->Rmask) {
slouken@2898
   233
        case 0xF800:
slouken@2898
   234
            return SDL_BlendRect_RGB565(dst, dstrect, blendMode, r, g, b, a);
slouken@2896
   235
        }
slouken@2896
   236
        break;
slouken@2896
   237
    case 32:
slouken@2898
   238
        switch (fmt->Rmask) {
slouken@2898
   239
        case 0x00FF0000:
slouken@2898
   240
            if (!fmt->Amask) {
slouken@2898
   241
                return SDL_BlendRect_RGB888(dst, dstrect, blendMode, r, g, b,
slouken@2898
   242
                                            a);
slouken@2899
   243
            } else {
slouken@2899
   244
                return SDL_BlendRect_ARGB8888(dst, dstrect, blendMode, r, g,
slouken@2899
   245
                                              b, a);
slouken@2898
   246
            }
slouken@2896
   247
            break;
slouken@2896
   248
        }
slouken@2898
   249
    default:
slouken@2896
   250
        break;
slouken@2896
   251
    }
slouken@2898
   252
slouken@2898
   253
    if (!fmt->Amask) {
slouken@2898
   254
        return SDL_BlendRect_RGB(dst, dstrect, blendMode, r, g, b, a);
slouken@2898
   255
    } else {
slouken@2898
   256
        return SDL_BlendRect_RGBA(dst, dstrect, blendMode, r, g, b, a);
slouken@2898
   257
    }
slouken@2888
   258
}
slouken@2888
   259
slouken@2888
   260
/* vi: set ts=4 sw=4 expandtab: */