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