1#include <stdint.h> 2#include <stdio.h> 3#include <stdlib.h> 4 5#include <X11/Xutil.h> /* for XDestroyImage */ 6#include <pixman.h> /* for pixman blt functions */ 7 8#include "test.h" 9 10static const XPoint points[]= { 11 /* top */ 12 { 0, 0}, 13 { 1, 0}, 14 { 2, 0}, 15 { 3, 0}, 16 { 4, 0}, 17 { 5, 0}, 18 { 6, 0}, 19 { 7, 0}, 20 { 8, 0}, 21 /* right */ 22 { 8, 1}, 23 { 8, 2}, 24 { 8, 3}, 25 { 8, 4}, 26 { 8, 5}, 27 { 8, 6}, 28 { 8, 7}, 29 { 8, 8}, 30 /* bottom */ 31 { 7, 8}, 32 { 6, 8}, 33 { 5, 8}, 34 { 4, 8}, 35 { 3, 8}, 36 { 2, 8}, 37 { 1, 8}, 38 { 0, 8}, 39 /* left */ 40 { 0, 7}, 41 { 0, 6}, 42 { 0, 5}, 43 { 0, 4}, 44 { 0, 3}, 45 { 0, 2}, 46 { 0, 1}, 47 { 0, 0} /* and origin again for luck */ 48}; 49#define NUM_POINTS (sizeof(points)/sizeof(points[0])) 50 51static void clear(struct test_display *dpy, struct test_target *tt) 52{ 53 XRenderColor render_color = {0}; 54 XRenderFillRectangle(dpy->dpy, PictOpClear, tt->picture, &render_color, 55 0, 0, tt->width, tt->height); 56} 57 58static void draw(struct test_display *dpy, struct test_target *tt, 59 int alu, int width, int style, int cap, 60 XSegment *seg, int nseg) 61{ 62 XGCValues val; 63 GC gc; 64 65 val.function = alu; 66 val.foreground = WhitePixel(dpy->dpy, 0); 67 val.line_width = width; 68 val.line_style = style; 69 val.cap_style = cap; 70 71 gc = XCreateGC(dpy->dpy, tt->draw, 72 GCForeground | 73 GCFunction | 74 GCLineWidth | 75 GCLineStyle | 76 GCCapStyle, 77 &val); 78 XDrawSegments(dpy->dpy, tt->draw, gc, seg, nseg); 79 XFreeGC(dpy->dpy, gc); 80} 81 82static void hv0(struct test *t, enum target target) 83{ 84 char buf[1024]; 85 struct test_target out, ref; 86 int a, alu, cap; 87 XSegment seg[(NUM_POINTS+1)*8]; 88 int n, x, y, nseg; 89 90 printf("Testing drawing of zero-width line segments (%s): ", 91 test_target_name(target)); 92 fflush(stdout); 93 94 test_target_create_render(&t->out, target, &out); 95 test_target_create_render(&t->ref, target, &ref); 96 97 y = x = n = 0; 98 for (a = 0; a <= NUM_POINTS; a++) { 99 seg[n].x1 = a + 64; 100 seg[n].y1 = y + 64; 101 seg[n].x2 = NUM_POINTS + 64; 102 seg[n].y2 = y + 64; 103 n++; y++; 104 105 seg[n].x1 = NUM_POINTS - a + 64; 106 seg[n].y1 = y + 64; 107 seg[n].x2 = 0 + 64; 108 seg[n].y2 = y + 64; 109 n++; y++; 110 111 seg[n].x2 = a + 64; 112 seg[n].y2 = y + 64; 113 seg[n].x1 = NUM_POINTS + 64; 114 seg[n].y1 = y + 64; 115 n++; y++; 116 117 seg[n].x2 = NUM_POINTS - a + 64; 118 seg[n].y2 = y + 64; 119 seg[n].x1 = 0 + 64; 120 seg[n].y1 = y + 64; 121 n++; y++; 122 123 124 seg[n].y1 = a + 64; 125 seg[n].x1 = x + 64; 126 seg[n].y2 = NUM_POINTS + 64; 127 seg[n].x2 = x + 64; 128 n++; x++; 129 130 seg[n].y1 = NUM_POINTS - a + 64; 131 seg[n].x1 = x + 64; 132 seg[n].y2 = 0 + 64; 133 seg[n].x2 = x + 64; 134 n++; x++; 135 136 seg[n].y2 = a + 64; 137 seg[n].x2 = x + 64; 138 seg[n].y1 = NUM_POINTS + 64; 139 seg[n].x1 = x + 64; 140 n++; x++; 141 142 seg[n].y2 = NUM_POINTS - a + 64; 143 seg[n].x2 = x + 64; 144 seg[n].y1 = 0 + 64; 145 seg[n].x1 = x + 64; 146 n++; x++; 147 } 148 149 for (alu = 0; alu < 16; alu++) { 150 for (cap = CapNotLast; cap <= CapProjecting; cap++) { 151 for (nseg = 0; nseg < n; nseg++) { 152 sprintf(buf, 153 "cap=%d, alu=%d, nseg=%d", 154 cap, alu, nseg); 155 156 clear(&t->out, &out); 157 clear(&t->ref, &ref); 158 159 draw(&t->out, &out, alu, 0, LineSolid, cap, 160 seg, nseg); 161 draw(&t->ref, &ref, alu, 0, LineSolid, cap, 162 seg, nseg); 163 164 test_compare(t, 165 out.draw, out.format, 166 ref.draw, ref.format, 167 0, 0, out.width, out.height, 168 buf); 169 } 170 } 171 } 172 173 test_target_destroy_render(&t->out, &out); 174 test_target_destroy_render(&t->ref, &ref); 175 176 printf("\n"); 177} 178 179static void general(struct test *t, enum target target) 180{ 181 char buf[1024]; 182 struct test_target out, ref; 183 int a, b, alu, lw, style, cap; 184 XSegment seg[NUM_POINTS*NUM_POINTS]; 185 int n = 0; 186 187 printf("Testing drawing of general line segments (%s): ", 188 test_target_name(target)); 189 fflush(stdout); 190 191 test_target_create_render(&t->out, target, &out); 192 test_target_create_render(&t->ref, target, &ref); 193 194 style = LineSolid; 195 196 for (a = 0; a < NUM_POINTS; a++) { 197 for (b = 0; b < NUM_POINTS; b++) { 198 seg[n].x1 = points[a].x + 64; 199 seg[n].y1 = points[a].y + 64; 200 seg[n].x2 = points[b].x + 64; 201 seg[n].y2 = points[b].y + 64; 202 n++; 203 } 204 } 205 206 for (alu = 0; alu < 16; alu++) { 207 for (cap = CapNotLast; cap <= CapProjecting; cap++) { 208 for (lw = 0; lw <= 4; lw++) { 209 sprintf(buf, 210 "width=%d, cap=%d, alu=%d", 211 lw, cap, alu); 212 213 clear(&t->out, &out); 214 clear(&t->ref, &ref); 215 216 draw(&t->out, &out, alu, lw, style, cap, 217 seg, n); 218 draw(&t->ref, &ref, alu, lw, style, cap, 219 seg, n); 220 221 test_compare(t, 222 out.draw, out.format, 223 ref.draw, ref.format, 224 0, 0, out.width, out.height, 225 buf); 226 } 227 } 228 } 229 230 test_target_destroy_render(&t->out, &out); 231 test_target_destroy_render(&t->ref, &ref); 232 233 printf("\n"); 234} 235 236int main(int argc, char **argv) 237{ 238 struct test test; 239 enum target t; 240 241 test_init(&test, argc, argv); 242 243 for (t = TARGET_FIRST; t <= TARGET_LAST; t++) { 244 hv0(&test, t); 245 general(&test, t); 246 } 247 248 return 0; 249} 250