summaryrefslogtreecommitdiff
path: root/do_tris.c
diff options
context:
space:
mode:
Diffstat (limited to 'do_tris.c')
-rw-r--r--do_tris.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/do_tris.c b/do_tris.c
new file mode 100644
index 0000000..836c6ef
--- /dev/null
+++ b/do_tris.c
@@ -0,0 +1,239 @@
+/* $Xorg: do_tris.c,v 1.3 2000/08/17 19:54:10 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.
+
+******************************************************************************/
+
+
+#undef POLYTRIANGLE_HACK /* don't use this code */
+#ifdef POLYTRIANGLE_HACK
+#include <X11/Xlibint.h>
+#endif
+
+#include "x11perf.h"
+#include "bitmaps.h"
+#include <stdio.h>
+#include <math.h>
+
+#define NUM_POINTS 3 /* 3 points to a triangle */
+static XPoint *points;
+static GC pgc;
+
+#ifndef PI
+#define PI 3.14159265357989
+#endif
+
+double Area(p1, p2, p3)
+ XPoint p1, p2, 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;
+}
+
+double Distance(p1, p2)
+ XPoint p1, p2;
+{
+ return sqrt((float) ((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y)));
+}
+
+int InitTriangles(xp, p, reps)
+ 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 {
+ /* Version 1.2's radius computation was completely bogus, and resulted
+ in triangles with sides about 50% longer than advertised. However,
+ this inadvertently resulted in triangles with areas just a little bit
+ smaller than the triangle that covers size^2 pixels, which would
+ make the area directly comparable to 10x10 rectangles and 10x10
+ trapezoids. So here's the new computation so -triangleN has the same
+ area as -rectN.
+ */
+ 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;
+/* printf("%6.1lf %6.1lf %6.1lf %6.1lf\n",
+ Distance(curPoint[-1], curPoint[-2]),
+ Distance(curPoint[-1], curPoint[-3]),
+ Distance(curPoint[-2], curPoint[-3]),
+ 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;
+ }
+ }
+ }
+/* printf("Average area = %6.2lf\n", aarea/p->objects); */
+
+ SetFillStyle(xp, p);
+
+ return reps;
+}
+
+#ifndef POLYTRIANGLE_HACK
+
+void DoTriangles(xp, p, reps)
+ 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;
+ }
+}
+
+#else
+void DoTriangles(xp, p, reps)
+ 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;
+ }
+}
+
+static xReq _dummy_request = {
+ 0, 0, 0
+};
+
+XPolyTriangle(dpy, d, gc, points, n_triangles, shape, mode)
+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();
+}
+#endif
+
+void EndTriangles(xp, p)
+ XParms xp;
+ Parms p;
+{
+ free(points);
+}
+