diff options
Diffstat (limited to 'do_lines.c')
-rw-r--r-- | do_lines.c | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/do_lines.c b/do_lines.c new file mode 100644 index 0000000..a12c759 --- /dev/null +++ b/do_lines.c @@ -0,0 +1,320 @@ +/* $Xorg: do_lines.c,v 1.3 2000/08/17 19:54:09 cpqbld Exp $ */ +/***************************************************************************** +Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************************/ + +#include "x11perf.h" + +static XPoint *points; +static GC pgc; + +static void GenerateLines(xp, p, ddashed) + XParms xp; + Parms p; + Bool ddashed; +{ + int size; + int half; /* Half of width if wide line */ + int i; + int rows; /* Number of rows filled in current column */ + int x, y; /* Next point */ + int xdir, ydir; /* Which direction x, y are going */ + int bigxdir; + int x1, y1; /* offsets to compute next point from current */ + int phase; /* how far into 0..4*(size_1) we are */ + float phasef; /* how far we are in real numbers */ + float phaseinc; /* how much to increment phasef at each segment */ + int size4; /* 4 * size */ + + if(ddashed) + pgc = xp->ddfggc; + else + pgc = xp->fggc; + + size = p->special; + size4 = 4 * (size+1); + half = (size + 19) / 20; + + points = (XPoint *)malloc((p->objects+1) * sizeof(XPoint)); + + /* All this x, x1, x1inc, etc. stuff is to create a pattern that + (1) scans down the screen vertically + + (2) rotates the endpoints through all possible orientations + + (3) bounces off bottom and top of window as needed + + (4) moves left or right at each bounce to make things less boring + */ + + x = half; + y = half; + xdir = 1; + ydir = 1; + bigxdir = 1; + phasef = 0.0; + phaseinc = ((float)size4) / ((float)p->objects); + if (phaseinc < 1.0) phaseinc = 1.0; + rows = 0; + + points[0].x = x; + points[0].y = y; + + for (i = 1; i != (p->objects+1); i++) { + phase = phasef; + switch (phase / (size+1)) { + case 0: + x1 = size; + y1 = phase; + break; + + case 1: + x1 = size - phase % (size+1); + y1 = size; + break; + + case 2: + x1 = phase % (size+1); + y1 = size; + break; + + case 3: + x1 = size; + y1 = size - phase % (size+1); + break; + } /* end switch */ + + /* Move down or up the screen */ + y += (ydir * y1); + + /* If off either top or bottom, backtrack to previous position and go + the other way instead. Also move in bigxdir if not already. */ + rows++; + if (y < half || y >= (HEIGHT-half) || rows > MAXROWS) { + rows = 0; + if (bigxdir > 0) { + if (x + size < WIDTH - half) { + xdir = 1; + } else { + bigxdir = -1; + } + } else { + if (x - size > half) { + xdir = -1; + } else { + bigxdir = 1; + } + } + ydir = -ydir; + y += (2 * ydir * y1); + /* If still off top or bottom, we can't do the line we want. + This will happen infrequently if the window is not twice the + length of the line. So instead, let's draw a line that puts + the line after this approximately through the center of the + window. Since it is very unlikely that both x and y will + need such adjustment, line length (in pixels) should not + change...we just can't get the slope we want for this line. */ + if (y < half) { + y = (HEIGHT - y1)/2; + ydir = 1; + } else if (y > (HEIGHT - half)) { + y = (HEIGHT + y1)/2; + ydir = -1; + } + } + + /* Move x left or right by x1 */ + x += (xdir * x1); + xdir = -xdir; + /* Again, if we are off the bottom then we can't really draw the line + we want. */ + if (x < half) { + x = (WIDTH - x1)/2; + xdir = 1; + } else if (x > (WIDTH - half)) { + x = (WIDTH + x1)/2; + xdir = -1; + } + points[i].x = x; + points[i].y = y; + + /* Increment phasef */ + phasef += phaseinc; + if (phasef >= size4) phasef -= size4; + + } +} + +int InitLines(xp, p, reps) + XParms xp; + Parms p; + int reps; +{ + GenerateLines(xp, p, False); + return reps; +} + +static int GenerateWideLines(xp, p, reps, ddashed) + XParms xp; + Parms p; + int reps; + Bool ddashed; +{ + int size; + + GenerateLines(xp, p, ddashed); + + size = p->special; + if(ddashed) { + XSetLineAttributes(xp->d, xp->ddbggc, (int) ((size + 9) / 10), + LineSolid, CapRound, JoinRound); + XSetLineAttributes(xp->d, xp->ddfggc, (int) ((size + 9) / 10), + LineSolid, CapRound, JoinRound); + } + else { + XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10), + LineSolid, CapRound, JoinRound); + XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10), + LineSolid, CapRound, JoinRound); + } + + return reps; +} + +int InitWideLines(xp, p, reps) + XParms xp; + Parms p; + int reps; +{ + return GenerateWideLines(xp, p, reps, False); +} + +int InitDashedLines(xp, p, reps) + XParms xp; + Parms p; + int reps; +{ + char dashes[2]; + + GenerateLines(xp, p, False); + + /* Modify GCs to draw dashed */ + XSetLineAttributes(xp->d, xp->bggc, 0, LineOnOffDash, CapButt, JoinMiter); + XSetLineAttributes(xp->d, xp->fggc, 0, LineOnOffDash, CapButt, JoinMiter); + dashes[0] = 3; dashes[1] = 2; + XSetDashes(xp->d, xp->fggc, 0, dashes, 2); + XSetDashes(xp->d, xp->bggc, 0, dashes, 2); + return reps; +} + +int InitWideDashedLines(xp, p, reps) + XParms xp; + Parms p; + int reps; +{ + int size; + XGCValues gcv; + char dashes[2]; + + (void)GenerateWideLines(xp, p, reps, False); + size = p->special; + size = (size + 9) / 10; + + /* Modify GCs to draw dashed */ + dashes[0] = 2*size; dashes[1] = 2*size; + gcv.line_style = LineOnOffDash; + XChangeGC(xp->d, xp->fggc, GCLineStyle, &gcv); + XChangeGC(xp->d, xp->bggc, GCLineStyle, &gcv); + XSetDashes(xp->d, xp->fggc, 0, dashes, 2); + XSetDashes(xp->d, xp->bggc, 0, dashes, 2); + return reps; +} + +int InitDoubleDashedLines(xp, p, reps) + XParms xp; + Parms p; + int reps; +{ + char dashes[2]; + + GenerateLines(xp, p, True); + + /* Modify GCs to draw dashed */ + XSetLineAttributes(xp->d, xp->ddbggc, 0, LineDoubleDash, CapButt, JoinMiter); + XSetLineAttributes(xp->d, xp->ddfggc, 0, LineDoubleDash, CapButt, JoinMiter); + dashes[0] = 3; dashes[1] = 2; + XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2); + XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2); + return reps; +} + +int InitWideDoubleDashedLines(xp, p, reps) + XParms xp; + Parms p; + int reps; +{ + int size; + XGCValues gcv; + char dashes[2]; + + (void)GenerateWideLines(xp, p, reps, True); + size = p->special; + size = (size + 9) / 10; + + /* Modify GCs to draw dashed */ + dashes[0] = 2*size; dashes[1] = 2*size; + gcv.line_style = LineDoubleDash; + XChangeGC(xp->d, xp->ddfggc, GCLineStyle, &gcv); + XChangeGC(xp->d, xp->ddbggc, GCLineStyle, &gcv); + XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2); + XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2); + return reps; +} + +void DoLines(xp, p, reps) + XParms xp; + Parms p; + int reps; +{ + int i; + + for (i = 0; i != reps; i++) + { + XDrawLines(xp->d, xp->w, pgc, points, p->objects+1, CoordModeOrigin); + if (pgc == xp->ddbggc) + pgc = xp->ddfggc; + else if(pgc == xp->ddfggc) + pgc = xp->ddbggc; + else if (pgc == xp->bggc) + pgc = xp->fggc; + else + pgc = xp->bggc; + } +} + +void EndLines(xp, p) + XParms xp; + Parms p; +{ + free(points); +} + |