#include "x11perf.h"
static XSegment *segments;
static GC pgc;
static void
GenerateSegments(XParms xp, Parms p, Bool ddashed)
{
int size;
int half;
int i;
int rows;
int x, y;
int x1=0, y1=0, x2=0, y2=0;
int phase;
int phaseinc;
int size8;
XGCValues gcv;
if(ddashed)
pgc = xp->ddfggc;
else
pgc = xp->fggc;
size = p->special;
size8 = 8 * size;
half = (size + 19) / 20;
segments = (XSegment *)malloc((p->objects) * sizeof(XSegment));
x = half; y = half;
phase = 0;
phaseinc = size8 / p->objects;
if (phaseinc == 0) phaseinc = 1;
rows = 0;
for (i = 0; i != p->objects; i++) {
switch (phase / size) {
case 0:
x1 = 0;
y1 = 0;
x2 = size;
y2 = phase;
break;
case 1:
x1 = phase % size;
y1 = 0;
x2 = size;
y2 = size;
break;
case 2:
x1 = size;
y1 = 0;
x2 = size - phase % size;
y2 = size;
break;
case 3:
x1 = size;
y1 = phase % size;
x2 = 0;
y2 = size;
break;
case 4:
x1 = size;
y1 = size;
x2 = 0;
y2 = size - phase % size;
break;
case 5:
x1 = size - phase % size;
y1 = size;
x2 = 0;
y2 = 0;
break;
case 6:
x1 = 0;
y1 = size;
x2 = phase % size;
y2 = 0;
break;
case 7:
x1 = 0;
y1 = size - phase % size;
x2 = size;
y2 = 0;
break;
}
segments[i].x1 = x + x1;
segments[i].y1 = y + y1;
segments[i].x2 = x + x2;
segments[i].y2 = y + y2;
rows++;
y += size;
if (y >= HEIGHT - size - half || rows == MAXROWS) {
rows = 0;
y = half;
x += size;
if (x >= WIDTH - size - half) {
x = half;
}
}
phase += phaseinc;
if (phase >= size8) phase -= size8;
}
gcv.cap_style = CapNotLast;
if(ddashed) {
XChangeGC(xp->d, xp->ddfggc, GCCapStyle, &gcv);
XChangeGC(xp->d, xp->ddbggc, GCCapStyle, &gcv);
} else {
XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
}
}
int
InitSegments(XParms xp, Parms p, int reps)
{
GenerateSegments(xp, p, False);
return reps;
}
int
InitDashedSegments(XParms xp, Parms p, int reps)
{
char dashes[2];
GenerateSegments(xp, p, False);
XSetLineAttributes
(xp->d, xp->bggc, 0, LineOnOffDash, CapNotLast, JoinMiter);
XSetLineAttributes
(xp->d, xp->fggc, 0, LineOnOffDash, CapNotLast, 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
InitDoubleDashedSegments(XParms xp, Parms p, int reps)
{
char dashes[2];
GenerateSegments(xp, p, True);
XSetLineAttributes
(xp->d, xp->ddbggc, 0, LineDoubleDash, CapNotLast, JoinMiter);
XSetLineAttributes
(xp->d, xp->ddfggc, 0, LineDoubleDash, CapNotLast, 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
InitHorizSegments(XParms xp, Parms p, int reps)
{
int size;
int half;
int i;
int rows;
int x, y;
int y1;
int inc;
XGCValues gcv;
pgc = xp->fggc;
size = p->special;
half = (size + 19) / 20;
segments = (XSegment *)malloc((p->objects) * sizeof(XSegment));
x = half;
y = half;
y1 = 0;
rows = 0;
inc = size / p->objects;
if (inc == 0) inc = 1;
for (i = 0; i != p->objects; i++) {
if (i % 2) {
segments[i].x1 = x + size;
segments[i].x2 = x;
segments[i].y1 = y + size - y1;
segments[i].y2 = y + size - y1;
y1 += inc;
if (y1 >= size) y1 -= size;
} else {
segments[i].x1 = x;
segments[i].x2 = x + size;
segments[i].y1 = y + y1;
segments[i].y2 = y + y1;
}
rows++;
y += size;
if (y >= HEIGHT - size - half || rows == MAXROWS) {
rows = 0;
y = half;
x += size;
if (x >= WIDTH - size - half)
x = half;
}
}
gcv.cap_style = CapNotLast;
XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
return reps;
}
int
InitWideHorizSegments(XParms xp, Parms p, int reps)
{
int size;
(void)InitHorizSegments(xp, p, reps);
size = p->special;
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
InitVertSegments(XParms xp, Parms p, int reps)
{
int size;
int half;
int i;
int rows;
int x, y;
int x1;
int inc;
XGCValues gcv;
pgc = xp->fggc;
size = p->special;
half = (size + 19) / 20;
segments = (XSegment *)malloc((p->objects) * sizeof(XSegment));
x = half;
y = half;
x1 = 0;
rows = 0;
inc = size / p->objects;
if (inc == 0) inc = 1;
for (i = 0; i != p->objects; i++) {
if (i % 2) {
segments[i].x1 = x + size - x1;
segments[i].x2 = x + size - x1;
segments[i].y1 = y + size;
segments[i].y2 = y;
x1 += inc;
if (x1 >= size) x1 -= size;
} else {
segments[i].x1 = x + x1;
segments[i].x2 = x + x1;
segments[i].y1 = y;
segments[i].y2 = y + size;
}
rows++;
y += size;
if (y >= HEIGHT - size - half || rows == MAXROWS) {
rows = 0;
y = half;
x += size;
if (x >= WIDTH - size - half) {
x = half;
}
}
}
gcv.cap_style = CapNotLast;
XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
return reps;
}
int
InitWideVertSegments(XParms xp, Parms p, int reps)
{
int size;
(void)InitVertSegments(xp, p, reps);
size = p->special;
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;
}
void
DoSegments(XParms xp, Parms p, int reps)
{
int i;
for (i = 0; i != reps; i++) {
XDrawSegments(xp->d, xp->w, pgc, segments, p->objects);
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
EndSegments(XParms xp, Parms p)
{
free(segments);
}