#undef POLYTRIANGLE_HACK
#ifdef POLYTRIANGLE_HACK
#include <X11/Xlibint.h>
#endif
#include "x11perf.h"
#include "bitmaps.h"
#include <stdio.h>
#include <math.h>
#define NUM_POINTS 3
static XPoint *points;
static GC pgc;
#ifndef PI
#define PI 3.14159265357989
#endif
static double
Area(XPoint p1, XPoint p2, XPoint p3)
{
return
(p1.x*p2.y - p1.x*p3.y + p2.x*p3.y - p2.x*p1.y + p3.x*p1.y - p3.x*p2.y)/2;
}
int
InitTriangles(XParms xp, Parms p, int reps)
{
int i, j, numPoints;
int rows;
int x, y;
int size, iradius;
double phi, phiinc, radius, delta, phi2, area, aarea;
XPoint *curPoint;
pgc = xp->fggc;
size = p->special;
phi = 0.0;
delta = 2.0 * PI / ((double) NUM_POINTS);
if (xp->version == VERSION1_2) {
radius = ((double) size) * sqrt(3.0)/2.0;
phiinc = delta/10.0;
} else {
radius = ((double) size) * sqrt(sqrt(16.0/27.0));
phiinc = 1.75*PI / ((double) p->objects);
}
iradius = (int) (radius + 0.5);
numPoints = (p->objects) * NUM_POINTS;
points = (XPoint *)malloc(numPoints * sizeof(XPoint));
curPoint = points;
x = iradius;
y = iradius;
rows = 0;
aarea = 0.0;
for (i = 0; i != p->objects; i++) {
for (j = 0; j != NUM_POINTS; j++) {
phi2 = phi + ((double) j) * delta;
curPoint->x = (int) ((double)x + (radius * cos(phi2)) + 0.5);
curPoint->y = (int) ((double)y + (radius * sin(phi2)) + 0.5);
curPoint++;
}
area = Area(curPoint[-1], curPoint[-2], curPoint[-3]);
aarea += area;
phi += phiinc;
y += 2 * iradius;
rows++;
if (y + iradius > HEIGHT || rows == MAXROWS) {
rows = 0;
y = iradius;
x += 2 * iradius;
if (x + iradius > WIDTH) {
x = iradius;
}
}
}
SetFillStyle(xp, p);
return reps;
}
#ifndef POLYTRIANGLE_HACK
void
DoTriangles(XParms xp, Parms p, int reps)
{
int i, j;
XPoint *curPoint;
for (i = 0; i != reps; i++) {
curPoint = points;
for (j = 0; j != p->objects; j++) {
XFillPolygon(xp->d, xp->w, pgc, curPoint, NUM_POINTS, Convex,
CoordModeOrigin);
curPoint += NUM_POINTS;
}
if (pgc == xp->bggc)
pgc = xp->fggc;
else
pgc = xp->bggc;
CheckAbort ();
}
}
#else
static xReq _dummy_request = {
0, 0, 0
};
static void
XPolyTriangle(register Display *dpy,
Drawable d, GC gc, XPoint *points,
int n_triangles, int shape, int mode)
{
register xFillPolyReq *req;
register long nbytes;
int max_triangles;
int n_this_time;
int *buf, *pts;
int gcid;
int last;
max_triangles = (dpy->bufmax - dpy->buffer) / 28;
LockDisplay(dpy);
FlushGC(dpy, gc);
dpy->request += n_triangles;
pts = (int *) points;
gcid = gc->gid;
last = shape | (mode << 8);
while (n_triangles)
{
if ((n_this_time = max_triangles) > n_triangles)
n_this_time = n_triangles;
n_triangles -= n_this_time;
GetReqExtra(FillPoly,
(SIZEOF(xFillPolyReq) + 12) * n_this_time - SIZEOF(xFillPolyReq), req);
--dpy->request;
buf = req;
while (n_this_time--)
{
buf[0] = X_FillPoly | (7 << 16);
buf[1] = d;
buf[2] = gcid;
buf[3] = last;
buf[4] = pts[0];
buf[5] = pts[1];
buf[6] = pts[2];
buf += 7;
pts += 3;
}
}
dpy->last_req = &_dummy_request;
UnlockDisplay(dpy);
SyncHandle();
}
void
DoTriangles(XParms xp, Parms p, int reps)
{
int i, j;
XPoint *curPoint;
for (i = 0; i != reps; i++) {
XPolyTriangle (xp->d, xp->w, pgc, points, p->objects, Convex,
CoordModeOrigin);
if (pgc == xp->bggc)
pgc = xp->fggc;
else
pgc = xp->bggc;
CheckAbort ();
}
}
#endif
void
EndTriangles(XParms xp, Parms p)
{
free(points);
}