--- 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: */