do_complex.c revision 736a7e2c
1/*****************************************************************************
2Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
3
4                        All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of Digital not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
21
22******************************************************************************/
23
24#include "x11perf.h"
25
26#define NUM_POINTS 4    /* 4 points to an arrowhead */
27#define NUM_ANGLES 3    /* But mostly it looks like a triangle */
28static XPoint   *points;
29static GC       pgc;
30
31#include <math.h>
32#if defined(QNX4) || defined(__CYGWIN__) || defined(__UNIXOS2__)
33#define PI 3.14159265358979323846
34#else
35#define PI M_PI
36#endif /* QNX4 */
37
38int
39InitComplexPoly(XParms xp, Parms p, int reps)
40{
41    int     i, j, numPoints;
42    int     x, y;
43    int     size, iradius;
44    double  phi, phiinc, radius, delta, phi2;
45    XPoint  *curPoint;
46
47    pgc = xp->fggc;
48
49    size = p->special;
50    phi = 0.0;
51    delta = 2.0 * PI / ((double) NUM_ANGLES);
52    if (xp->version == VERSION1_2) {
53	radius = ((double) size) * sqrt(3.0)/2.0;
54	phiinc = delta/10.0;
55    } else {
56	/* Version 1.2's radius computation was completely bogus, and resulted
57	   in triangles with sides about 50% longer than advertised.  Since
58	   in version 1.3 triangles are scaled to cover size^2 pixels, we do
59	   the same computation here.  The arrowheads are a little larger than
60	   simple triangles, because they lose 1/3 of their area due to the
61	   notch cut out from them, so radius has to be sqrt(3/2) larger than
62	   for simple triangles.
63	 */
64	radius = ((double) size) * sqrt(sqrt(4.0/3.0));
65	phiinc = 1.75*PI / ((double) p->objects);
66    }
67    iradius = (int) radius + 1;
68
69    numPoints = (p->objects) * NUM_POINTS;
70    points = (XPoint *)malloc(numPoints * sizeof(XPoint));
71    curPoint = points;
72    x = iradius;
73    y = iradius;
74    for (i = 0; i != p->objects; i++) {
75	for (j = 0; j != NUM_ANGLES; j++) {
76	    phi2 = phi + ((double) j) * delta;
77	    curPoint->x = (int) ((double)x + (radius * cos(phi2)) + 0.5);
78	    curPoint->y = (int) ((double)y + (radius * sin(phi2)) + 0.5);
79	    curPoint++;
80	}
81	curPoint->x = x;
82	curPoint->y = y;
83	curPoint++;
84
85	phi += phiinc;
86	y += 2 * iradius;
87	if (y + iradius >= HEIGHT) {
88	    y = iradius;
89	    x += 2 * iradius;
90	    if (x + iradius >= WIDTH) {
91		x = iradius;
92	    }
93	}
94    }
95    return reps;
96}
97
98void
99DoComplexPoly(XParms xp, Parms p, int reps)
100{
101    int     i, j;
102    XPoint  *curPoint;
103
104    for (i = 0; i != reps; i++) {
105        curPoint = points;
106        for (j = 0; j != p->objects; j++) {
107            XFillPolygon(xp->d, xp->w, pgc, curPoint, NUM_POINTS, Complex,
108			 CoordModeOrigin);
109            curPoint += NUM_POINTS;
110	  }
111        if (pgc == xp->bggc)
112            pgc = xp->fggc;
113        else
114            pgc = xp->bggc;
115	CheckAbort ();
116    }
117}
118
119void
120EndComplexPoly(XParms xp, Parms p)
121{
122    free(points);
123}
124
125int
126InitGeneralPoly(XParms xp, Parms p, int reps)
127{
128    int     i, j, numPoints;
129    int	    nsides;
130    int	    x, y;
131    int     size, iradius;
132    double  phi, phiinc, inner_radius, outer_radius, delta, phi2;
133    XPoint  *curPoint;
134
135    pgc = xp->fggc;
136    size = p->special;
137    nsides = (long) p->font;
138    phi = 0.0;
139    delta = 2.0 * PI / ((double) nsides);
140    phiinc = delta / 10.0;
141
142    inner_radius = size / sqrt (nsides * tan (PI / nsides));
143    outer_radius = inner_radius / cos (PI / (2 * nsides));
144    numPoints = p->objects * nsides;
145    points = (XPoint *) malloc (numPoints * sizeof (XPoint));
146    curPoint = points;
147    iradius = outer_radius + 1;
148    x = iradius;
149    y = iradius;
150    for (i = 0; i < p->objects; i++) {
151	phi2 = phi;
152	for (j = 0; j < nsides; j++) {
153	    curPoint->x = x + (outer_radius * cos(phi2) + 0.5);
154	    curPoint->y = y + (outer_radius * sin(phi2) + 0.5);
155	    curPoint++;
156	    phi2 += delta;
157	}
158	phi += phiinc;
159	y += 2 * iradius;
160	if (y + iradius >= HEIGHT) {
161	    y = iradius;
162	    x += 2 * iradius;
163	    if (x + iradius >= WIDTH) {
164		x = iradius;
165	    }
166	}
167    }
168    return reps;
169}
170
171void
172DoGeneralPoly(XParms xp, Parms p, int reps)
173{
174    int     i, j;
175    int	    nsides;
176    int	    mode;
177    XPoint  *curPoint;
178
179    nsides = (long) p->font;
180    mode = (long) p->bfont;
181    for (i = 0; i != reps; i++) {
182        curPoint = points;
183        for (j = 0; j != p->objects; j++) {
184            XFillPolygon(xp->d, xp->w, pgc, curPoint, nsides, mode,
185			 CoordModeOrigin);
186            curPoint += nsides;
187	  }
188        if (pgc == xp->bggc)
189            pgc = xp->fggc;
190        else
191            pgc = xp->bggc;
192	CheckAbort ();
193    }
194}
195