103b705cfSriastradh#include <stdint.h>
203b705cfSriastradh#include <stdio.h>
303b705cfSriastradh#include <stdlib.h>
403b705cfSriastradh
503b705cfSriastradh#include <X11/Xutil.h> /* for XDestroyImage */
603b705cfSriastradh#include <pixman.h> /* for pixman blt functions */
703b705cfSriastradh
803b705cfSriastradh#include "test.h"
903b705cfSriastradh
1003b705cfSriastradhstatic const XPoint points[]= {
1103b705cfSriastradh	/* top */
1203b705cfSriastradh	{ 0, 0},
1303b705cfSriastradh	{ 1, 0},
1403b705cfSriastradh	{ 2, 0},
1503b705cfSriastradh	{ 3, 0},
1603b705cfSriastradh	{ 4, 0},
1703b705cfSriastradh	{ 5, 0},
1803b705cfSriastradh	{ 6, 0},
1903b705cfSriastradh	{ 7, 0},
2003b705cfSriastradh	{ 8, 0},
2103b705cfSriastradh	/* right */
2203b705cfSriastradh	{ 8, 1},
2303b705cfSriastradh	{ 8, 2},
2403b705cfSriastradh	{ 8, 3},
2503b705cfSriastradh	{ 8, 4},
2603b705cfSriastradh	{ 8, 5},
2703b705cfSriastradh	{ 8, 6},
2803b705cfSriastradh	{ 8, 7},
2903b705cfSriastradh	{ 8, 8},
3003b705cfSriastradh	/* bottom */
3103b705cfSriastradh	{ 7, 8},
3203b705cfSriastradh	{ 6, 8},
3303b705cfSriastradh	{ 5, 8},
3403b705cfSriastradh	{ 4, 8},
3503b705cfSriastradh	{ 3, 8},
3603b705cfSriastradh	{ 2, 8},
3703b705cfSriastradh	{ 1, 8},
3803b705cfSriastradh	{ 0, 8},
3903b705cfSriastradh	/* left */
4003b705cfSriastradh	{ 0, 7},
4103b705cfSriastradh	{ 0, 6},
4203b705cfSriastradh	{ 0, 5},
4303b705cfSriastradh	{ 0, 4},
4403b705cfSriastradh	{ 0, 3},
4503b705cfSriastradh	{ 0, 2},
4603b705cfSriastradh	{ 0, 1},
4703b705cfSriastradh	{ 0, 0} /* and origin again for luck */
4803b705cfSriastradh};
4903b705cfSriastradh#define NUM_POINTS (sizeof(points)/sizeof(points[0]))
5003b705cfSriastradh
5103b705cfSriastradhstatic void clear(struct test_display *dpy, struct test_target *tt)
5203b705cfSriastradh{
5303b705cfSriastradh	XRenderColor render_color = {0};
5403b705cfSriastradh	XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
5503b705cfSriastradh			     0, 0, tt->width, tt->height);
5603b705cfSriastradh}
5703b705cfSriastradh
5803b705cfSriastradhstatic void draw_line(struct test_display *dpy, struct test_target *tt,
5903b705cfSriastradh		      int alu, int width, int style, int cap,
6003b705cfSriastradh		      const XPoint *p1, const XPoint *p2,
6103b705cfSriastradh		      int dx, int dy)
6203b705cfSriastradh{
6303b705cfSriastradh	XGCValues val;
6403b705cfSriastradh	GC gc;
6503b705cfSriastradh
6603b705cfSriastradh	val.function = GXcopy;
6703b705cfSriastradh	val.foreground = WhitePixel(dpy->dpy, 0);
6803b705cfSriastradh	val.line_width = width;
6903b705cfSriastradh	val.line_style = style;
7003b705cfSriastradh	val.cap_style = cap;
7103b705cfSriastradh
7203b705cfSriastradh	gc = XCreateGC(dpy->dpy, tt->draw,
7303b705cfSriastradh		       GCForeground |
7403b705cfSriastradh		       GCFunction |
7503b705cfSriastradh		       GCLineWidth |
7603b705cfSriastradh		       GCLineStyle |
7703b705cfSriastradh		       GCCapStyle,
7803b705cfSriastradh		       &val);
7903b705cfSriastradh	XDrawLine(dpy->dpy, tt->draw, gc,
8003b705cfSriastradh		  p1->x + dx, p1->y + dy,
8103b705cfSriastradh		  p2->x + dx, p2->y + dy);
8203b705cfSriastradh	XFreeGC(dpy->dpy, gc);
8303b705cfSriastradh}
8403b705cfSriastradh
8503b705cfSriastradhstatic void line_tests(struct test *t, enum target target)
8603b705cfSriastradh{
8703b705cfSriastradh	char buf[1024];
8842542f5fSchristos	struct test_target out, ref;
8903b705cfSriastradh	int a, b, alu, lw, style, cap;
9003b705cfSriastradh
9103b705cfSriastradh	printf("Testing drawing of single line segments (%s): ",
9203b705cfSriastradh	       test_target_name(target));
9303b705cfSriastradh	fflush(stdout);
9403b705cfSriastradh
9542542f5fSchristos	test_target_create_render(&t->out, target, &out);
9603b705cfSriastradh	test_target_create_render(&t->ref, target, &ref);
9703b705cfSriastradh
9803b705cfSriastradh	style = LineSolid;
9903b705cfSriastradh
10003b705cfSriastradh	for (alu = 0; alu < 16; alu++) {
10103b705cfSriastradh		for (cap = CapNotLast; cap <= CapProjecting; cap++) {
10203b705cfSriastradh			for (lw = 0; lw <= 4; lw++) {
10303b705cfSriastradh				for (a = 0; a < NUM_POINTS; a++) {
10403b705cfSriastradh					for (b = 0; b < NUM_POINTS; b++) {
10503b705cfSriastradh						sprintf(buf,
10603b705cfSriastradh							"p1=(%d, %d), p2=(%d, %d), width=%d, cap=%d, alu=%d",
10703b705cfSriastradh							points[a].x, points[a].y,
10803b705cfSriastradh							points[b].x, points[b].y,
10903b705cfSriastradh							lw, cap, alu);
11003b705cfSriastradh
11142542f5fSchristos						clear(&t->out, &out);
11203b705cfSriastradh						clear(&t->ref, &ref);
11303b705cfSriastradh
11442542f5fSchristos						draw_line(&t->out, &out, alu, lw, style, cap,
11503b705cfSriastradh							  &points[a], &points[b], 64, 64);
11603b705cfSriastradh						draw_line(&t->ref, &ref, alu, lw, style, cap,
11703b705cfSriastradh							  &points[a], &points[b], 64, 64);
11803b705cfSriastradh
11903b705cfSriastradh						test_compare(t,
12042542f5fSchristos							     out.draw, out.format,
12103b705cfSriastradh							     ref.draw, ref.format,
12242542f5fSchristos							     0, 0, out.width, out.height,
12303b705cfSriastradh							     buf);
12403b705cfSriastradh					}
12503b705cfSriastradh				}
12603b705cfSriastradh			}
12703b705cfSriastradh		}
12803b705cfSriastradh	}
12903b705cfSriastradh
13042542f5fSchristos	test_target_destroy_render(&t->out, &out);
13103b705cfSriastradh	test_target_destroy_render(&t->ref, &ref);
13203b705cfSriastradh
13303b705cfSriastradh	printf("\n");
13403b705cfSriastradh}
13503b705cfSriastradh
13603b705cfSriastradhint main(int argc, char **argv)
13703b705cfSriastradh{
13803b705cfSriastradh	struct test test;
13903b705cfSriastradh	enum target t;
14003b705cfSriastradh
14103b705cfSriastradh	test_init(&test, argc, argv);
14203b705cfSriastradh
14303b705cfSriastradh	for (t = TARGET_FIRST; t <= TARGET_LAST; t++)
14403b705cfSriastradh		line_tests(&test, t);
14503b705cfSriastradh
14603b705cfSriastradh	return 0;
14703b705cfSriastradh}
148