diff options
author | Lars Knoll <lars@trolltech.com> | 2006-03-08 06:13:42 +0000 |
---|---|---|
committer | Lars Knoll <lars@trolltech.com> | 2006-03-08 06:13:42 +0000 |
commit | 00f788fc2785db30ee294281c027f82d09256be6 (patch) | |
tree | 0ed69842cb3f85c77c142a33d5f98415fe9691e7 | |
parent | 4fd03c7cf419c84b8bdfcf25745627659e794300 (diff) |
add testing for linear gradients.XORG-7_0_99_901
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | main.c | 11 | ||||
-rw-r--r-- | rendercheck.h | 3 | ||||
-rw-r--r-- | t_gradient.c | 238 | ||||
-rw-r--r-- | tests.c | 23 |
5 files changed, 273 insertions, 5 deletions
diff --git a/Makefile.am b/Makefile.am index b326818..41e0957 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,8 @@ rendercheck_SOURCES = \ t_dstcoords.c \ t_fill.c \ t_srccoords.c \ - t_tsrccoords.c + t_tsrccoords.c \ + t_gradient.c INCLUDES = $(RC_CFLAGS) rendercheck_LDADD = $(RC_LIBS) @@ -104,12 +104,13 @@ describe_format(char *desc, int len, XRenderPictFormat *format) } } - static void usage (char *program) { fprintf(stderr, "usage: %s [-d|--display display] [-v|--verbose]\n" - "\t[-t test1,test2,...] [--sync]\n", + "\t[-t test1,test2,...] [--sync]\n" + "\tAvailable tests: dcoors,scoords,mcoords,tscoords,\n" + "\t\ttmcoords,blend,composite,cacomposite,gradients\n", program); exit(1); } @@ -168,11 +169,13 @@ int main(int argc, char **argv) enabled_tests |= TEST_COMPOSITE; } else if (strcmp(test, "cacomposite") == 0) { enabled_tests |= TEST_CACOMPOSITE; + } else if (strcmp(test, "gradients") == 0) { + enabled_tests |= TEST_GRADIENTS; } else { usage(argv[0]); } } - + break; case 'v': is_verbose = TRUE; @@ -243,5 +246,7 @@ int main(int argc, char **argv) exit(0); } } + + XCloseDisplay(dpy); return 0; } diff --git a/rendercheck.h b/rendercheck.h index 41cb48d..98de62a 100644 --- a/rendercheck.h +++ b/rendercheck.h @@ -59,6 +59,7 @@ struct op_info { #define TEST_BLEND 0x0040 #define TEST_COMPOSITE 0x0080 #define TEST_CACOMPOSITE 0x0100 +#define TEST_GRADIENTS 0x0200 extern int pixmap_move_iter; extern int win_width, win_height; @@ -119,3 +120,5 @@ Bool trans_coords_test(Display *dpy, picture_info *win, picture_info *white, Bool test_mask); +Bool linear_gradient_test(Display *dpy, picture_info *win, + picture_info *dst, int op, picture_info *dst_color); diff --git a/t_gradient.c b/t_gradient.c new file mode 100644 index 0000000..da02724 --- /dev/null +++ b/t_gradient.c @@ -0,0 +1,238 @@ +#include <stdio.h> +#include <assert.h> +#include "rendercheck.h" + +typedef struct _stop { + double x; + color4d color; +} stop; + +static const stop stop_list[][10] = { + { + { 0., {0, 0, 1.0, 1.0} }, + { 1., {1.0, 0, 0, 1.0} }, + { -1, {0, 0, 0, 0} } + }, + { + { 0., {0, 0, 1.0, 1.0} }, + { .5, {0, 1.0, 0, 1.0} }, + { 1., {1.0, 0, 0, 1.0} }, + { -1, {0, 0, 0, 0} } + }, + { + { 0., {0, 0, 1.0, 0} }, + { 1., {1.0, 0, 0, 1.0} }, + { -1, {0, 0, 0, 0} } + }, + { + { 0., {0, 0, 1.0, 0} }, + { .5, {0, 1.0, 0, .75} }, + { 1., {1.0, 0, 0, .5} }, + { -1, {0, 0, 0, 0} } + } +}; +const int n_stop_list = sizeof(stop_list)/(10*sizeof(stop)); + +typedef struct _point { + double x; + double y; +} point; + +static const point linear_gradient_points[] = { + { -5, -5 }, { 5, 5 }, + { 0, 0 }, { 10, 10 }, +}; + +typedef struct _pixel { + int x; + int y; +} pixel; + +static const pixel test_pixels [] = { + {0, 0}, + {0, 5}, + {5, 0}, + {5, 5}, + {3, 7}, + {7, 3}, + {20, 20}, + {30, 13}, + {39, 39}, + {-1, -1} +}; + +const int n_linear_gradient_points = sizeof(linear_gradient_points)/(2*sizeof(point)); + +static void gradientPixel(const stop *stops, double pos, unsigned int spread, color4d *result) +{ + const int PRECISION = 1<<16; + int ipos = pos * PRECISION - 1; + int i; + double frac; + + /* calculate the actual offset. */ + if (ipos < 0 || ipos >= PRECISION) { + if (spread == RepeatNormal) { + ipos = ipos % PRECISION; + ipos = ipos < 0 ? PRECISION + ipos : ipos; + + } else if (spread == RepeatReflect) { + const int limit = PRECISION * 2 - 1; + ipos = ipos % limit; + ipos = ipos < 0 ? limit + ipos : ipos; + ipos = ipos >= PRECISION ? limit - ipos : ipos; + + } else if (spread == RepeatPad) { + if (ipos < 0) + ipos = 0; + else if (ipos >= PRECISION) + ipos = PRECISION-1; + } else { /* RepeatNone */ + result->r = 0; + result->g = 0; + result->b = 0; + result->a = 0; + return; + } + } + + assert(ipos >= 0); + assert(ipos < PRECISION); + + pos = ipos/(double)PRECISION; + + if (pos <= stops[0].x) { + *result = stops[0].color; + return; + } + + for (i = 0; i < 10; ++i) { + if (stops[i].x >= pos) + break; + if (stops[i].x < 0) { + *result = stops[i-1].color; + result->r *= result->a; + result->g *= result->a; + result->b *= result->a; + return; + } + } + + frac = (pos - stops[i-1].x)/(stops[i].x - stops[i-1].x); + + result->r = (1.-frac)*stops[i-1].color.r + frac*stops[i].color.r; + result->g = (1.-frac)*stops[i-1].color.g + frac*stops[i].color.g; + result->b = (1.-frac)*stops[i-1].color.b + frac*stops[i].color.b; + result->a = (1.-frac)*stops[i-1].color.a + frac*stops[i].color.a; + + result->r *= result->a; + result->g *= result->a; + result->b *= result->a; + + return; +} + +static void calculate_linear_gradient_color(int x, int y, + const point *points, + const stop *stops, + color4d *tgradient, int repeat) +{ + double dx, dy, l, xrel, yrel, pos; + dx = points[1].x - points[0].x; + dy = points[1].y - points[0].y; + l = dx*dx + dy*dy; + + xrel = x - points[0].x; + yrel = y - points[0].y; + + pos = (dx*xrel + dy*yrel)/l; + gradientPixel(stops, pos, repeat, tgradient); +} + + + +Bool linear_gradient_test(Display *dpy, picture_info *win, + picture_info *dst, int op, picture_info *dst_color) +{ + color4d expected, tested, tdst, tgradient; + int i, s, p, repeat; + Picture gradient; + char testname[40]; + Bool success = True; + + for (s = 0; s < n_stop_list; ++s) { + for (p = 0; p < n_linear_gradient_points; p += 2) { + XLinearGradient g; + XFixed stops[10]; + XRenderColor colors[10]; + const stop *stps = &stop_list[s][0]; + g.p1.x = XDoubleToFixed(linear_gradient_points[p].x); + g.p1.y = XDoubleToFixed(linear_gradient_points[p].y); + g.p2.x = XDoubleToFixed(linear_gradient_points[p+1].x); + g.p2.y = XDoubleToFixed(linear_gradient_points[p+1].y); + for (i = 0; i < 10; ++i) { + if (stps[i].x < 0) + break; + stops[i] = XDoubleToFixed(stps[i].x); + colors[i].red = stps[i].color.r*65535; + colors[i].green = stps[i].color.g*65535; + colors[i].blue = stps[i].color.b*65535; + colors[i].alpha = stps[i].color.a*65535; + } + gradient = XRenderCreateLinearGradient(dpy, &g, stops, colors, i); + + for (repeat = 1; repeat < 4; ++repeat) { + const pixel *pix; + XRenderPictureAttributes pa; + pa.repeat = repeat; + XRenderChangePicture(dpy, gradient, CPRepeat, &pa); + + XRenderComposite(dpy, PictOpSrc, dst_color->pict, 0, dst->pict, 0, 0, + 0, 0, 0, 0, win_width, win_height); + XRenderComposite(dpy, ops[op].op, gradient, 0, + dst->pict, 0, 0, 0, 0, 0, 0, win_width, win_height); + + /* Copy the output to the window, so the user sees something visual. */ + if (win != dst) + XRenderComposite(dpy, PictOpSrc, dst->pict, 0, win->pict, 0, 0, + 0, 0, 0, 0, win_width, win_height); + + pix = test_pixels; + while (pix->x >= 0) { + + get_pixel(dpy, dst, pix->x, pix->y, &tested); + + calculate_linear_gradient_color(pix->x, pix->y, &linear_gradient_points[p], + stps, &tgradient, repeat); + + tdst = dst_color->color; + color_correct(dst, &tdst); + do_composite(ops[op].op, &tgradient, 0, &tdst, + &expected, False); + color_correct(dst, &expected); + + snprintf(testname, 40, "%s linear gradient", ops[op].name); + if (!eval_diff(testname, &expected, &tested, 0, 0, is_verbose)) { + printf("gradient: %d stops: %d repeat: %d pos: %d/%d\n" + "src color: %.2f %.2f %.2f %.2f\n" + "dst color: %.2f %.2f %.2f %.2f\n", + p/2, s, + repeat, pix->x, pix->y, + tgradient.r, tgradient.g, + tgradient.b, tgradient.a, + dst_color->color.r, dst_color->color.g, + dst_color->color.b, dst_color->color.a); + success = FALSE; + } else if (is_verbose) { + printf("src: %d/%d, dst: %s\n", s, p, dst->name); + } + ++pix; + } + } + XRenderFreePicture(dpy, gradient); + } + } + return success; +} + + @@ -192,7 +192,7 @@ argb_fill(Display *dpy, picture_info *p, int x, int y, int w, int h, float a, void begin_test(Display *dpy, picture_info *win) { - int i, j, src, dst, mask; + int i, j, src, dst = 0, mask; int num_dests, num_formats; picture_info *dests, *pictures_1x1, *pictures_10x10, picture_3x3, *pictures_solid; @@ -459,4 +459,25 @@ begin_test(Display *dpy, picture_info *win) } } } + + if (enabled_tests & TEST_GRADIENTS) { + for (i = 0; i < num_ops; i++) { + for (j = 0; j <= num_dests; j++) { + picture_info *pi; + + if (j != num_dests) + pi = &dests[j]; + else + pi = win; + printf("Beginning %s linear gradient test on %s\n", + ops[i].name, pi->name); + + for (src = 0; src < num_colors; src++) { + for (mask = 0; mask < num_colors; mask++) { + linear_gradient_test(dpy, win, pi, i, &pictures_1x1[dst]); + } + } + } + } + } } |