do_arcs.c revision 533545b5
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
26static XArc *arcs;
27static GC   pgc;
28
29#define DegreesToX(degrees) (degrees * 64)
30
31static void
32GenerateCircles(XParms xp, Parms p, Bool partialArcs, Bool ddashed)
33{
34    int     i;
35    int     rows;       /* Number of rows filled in current column	    */
36    int     x, y;       /* base of square to draw the circle in		    */
37    int     xorg, yorg; /* Used to get from column to column or row to row  */
38    int     size;
39    int     half;
40    int     startAngle, arcAngle;
41
42    if(ddashed)
43	pgc = xp->ddfggc;
44    else
45	pgc = xp->fggc;
46
47    size = p->special;
48    half = (size + 19) / 20;
49    arcs = (XArc *)malloc((p->objects) * sizeof(XArc));
50    x = xorg = half; y = yorg = half;
51    rows = 0;
52    startAngle = DegreesToX(0);
53    arcAngle = DegreesToX(360);
54
55    for (i = 0; i != p->objects; i++) {
56	arcs[i].x = x;
57	arcs[i].y = y;
58	arcs[i].width = size;
59	arcs[i].height = size;
60	arcs[i].angle1 = startAngle;
61	arcs[i].angle2 = arcAngle;
62
63	if (partialArcs) {
64	    startAngle += DegreesToX(30);
65	    if (startAngle >= DegreesToX(360)) startAngle -= DegreesToX(360);
66	    arcAngle -= DegreesToX(20);
67	    if (arcAngle <= DegreesToX(0)) arcAngle += DegreesToX(360);
68	}
69
70	y += size + 1;
71	rows++;
72	if (y >= HEIGHT - size  - half || rows == MAXROWS) {
73	    /* Go to next column */
74	    rows = 0;
75	    x += size + 1;
76	    if (x >= WIDTH - size) {
77		yorg++;
78		if (yorg >= size + half || yorg >= HEIGHT - size - half) {
79		    yorg = half;
80		    xorg++;
81		    if (xorg >= size + half || xorg >= WIDTH - size - half) {
82			xorg = half;
83		    }
84		}
85		x = xorg;
86	    }
87	    y = yorg;
88	}
89    }
90}
91
92int
93InitCircles(XParms xp, Parms p, int64_t reps)
94{
95    GenerateCircles(xp, p, False, False);
96    return reps;
97}
98
99int
100InitPartCircles(XParms xp, Parms p, int64_t reps)
101{
102    GenerateCircles(xp, p, True, False);
103    return reps;
104}
105
106
107int
108InitChordPartCircles(XParms xp, Parms p, int64_t reps)
109{
110    GenerateCircles(xp, p, True, False);
111    XSetArcMode(xp->d, xp->bggc, ArcChord);
112    XSetArcMode(xp->d, xp->fggc, ArcChord);
113    return reps;
114}
115
116
117int
118InitSlicePartCircles(XParms xp, Parms p, int64_t reps)
119{
120    GenerateCircles(xp, p, True, False);
121    XSetArcMode(xp->d, xp->bggc, ArcPieSlice);
122    XSetArcMode(xp->d, xp->fggc, ArcPieSlice);
123    return reps;
124}
125
126static void
127GenerateWideCircles(XParms xp, Parms p, Bool partialArcs, Bool ddashed)
128{
129    int	    size;
130
131    GenerateCircles(xp, p, partialArcs, ddashed);
132
133    size = p->special;
134    if(ddashed) {
135	XSetLineAttributes(xp->d, xp->ddbggc, (int) ((size + 9) / 10),
136	    LineSolid, CapRound, JoinRound);
137	XSetLineAttributes(xp->d, xp->ddfggc, (int) ((size + 9) / 10),
138	    LineSolid, CapRound, JoinRound);
139    }
140    else {
141	XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10),
142	    LineSolid, CapRound, JoinRound);
143	XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10),
144	    LineSolid, CapRound, JoinRound);
145    }
146}
147
148int
149InitWideCircles(XParms xp, Parms p, int64_t reps)
150{
151    GenerateWideCircles (xp, p, False, False);
152    return reps;
153}
154
155int
156InitPartWideCircles(XParms xp, Parms p, int64_t reps)
157{
158    GenerateWideCircles (xp, p, True, False);
159    return reps;
160}
161
162int
163InitDashedCircles(XParms xp, Parms p, int64_t reps)
164{
165    char dashes[2];
166
167    GenerateCircles(xp, p, False, False);
168
169    /* Modify GCs to draw dashed */
170    XSetLineAttributes(xp->d, xp->bggc, 0, LineOnOffDash, CapButt, JoinMiter);
171    XSetLineAttributes(xp->d, xp->fggc, 0, LineOnOffDash, CapButt, JoinMiter);
172    dashes[0] = 3;   dashes[1] = 2;
173    XSetDashes(xp->d, xp->fggc, 0, dashes, 2);
174    XSetDashes(xp->d, xp->bggc, 0, dashes, 2);
175    return reps;
176}
177
178int
179InitWideDashedCircles(XParms xp, Parms p, int64_t reps)
180{
181    int		size;
182    XGCValues   gcv;
183    char	dashes[2];
184
185    GenerateWideCircles(xp, p, False, False);
186    size = p->special;
187    size = (size + 9) / 10;
188
189    /* Modify GCs to draw dashed */
190    dashes[0] = 2*size;   dashes[1] = 2*size;
191    gcv.line_style = LineOnOffDash;
192    XChangeGC(xp->d, xp->fggc, GCLineStyle, &gcv);
193    XChangeGC(xp->d, xp->bggc, GCLineStyle, &gcv);
194    XSetDashes(xp->d, xp->fggc, 0, dashes, 2);
195    XSetDashes(xp->d, xp->bggc, 0, dashes, 2);
196    return reps;
197}
198
199int
200InitDoubleDashedCircles(XParms xp, Parms p, int64_t reps)
201{
202    char dashes[2];
203
204    GenerateCircles(xp, p, False, True);
205
206    /* Modify GCs to draw dashed */
207    XSetLineAttributes(xp->d, xp->ddbggc, 0, LineDoubleDash, CapButt, JoinMiter);
208    XSetLineAttributes(xp->d, xp->ddfggc, 0, LineDoubleDash, CapButt, JoinMiter);
209    dashes[0] = 3;   dashes[1] = 2;
210    XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2);
211    XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2);
212    return reps;
213}
214
215int
216InitWideDoubleDashedCircles(XParms xp, Parms p, int64_t reps)
217{
218    int		size;
219    XGCValues   gcv;
220    char	dashes[2];
221
222    GenerateWideCircles(xp, p, False, True);
223    size = p->special;
224    size = (size + 9) / 10;
225
226    /* Modify GCs to draw dashed */
227    dashes[0] = 2*size;   dashes[1] = 2*size;
228    gcv.line_style = LineDoubleDash;
229    XChangeGC(xp->d, xp->ddfggc, GCLineStyle, &gcv);
230    XChangeGC(xp->d, xp->ddbggc, GCLineStyle, &gcv);
231    XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2);
232    XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2);
233    return reps;
234}
235
236static void
237GenerateEllipses(XParms xp, Parms p, int partialArcs, Bool ddashed)
238{
239    int     size;
240    int     half;
241    int     rows;       /* Number of rows filled in current column	    */
242    int     i;
243    int     x, y;	    /* base of square to draw ellipse in	    */
244    int     vsize, vsizeinc;
245    int     dir;
246    int     startAngle, arcAngle;
247
248    if(ddashed)
249	pgc = xp->ddfggc;
250    else
251	pgc = xp->fggc;
252
253    size = p->special;
254    half = (size + 19) / 20;
255    arcs = (XArc *)malloc((p->objects) * sizeof(XArc));
256    vsize = 1;
257    vsizeinc = (size - 1) / (p->objects - 1);
258    if (vsizeinc == 0) vsizeinc = 1;
259
260    x = half; y = half;
261    dir = 0;
262    rows = 0;
263    startAngle = DegreesToX(0);
264    arcAngle = DegreesToX(360);
265
266    for (i = 0; i != p->objects; i++) {
267	arcs[i].x = x;
268	arcs[i].y = y;
269	if ((i & 1) ^ dir) {
270	    /* Make vertical axis longer */
271	    arcs[i].width = vsize;
272	    arcs[i].height = size;
273	} else {
274	    /* Make horizontal axis longer */
275	    arcs[i].width = size;
276	    arcs[i].height = vsize;
277	}
278	arcs[i].angle1 = startAngle;
279	arcs[i].angle2 = arcAngle;
280
281	if (partialArcs) {
282	    startAngle += DegreesToX(30);
283	    if (startAngle >= DegreesToX(360)) startAngle -= DegreesToX(360);
284	    arcAngle -= DegreesToX(20);
285	    if (arcAngle <= DegreesToX(0)) arcAngle += DegreesToX(360);
286	}
287
288	y += size + 1;
289	rows++;
290	if (y >= HEIGHT - size - half || rows == MAXROWS) {
291	    /* Go to next column */
292	    rows = 0;
293	    y = half;
294	    x += size + 1;
295	    if (x >= WIDTH - size - half) {
296		x = half;
297	    }
298	}
299
300	vsize += vsizeinc;
301	if (vsize > size) {
302	    vsize -= size;
303	    dir = 1 - dir;
304	}
305    }
306}
307
308int
309InitEllipses(XParms xp, Parms p, int64_t reps)
310{
311    GenerateEllipses(xp, p, False, False);
312    return reps;
313}
314
315
316int
317InitPartEllipses(XParms xp, Parms p, int64_t reps)
318{
319    GenerateEllipses(xp, p, True, False);
320    return reps;
321}
322
323
324int
325InitChordPartEllipses(XParms xp, Parms p, int64_t reps)
326{
327    GenerateEllipses(xp, p, True, False);
328    XSetArcMode(xp->d, xp->bggc, ArcChord);
329    XSetArcMode(xp->d, xp->fggc, ArcChord);
330    return reps;
331}
332
333
334int
335InitSlicePartEllipses(XParms xp, Parms p, int64_t reps)
336{
337    GenerateEllipses(xp, p, True, False);
338    XSetArcMode(xp->d, xp->bggc, ArcPieSlice);
339    XSetArcMode(xp->d, xp->fggc, ArcPieSlice);
340    return reps;
341}
342
343
344static void
345GenerateWideEllipses(XParms xp, Parms p, Bool partialArcs, Bool ddashed)
346{
347    int size;
348
349    GenerateEllipses (xp, p, partialArcs, ddashed);
350    size = p->special;
351    if(ddashed) {
352	XSetLineAttributes(xp->d, xp->ddbggc, (int) ((size + 9) / 10),
353	    LineSolid, CapRound, JoinRound);
354	XSetLineAttributes(xp->d, xp->ddfggc, (int) ((size + 9) / 10),
355	    LineSolid, CapRound, JoinRound);
356    }
357    else {
358	XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10),
359	    LineSolid, CapRound, JoinRound);
360	XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10),
361	    LineSolid, CapRound, JoinRound);
362    }
363
364}
365
366int
367InitWideEllipses(XParms xp, Parms p, int64_t reps)
368{
369    GenerateWideEllipses(xp, p, False, False);
370    return reps;
371}
372
373int
374InitPartWideEllipses(XParms xp, Parms p, int64_t reps)
375{
376    GenerateWideEllipses(xp, p, True, False);
377    return reps;
378}
379
380int
381InitDashedEllipses(XParms xp, Parms p, int64_t reps)
382{
383    char dashes[2];
384
385    GenerateEllipses(xp, p, False, False);
386
387    /* Modify GCs to draw dashed */
388    XSetLineAttributes(xp->d, xp->bggc, 0, LineOnOffDash, CapButt, JoinMiter);
389    XSetLineAttributes(xp->d, xp->fggc, 0, LineOnOffDash, CapButt, JoinMiter);
390    dashes[0] = 3;   dashes[1] = 2;
391    XSetDashes(xp->d, xp->fggc, 0, dashes, 2);
392    XSetDashes(xp->d, xp->bggc, 0, dashes, 2);
393    return reps;
394}
395
396int
397InitWideDashedEllipses(XParms xp, Parms p, int64_t reps)
398{
399    int		size;
400    XGCValues   gcv;
401    char	dashes[2];
402
403    GenerateWideEllipses(xp, p, False, False);
404    size = p->special;
405    size = (size + 9) / 10;
406
407    /* Modify GCs to draw dashed */
408    dashes[0] = 2*size;   dashes[1] = 2*size;
409    gcv.line_style = LineOnOffDash;
410    XChangeGC(xp->d, xp->fggc, GCLineStyle, &gcv);
411    XChangeGC(xp->d, xp->bggc, GCLineStyle, &gcv);
412    XSetDashes(xp->d, xp->fggc, 0, dashes, 2);
413    XSetDashes(xp->d, xp->bggc, 0, dashes, 2);
414    return reps;
415}
416
417int
418InitDoubleDashedEllipses(XParms xp, Parms p, int64_t reps)
419{
420    char dashes[2];
421
422    GenerateEllipses(xp, p, False, True);
423
424    /* Modify GCs to draw dashed */
425    XSetLineAttributes(xp->d, xp->ddbggc, 0, LineDoubleDash, CapButt, JoinMiter);
426    XSetLineAttributes(xp->d, xp->ddfggc, 0, LineDoubleDash, CapButt, JoinMiter);
427    dashes[0] = 3;   dashes[1] = 2;
428    XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2);
429    XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2);
430    return reps;
431}
432
433int
434InitWideDoubleDashedEllipses(XParms xp, Parms p, int64_t reps)
435{
436    int		size;
437    XGCValues   gcv;
438    char	dashes[2];
439
440    GenerateWideEllipses(xp, p, False, True);
441    size = p->special;
442    size = (size + 9) / 10;
443
444    /* Modify GCs to draw dashed */
445    dashes[0] = 2*size;   dashes[1] = 2*size;
446    gcv.line_style = LineDoubleDash;
447    XChangeGC(xp->d, xp->ddfggc, GCLineStyle, &gcv);
448    XChangeGC(xp->d, xp->ddbggc, GCLineStyle, &gcv);
449    XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2);
450    XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2);
451    return reps;
452}
453
454void
455DoArcs(XParms xp, Parms p, int64_t reps)
456{
457    int i;
458
459    for (i = 0; i != reps; i++) {
460        XDrawArcs(xp->d, xp->w, pgc, arcs, p->objects);
461        if (pgc == xp->ddbggc)
462            pgc = xp->ddfggc;
463        else if(pgc == xp->ddfggc)
464            pgc = xp->ddbggc;
465        else if (pgc == xp->bggc)
466            pgc = xp->fggc;
467        else
468            pgc = xp->bggc;
469	CheckAbort ();
470    }
471}
472
473void
474DoFilledArcs(XParms xp, Parms p, int64_t reps)
475{
476    int i;
477
478    for (i = 0; i != reps; i++) {
479        XFillArcs(xp->d, xp->w, pgc, arcs, p->objects);
480        if (pgc == xp->ddbggc)
481            pgc = xp->ddfggc;
482        else if(pgc == xp->ddfggc)
483            pgc = xp->ddbggc;
484        else if (pgc == xp->bggc)
485            pgc = xp->fggc;
486        else
487            pgc = xp->bggc;
488	CheckAbort ();
489    }
490}
491
492void
493EndArcs(XParms xp, Parms p)
494{
495    free(arcs);
496}
497
498