113496ba1Ssnj#include <stdint.h>
213496ba1Ssnj#include <stdio.h>
313496ba1Ssnj#include <stdlib.h>
413496ba1Ssnj
513496ba1Ssnj#include <X11/Xutil.h> /* for XDestroyImage */
613496ba1Ssnj#include <pixman.h> /* for pixman blt functions */
713496ba1Ssnj
813496ba1Ssnj#include "test.h"
913496ba1Ssnj
1013496ba1Ssnjstatic const XPoint points[]= {
1113496ba1Ssnj	/* top */
1213496ba1Ssnj	{ 0, 0},
1313496ba1Ssnj	{ 1, 0},
1413496ba1Ssnj	{ 2, 0},
1513496ba1Ssnj	{ 3, 0},
1613496ba1Ssnj	{ 4, 0},
1713496ba1Ssnj	{ 5, 0},
1813496ba1Ssnj	{ 6, 0},
1913496ba1Ssnj	{ 7, 0},
2013496ba1Ssnj	{ 8, 0},
2113496ba1Ssnj	/* right */
2213496ba1Ssnj	{ 8, 1},
2313496ba1Ssnj	{ 8, 2},
2413496ba1Ssnj	{ 8, 3},
2513496ba1Ssnj	{ 8, 4},
2613496ba1Ssnj	{ 8, 5},
2713496ba1Ssnj	{ 8, 6},
2813496ba1Ssnj	{ 8, 7},
2913496ba1Ssnj	{ 8, 8},
3013496ba1Ssnj	/* bottom */
3113496ba1Ssnj	{ 7, 8},
3213496ba1Ssnj	{ 6, 8},
3313496ba1Ssnj	{ 5, 8},
3413496ba1Ssnj	{ 4, 8},
3513496ba1Ssnj	{ 3, 8},
3613496ba1Ssnj	{ 2, 8},
3713496ba1Ssnj	{ 1, 8},
3813496ba1Ssnj	{ 0, 8},
3913496ba1Ssnj	/* left */
4013496ba1Ssnj	{ 0, 7},
4113496ba1Ssnj	{ 0, 6},
4213496ba1Ssnj	{ 0, 5},
4313496ba1Ssnj	{ 0, 4},
4413496ba1Ssnj	{ 0, 3},
4513496ba1Ssnj	{ 0, 2},
4613496ba1Ssnj	{ 0, 1},
4713496ba1Ssnj	{ 0, 0} /* and origin again for luck */
4813496ba1Ssnj};
4913496ba1Ssnj#define NUM_POINTS (sizeof(points)/sizeof(points[0]))
5013496ba1Ssnj
5113496ba1Ssnjstatic void clear(struct test_display *dpy, struct test_target *tt)
5213496ba1Ssnj{
5313496ba1Ssnj	XRenderColor render_color = {0};
5413496ba1Ssnj	XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color,
5513496ba1Ssnj			     0, 0, tt->width, tt->height);
5613496ba1Ssnj}
5713496ba1Ssnj
5813496ba1Ssnjstatic void draw(struct test_display *dpy, struct test_target *tt,
5913496ba1Ssnj		 int alu, int width, int style, int cap,
6013496ba1Ssnj		 XSegment *seg, int nseg)
6113496ba1Ssnj{
6213496ba1Ssnj	XGCValues val;
6313496ba1Ssnj	GC gc;
6413496ba1Ssnj
6513496ba1Ssnj	val.function = alu;
6613496ba1Ssnj	val.foreground = WhitePixel(dpy->dpy, 0);
6713496ba1Ssnj	val.line_width = width;
6813496ba1Ssnj	val.line_style = style;
6913496ba1Ssnj	val.cap_style = cap;
7013496ba1Ssnj
7113496ba1Ssnj	gc = XCreateGC(dpy->dpy, tt->draw,
7213496ba1Ssnj		       GCForeground |
7313496ba1Ssnj		       GCFunction |
7413496ba1Ssnj		       GCLineWidth |
7513496ba1Ssnj		       GCLineStyle |
7613496ba1Ssnj		       GCCapStyle,
7713496ba1Ssnj		       &val);
7813496ba1Ssnj	XDrawSegments(dpy->dpy, tt->draw, gc, seg, nseg);
7913496ba1Ssnj	XFreeGC(dpy->dpy, gc);
8013496ba1Ssnj}
8113496ba1Ssnj
8213496ba1Ssnjstatic void hv0(struct test *t, enum target target)
8313496ba1Ssnj{
8413496ba1Ssnj	char buf[1024];
8513496ba1Ssnj	struct test_target out, ref;
8613496ba1Ssnj	int a, alu, cap;
8713496ba1Ssnj	XSegment seg[(NUM_POINTS+1)*8];
8813496ba1Ssnj	int n, x, y, nseg;
8913496ba1Ssnj
9013496ba1Ssnj	printf("Testing drawing of zero-width line segments (%s): ",
9113496ba1Ssnj	       test_target_name(target));
9213496ba1Ssnj	fflush(stdout);
9313496ba1Ssnj
9413496ba1Ssnj	test_target_create_render(&t->out, target, &out);
9513496ba1Ssnj	test_target_create_render(&t->ref, target, &ref);
9613496ba1Ssnj
9713496ba1Ssnj	y = x = n = 0;
9813496ba1Ssnj	for (a = 0; a <= NUM_POINTS; a++) {
9913496ba1Ssnj		seg[n].x1 = a + 64;
10013496ba1Ssnj		seg[n].y1 = y + 64;
10113496ba1Ssnj		seg[n].x2 = NUM_POINTS + 64;
10213496ba1Ssnj		seg[n].y2 = y + 64;
10313496ba1Ssnj		n++; y++;
10413496ba1Ssnj
10513496ba1Ssnj		seg[n].x1 = NUM_POINTS - a + 64;
10613496ba1Ssnj		seg[n].y1 = y + 64;
10713496ba1Ssnj		seg[n].x2 = 0 + 64;
10813496ba1Ssnj		seg[n].y2 = y + 64;
10913496ba1Ssnj		n++; y++;
11013496ba1Ssnj
11113496ba1Ssnj		seg[n].x2 = a + 64;
11213496ba1Ssnj		seg[n].y2 = y + 64;
11313496ba1Ssnj		seg[n].x1 = NUM_POINTS + 64;
11413496ba1Ssnj		seg[n].y1 = y + 64;
11513496ba1Ssnj		n++; y++;
11613496ba1Ssnj
11713496ba1Ssnj		seg[n].x2 = NUM_POINTS - a + 64;
11813496ba1Ssnj		seg[n].y2 = y + 64;
11913496ba1Ssnj		seg[n].x1 = 0 + 64;
12013496ba1Ssnj		seg[n].y1 = y + 64;
12113496ba1Ssnj		n++; y++;
12213496ba1Ssnj
12313496ba1Ssnj
12413496ba1Ssnj		seg[n].y1 = a + 64;
12513496ba1Ssnj		seg[n].x1 = x + 64;
12613496ba1Ssnj		seg[n].y2 = NUM_POINTS + 64;
12713496ba1Ssnj		seg[n].x2 = x + 64;
12813496ba1Ssnj		n++; x++;
12913496ba1Ssnj
13013496ba1Ssnj		seg[n].y1 = NUM_POINTS - a + 64;
13113496ba1Ssnj		seg[n].x1 = x + 64;
13213496ba1Ssnj		seg[n].y2 = 0 + 64;
13313496ba1Ssnj		seg[n].x2 = x + 64;
13413496ba1Ssnj		n++; x++;
13513496ba1Ssnj
13613496ba1Ssnj		seg[n].y2 = a + 64;
13713496ba1Ssnj		seg[n].x2 = x + 64;
13813496ba1Ssnj		seg[n].y1 = NUM_POINTS + 64;
13913496ba1Ssnj		seg[n].x1 = x + 64;
14013496ba1Ssnj		n++; x++;
14113496ba1Ssnj
14213496ba1Ssnj		seg[n].y2 = NUM_POINTS - a + 64;
14313496ba1Ssnj		seg[n].x2 = x + 64;
14413496ba1Ssnj		seg[n].y1 = 0 + 64;
14513496ba1Ssnj		seg[n].x1 = x + 64;
14613496ba1Ssnj		n++; x++;
14713496ba1Ssnj	}
14813496ba1Ssnj
14913496ba1Ssnj	for (alu = 0; alu < 16; alu++) {
15013496ba1Ssnj		for (cap = CapNotLast; cap <= CapProjecting; cap++) {
15113496ba1Ssnj			for (nseg = 0; nseg < n; nseg++) {
15213496ba1Ssnj				sprintf(buf,
15313496ba1Ssnj					"cap=%d, alu=%d, nseg=%d",
15413496ba1Ssnj					cap, alu, nseg);
15513496ba1Ssnj
15613496ba1Ssnj				clear(&t->out, &out);
15713496ba1Ssnj				clear(&t->ref, &ref);
15813496ba1Ssnj
15913496ba1Ssnj				draw(&t->out, &out, alu, 0, LineSolid, cap,
16013496ba1Ssnj				     seg, nseg);
16113496ba1Ssnj				draw(&t->ref, &ref, alu, 0, LineSolid, cap,
16213496ba1Ssnj				     seg, nseg);
16313496ba1Ssnj
16413496ba1Ssnj				test_compare(t,
16513496ba1Ssnj					     out.draw, out.format,
16613496ba1Ssnj					     ref.draw, ref.format,
16713496ba1Ssnj					     0, 0, out.width, out.height,
16813496ba1Ssnj					     buf);
16913496ba1Ssnj			}
17013496ba1Ssnj		}
17113496ba1Ssnj	}
17213496ba1Ssnj
17313496ba1Ssnj	test_target_destroy_render(&t->out, &out);
17413496ba1Ssnj	test_target_destroy_render(&t->ref, &ref);
17513496ba1Ssnj
17613496ba1Ssnj	printf("\n");
17713496ba1Ssnj}
17813496ba1Ssnj
17913496ba1Ssnjstatic void general(struct test *t, enum target target)
18013496ba1Ssnj{
18113496ba1Ssnj	char buf[1024];
18213496ba1Ssnj	struct test_target out, ref;
18313496ba1Ssnj	int a, b, alu, lw, style, cap;
18413496ba1Ssnj	XSegment seg[NUM_POINTS*NUM_POINTS];
18513496ba1Ssnj	int n = 0;
18613496ba1Ssnj
18713496ba1Ssnj	printf("Testing drawing of general line segments (%s): ",
18813496ba1Ssnj	       test_target_name(target));
18913496ba1Ssnj	fflush(stdout);
19013496ba1Ssnj
19113496ba1Ssnj	test_target_create_render(&t->out, target, &out);
19213496ba1Ssnj	test_target_create_render(&t->ref, target, &ref);
19313496ba1Ssnj
19413496ba1Ssnj	style = LineSolid;
19513496ba1Ssnj
19613496ba1Ssnj	for (a = 0; a < NUM_POINTS; a++) {
19713496ba1Ssnj		for (b = 0; b < NUM_POINTS; b++) {
19813496ba1Ssnj			seg[n].x1 = points[a].x + 64;
19913496ba1Ssnj			seg[n].y1 = points[a].y + 64;
20013496ba1Ssnj			seg[n].x2 = points[b].x + 64;
20113496ba1Ssnj			seg[n].y2 = points[b].y + 64;
20213496ba1Ssnj			n++;
20313496ba1Ssnj		}
20413496ba1Ssnj	}
20513496ba1Ssnj
20613496ba1Ssnj	for (alu = 0; alu < 16; alu++) {
20713496ba1Ssnj		for (cap = CapNotLast; cap <= CapProjecting; cap++) {
20813496ba1Ssnj			for (lw = 0; lw <= 4; lw++) {
20913496ba1Ssnj				sprintf(buf,
21013496ba1Ssnj					"width=%d, cap=%d, alu=%d",
21113496ba1Ssnj					lw, cap, alu);
21213496ba1Ssnj
21313496ba1Ssnj				clear(&t->out, &out);
21413496ba1Ssnj				clear(&t->ref, &ref);
21513496ba1Ssnj
21613496ba1Ssnj				draw(&t->out, &out, alu, lw, style, cap,
21713496ba1Ssnj					  seg, n);
21813496ba1Ssnj				draw(&t->ref, &ref, alu, lw, style, cap,
21913496ba1Ssnj					  seg, n);
22013496ba1Ssnj
22113496ba1Ssnj				test_compare(t,
22213496ba1Ssnj					     out.draw, out.format,
22313496ba1Ssnj					     ref.draw, ref.format,
22413496ba1Ssnj					     0, 0, out.width, out.height,
22513496ba1Ssnj					     buf);
22613496ba1Ssnj			}
22713496ba1Ssnj		}
22813496ba1Ssnj	}
22913496ba1Ssnj
23013496ba1Ssnj	test_target_destroy_render(&t->out, &out);
23113496ba1Ssnj	test_target_destroy_render(&t->ref, &ref);
23213496ba1Ssnj
23313496ba1Ssnj	printf("\n");
23413496ba1Ssnj}
23513496ba1Ssnj
23613496ba1Ssnjint main(int argc, char **argv)
23713496ba1Ssnj{
23813496ba1Ssnj	struct test test;
23913496ba1Ssnj	enum target t;
24013496ba1Ssnj
24113496ba1Ssnj	test_init(&test, argc, argv);
24213496ba1Ssnj
24313496ba1Ssnj	for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
24413496ba1Ssnj		hv0(&test, t);
24513496ba1Ssnj		general(&test, t);
24613496ba1Ssnj	}
24713496ba1Ssnj
24813496ba1Ssnj	return 0;
24913496ba1Ssnj}
250