Mercurial > sdl-ios-xcode
diff src/video/SDL_blendline.c @ 3596:f638ded38b8a
Added SDL_RenderClear() as a fast method of clearing the screen to the drawing color.
Renamed SDL_RenderPoint() and SDL_RenderLine() to SDL_RenderDrawPoint() and SDL_RenderDrawLine().
Added API for rectangle drawing (as opposed to filling)
Added placeholder API functions for circles and ellipses ... I'm not sure whether these will stay.
Optimized software line drawing quite a bit.
Added support for Wu's anti-aliased line drawing, currently disabled by default.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 23 Dec 2009 01:55:00 +0000 |
parents | c8bed77b0386 |
children | f7b03b6838cb |
line wrap: on
line diff
--- a/src/video/SDL_blendline.c Fri Dec 18 08:19:18 2009 +0000 +++ b/src/video/SDL_blendline.c Wed Dec 23 01:55:00 2009 +0000 @@ -23,241 +23,713 @@ #include "SDL_draw.h" -static int -SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, - SDL_bool draw_end) + +static void +SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2, + int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) { - unsigned inva = 0xff - a; + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); - switch (blendMode) { - case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB555, draw_end); - break; - case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB555, draw_end); - break; - case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB555, draw_end); - break; - default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB555, draw_end); - break; + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + VLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY2_BLEND_RGB, DRAW_SETPIXELXY2_BLEND_RGB, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY2_ADD_RGB, DRAW_SETPIXELXY2_ADD_RGB, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY2_MOD_RGB, DRAW_SETPIXELXY2_MOD_RGB, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY2_RGB, DRAW_SETPIXELXY2_BLEND_RGB, + draw_end); + break; + } } - return 0; } -static int -SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, - SDL_bool draw_end) -{ - unsigned inva = 0xff - a; - - switch (blendMode) { - case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB565, draw_end); - break; - case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB565, draw_end); - break; - case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB565, draw_end); - break; - default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB565, draw_end); - break; - } - return 0; -} - -static int -SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, +static void +SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2, + int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, SDL_bool draw_end) { - unsigned inva = 0xff - a; + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; - switch (blendMode) { - case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_RGB888, draw_end); - break; - case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_RGB888, draw_end); - break; - case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_RGB888, draw_end); - break; - default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_RGB888, draw_end); - break; + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; } - return 0; -} + inva = (a ^ 0xff); -static int -SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, - SDL_bool draw_end) -{ - unsigned inva = 0xff - a; - - switch (blendMode) { - case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_BLEND_ARGB8888, draw_end); - break; - case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ADD_ARGB8888, draw_end); - break; - case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_MOD_ARGB8888, draw_end); - break; - default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY_ARGB8888, draw_end); - break; + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end); + break; + default: + HLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end); + break; + default: + VLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end); + break; + default: + DLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_BLEND_RGB555, DRAW_SETPIXELXY_BLEND_RGB555, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ADD_RGB555, DRAW_SETPIXELXY_ADD_RGB555, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_MOD_RGB555, DRAW_SETPIXELXY_MOD_RGB555, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_RGB555, DRAW_SETPIXELXY_BLEND_RGB555, + draw_end); + break; + } } - return 0; } -static int -SDL_BlendLine_RGB(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, - SDL_bool draw_end) +static void +SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2, + int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) { - SDL_PixelFormat *fmt = dst->format; - unsigned inva = 0xff - a; + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; - switch (fmt->BytesPerPixel) { - case 2: + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_BLEND_RGB, draw_end); + HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_ADD_RGB, draw_end); + HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_MOD_RGB, draw_end); + HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY2_RGB, draw_end); + HLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end); break; } - return 0; - case 4: + } else if (x1 == x2) { switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGB, draw_end); + VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end); + break; + default: + VLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGB, draw_end); + DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGB, draw_end); + DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGB, draw_end); + DLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end); break; } - return 0; - default: - SDL_Unsupported(); - return -1; + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_BLEND_RGB565, DRAW_SETPIXELXY_BLEND_RGB565, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ADD_RGB565, DRAW_SETPIXELXY_ADD_RGB565, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_MOD_RGB565, DRAW_SETPIXELXY_MOD_RGB565, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_RGB565, DRAW_SETPIXELXY_BLEND_RGB565, + draw_end); + break; + } } } -static int -SDL_BlendLine_RGBA(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, +static void +SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2, + int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, SDL_bool draw_end) { - SDL_PixelFormat *fmt = dst->format; - unsigned inva = 0xff - a; + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); - switch (fmt->BytesPerPixel) { - case 4: + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + VLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end); + break; + default: + DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end); + break; + } + } else { switch (blendMode) { case SDL_BLENDMODE_BLEND: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_BLEND_RGBA, draw_end); + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_BLEND_RGB, DRAW_SETPIXELXY4_BLEND_RGB, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_ADD_RGB, DRAW_SETPIXELXY4_ADD_RGB, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_MOD_RGB, DRAW_SETPIXELXY4_MOD_RGB, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_RGB, DRAW_SETPIXELXY4_BLEND_RGB, + draw_end); + break; + } + } +} + +static void +SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2, + int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end); + break; + default: + HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end); + break; + default: + VLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end); + break; + default: + DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_BLEND_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA, + draw_end); break; case SDL_BLENDMODE_ADD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_ADD_RGBA, draw_end); + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_ADD_RGBA, DRAW_SETPIXELXY4_ADD_RGBA, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_MOD_RGBA, DRAW_SETPIXELXY4_MOD_RGBA, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY4_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA, + draw_end); + break; + } + } +} + +static void +SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2, + int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end); break; case SDL_BLENDMODE_MOD: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_MOD_RGBA, draw_end); + HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end); + break; + default: + HLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end); + break; + default: + VLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end); + break; + } + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB888, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB888, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB888, draw_end); + break; + default: + DLINE(Uint32, DRAW_SETPIXEL_RGB888, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_BLEND_RGB888, DRAW_SETPIXELXY_BLEND_RGB888, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ADD_RGB888, DRAW_SETPIXELXY_ADD_RGB888, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_MOD_RGB888, DRAW_SETPIXELXY_MOD_RGB888, + draw_end); break; default: - DRAWLINE(x1, y1, x2, y2, DRAW_SETPIXELXY4_RGBA, draw_end); + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_RGB888, DRAW_SETPIXELXY_BLEND_RGB888, + draw_end); + break; + } + } +} + +static void +SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2, + int blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) +{ + const SDL_PixelFormat *fmt = dst->format; + unsigned r, g, b, a, inva; + + if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { + r = DRAW_MUL(_r, _a); + g = DRAW_MUL(_g, _a); + b = DRAW_MUL(_b, _a); + a = _a; + } else { + r = _r; + g = _g; + b = _b; + a = _a; + } + inva = (a ^ 0xff); + + if (y1 == y2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + HLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_ADD: + HLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_MOD: + HLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end); + break; + default: + HLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end); + break; + } + } else if (x1 == x2) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + VLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_ADD: + VLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_MOD: + VLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end); + break; + default: + VLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end); break; } - return 0; - default: - SDL_Unsupported(); - return -1; + } else if (ABS(x1 - x2) == ABS(y1 - y2)) { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + DLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_ADD: + DLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end); + break; + case SDL_BLENDMODE_MOD: + DLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end); + break; + default: + DLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end); + break; + } + } else { + switch (blendMode) { + case SDL_BLENDMODE_BLEND: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_BLEND_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888, + draw_end); + break; + case SDL_BLENDMODE_ADD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ADD_ARGB8888, DRAW_SETPIXELXY_ADD_ARGB8888, + draw_end); + break; + case SDL_BLENDMODE_MOD: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_MOD_ARGB8888, DRAW_SETPIXELXY_MOD_ARGB8888, + draw_end); + break; + default: + AALINE(x1, y1, x2, y2, + DRAW_SETPIXELXY_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888, + draw_end); + break; + } } } +typedef void (*BlendLineFunc) (SDL_Surface * dst, + int x1, int y1, int x2, int y2, + int blendMode, + Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end); + +static BlendLineFunc +SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt) +{ + switch (fmt->BytesPerPixel) { + case 2: + if (fmt->Rmask == 0x7C00) { + return SDL_BlendLine_RGB555; + } else if (fmt->Rmask == 0xF800) { + return SDL_BlendLine_RGB565; + } else { + return SDL_BlendLine_RGB2; + } + break; + case 4: + if (fmt->Rmask == 0x00FF0000) { + if (fmt->Amask) { + return SDL_BlendLine_ARGB8888; + } else { + return SDL_BlendLine_RGB888; + } + } else { + if (fmt->Amask) { + return SDL_BlendLine_RGBA4; + } else { + return SDL_BlendLine_RGB4; + } + } + } + return NULL; +} + int SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { - /* This function doesn't work on surfaces < 8 bpp */ - if (dst->format->BitsPerPixel < 8) { + BlendLineFunc func; + + if (!dst) { + SDL_SetError("SDL_BlendLine(): Passed NULL destination surface"); + return -1; + } + + func = SDL_CalculateBlendLineFunc(dst->format); + if (!func) { SDL_SetError("SDL_BlendLine(): Unsupported surface format"); - return (-1); + return -1; } /* Perform clipping */ + /* FIXME: We don't actually want to clip, as it may change line slope */ if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { - return (0); - } - - - if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) { - r = DRAW_MUL(r, a); - g = DRAW_MUL(g, a); - b = DRAW_MUL(b, a); + return 0; } - switch (dst->format->BitsPerPixel) { - case 15: - switch (dst->format->Rmask) { - case 0x7C00: - return SDL_BlendLine_RGB555(dst, x1, y1, x2, y2, blendMode, r, g, - b, a, SDL_TRUE); - } - break; - case 16: - switch (dst->format->Rmask) { - case 0xF800: - return SDL_BlendLine_RGB565(dst, x1, y1, x2, y2, blendMode, r, g, - b, a, SDL_TRUE); - } - break; - case 32: - switch (dst->format->Rmask) { - case 0x00FF0000: - if (!dst->format->Amask) { - return SDL_BlendLine_RGB888(dst, x1, y1, x2, y2, blendMode, r, - g, b, a, SDL_TRUE); - } else { - return SDL_BlendLine_ARGB8888(dst, x1, y1, x2, y2, blendMode, - r, g, b, a, SDL_TRUE); - } - break; - } - break; - default: - break; - } - - if (!dst->format->Amask) { - return SDL_BlendLine_RGB(dst, x1, y1, x2, y2, blendMode, - r, g, b, a, SDL_TRUE); - } else { - return SDL_BlendLine_RGBA(dst, x1, y1, x2, y2, blendMode, - r, g, b, a, SDL_TRUE); - } + func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_TRUE); + return 0; } int @@ -267,62 +739,18 @@ int i; int x1, y1; int x2, y2; - int (*func)(SDL_Surface * dst, int x1, int y1, int x2, int y2, - int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a, - SDL_bool draw_end) = NULL; - int status = 0; + SDL_bool draw_end; + BlendLineFunc func; 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_BlendLines(): Unsupported surface format"); + SDL_SetError("SDL_BlendLines(): Passed NULL destination surface"); 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_BlendLine_RGB555; - } - break; - case 16: - switch (dst->format->Rmask) { - case 0xF800: - func = SDL_BlendLine_RGB565; - } - break; - case 32: - switch (dst->format->Rmask) { - case 0x00FF0000: - if (!dst->format->Amask) { - func = SDL_BlendLine_RGB888; - } else { - func = SDL_BlendLine_ARGB8888; - } - break; - } - default: - break; - } - + func = SDL_CalculateBlendLineFunc(dst->format); if (!func) { - if (!dst->format->Amask) { - func = SDL_BlendLine_RGB; - } else { - func = SDL_BlendLine_RGBA; - } + SDL_SetError("SDL_BlendLines(): Unsupported surface format"); + return -1; } for (i = 1; i < count; ++i) { @@ -337,12 +765,16 @@ continue; } - status = func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_FALSE); + /* Draw the end if it was clipped */ + draw_end = (x2 != points[i].x || y2 != points[i].y); + + func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end); } if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { - SDL_BlendPoint(dst, points[count-1].x, points[count-1].y, r, g, b, a); + SDL_BlendPoint(dst, points[count-1].x, points[count-1].y, + blendMode, r, g, b, a); } - return status; + return 0; } /* vi: set ts=4 sw=4 expandtab: */