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