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