src/video/SDL_blendline.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 21 Dec 2008 08:28:25 +0000
changeset 2898 e40448bc7727
parent 2896 1ef2f1e75ff7
child 2899 a0c837a16e4c
permissions -rw-r--r--
Share code between fill and line drawing
Added general RGB surface format fallbacks to drawing code
Fixed issues with destination surface alpha channel
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@2898
    24
#include "SDL_draw.h"
slouken@2898
    25
slouken@2898
    26
static int
slouken@2898
    27
SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2,
slouken@2898
    28
                     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
    29
{
slouken@2898
    30
    unsigned inva = 0xff - a;
slouken@2888
    31
slouken@2898
    32
    switch (blendMode) {
slouken@2898
    33
    case SDL_BLENDMODE_BLEND:
slouken@2898
    34
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB555);
slouken@2898
    35
        break;
slouken@2898
    36
    case SDL_BLENDMODE_ADD:
slouken@2898
    37
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB555);
slouken@2898
    38
        break;
slouken@2898
    39
    case SDL_BLENDMODE_MOD:
slouken@2898
    40
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB555);
slouken@2898
    41
        break;
slouken@2898
    42
    default:
slouken@2898
    43
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB555);
slouken@2898
    44
        break;
slouken@2898
    45
    }
slouken@2898
    46
    return 0;
slouken@2898
    47
}
slouken@2896
    48
slouken@2898
    49
static int
slouken@2898
    50
SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2,
slouken@2898
    51
                     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
    52
{
slouken@2898
    53
    unsigned inva = 0xff - a;
slouken@2896
    54
slouken@2898
    55
    switch (blendMode) {
slouken@2898
    56
    case SDL_BLENDMODE_BLEND:
slouken@2898
    57
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB565);
slouken@2898
    58
        break;
slouken@2898
    59
    case SDL_BLENDMODE_ADD:
slouken@2898
    60
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB565);
slouken@2898
    61
        break;
slouken@2898
    62
    case SDL_BLENDMODE_MOD:
slouken@2898
    63
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB565);
slouken@2898
    64
        break;
slouken@2898
    65
    default:
slouken@2898
    66
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB565);
slouken@2898
    67
        break;
slouken@2898
    68
    }
slouken@2898
    69
    return 0;
slouken@2898
    70
}
slouken@2898
    71
slouken@2898
    72
static int
slouken@2898
    73
SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2,
slouken@2898
    74
                     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
    75
{
slouken@2898
    76
    unsigned inva = 0xff - a;
slouken@2898
    77
slouken@2898
    78
    switch (blendMode) {
slouken@2898
    79
    case SDL_BLENDMODE_BLEND:
slouken@2898
    80
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB888);
slouken@2898
    81
        break;
slouken@2898
    82
    case SDL_BLENDMODE_ADD:
slouken@2898
    83
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB888);
slouken@2898
    84
        break;
slouken@2898
    85
    case SDL_BLENDMODE_MOD:
slouken@2898
    86
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB888);
slouken@2898
    87
        break;
slouken@2898
    88
    default:
slouken@2898
    89
        BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB888);
slouken@2898
    90
        break;
slouken@2898
    91
    }
slouken@2898
    92
    return 0;
slouken@2896
    93
}
slouken@2896
    94
slouken@2898
    95
static int
slouken@2898
    96
SDL_BlendLine_RGB(SDL_Surface * dst, int x1, int y1, int x2, int y2,
slouken@2898
    97
                  int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
    98
{
slouken@2898
    99
    SDL_PixelFormat *fmt = dst->format;
slouken@2898
   100
    unsigned inva = 0xff - a;
slouken@2896
   101
slouken@2898
   102
    switch (fmt->BytesPerPixel) {
slouken@2898
   103
    case 2:
slouken@2898
   104
        switch (blendMode) {
slouken@2898
   105
        case SDL_BLENDMODE_BLEND:
slouken@2898
   106
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY2_BLEND_RGB);
slouken@2898
   107
            break;
slouken@2898
   108
        case SDL_BLENDMODE_ADD:
slouken@2898
   109
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY2_ADD_RGB);
slouken@2898
   110
            break;
slouken@2898
   111
        case SDL_BLENDMODE_MOD:
slouken@2898
   112
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY2_MOD_RGB);
slouken@2898
   113
            break;
slouken@2898
   114
        default:
slouken@2898
   115
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY2_RGB);
slouken@2898
   116
            break;
slouken@2898
   117
        }
slouken@2898
   118
        return 0;
slouken@2898
   119
    case 4:
slouken@2898
   120
        switch (blendMode) {
slouken@2898
   121
        case SDL_BLENDMODE_BLEND:
slouken@2898
   122
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGB);
slouken@2898
   123
            break;
slouken@2898
   124
        case SDL_BLENDMODE_ADD:
slouken@2898
   125
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGB);
slouken@2898
   126
            break;
slouken@2898
   127
        case SDL_BLENDMODE_MOD:
slouken@2898
   128
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGB);
slouken@2898
   129
            break;
slouken@2898
   130
        default:
