#include "x11perf.h"
static XPoint *points;
static GC pgc;
static void
GenerateLines(XParms xp, Parms p, Bool ddashed)
{
int size;
int half;
int i;
int rows;
int x, y;
int xdir, ydir;
int bigxdir;
int x1 = 0, y1 = 0;
int phase;
float phasef;
float phaseinc;
int size4;
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));
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;
}
y += (ydir * y1);
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 (y < half) {
y = (HEIGHT - y1)/2;
ydir = 1;
} else if (y > (HEIGHT - half)) {
y = (HEIGHT + y1)/2;
ydir = -1;
}
}
x += (xdir * x1);
xdir = -xdir;
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;
phasef += phaseinc;
if (phasef >= size4) phasef -= size4;
}
}
int
InitLines(XParms xp, Parms p, int reps)
{
GenerateLines(xp, p, False);
return reps;
}
static int
GenerateWideLines(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(XParms xp, Parms p, int reps)
{
return GenerateWideLines(xp, p, reps, False);
}
int
InitDashedLines(XParms xp, Parms p, int reps)
{
char dashes[2];
GenerateLines(xp, p, False);
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(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;
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(XParms xp, Parms p, int reps)
{
char dashes[2];
GenerateLines(xp, p, True);
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(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;
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(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;
CheckAbort ();
}
}
void
EndLines(XParms xp, Parms p)
{
free(points);
}