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
     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_video.h"
    25 #include "SDL_draw.h"
    26 
    27 static int
    28 SDL_BlendRect_RGB555(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
    29                      Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    30 {
    31     unsigned inva = 0xff - a;
    32 
    33     switch (blendMode) {
    34     case SDL_BLENDMODE_BLEND:
    35         FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
    36         break;
    37     case SDL_BLENDMODE_ADD:
    38         FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
    39         break;
    40     case SDL_BLENDMODE_MOD:
    41         FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
    42         break;
    43     default:
    44         FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
    45         break;
    46     }
    47     return 0;
    48 }
    49 
    50 static int
    51 SDL_BlendRect_RGB565(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
    52                      Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    53 {
    54     unsigned inva = 0xff - a;
    55 
    56     switch (blendMode) {
    57     case SDL_BLENDMODE_BLEND:
    58         FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
    59         break;
    60     case SDL_BLENDMODE_ADD:
    61         FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
    62         break;
    63     case SDL_BLENDMODE_MOD:
    64         FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
    65         break;
    66     default:
    67         FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
    68         break;
    69     }
    70     return 0;
    71 }
    72 
    73 static int
    74 SDL_BlendRect_RGB888(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
    75                      Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    76 {
    77     unsigned inva = 0xff - a;
    78 
    79     switch (blendMode) {
    80     case SDL_BLENDMODE_BLEND:
    81         FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888);
    82         break;
    83     case SDL_BLENDMODE_ADD:
    84         FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888);
    85         break;
    86     case SDL_BLENDMODE_MOD:
    87         FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
    88         break;
    89     default:
    90         FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
    91         break;
    92     }
    93     return 0;
    94 }
    95 
    96 static int
    97 SDL_BlendRect_ARGB8888(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
    98                        Uint8 r, Uint8 g, Uint8 b, Uint8 a)
    99 {
   100     unsigned inva = 0xff - a;
   101 
   102     switch (blendMode) {
   103     case SDL_BLENDMODE_BLEND:
   104         FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
   105         break;
   106     case SDL_BLENDMODE_ADD:
   107         FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
   108         break;
   109     case SDL_BLENDMODE_MOD:
   110         FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
   111         break;
   112     default:
   113         FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
   114         break;
   115     }
   116     return 0;
   117 }
   118 
   119 static int
   120 SDL_BlendRect_RGB(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
   121                   Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   122 {
   123     SDL_PixelFormat *fmt = dst->format;
   124     unsigned inva = 0xff - a;
   125 
   126     switch (fmt->BytesPerPixel) {
   127     case 2:
   128         switch (blendMode) {
   129         case SDL_BLENDMODE_BLEND:
   130             FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
   131             break;
   132         case SDL_BLENDMODE_ADD:
   133             FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
   134             break;
   135         case SDL_BLENDMODE_MOD:
   136             FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
   137             break;
   138         default:
   139             FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
   140             break;
   141         }
   142         return 0;
   143     case 4:
   144         switch (blendMode) {
   145         case SDL_BLENDMODE_BLEND:
   146             FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
   147             break;
   148         case SDL_BLENDMODE_ADD:
   149             FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
   150             break;
   151         case SDL_BLENDMODE_MOD:
   152             FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
   153             break;
   154         default:
   155             FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
   156             break;
   157         }
   158         return 0;
   159     default:
   160         SDL_Unsupported();
   161         return -1;
   162     }
   163 }
   164 
   165 static int
   166 SDL_BlendRect_RGBA(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode,
   167                    Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   168 {
   169     SDL_PixelFormat *fmt = dst->format;
   170     unsigned inva = 0xff - a;
   171 
   172     switch (fmt->BytesPerPixel) {
   173     case 4:
   174         switch (blendMode) {
   175         case SDL_BLENDMODE_BLEND:
   176             FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
   177             break;
   178         case SDL_BLENDMODE_ADD:
   179             FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
   180             break;
   181         case SDL_BLENDMODE_MOD:
   182             FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
   183             break;
   184         default:
   185             FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
   186             break;
   187         }
   188         return 0;
   189     default:
   190         SDL_Unsupported();
   191         return -1;
   192     }
   193 }
   194 
   195 int
   196 SDL_BlendRect(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode, Uint8 r,
   197               Uint8 g, Uint8 b, Uint8 a)
   198 {
   199     SDL_PixelFormat *fmt = dst->format;
   200 
   201     /* This function doesn't work on surfaces < 8 bpp */
   202     if (fmt->BitsPerPixel < 8) {
   203         SDL_SetError("SDL_BlendRect(): Unsupported surface format");
   204         return (-1);
   205     }
   206 
   207     /* If 'dstrect' == NULL, then fill the whole surface */
   208     if (dstrect) {
   209         /* Perform clipping */
   210         if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
   211             return (0);
   212         }
   213     } else {
   214         dstrect = &dst->clip_rect;
   215     }
   216 
   217     if ((blendMode == SDL_BLENDMODE_BLEND)
   218         || (blendMode == SDL_BLENDMODE_ADD)) {
   219         r = DRAW_MUL(r, a);
   220         g = DRAW_MUL(g, a);
   221         b = DRAW_MUL(b, a);
   222     }
   223 
   224     switch (fmt->BitsPerPixel) {
   225     case 15:
   226         switch (fmt->Rmask) {
   227         case 0x7C00:
   228             return SDL_BlendRect_RGB555(dst, dstrect, blendMode, r, g, b, a);
   229         }
   230         break;
   231     case 16:
   232         switch (fmt->Rmask) {
   233         case 0xF800:
   234             return SDL_BlendRect_RGB565(dst, dstrect, blendMode, r, g, b, a);
   235         }
   236         break;
   237     case 32:
   238         switch (fmt->Rmask) {
   239         case 0x00FF0000:
   240             if (!fmt->Amask) {
   241                 return SDL_BlendRect_RGB888(dst, dstrect, blendMode, r, g, b,
   242                                             a);
   243             } else {
   244                 return SDL_BlendRect_ARGB8888(dst, dstrect, blendMode, r, g,
   245                                               b, a);
   246             }
   247             break;
   248         }
   249     default:
   250         break;
   251     }
   252 
   253     if (!fmt->Amask) {
   254         return SDL_BlendRect_RGB(dst, dstrect, blendMode, r, g, b, a);
   255     } else {
   256         return SDL_BlendRect_RGBA(dst, dstrect, blendMode, r, g, b, a);
   257     }
   258 }
   259 
   260 /* vi: set ts=4 sw=4 expandtab: */