slouken@2898
   131
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGB);
slouken@2898
   132
            break;
slouken@2898
   133
        }
slouken@2898
   134
        return 0;
slouken@2898
   135
    default:
slouken@2898
   136
        SDL_Unsupported();
slouken@2898
   137
        return -1;
slouken@2898
   138
    }
slouken@2898
   139
}
slouken@2896
   140
slouken@2898
   141
static int
slouken@2898
   142
SDL_BlendLine_RGBA(SDL_Surface * dst, int x1, int y1, int x2, int y2,
slouken@2898
   143
                   int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2898
   144
{
slouken@2898
   145
    SDL_PixelFormat *fmt = dst->format;
slouken@2898
   146
    unsigned inva = 0xff - a;
slouken@2896
   147
slouken@2898
   148
    switch (fmt->BytesPerPixel) {
slouken@2898
   149
    case 4:
slouken@2898
   150
        switch (blendMode) {
slouken@2898
   151
        case SDL_BLENDMODE_BLEND:
slouken@2898
   152
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGBA);
slouken@2898
   153
            break;
slouken@2898
   154
        case SDL_BLENDMODE_ADD:
slouken@2898
   155
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGBA);
slouken@2898
   156
            break;
slouken@2898
   157
        case SDL_BLENDMODE_MOD:
slouken@2898
   158
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGBA);
slouken@2898
   159
            break;
slouken@2898
   160
        default:
slouken@2898
   161
            BRESENHAM(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGBA);
slouken@2898
   162
            break;
slouken@2898
   163
        }
slouken@2898
   164
        return 0;
slouken@2898
   165
    default:
slouken@2898
   166
        SDL_Unsupported();
slouken@2898
   167
        return -1;
slouken@2898
   168
    }
slouken@2898
   169
}
slouken@2888
   170
slouken@2888
   171
int
slouken@2888
   172
SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
slouken@2888
   173
              int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
slouken@2888
   174
{
slouken@2898
   175
    SDL_PixelFormat *fmt = dst->format;
slouken@2898
   176
slouken@2888
   177
    /* This function doesn't work on surfaces < 8 bpp */
slouken@2888
   178
    if (dst->format->BitsPerPixel < 8) {
slouken@2888
   179
        SDL_SetError("SDL_BlendLine(): Unsupported surface format");
slouken@2888
   180
        return (-1);
slouken@2888
   181
    }
slouken@2888
   182
slouken@2888
   183
    /* Perform clipping */
slouken@2888
   184
    /* FIXME
slouken@2888
   185
       if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
slouken@2888
   186
       return (0);
slouken@2888
   187
       }
slouken@2888
   188
     */
slouken@2888
   189
slouken@2896
   190
    if ((blendMode == SDL_BLENDMODE_BLEND)
slouken@2896
   191
        || (blendMode == SDL_BLENDMODE_ADD)) {
slouken@2898
   192
        r = DRAW_MUL(r, a);
slouken@2898
   193
        g = DRAW_MUL(g, a);
slouken@2898
   194
        b = DRAW_MUL(b, a);
slouken@2896
   195
    }
slouken@2898
   196
slouken@2898
   197
    switch (fmt->BitsPerPixel) {
slouken@2896
   198
    case 15:
slouken@2898
   199
        switch (fmt->Rmask) {
slouken@2898
   200
        case 0x7C00:
slouken@2898
   201
            return SDL_BlendLine_RGB555(dst, x1, y1, x2, y2, blendMode, r, g,
slouken@2898
   202
                                        b, a);
slouken@2896
   203
        }
slouken@2896
   204
        break;
slouken@2896
   205
    case 16:
slouken@2898
   206
        switch (fmt->Rmask) {
slouken@2898
   207
        case 0xF800:
slouken@2898
   208
            return SDL_BlendLine_RGB565(dst, x1, y1, x2, y2, blendMode, r, g,
slouken@2898
   209
                                        b, a);
slouken@2896
   210
        }
slouken@2896
   211
        break;
slouken@2896
   212
    case 32:
slouken@2898
   213
        switch (fmt->Rmask) {
slouken@2898
   214
        case 0x00FF0000:
slouken@2898
   215
            if (!fmt->Amask) {
slouken@2898
   216
                return SDL_BlendLine_RGB888(dst, x1, y1, x2, y2, blendMode, r,
slouken@2898
   217
                                            g, b, a);
slouken@2898
   218
            }
slouken@2896
   219
            break;
slouken@2896
   220
        }
slouken@2898
   221
    default:
slouken@2896
   222
        break;
slouken@2896
   223
    }
slouken@2898
   224
slouken@2898
   225
    if (!fmt->Amask) {
slouken@2898
   226
        return SDL_BlendLine_RGB(dst, x1, y1, x2, y2, blendMode, r, g, b, a);
slouken@2898
   227
    } else {
slouken@2898
   228
        return SDL_BlendLine_RGBA(dst, x1, y1, x2, y2, blendMode, r, g, b, a);
slouken@2898
   229
    }
slouken@2888
   230
}
slouken@2888
   231
slouken@2888
   232
/* vi: set ts=4 sw=4 expandtab: */