In the process of adding rectangle drawing
authorSam Lantinga <slouken@libsdl.org>
Fri, 18 Dec 2009 07:03:09 +0000
changeset 3593 b931bcfd94a0
parent 3592 25dc4a86132c
child 3594 c8bed77b0386
In the process of adding rectangle drawing
include/SDL_surface.h
src/video/SDL_blendfillrect.c
src/video/SDL_blendrect.c
src/video/SDL_draw.h
src/video/SDL_drawrect.c
--- a/include/SDL_surface.h	Thu Dec 17 07:47:03 2009 +0000
+++ b/include/SDL_surface.h	Fri Dec 18 07:03:09 2009 +0000
@@ -416,7 +416,7 @@
  *  
  *  \return 0 on success, or -1 on error.
  */
-extern DECLSPEC int SDLCALL SDL_BlendPoint
+extern DECLSPEC int SDLCALL SDL_BlendDrawPoint
     (SDL_Surface * dst, int x, int y,
      int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
 extern DECLSPEC int SDLCALL SDL_BlendPoints
@@ -449,6 +449,35 @@
      int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
 
 /**
+ *  Draws the given rectangle with \c color.
+ *  
+ *  If \c rect is NULL, the whole surface will be outlined with \c color.
+ *  
+ *  The color should be a pixel of the format used by the surface, and 
+ *  can be generated by the SDL_MapRGB() function.
+ *  
+ *  \return 0 on success, or -1 on error.
+ */
+extern DECLSPEC int SDLCALL SDL_DrawRect
+    (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color);
+extern DECLSPEC int SDLCALL SDL_DrawRects
+    (SDL_Surface * dst, const SDL_Rect ** rects, int count, Uint32 color);
+
+/**
+ *  Blends the given rectangle with \c color.
+ *  
+ *  If \c rect is NULL, the whole surface will have a blended outline of \c color.
+ *  
+ *  \return 0 on success, or -1 on error.
+ */
+extern DECLSPEC int SDLCALL SDL_BlendRect
+    (SDL_Surface * dst, const SDL_Rect * rect,
+     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+extern DECLSPEC int SDLCALL SDL_BlendRects
+    (SDL_Surface * dst, const SDL_Rect ** rects, int count,
+     int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+
+/**
  *  Performs a fast fill of the given rectangle with \c color.
  *  
  *  If \c rect is NULL, the whole surface will be filled with \c color.
@@ -466,14 +495,14 @@
 /**
  *  Blends an RGBA value into the given rectangle.
  *  
- *  If \c rect is NULL, the whole surface will be filled with \c color.
+ *  If \c rect is NULL, the whole surface will be blended with \c color.
  *  
  *  \return This function returns 0 on success, or -1 on error.
  */
-extern DECLSPEC int SDLCALL SDL_BlendRect
+extern DECLSPEC int SDLCALL SDL_BlendFillRect
     (SDL_Surface * dst, const SDL_Rect * rect,
      int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
-extern DECLSPEC int SDLCALL SDL_BlendRects
+extern DECLSPEC int SDLCALL SDL_BlendFillRects
     (SDL_Surface * dst, const SDL_Rect ** rects, int count,
      int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/SDL_blendfillrect.c	Fri Dec 18 07:03:09 2009 +0000
@@ -0,0 +1,357 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2009 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_video.h"
+#include "SDL_draw.h"
+
+static int
+SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect,
+                         int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    unsigned inva = 0xff - a;
+
+    switch (blendMode) {
+    case SDL_BLENDMODE_BLEND:
+        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
+        break;
+    case SDL_BLENDMODE_ADD:
+        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
+        break;
+    case SDL_BLENDMODE_MOD:
+        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
+        break;
+    default:
+        FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
+        break;
+    }
+    return 0;
+}
+
+static int
+SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect,
+                         int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    unsigned inva = 0xff - a;
+
+    switch (blendMode) {
+    case SDL_BLENDMODE_BLEND:
+        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
+        break;
+    case SDL_BLENDMODE_ADD:
+        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
+        break;
+    case SDL_BLENDMODE_MOD:
+        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
+        break;
+    default:
+        FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
+        break;
+    }
+    return 0;
+}
+
+static int
+SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect,
+                         int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    unsigned inva = 0xff - a;
+
+    switch (blendMode) {
+    case SDL_BLENDMODE_BLEND:
+        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888);
+        break;
+    case SDL_BLENDMODE_ADD:
+        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888);
+        break;
+    case SDL_BLENDMODE_MOD:
+        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
+        break;
+    default:
+        FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
+        break;
+    }
+    return 0;
+}
+
+static int
+SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect,
+                           int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    unsigned inva = 0xff - a;
+
+    switch (blendMode) {
+    case SDL_BLENDMODE_BLEND:
+        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
+        break;
+    case SDL_BLENDMODE_ADD:
+        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
+        break;
+    case SDL_BLENDMODE_MOD:
+        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
+        break;
+    default:
+        FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
+        break;
+    }
+    return 0;
+}
+
+static int
+SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect,
+                      int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    SDL_PixelFormat *fmt = dst->format;
+    unsigned inva = 0xff - a;
+
+    switch (fmt->BytesPerPixel) {
+    case 2:
+        switch (blendMode) {
+        case SDL_BLENDMODE_BLEND:
+            FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
+            break;
+        case SDL_BLENDMODE_ADD:
+            FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
+            break;
+        case SDL_BLENDMODE_MOD:
+            FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
+            break;
+        default:
+            FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
+            break;
+        }
+        return 0;
+    case 4:
+        switch (blendMode) {
+        case SDL_BLENDMODE_BLEND:
+            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
+            break;
+        case SDL_BLENDMODE_ADD:
+            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
+            break;
+        case SDL_BLENDMODE_MOD:
+            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
+            break;
+        default:
+            FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
+            break;
+        }
+        return 0;
+    default:
+        SDL_Unsupported();
+        return -1;
+    }
+}
+
+static int
+SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect,
+                       int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    SDL_PixelFormat *fmt = dst->format;
+    unsigned inva = 0xff - a;
+
+    switch (fmt->BytesPerPixel) {
+    case 4:
+        switch (blendMode) {
+        case SDL_BLENDMODE_BLEND:
+            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
+            break;
+        case SDL_BLENDMODE_ADD:
+            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
+            break;
+        case SDL_BLENDMODE_MOD:
+            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
+            break;
+        default:
+            FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
+            break;
+        }
+        return 0;
+    default:
+        SDL_Unsupported();
+        return -1;
+    }
+}
+
+int
+SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect,
+                  int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    SDL_Rect clipped;
+
+    if (!dst) {
+        SDL_SetError("Passed NULL destination surface");
+        return -1;
+    }
+
+    if (blendMode < SDL_BLENDMODE_BLEND) {
+        Uint32 color = SDL_MapRGBA(dst->format, r, g, b, a);
+        return SDL_FillRect(dst, rect, color);
+    }
+
+    /* This function doesn't work on surfaces < 8 bpp */
+    if (dst->format->BitsPerPixel < 8) {
+        SDL_SetError("SDL_BlendFillRect(): Unsupported surface format");
+        return -1;
+    }
+
+    /* If 'rect' == NULL, then fill the whole surface */
+    if (rect) {
+        /* Perform clipping */
+        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
+            return 0;
+        }
+        rect = &clipped;
+    } else {
+        rect = &dst->clip_rect;
+    }
+
+    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
+        r = DRAW_MUL(r, a);
+        g = DRAW_MUL(g, a);
+        b = DRAW_MUL(b, a);
+    }
+
+    switch (dst->format->BitsPerPixel) {
+    case 15:
+        switch (dst->format->Rmask) {
+        case 0x7C00:
+            return SDL_BlendFillRect_RGB555(dst, rect, blendMode, r, g, b, a);
+        }
+        break;
+    case 16:
+        switch (dst->format->Rmask) {
+        case 0xF800:
+            return SDL_BlendFillRect_RGB565(dst, rect, blendMode, r, g, b, a);
+        }
+        break;
+    case 32:
+        switch (dst->format->Rmask) {
+        case 0x00FF0000:
+            if (!dst->format->Amask) {
+                return SDL_BlendFillRect_RGB888(dst, rect, blendMode, r, g, b, a);
+            } else {
+                return SDL_BlendFillRect_ARGB8888(dst, rect, blendMode, r, g, b, a);
+            }
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+
+    if (!dst->format->Amask) {
+        return SDL_BlendFillRect_RGB(dst, rect, blendMode, r, g, b, a);
+    } else {
+        return SDL_BlendFillRect_RGBA(dst, rect, blendMode, r, g, b, a);
+    }
+}
+
+int
+SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
+                   int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+    SDL_Rect clipped;
+    int i;
+    int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
+                int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
+    int status = 0;
+
+    if (!dst) {
+        SDL_SetError("Passed NULL destination surface");
+        return -1;
+    }
+
+    if (blendMode < SDL_BLENDMODE_BLEND) {
+        Uint32 color = SDL_MapRGBA(dst->format, r, g, b, a);
+        return SDL_FillRects(dst, rects, color);
+    }
+
+    /* This function doesn't work on surfaces < 8 bpp */
+    if (dst->format->BitsPerPixel < 8) {
+        SDL_SetError("SDL_BlendFillRects(): Unsupported surface format");
+        return -1;
+    }
+
+    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
+        r = DRAW_MUL(r, a);
+        g = DRAW_MUL(g, a);
+        b = DRAW_MUL(b, a);
+    }
+
+    /* FIXME: Does this function pointer slow things down significantly? */
+    switch (dst->format->BitsPerPixel) {
+    case 15:
+        switch (dst->format->Rmask) {
+        case 0x7C00:
+            func = SDL_BlendFillRect_RGB555;
+        }
+        break;
+    case 16:
+        switch (dst->format->Rmask) {
+        case 0xF800:
+            func = SDL_BlendFillRect_RGB565;
+        }
+        break;
+    case 32:
+        switch (dst->format->Rmask) {
+        case 0x00FF0000:
+            if (!dst->format->Amask) {
+                func = SDL_BlendFillRect_RGB888;
+            } else {
+                func = SDL_BlendFillRect_ARGB8888;
+            }
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+
+    if (!func) {
+        if (!dst->format->Amask) {
+            func = SDL_BlendFillRect_RGB;
+        } else {
+            func = SDL_BlendFillRect_RGBA;
+        }
+    }
+
+    for (i = 0; i < count; ++i) {
+        const SDL_Rect * rect = rects[i];
+
+        /* If 'rect' == NULL, then fill the whole surface */
+        if (rect) {
+            /* Perform clipping */
+            if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
+                continue;
+            }
+            rect = &clipped;
+        } else {
+            rect = &dst->clip_rect;
+        }
+
+        status = func(dst, rect, blendMode, r, g, b, a);
+    }
+    return status;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/SDL_blendrect.c	Thu Dec 17 07:47:03 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997-2009 Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    Sam Lantinga
-    slouken@libsdl.org
-*/
-#include "SDL_config.h"
-
-#include "SDL_video.h"
-#include "SDL_draw.h"
-
-static int
-SDL_BlendRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
-                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
-    unsigned inva = 0xff - a;
-
-    switch (blendMode) {
-    case SDL_BLENDMODE_BLEND:
-        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
-        break;
-    case SDL_BLENDMODE_ADD:
-        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
-        break;
-    case SDL_BLENDMODE_MOD:
-        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
-        break;
-    default:
-        FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
-        break;
-    }
-    return 0;
-}
-
-static int
-SDL_BlendRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
-                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
-    unsigned inva = 0xff - a;
-
-    switch (blendMode) {
-    case SDL_BLENDMODE_BLEND:
-        FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
-        break;
-    case SDL_BLENDMODE_ADD:
-        FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
-        break;
-    case SDL_BLENDMODE_MOD:
-        FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
-        break;
-    default:
-        FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
-        break;
-    }
-    return 0;
-}
-
-static int
-SDL_BlendRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
-                     Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
-    unsigned inva = 0xff - a;
-
-    switch (blendMode) {
-    case SDL_BLENDMODE_BLEND:
-        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB888);
-        break;
-    case SDL_BLENDMODE_ADD:
-        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB888);
-        break;
-    case SDL_BLENDMODE_MOD:
-        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB888);
-        break;
-    default:
-        FILLRECT(Uint32, DRAW_SETPIXEL_RGB888);
-        break;
-    }
-    return 0;
-}
-
-static int
-SDL_BlendRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
-                       Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
-    unsigned inva = 0xff - a;
-
-    switch (blendMode) {
-    case SDL_BLENDMODE_BLEND:
-        FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
-        break;
-    case SDL_BLENDMODE_ADD:
-        FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
-        break;
-    case SDL_BLENDMODE_MOD:
-        FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
-        break;
-    default:
-        FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
-        break;
-    }
-    return 0;
-}
-
-static int
-SDL_BlendRect_RGB(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
-                  Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
-    SDL_PixelFormat *fmt = dst->format;
-    unsigned inva = 0xff - a;
-
-    switch (fmt->BytesPerPixel) {
-    case 2:
-        switch (blendMode) {
-        case SDL_BLENDMODE_BLEND:
-            FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
-            break;
-        case SDL_BLENDMODE_ADD:
-            FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
-            break;
-        case SDL_BLENDMODE_MOD:
-            FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
-            break;
-        default:
-            FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
-            break;
-        }
-        return 0;
-    case 4:
-        switch (blendMode) {
-        case SDL_BLENDMODE_BLEND:
-            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
-            break;
-        case SDL_BLENDMODE_ADD:
-            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
-            break;
-        case SDL_BLENDMODE_MOD:
-            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
-            break;
-        default:
-            FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
-            break;
-        }
-        return 0;
-    default:
-        SDL_Unsupported();
-        return -1;
-    }
-}
-
-static int
-SDL_BlendRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect, int blendMode,
-                   Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
-    SDL_PixelFormat *fmt = dst->format;
-    unsigned inva = 0xff - a;
-
-    switch (fmt->BytesPerPixel) {
-    case 4:
-        switch (blendMode) {
-        case SDL_BLENDMODE_BLEND:
-            FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
-            break;
-        case SDL_BLENDMODE_ADD:
-            FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
-            break;
-        case SDL_BLENDMODE_MOD:
-            FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
-            break;
-        default:
-            FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
-            break;
-        }
-        return 0;
-    default:
-        SDL_Unsupported();
-        return -1;
-    }
-}
-
-int
-SDL_BlendRect(SDL_Surface * dst, const SDL_Rect * rect,
-              int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
-    SDL_Rect clipped;
-
-    if (!dst) {
-        SDL_SetError("Passed NULL destination surface");
-        return -1;
-    }
-
-    /* This function doesn't work on surfaces < 8 bpp */
-    if (dst->format->BitsPerPixel < 8) {
-        SDL_SetError("SDL_BlendRect(): Unsupported surface format");
-        return -1;
-    }
-
-    /* If 'rect' == NULL, then fill the whole surface */
-    if (rect) {
-        /* Perform clipping */
-        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
-            return 0;
-        }
-        rect = &clipped;
-    } else {
-        rect = &dst->clip_rect;
-    }
-
-    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
-        r = DRAW_MUL(r, a);
-        g = DRAW_MUL(g, a);
-        b = DRAW_MUL(b, a);
-    }
-
-    switch (dst->format->BitsPerPixel) {
-    case 15:
-        switch (dst->format->Rmask) {
-        case 0x7C00:
-            return SDL_BlendRect_RGB555(dst, rect, blendMode, r, g, b, a);
-        }
-        break;
-    case 16:
-        switch (dst->format->Rmask) {
-        case 0xF800:
-            return SDL_BlendRect_RGB565(dst, rect, blendMode, r, g, b, a);
-        }
-        break;
-    case 32:
-        switch (dst->format->Rmask) {
-        case 0x00FF0000:
-            if (!dst->format->Amask) {
-                return SDL_BlendRect_RGB888(dst, rect, blendMode, r, g, b, a);
-            } else {
-                return SDL_BlendRect_ARGB8888(dst, rect, blendMode, r, g, b, a);
-            }
-            break;
-        }
-        break;
-    default:
-        break;
-    }
-
-    if (!dst->format->Amask) {
-        return SDL_BlendRect_RGB(dst, rect, blendMode, r, g, b, a);
-    } else {
-        return SDL_BlendRect_RGBA(dst, rect, blendMode, r, g, b, a);
-    }
-}
-
-int
-SDL_BlendRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
-               int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
-{
-    SDL_Rect clipped;
-    int i;
-    int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
-                int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
-    int status = 0;
-
-    if (!dst) {
-        SDL_SetError("Passed NULL destination surface");
-        return -1;
-    }
-
-    /* This function doesn't work on surfaces < 8 bpp */
-    if (dst->format->BitsPerPixel < 8) {
-        SDL_SetError("SDL_BlendRects(): Unsupported surface format");
-        return -1;
-    }
-
-    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
-        r = DRAW_MUL(r, a);
-        g = DRAW_MUL(g, a);
-        b = DRAW_MUL(b, a);
-    }
-
-    /* FIXME: Does this function pointer slow things down significantly? */
-    switch (dst->format->BitsPerPixel) {
-    case 15:
-        switch (dst->format->Rmask) {
-        case 0x7C00:
-            func = SDL_BlendRect_RGB555;
-        }
-        break;
-    case 16:
-        switch (dst->format->Rmask) {
-        case 0xF800:
-            func = SDL_BlendRect_RGB565;
-        }
-        break;
-    case 32:
-        switch (dst->format->Rmask) {
-        case 0x00FF0000:
-            if (!dst->format->Amask) {
-                func = SDL_BlendRect_RGB888;
-            } else {
-                func = SDL_BlendRect_ARGB8888;
-            }
-            break;
-        }
-        break;
-    default:
-        break;
-    }
-
-    if (!func) {
-        if (!dst->format->Amask) {
-            func = SDL_BlendRect_RGB;
-        } else {
-            func = SDL_BlendRect_RGBA;
-        }
-    }
-
-    for (i = 0; i < count; ++i) {
-        const SDL_Rect * rect = rects[i];
-
-        /* If 'rect' == NULL, then fill the whole surface */
-        if (rect) {
-            /* Perform clipping */
-            if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
-                continue;
-            }
-            rect = &clipped;
-        } else {
-            rect = &dst->clip_rect;
-        }
-
-        status = func(dst, rect, blendMode, r, g, b, a);
-    }
-    return status;
-}
-
-/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/SDL_draw.h	Thu Dec 17 07:47:03 2009 +0000
+++ b/src/video/SDL_draw.h	Fri Dec 18 07:03:09 2009 +0000
@@ -341,7 +341,44 @@
 #define DRAWLINE(x0, y0, x1, y1, op)	BRESENHAM(x0, y0, x1, y1, op)
 
 /*
- * Define blend fill macro
+ * Define draw rect macro
+ */
+#define DRAWRECT(type, op) \
+do { \
+    int width = rect->w; \
+    int height = rect->h; \
+    int pitch = (dst->pitch / dst->format->BytesPerPixel); \
+    int skip = pitch - width; \
+    type *pixel; \
+    pixel = (type *)dst->pixels + rect->y * pitch + rect->x; \
+    { int n = (width+3)/4; \
+        switch (width & 3) { \
+        case 0: do {   op; pixel++; \
+        case 3:        op; pixel++; \
+        case 2:        op; pixel++; \
+        case 1:        op; pixel++; \
+                } while ( --n > 0 ); \
+        } \
+    } \
+    pixel += skip; \
+    width -= 1; \
+    height -= 2; \
+    while (height--) { \
+        op; pixel += width; op; pixel += skip; \
+    } \
+    { int n = (width+3)/4; \
+        switch (width & 3) { \
+        case 0: do {   op; pixel++; \
+        case 3:        op; pixel++; \
+        case 2:        op; pixel++; \
+        case 1:        op; pixel++; \
+                } while ( --n > 0 ); \
+        } \
+    } \
+} while (0)
+
+/*
+ * Define fill rect macro
  */
 
 #define FILLRECT(type, op) \
