Mercurial > sdl-ios-xcode
changeset 3593:b931bcfd94a0
In the process of adding rectangle drawing
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 18 Dec 2009 07:03:09 +0000 |
parents | 25dc4a86132c |
children | c8bed77b0386 |
files | include/SDL_surface.h src/video/SDL_blendfillrect.c src/video/SDL_blendrect.c src/video/SDL_draw.h src/video/SDL_drawrect.c |
diffstat | 5 files changed, 860 insertions(+), 356 deletions(-) [+] |
line wrap: on
line diff
--- 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: */