do_segs.c revision 736a7e2c
1/***************************************************************************** 2Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 3 4 All Rights Reserved 5 6Permission to use, copy, modify, and distribute this software and its 7documentation for any purpose and without fee is hereby granted, 8provided that the above copyright notice appear in all copies and that 9both that copyright notice and this permission notice appear in 10supporting documentation, and that the name of Digital not be 11used in advertising or publicity pertaining to distribution of the 12software without specific, written prior permission. 13 14DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 16DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20SOFTWARE. 21 22******************************************************************************/ 23 24#include "x11perf.h" 25 26static XSegment *segments; 27static GC pgc; 28 29static void 30GenerateSegments(XParms xp, Parms p, Bool ddashed) 31{ 32 int size; 33 int half; 34 int i; 35 int rows; /* Number of rows filled in current column */ 36 int x, y; /* base of square to draw in */ 37 int x1=0, y1=0, x2=0, y2=0; /* offsets into square */ 38 int phase; /* how far into 0..8*size we are */ 39 int phaseinc; /* how much to increment phase at each segment */ 40 int size8; /* 8 * size */ 41 XGCValues gcv; 42 43 if(ddashed) 44 pgc = xp->ddfggc; 45 else 46 pgc = xp->fggc; 47 48 49 size = p->special; 50 size8 = 8 * size; 51 half = (size + 19) / 20; 52 53 segments = (XSegment *)malloc((p->objects) * sizeof(XSegment)); 54 55 /* All this x, x1, etc. stuff is to create a pattern that 56 (1) scans down the screen vertically, with each new segment going 57 into a square of size^2. 58 59 (2) rotates the endpoints clockwise around the square 60 61 (3) rotates by ``large'' steps if we aren't going to paint enough 62 segments to get full coverage 63 64 (4) uses CapNotLast so we can create segments of length 1 that 65 nonetheless have a distinct direction 66 */ 67 68 x = half; y = half; 69 phase = 0; 70 phaseinc = size8 / p->objects; 71 if (phaseinc == 0) phaseinc = 1; 72 rows = 0; 73 74 for (i = 0; i != p->objects; i++) { 75 switch (phase / size) { 76 case 0: 77 x1 = 0; 78 y1 = 0; 79 x2 = size; 80 y2 = phase; 81 break; 82 83 case 1: 84 x1 = phase % size; 85 y1 = 0; 86 x2 = size; 87 y2 = size; 88 break; 89 90 case 2: 91 x1 = size; 92 y1 = 0; 93 x2 = size - phase % size; 94 y2 = size; 95 break; 96 97 case 3: 98 x1 = size; 99 y1 = phase % size; 100 x2 = 0; 101 y2 = size; 102 break; 103 104 case 4: 105 x1 = size; 106 y1 = size; 107 x2 = 0; 108 y2 = size - phase % size; 109 break; 110 111 case 5: 112 x1 = size - phase % size; 113 y1 = size; 114 x2 = 0; 115 y2 = 0; 116 break; 117 118 case 6: 119 x1 = 0; 120 y1 = size; 121 x2 = phase % size; 122 y2 = 0; 123 break; 124 125 case 7: 126 x1 = 0; 127 y1 = size - phase % size; 128 x2 = size; 129 y2 = 0; 130 break; 131 } /* end switch */ 132 133 segments[i].x1 = x + x1; 134 segments[i].y1 = y + y1; 135 segments[i].x2 = x + x2; 136 segments[i].y2 = y + y2; 137 138 /* Change square to draw segment in */ 139 rows++; 140 y += size; 141 if (y >= HEIGHT - size - half || rows == MAXROWS) { 142 /* Go to next column */ 143 rows = 0; 144 y = half; 145 x += size; 146 if (x >= WIDTH - size - half) { 147 x = half; 148 } 149 } 150 151 /* Increment phase */ 152 phase += phaseinc; 153 if (phase >= size8) phase -= size8; 154 155 } 156 157 gcv.cap_style = CapNotLast; 158 159 if(ddashed) { 160 XChangeGC(xp->d, xp->ddfggc, GCCapStyle, &gcv); 161 XChangeGC(xp->d, xp->ddbggc, GCCapStyle, &gcv); 162 } else { 163 XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv); 164 XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv); 165 } 166} 167 168int 169InitSegments(XParms xp, Parms p, int reps) 170{ 171 GenerateSegments(xp, p, False); 172 return reps; 173} 174 175int 176InitDashedSegments(XParms xp, Parms p, int reps) 177{ 178 char dashes[2]; 179 180 GenerateSegments(xp, p, False); 181 182 /* Modify GCs to draw dashed */ 183 XSetLineAttributes 184 (xp->d, xp->bggc, 0, LineOnOffDash, CapNotLast, JoinMiter); 185 XSetLineAttributes 186 (xp->d, xp->fggc, 0, LineOnOffDash, CapNotLast, JoinMiter); 187 dashes[0] = 3; dashes[1] = 2; 188 XSetDashes(xp->d, xp->fggc, 0, dashes, 2); 189 XSetDashes(xp->d, xp->bggc, 0, dashes, 2); 190 return reps; 191} 192 193int 194InitDoubleDashedSegments(XParms xp, Parms p, int reps) 195{ 196 char dashes[2]; 197 198 GenerateSegments(xp, p, True); 199 200 /* Modify GCs to draw dashed */ 201 XSetLineAttributes 202 (xp->d, xp->ddbggc, 0, LineDoubleDash, CapNotLast, JoinMiter); 203 XSetLineAttributes 204 (xp->d, xp->ddfggc, 0, LineDoubleDash, CapNotLast, JoinMiter); 205 dashes[0] = 3; dashes[1] = 2; 206 XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2); 207 XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2); 208 return reps; 209} 210 211int 212InitHorizSegments(XParms xp, Parms p, int reps) 213{ 214 int size; 215 int half; 216 int i; 217 int rows; /* Number of rows filled in current column */ 218 int x, y; /* base of square to draw in */ 219 int y1; /* y position inside square */ 220 int inc; 221 XGCValues gcv; 222 223 pgc = xp->fggc; 224 225 size = p->special; 226 half = (size + 19) / 20; 227 228 segments = (XSegment *)malloc((p->objects) * sizeof(XSegment)); 229 230 x = half; 231 y = half; 232 y1 = 0; 233 rows = 0; 234 inc = size / p->objects; 235 if (inc == 0) inc = 1; 236 237 for (i = 0; i != p->objects; i++) { 238 if (i % 2) { 239 segments[i].x1 = x + size; 240 segments[i].x2 = x; 241 segments[i].y1 = y + size - y1; 242 segments[i].y2 = y + size - y1; 243 y1 += inc; 244 if (y1 >= size) y1 -= size; 245 } else { 246 segments[i].x1 = x; 247 segments[i].x2 = x + size; 248 segments[i].y1 = y + y1; 249 segments[i].y2 = y + y1; 250 } 251 rows++; 252 y += size; 253 if (y >= HEIGHT - size - half || rows == MAXROWS) { 254 rows = 0; 255 y = half; 256 x += size; 257 if (x >= WIDTH - size - half) 258 x = half; 259 } 260 } 261 gcv.cap_style = CapNotLast; 262 XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv); 263 XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv); 264 return reps; 265} 266 267int 268InitWideHorizSegments(XParms xp, Parms p, int reps) 269{ 270 int size; 271 272 (void)InitHorizSegments(xp, p, reps); 273 274 size = p->special; 275 XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10), 276 LineSolid, CapRound, JoinRound); 277 XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10), 278 LineSolid, CapRound, JoinRound); 279 280 return reps; 281} 282 283 284int 285InitVertSegments(XParms xp, Parms p, int reps) 286{ 287 int size; 288 int half; 289 int i; 290 int rows; /* Number of rows filled in current column */ 291 int x, y; /* base of square to draw in */ 292 int x1; /* x position inside square */ 293 int inc; 294 XGCValues gcv; 295 296 pgc = xp->fggc; 297 298 size = p->special; 299 half = (size + 19) / 20; 300 301 segments = (XSegment *)malloc((p->objects) * sizeof(XSegment)); 302 303 x = half; 304 y = half; 305 x1 = 0; 306 rows = 0; 307 inc = size / p->objects; 308 if (inc == 0) inc = 1; 309 310 for (i = 0; i != p->objects; i++) { 311 if (i % 2) { 312 segments[i].x1 = x + size - x1; 313 segments[i].x2 = x + size - x1; 314 segments[i].y1 = y + size; 315 segments[i].y2 = y; 316 x1 += inc; 317 if (x1 >= size) x1 -= size; 318 } else { 319 segments[i].x1 = x + x1; 320 segments[i].x2 = x + x1; 321 segments[i].y1 = y; 322 segments[i].y2 = y + size; 323 } 324 rows++; 325 y += size; 326 if (y >= HEIGHT - size - half || rows == MAXROWS) { 327 /* Go to next column */ 328 rows = 0; 329 y = half; 330 x += size; 331 if (x >= WIDTH - size - half) { 332 x = half; 333 } 334 } 335 } 336 gcv.cap_style = CapNotLast; 337 XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv); 338 XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv); 339 return reps; 340} 341 342int 343InitWideVertSegments(XParms xp, Parms p, int reps) 344{ 345 int size; 346 347 (void)InitVertSegments(xp, p, reps); 348 349 size = p->special; 350 XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10), 351 LineSolid, CapRound, JoinRound); 352 XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10), 353 LineSolid, CapRound, JoinRound); 354 355 return reps; 356} 357 358 359void 360DoSegments(XParms xp, Parms p, int reps) 361{ 362 int i; 363 364 for (i = 0; i != reps; i++) { 365 XDrawSegments(xp->d, xp->w, pgc, segments, p->objects); 366 if (pgc == xp->ddbggc) 367 pgc = xp->ddfggc; 368 else if(pgc == xp->ddfggc) 369 pgc = xp->ddbggc; 370 else if (pgc == xp->bggc) 371 pgc = xp->fggc; 372 else 373 pgc = xp->bggc; 374 CheckAbort (); 375 } 376} 377 378void 379EndSegments(XParms xp, Parms p) 380{ 381 free(segments); 382} 383 384