@@ -365,8 +402,4 @@
     } \
 } while (0)
 
-/*
- * Define blend line macro
- */
-
 /* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/SDL_drawrect.c	Fri Dec 18 07:03:09 2009 +0000
@@ -0,0 +1,432 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2009 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_video.h"
+#include "SDL_blit.h"
+
+
+#ifdef __SSE__
+/* *INDENT-OFF* */
+
+#ifdef _MSC_VER
+#define SSE_BEGIN \
+    __m128 c128; \
+    c128.m128_u32[0] = color; \
+    c128.m128_u32[1] = color; \
+    c128.m128_u32[2] = color; \
+    c128.m128_u32[3] = color;
+#else
+#define SSE_BEGIN \
+    DECLARE_ALIGNED(Uint32, cccc[4], 16); \
+    cccc[0] = color; \
+    cccc[1] = color; \
+    cccc[2] = color; \
+    cccc[3] = color; \
+    __m128 c128 = *(__m128 *)cccc;
+#endif
+
+#define SSE_WORK \
+    for (i = n / 64; i--;) { \
+        _mm_stream_ps((float *)(p+0), c128); \
+        _mm_stream_ps((float *)(p+16), c128); \
+        _mm_stream_ps((float *)(p+32), c128); \
+        _mm_stream_ps((float *)(p+48), c128); \
+        p += 64; \
+    }
+
+#define SSE_END
+
+#define DEFINE_SSE_FILLRECT(bpp, type) \
+static void \
+SDL_DrawRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
+{ \
+    SSE_BEGIN; \
+ \
+    while (h--) { \
+        int i, n = w * bpp; \
+        Uint8 *p = pixels; \
+ \
+        if (n > 63) { \
+            int adjust = 16 - ((uintptr_t)p & 15); \
+            if (adjust < 16) { \
+                n -= adjust; \
+                adjust /= bpp; \
+                while (adjust--) { \
+                    *((type *)p) = (type)color; \
+                    p += bpp; \
+                } \
+            } \
+            SSE_WORK; \
+        } \
+        if (n & 63) { \
+            int remainder = (n & 63); \
+            remainder /= bpp; \
+            while (remainder--) { \
+                *((type *)p) = (type)color; \
+                p += bpp; \
+            } \
+        } \
+        pixels += pitch; \
+    } \
+ \
+    SSE_END; \
+}
+
+static void
+SDL_DrawRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
+{
+    SSE_BEGIN;
+
+    while (h--) {
+        int i, n = w;
+        Uint8 *p = pixels;
+
+        if (n > 63) {
+            int adjust = 16 - ((uintptr_t)p & 15);
+            if (adjust) {
+                n -= adjust;
+                SDL_memset(p, color, adjust);
+                p += adjust;
+            }
+            SSE_WORK;
+        }
+        if (n & 63) {
+            int remainder = (n & 63);
+            SDL_memset(p, color, remainder);
+            p += remainder;
+        }
+        pixels += pitch;
+    }
+
+    SSE_END;
+}
+/*DEFINE_SSE_FILLRECT(1, Uint8)*/
+DEFINE_SSE_FILLRECT(2, Uint16)
+DEFINE_SSE_FILLRECT(4, Uint32)
+
+/* *INDENT-ON* */
+#endif /* __SSE__ */
+
+#ifdef __MMX__
+/* *INDENT-OFF* */
+
+#define MMX_BEGIN \
+    __m64 c64 = _mm_set_pi32(color, color)
+
+#define MMX_WORK \
+    for (i = n / 64; i--;) { \
+        _mm_stream_pi((__m64 *)(p+0), c64); \
+        _mm_stream_pi((__m64 *)(p+8), c64); \
+        _mm_stream_pi((__m64 *)(p+16), c64); \
+        _mm_stream_pi((__m64 *)(p+24), c64); \
+        _mm_stream_pi((__m64 *)(p+32), c64); \
+        _mm_stream_pi((__m64 *)(p+40), c64); \
+        _mm_stream_pi((__m64 *)(p+48), c64); \
+        _mm_stream_pi((__m64 *)(p+56), c64); \
+        p += 64; \
+    }
+
+#define MMX_END \
+    _mm_empty()
+
+#define DEFINE_MMX_FILLRECT(bpp, type) \
+static void \
+SDL_DrawRect##bpp##MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \
+{ \
+    MMX_BEGIN; \
+ \
+    while (h--) { \
+        int i, n = w * bpp; \
+        Uint8 *p = pixels; \
+ \
+        if (n > 63) { \
+            int adjust = 8 - ((uintptr_t)p & 7); \
+            if (adjust < 8) { \
+                n -= adjust; \
+                adjust /= bpp; \
+                while (adjust--) { \
+                    *((type *)p) = (type)color; \
+                    p += bpp; \
+                } \
+            } \
+            MMX_WORK; \
+        } \
+        if (n & 63) { \
+            int remainder = (n & 63); \
+            remainder /= bpp; \
+            while (remainder--) { \
+                *((type *)p) = (type)color; \
+                p += bpp; \
+            } \
+        } \
+        pixels += pitch; \
+    } \
+ \
+    MMX_END; \
+}
+
+static void
+SDL_DrawRect1MMX(Uint8 *pixels, int pitch, Uint32 color, int w, int h)
+{
+    MMX_BEGIN;
+
+    while (h--) {
+        int i, n = w;
+        Uint8 *p = pixels;
+
+        if (n > 63) {
+            int adjust = 8 - ((uintptr_t)p & 7);
+            if (adjust) {
+                n -= adjust;
+                SDL_memset(p, color, adjust);
+                p += adjust;
+            }
+            MMX_WORK;
+        }
+        if (n & 63) {
+            int remainder = (n & 63);
+            SDL_memset(p, color, remainder);
+            p += remainder;
+        }
+        pixels += pitch;
+    }
+
+    MMX_END;
+}
+/*DEFINE_MMX_FILLRECT(1, Uint8)*/
+DEFINE_MMX_FILLRECT(2, Uint16)
+DEFINE_MMX_FILLRECT(4, Uint32)
+
+/* *INDENT-ON* */
+#endif /* __MMX__ */
+
+static void
+SDL_DrawRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
+{
+    while (h--) {
+        int n = w;
+        Uint8 *p = pixels;
+
+        if (n > 3) {
+            switch ((uintptr_t) p & 3) {
+            case 1:
+                *p++ = (Uint8) color;
+                --n;
+            case 2:
+                *p++ = (Uint8) color;
+                --n;
+            case 3:
+                *p++ = (Uint8) color;
+                --n;
+            }
+            SDL_memset4(p, color, (n >> 2));
+        }
+        if (n & 3) {
+            p += (n & ~3);
+            switch (n & 3) {
+            case 3:
+                *p++ = (Uint8) color;
+            case 2:
+                *p++ = (Uint8) color;
+            case 1:
+                *p++ = (Uint8) color;
+            }
+        }
+        pixels += pitch;
+    }
+}
+
+static void
+SDL_DrawRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
+{
+    while (h--) {
+        int n = w;
+        Uint16 *p = (Uint16 *) pixels;
+
+        if (n > 1) {
+            if ((uintptr_t) p & 2) {
+                *p++ = (Uint16) color;
+                --n;
+            }
+            SDL_memset4(p, color, (n >> 1));
+        }
+        if (n & 1) {
+            p[n - 1] = (Uint16) color;
+        }
+        pixels += pitch;
+    }
+}
+
+static void
+SDL_DrawRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
+{
+    Uint8 r = (Uint8) ((color >> 16) & 0xFF);
+    Uint8 g = (Uint8) ((color >> 8) & 0xFF);
+    Uint8 b = (Uint8) (color & 0xFF);
+
+    while (h--) {
+        int n = w;
+        Uint8 *p = pixels;
+
+        while (n--) {
+            *p++ = r;
+            *p++ = g;
+            *p++ = b;
+        }
+        pixels += pitch;
+    }
+}
+
+static void
+SDL_DrawRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
+{
+    while (h--) {
+        SDL_memset4(pixels, color, w);
+        pixels += pitch;
+    }
+}
+
+/* 
+ * This function performs a fast fill of the given rectangle with 'color'
+ */
+int
+SDL_DrawRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
+{
+    SDL_Rect clipped;
+    Uint8 *pixels;
+
+    if (!dst) {
+        SDL_SetError("Passed NULL destination surface");
+        return -1;
+    }
+
+    /* This function doesn't work on surfaces < 8 bpp */
+    if (dst->format->BitsPerPixel < 8) {
+        SDL_SetError("SDL_DrawRect(): Unsupported surface format");
+        return -1;
+    }
+
+    /* If 'rect' == NULL, then fill the whole surface */
+    if (rect) {
+        /* Perform clipping */
+        if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
+            return 0;
+        }
+        rect = &clipped;
+    } else {
+        rect = &dst->clip_rect;
+    }
+
+    /* Perform software fill */
+    if (!dst->pixels) {
+        SDL_SetError("SDL_DrawRect(): You must lock the surface");
+        return (-1);
+    }
+
+    pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch +
+                                     rect->x * dst->format->BytesPerPixel;
+
+    switch (dst->format->BytesPerPixel) {
+    case 1:
+        {
+            color |= (color << 8);
+            color |= (color << 16);
+#ifdef __SSE__
+            if (SDL_HasSSE()) {
+                SDL_DrawRect1SSE(pixels, dst->pitch, color, rect->w, rect->h);
+                break;
+            }
+#endif
+#ifdef __MMX__
+            if (SDL_HasMMX()) {
+                SDL_DrawRect1MMX(pixels, dst->pitch, color, rect->w, rect->h);
+                break;
+            }
+#endif
+            SDL_DrawRect1(pixels, dst->pitch, color, rect->w, rect->h);
+            break;
+        }
+
+    case 2:
+        {
+            color |= (color << 16);
+#ifdef __SSE__
+            if (SDL_HasSSE()) {
+                SDL_DrawRect2SSE(pixels, dst->pitch, color, rect->w, rect->h);
+                break;
+            }
+#endif
+#ifdef __MMX__
+            if (SDL_HasMMX()) {
+                SDL_DrawRect2MMX(pixels, dst->pitch, color, rect->w, rect->h);
+                break;
+            }
+#endif
+            SDL_DrawRect2(pixels, dst->pitch, color, rect->w, rect->h);
+            break;
+        }
+
+    case 3:
+        /* 24-bit RGB is a slow path, at least for now. */
+        {
+            SDL_DrawRect3(pixels, dst->pitch, color, rect->w, rect->h);
+            break;
+        }
+
+    case 4:
+        {
+#ifdef __SSE__
+            if (SDL_HasSSE()) {
+                SDL_DrawRect4SSE(pixels, dst->pitch, color, rect->w, rect->h);
+                break;
+            }
+#endif
+#ifdef __MMX__
+            if (SDL_HasMMX()) {
+                SDL_DrawRect4MMX(pixels, dst->pitch, color, rect->w, rect->h);
+                break;
+            }
+#endif
+            SDL_DrawRect4(pixels, dst->pitch, color, rect->w, rect->h);
+            break;
+        }
+    }
+
+    /* We're done! */
+    return 0;
+}
+
+int
+SDL_DrawRects(SDL_Surface * dst, const SDL_Rect ** rects, int count,
+              Uint32 color)
+{
+    int i;
+    int status = 0;
+
+    for (i = 0; i < count; ++i) {
+        status = SDL_DrawRect(dst, rects[i], color);
+    }
+    return status;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */