This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project gfxprim.git.
The branch, master has been updated via b0791316458c7edc23a03dc8eb1d9bc346dc3b3a (commit) from a52536952b40f8337b4415fe265217c5976f2f77 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- http://repo.or.cz/w/gfxprim.git/commit/b0791316458c7edc23a03dc8eb1d9bc346dc3...
commit b0791316458c7edc23a03dc8eb1d9bc346dc3b3a Author: Cyril Hrubis metan@ucw.cz Date: Thu Jan 5 01:29:43 2012 +0100
gfx: working on Anti Aliased rectangles.
* the coordinates are rooted to the center of the pixels (which is consistent to the rest of primitives)
* most of the code is ready - the four pixels in the corners are not correct yet - some of the corner cases are wrong, generally when line is not grid aligned and grid width or height is smaller than 3px
diff --git a/include/core/GP_FixedPoint.h b/include/core/GP_FixedPoint.h index baf4ed4..d8556d9 100644 --- a/include/core/GP_FixedPoint.h +++ b/include/core/GP_FixedPoint.h @@ -49,7 +49,7 @@ typedef uint8_t GP_FP_Frac; /* * One Half */ -#define GP_FP_1_2 ((1<<(GP_FP_FRAC_BITS - 1)) +#define GP_FP_1_2 (1<<(GP_FP_FRAC_BITS - 1))
/* * Fraction part bitmask. @@ -57,6 +57,11 @@ typedef uint8_t GP_FP_Frac; #define GP_FP_FRAC_MASK ((1<<GP_FP_FRAC_BITS)-1)
/* + * Integer part bitmask. + */ +#define GP_FP_INT_MASK (~GP_FP_FRAC_MASK) + +/* * Addition. */ #define GP_FP_ADD(a, b) ((a)+(b)) @@ -69,22 +74,27 @@ typedef uint8_t GP_FP_Frac; /* * Floor. */ -#define GP_FP_FLOOR(a) ((a)>>GP_FP_FRAC_BITS) +#define GP_FP_FLOOR(a) ((a) & GP_FP_INT_MASK) + +/* + * Floor with conversion to integer. + */ +#define GP_FP_FLOOR_TO_INT(a) ((a)>>GP_FP_FRAC_BITS)
/* - * Ceilling. + * Ceiling. */ -#define GP_FP_CEIL(a) (((a)>>GP_FP_FRAC_BITS) + !!(GP_FP_FRAC(a))) +#define GP_FP_CEIL(a) (((a) & GP_FP_INT_MASK) + ((a) & GP_FP_FRAC_MASK) ? GP_FP_1 : 0)
/* - * Rounding. + * Ceilling with conversion to integer. */ -#define GP_FP_ROUND(a) (((a) + GP_FP_1_2))>>GP_FP_FRAC_BITS +#define GP_FP_CEIL_TO_INT(a) (((a)>>GP_FP_FRAC_BITS) + !!(GP_FP_FRAC(a)))
/* - * Integer part. + * Rounding wiht conversion to integer. */ -#define GP_FP_INT(a) GP_FP_FLOOR(a) +#define GP_FP_ROUND_TO_INT(a) (((a) + GP_FP_1_2))>>GP_FP_FRAC_BITS
/* * Fractional part. diff --git a/libs/gfx/GP_RectAA.c b/libs/gfx/GP_RectAA.c index 66e24b6..c68c377 100644 --- a/libs/gfx/GP_RectAA.c +++ b/libs/gfx/GP_RectAA.c @@ -28,6 +28,8 @@ #include "GP_Rect.h" #include "GP_RectAA.h"
+ + void GP_FillRectXYXY_AA_Raw(GP_Context *context, GP_Coord x0, GP_Coord y0, GP_Coord x1, GP_Coord y1, GP_Pixel pixel) { @@ -39,80 +41,113 @@ void GP_FillRectXYXY_AA_Raw(GP_Context *context, GP_Coord x0, GP_Coord y0, if (y0 > y1) GP_SWAP(y0, y1);
+ /* Outer coordinates */ + GP_Coord out_x0 = GP_FP_FLOOR_TO_INT(x0 + GP_FP_1_2); + GP_Coord out_y0 = GP_FP_FLOOR_TO_INT(y0 + GP_FP_1_2); + GP_Coord out_x1 = GP_FP_CEIL_TO_INT(x1 - GP_FP_1_2); + GP_Coord out_y1 = GP_FP_CEIL_TO_INT(y1 - GP_FP_1_2); + + /* Size */ GP_Size w = x1 - x0; GP_Size h = y1 - y0;
- printf("W = %f, H = %f, X = %f, Y = %fn", - GP_FP_TO_FLOAT(w), GP_FP_TO_FLOAT(h), - GP_FP_TO_FLOAT(x0), GP_FP_TO_FLOAT(y0)); + /* Special case, vertical 1px line */ + if (out_x0 == out_x1) { + uint8_t mix = GP_GammaToLinear(w); + GP_Coord i;
- /* This are integer coordinates of the "inner" rectangle */ - GP_Coord xi0 = GP_FP_CEIL(x0); - GP_Coord yi0 = GP_FP_CEIL(y0); - GP_Coord xi1 = GP_FP_FLOOR(x1); - GP_Coord yi1 = GP_FP_FLOOR(y1); + /* Special case 1px 100% width line */ + if (w == GP_FP_1) + mix = 255;
- if (xi1 >= xi0 && yi1 >= yi0) - GP_FillRect_Raw(context, xi0, yi0, xi1, yi1, pixel); - - printf("%i %i %i %in", xi0, yi0, yi1, yi1); - - /* Draw the "frame" around */ - GP_Coord i; + for (i = out_y0; i <= out_y1; i++) { + GP_Pixel p = GP_GetPixel_Raw_Clipped(context, out_x0, i); + p = GP_MixPixels(pixel, p, mix, context->pixel_type); + GP_PutPixel_Raw_Clipped(context, out_x0, i, p); + }
- uint8_t u_perc; - uint8_t d_perc; - - u_perc = GP_GammaToLinear(GP_FP_1 - GP_FP_FRAC(y0)); - d_perc = GP_GammaToLinear(GP_FP_FRAC(y1)); + return; + }
- for (i = GP_FP_CEIL(x0); i <= GP_FP_FLOOR(x1); i++) { - GP_Pixel u = GP_GetPixel_Raw_Clipped(context, i, GP_FP_FLOOR(y0)); - GP_Pixel d = GP_GetPixel_Raw_Clipped(context, i, GP_FP_CEIL(y1)); - - u = GP_MixPixels(pixel, u, u_perc, context->pixel_type); - d = GP_MixPixels(pixel, d, d_perc, context->pixel_type); + /* Special case, horizontal 1px line */ + if (out_y0 == out_y1) { + uint8_t mix = GP_GammaToLinear(h); + GP_Coord i; - GP_PutPixel_Raw_Clipped(context, i, GP_FP_FLOOR(y0), u); - GP_PutPixel_Raw_Clipped(context, i, GP_FP_CEIL(y1), d); + /* Special case 1px 100% height line */ + if (h == GP_FP_1) + mix = 255; + + for (i = out_x0; i <= out_x1; i++) { + GP_Pixel p = GP_GetPixel_Raw_Clipped(context, i, out_y0); + p = GP_MixPixels(pixel, p, mix, context->pixel_type); + GP_PutPixel_Raw_Clipped(context, i, out_y0, p); + } + + return; }
- u_perc = GP_GammaToLinear(GP_FP_1 - GP_FP_FRAC(x0)); - d_perc = GP_GammaToLinear(GP_FP_FRAC(x1)); + /* This are integer coordinates of the "inner" rectangle */ + GP_Coord in_x0 = GP_FP_CEIL_TO_INT(x0 + GP_FP_1_2); + GP_Coord in_y0 = GP_FP_CEIL_TO_INT(y0 + GP_FP_1_2); + GP_Coord in_x1 = GP_FP_FLOOR_TO_INT(x1 - GP_FP_1_2); + GP_Coord in_y1 = GP_FP_FLOOR_TO_INT(y1 - GP_FP_1_2); - for (i = GP_FP_CEIL(y0); i <= GP_FP_FLOOR(y1); i++) { - GP_Pixel u = GP_GetPixel_Raw_Clipped(context, GP_FP_FLOOR(x0), i); - GP_Pixel d = GP_GetPixel_Raw_Clipped(context, GP_FP_CEIL(x1), i); - - u = GP_MixPixels(pixel, u, u_perc, context->pixel_type); - d = GP_MixPixels(pixel, d, d_perc, context->pixel_type); - - GP_PutPixel_Raw_Clipped(context, GP_FP_FLOOR(x0), i, u); - GP_PutPixel_Raw_Clipped(context, GP_FP_CEIL(x1), i, d); + /* + * Draw the inner rectanle in 100% intensity. + * + * Note that if out_x0 == in_x1 is 2px wide and both lines has less than + * 100% intensity. The same goes for out_y0 == in_y1. + */ + if (in_x1 >= in_x0 && out_x0 != in_x1 && in_y1 >= in_y0 && out_y0 != in_y1) + GP_FillRectXYXY_Raw(context, in_x0, in_y0, in_x1, in_y1, pixel); + + /* if the outer and innter coordinates doesn't match, draw blurred edge */ + if (in_y0 != out_y0 && out_x0 != in_x1) { + uint8_t mix = GP_GammaToLinear(GP_FP_FROM_INT(in_y0) + GP_FP_1_2 - y0); + GP_Coord i; + + for (i = out_x0; i <= out_x1; i++) { + GP_Pixel p = GP_GetPixel_Raw_Clipped(context, i, out_y0); + p = GP_MixPixels(pixel, p, mix, context->pixel_type); + GP_PutPixel_Raw_Clipped(context, i, out_y0, p); + } + } + + if (in_y1 != out_y1 && out_x0 != in_x1) { + uint8_t mix = GP_GammaToLinear(y1 - GP_FP_FROM_INT(in_y0) - GP_FP_1_2); + GP_Coord i; + + for (i = out_x0; i <= out_x1; i++) { + GP_Pixel p = GP_GetPixel_Raw_Clipped(context, i, out_y1); + p = GP_MixPixels(pixel, p, mix, context->pixel_type); + GP_PutPixel_Raw_Clipped(context, i, out_y1, p); + } }
- uint8_t perc; - GP_Pixel p; - - perc = GP_GammaToLinear(GP_FP_1 - (GP_FP_FRAC(x0) + GP_FP_1 - GP_FP_FRAC(y0) + 2)/4); - p = GP_GetPixel_Raw_Clipped(context, GP_FP_FLOOR(x0), GP_FP_FLOOR(y0)); - p = GP_MixPixels(pixel, p, perc, context->pixel_type); - GP_PutPixel_Raw_Clipped(context, GP_FP_FLOOR(x0), GP_FP_FLOOR(y0), p); - - perc = GP_GammaToLinear((GP_FP_FRAC(x1) + GP_FP_1 - GP_FP_FRAC(y0) + 2)/4); - p = GP_GetPixel_Raw_Clipped(context, GP_FP_CEIL(x1), GP_FP_FLOOR(y0)); - p = GP_MixPixels(pixel, p, perc, context->pixel_type); - GP_PutPixel_Raw_Clipped(context, GP_FP_CEIL(x1), GP_FP_FLOOR(y0), p); + if (in_x0 != out_x0 && out_y0 != in_y1) { + uint8_t mix = GP_GammaToLinear(GP_FP_FROM_INT(in_x0) + GP_FP_1_2 - x0); + GP_Coord i; + + for (i = out_y0; i <= out_y1; i++) { + GP_Pixel p = GP_GetPixel_Raw_Clipped(context, out_x0, i); + p = GP_MixPixels(pixel, p, mix, context->pixel_type); + GP_PutPixel_Raw_Clipped(context, out_x0, i, p); + } + }
- perc = GP_GammaToLinear((GP_FP_1 - GP_FP_FRAC(x0) + GP_FP_FRAC(y1) + 2)/4); - p = GP_GetPixel_Raw_Clipped(context, GP_FP_FLOOR(x0), GP_FP_CEIL(y1)); - p = GP_MixPixels(pixel, p, perc, context->pixel_type); - GP_PutPixel_Raw_Clipped(context, GP_FP_FLOOR(x0), GP_FP_CEIL(y1), p); + if (in_x1 != out_x1 && out_y0 != in_y1) { + uint8_t mix = GP_GammaToLinear(x1 - GP_FP_FROM_INT(in_x1) - GP_FP_1_2); + GP_Coord i; - perc = GP_GammaToLinear((GP_FP_FRAC(x1) + GP_FP_FRAC(y1) + 2)/4); - p = GP_GetPixel_Raw_Clipped(context, GP_FP_CEIL(x1), GP_FP_CEIL(y1)); - p = GP_MixPixels(pixel, p, perc, context->pixel_type); - GP_PutPixel_Raw_Clipped(context, GP_FP_CEIL(x1), GP_FP_CEIL(y1), p); + for (i = out_y0; i <= out_y1; i++) { + GP_Pixel p = GP_GetPixel_Raw_Clipped(context, out_x1, i); + p = GP_MixPixels(pixel, p, mix, context->pixel_type); + GP_PutPixel_Raw_Clipped(context, out_x1, i, p); + } + } + + //TODO four corner pixels!!! }
void GP_FillRectXYWH_AA_Raw(GP_Context *context, GP_Coord x, GP_Coord y, diff --git a/tests/SDL/aatest.c b/tests/SDL/aatest.c index 247c553..6eba9a6 100644 --- a/tests/SDL/aatest.c +++ b/tests/SDL/aatest.c @@ -33,8 +33,8 @@ SDL_Surface *display = NULL; GP_Context context;
-static GP_Coord x = 10<<8; -static GP_Coord y = 10<<8; +static GP_Coord x = 10 * GP_FP_1 + GP_FP_1_2; +static GP_Coord y = 10 * GP_FP_1 + GP_FP_1_2;
SDL_UserEvent timer_event;
@@ -49,6 +49,9 @@ static void draw(void) GP_Coord i;
for (i = 0; i < 24; i++) { + // GP_FillRect(ctx, (x>>8), (y + (10*i<<8) - 128)>>8, + // (x>>8) + 60, (y + ((10*i)<<8) + 64*i + 64 + 128)>>8, green_pixel); + GP_FillRect_AA(ctx, x, y + ((10*i)<<8), x + (60<<8), y + ((10*i)<<8) + 64*i + 64, 0); @@ -60,7 +63,7 @@ static void draw(void) GP_FillRect_AA(ctx, x + (240<<8), y + ((10*i)<<8) + 192, x + (300<<8), y + ((10*i)<<8) + 64*i + 256, 0); - printf("--------------------------------------------------------n"); + printf("%i --------------------------------------------------------n", i); }
SDL_Flip(display); @@ -133,7 +136,7 @@ int main(int argc, char **argv) return 1; }
- display = SDL_SetVideoMode(320, 240, display_bpp, SDL_SWSURFACE); + display = SDL_SetVideoMode(320, 320, display_bpp, SDL_SWSURFACE); if (display == NULL) { fprintf(stderr, "Could not open display: %sn", SDL_GetError()); goto fail;
-----------------------------------------------------------------------
Summary of changes: include/core/GP_FixedPoint.h | 26 +++++-- libs/gfx/GP_RectAA.c | 153 ++++++++++++++++++++++++++---------------- tests/SDL/aatest.c | 11 ++- 3 files changed, 119 insertions(+), 71 deletions(-)
repo.or.cz automatic notification. Contact project admin jiri.bluebear.dluhos@gmail.com if you want to unsubscribe, or site admin admin@repo.or.cz if you receive no reply.