1
2
3
4/*****************************************************************************
5Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
6
7                        All Rights Reserved
8
9Permission to use, copy, modify, and distribute this software and its
10documentation for any purpose and without fee is hereby granted,
11provided that the above copyright notice appear in all copies and that
12both that copyright notice and this permission notice appear in
13supporting documentation, and that the name of Digital not be
14used in advertising or publicity pertaining to distribution of the
15software without specific, written prior permission.
16
17DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
23SOFTWARE.
24
25******************************************************************************/
26
27
28#undef POLYTRIANGLE_HACK    /* don't use this code */
29#ifdef POLYTRIANGLE_HACK
30#include <X11/Xlibint.h>
31#endif
32
33#include "x11perf.h"
34#include "bitmaps.h"
35#include <stdio.h>
36#include <math.h>
37
38#define NUM_POINTS 3   /* 3 points to a triangle */
39static XPoint *points;
40static GC     pgc;
41
42#ifndef PI
43#define PI  3.14159265357989
44#endif
45
46static double
47Area(XPoint p1, XPoint p2, XPoint p3)
48{
49    return
50      (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;
51}
52
53/*
54static double
55Distance(XPoint p1, XPoint p2)
56{
57    return sqrt((float) ((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y)));
58}
59*/
60
61int
62InitTriangles(XParms xp, Parms p, int64_t reps)
63{
64    int     numPoints;
65    int     rows;
66    int     x, y;
67    int     size, iradius;
68    double  phi, phiinc, radius, delta, phi2, area, aarea;
69    XPoint  *curPoint;
70
71    pgc = xp->fggc;
72
73    size = p->special;
74    phi = 0.0;
75    delta = 2.0 * PI / ((double) NUM_POINTS);
76    if (xp->version == VERSION1_2) {
77	radius = ((double) size) * sqrt(3.0)/2.0;
78	phiinc = delta/10.0;
79    } else {
80	/* Version 1.2's radius computation was completely bogus, and resulted
81	   in triangles with sides about 50% longer than advertised.  However,
82	   this inadvertently resulted in triangles with areas just a little bit
83	   smaller than the triangle that covers size^2 pixels, which would
84	   make the area directly comparable to 10x10 rectangles and 10x10
85	   trapezoids.  So here's the new computation so -triangleN has the same
86	   area as -rectN.
87	 */
88	radius = ((double) size) * sqrt(sqrt(16.0/27.0));
89	phiinc = 1.75*PI / ((double) p->objects);
90    }
91    iradius = (int) (radius + 0.5);
92
93    numPoints = (p->objects) * NUM_POINTS;
94    points = malloc(numPoints * sizeof(XPoint));
95    curPoint = points;
96    x = iradius;
97    y = iradius;
98    rows = 0;
99    aarea = 0.0;
100
101    for (int i = 0; i != p->objects; i++) {
102	for (int j = 0; j != NUM_POINTS; j++) {
103	    phi2 = phi + ((double) j) * delta;
104	    curPoint->x = (int) ((double)x + (radius * cos(phi2)) + 0.5);
105	    curPoint->y = (int) ((double)y + (radius * sin(phi2)) + 0.5);
106	    curPoint++;
107	}
108	area = Area(curPoint[-1], curPoint[-2], curPoint[-3]);
109	aarea += area;
110/*	printf("%6.1lf %6.1lf %6.1lf   %6.1lf\n",
111	    Distance(curPoint[-1], curPoint[-2]),
112	    Distance(curPoint[-1], curPoint[-3]),
113	    Distance(curPoint[-2], curPoint[-3]),
114	    area);
115*/
116	phi += phiinc;
117	y += 2 * iradius;
118	rows++;
119	if (y + iradius > HEIGHT || rows == MAXROWS) {
120	    rows = 0;
121	    y = iradius;
122	    x += 2 * iradius;
123	    if (x + iradius > WIDTH) {
124		x = iradius;
125	    }
126	}
127    }
128/*    printf("Average area = %6.2lf\n", aarea/p->objects); */
129
130    SetFillStyle(xp, p);
131
132    return reps;
133}
134
135#ifndef POLYTRIANGLE_HACK
136
137void
138DoTriangles(XParms xp, Parms p, int64_t reps)
139{
140    for (int i = 0; i != reps; i++) {
141        XPoint  *curPoint = points;
142        for (int j = 0; j != p->objects; j++) {
143            XFillPolygon(xp->d, xp->w, pgc, curPoint, NUM_POINTS, Convex,
144			 CoordModeOrigin);
145            curPoint += NUM_POINTS;
146	}
147        if (pgc == xp->bggc)
148            pgc = xp->fggc;
149        else
150            pgc = xp->bggc;
151	CheckAbort ();
152    }
153}
154
155#else
156
157static xReq _dummy_request = {
158	0, 0, 0
159};
160
161static void
162XPolyTriangle(register Display *dpy,
163	      Drawable d, GC gc, XPoint *points,
164	      int n_triangles, int shape, int mode)
165{
166    register xFillPolyReq *req;
167    register long nbytes;
168    int		max_triangles;
169    int		n_this_time;
170    int		*buf, *pts;
171    int		gcid;
172    int		last;
173
174    max_triangles = (dpy->bufmax - dpy->buffer) / 28;
175    LockDisplay(dpy);
176    FlushGC(dpy, gc);
177    dpy->request += n_triangles;
178    pts = (int *) points;
179    gcid = gc->gid;
180    last = shape | (mode << 8);
181    while (n_triangles)
182    {
183	if ((n_this_time = max_triangles) > n_triangles)
184	    n_this_time = n_triangles;
185	n_triangles -= n_this_time;
186	GetReqExtra(FillPoly,
187	    (SIZEOF(xFillPolyReq) + 12) * n_this_time - SIZEOF(xFillPolyReq), req);
188	--dpy->request;
189
190	buf = req;
191        while (n_this_time--)
192	{
193	    buf[0] = X_FillPoly | (7 << 16);
194	    buf[1] = d;
195	    buf[2] = gcid;
196	    buf[3] = last;
197	    buf[4] = pts[0];
198	    buf[5] = pts[1];
199	    buf[6] = pts[2];
200	    buf += 7;
201	    pts += 3;
202	}
203    }
204    dpy->last_req = &_dummy_request;
205    UnlockDisplay(dpy);
206    SyncHandle();
207}
208
209void
210DoTriangles(XParms xp, Parms p, int64_t reps)
211{
212    for (int i = 0; i != reps; i++) {
213        XPolyTriangle (xp->d, xp->w, pgc, points, p->objects, Convex,
214			 CoordModeOrigin);
215        if (pgc == xp->bggc)
216            pgc = xp->fggc;
217        else
218            pgc = xp->bggc;
219	CheckAbort ();
220    }
221}
222#endif
223
224void
225EndTriangles(XParms xp, Parms p)
226{
227    free(points);
228}
229
230