do_segs.c revision 533545b5
1264fa531Smrg/*****************************************************************************
2264fa531SmrgCopyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
3264fa531Smrg
4264fa531Smrg                        All Rights Reserved
5264fa531Smrg
6264fa531SmrgPermission to use, copy, modify, and distribute this software and its
7264fa531Smrgdocumentation for any purpose and without fee is hereby granted,
8264fa531Smrgprovided that the above copyright notice appear in all copies and that
9264fa531Smrgboth that copyright notice and this permission notice appear in
10264fa531Smrgsupporting documentation, and that the name of Digital not be
11264fa531Smrgused in advertising or publicity pertaining to distribution of the
12264fa531Smrgsoftware without specific, written prior permission.
13264fa531Smrg
14264fa531SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15264fa531SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16264fa531SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17264fa531SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18264fa531SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19264fa531SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20264fa531SmrgSOFTWARE.
21264fa531Smrg
22264fa531Smrg******************************************************************************/
23264fa531Smrg
24264fa531Smrg#include "x11perf.h"
25264fa531Smrg
26264fa531Smrgstatic XSegment *segments;
27264fa531Smrgstatic GC       pgc;
28264fa531Smrg
29264fa531Smrgstatic void
30264fa531SmrgGenerateSegments(XParms xp, Parms p, Bool ddashed)
31264fa531Smrg{
32264fa531Smrg    int     size;
33264fa531Smrg    int     half;
34264fa531Smrg    int     i;
35264fa531Smrg    int     rows;	    /* Number of rows filled in current column      */
36264fa531Smrg    int     x, y;	    /* base of square to draw in		    */
37264fa531Smrg    int     x1=0, y1=0, x2=0, y2=0; /* offsets into square		    */
38264fa531Smrg    int     phase;	    /* how far into 0..8*size we are		    */
39264fa531Smrg    int     phaseinc;       /* how much to increment phase at each segment  */
40264fa531Smrg    int     size8;	    /* 8 * size					    */
41264fa531Smrg    XGCValues   gcv;
42264fa531Smrg
43264fa531Smrg    if(ddashed)
44264fa531Smrg	pgc = xp->ddfggc;
45264fa531Smrg    else
46264fa531Smrg	pgc = xp->fggc;
47264fa531Smrg
48264fa531Smrg
49264fa531Smrg    size = p->special;
50264fa531Smrg    size8 = 8 * size;
51264fa531Smrg    half = (size + 19) / 20;
52264fa531Smrg
53264fa531Smrg    segments = (XSegment *)malloc((p->objects) * sizeof(XSegment));
54264fa531Smrg
55264fa531Smrg    /* All this x, x1, etc. stuff is to create a pattern that
56264fa531Smrg	(1) scans down the screen vertically, with each new segment going
57264fa531Smrg	    into a square of size^2.
58264fa531Smrg
59264fa531Smrg	(2) rotates the endpoints clockwise around the square
60264fa531Smrg
61264fa531Smrg	(3) rotates by ``large'' steps if we aren't going to paint enough
62264fa531Smrg	    segments to get full coverage
63264fa531Smrg
64264fa531Smrg	(4) uses CapNotLast so we can create segments of length 1 that
65264fa531Smrg	    nonetheless have a distinct direction
66264fa531Smrg    */
67264fa531Smrg
68264fa531Smrg    x     = half;  y     = half;
69264fa531Smrg    phase = 0;
70264fa531Smrg    phaseinc = size8 / p->objects;
71264fa531Smrg    if (phaseinc == 0) phaseinc = 1;
72264fa531Smrg    rows = 0;
73264fa531Smrg
74264fa531Smrg    for (i = 0; i != p->objects; i++) {
75264fa531Smrg	switch (phase / size) {
76264fa531Smrg	case 0:
77264fa531Smrg	    x1 = 0;
78264fa531Smrg	    y1 = 0;
79264fa531Smrg	    x2 = size;
80264fa531Smrg	    y2 = phase;
81264fa531Smrg	    break;
82264fa531Smrg
83264fa531Smrg	case 1:
84264fa531Smrg	    x1 = phase % size;
85264fa531Smrg	    y1 = 0;
86264fa531Smrg	    x2 = size;
87264fa531Smrg	    y2 = size;
88264fa531Smrg	    break;
89264fa531Smrg
90264fa531Smrg	case 2:
91264fa531Smrg	    x1 = size;
92264fa531Smrg	    y1 = 0;
93264fa531Smrg	    x2 = size - phase % size;
94264fa531Smrg	    y2 = size;
95264fa531Smrg	    break;
96264fa531Smrg
97264fa531Smrg	case 3:
98264fa531Smrg	    x1 = size;
99264fa531Smrg	    y1 = phase % size;
100264fa531Smrg	    x2 = 0;
101264fa531Smrg	    y2 = size;
102264fa531Smrg	    break;
103264fa531Smrg
104264fa531Smrg	case 4:
105264fa531Smrg	    x1 = size;
106264fa531Smrg	    y1 = size;
107264fa531Smrg	    x2 = 0;
108264fa531Smrg	    y2 = size - phase % size;
109264fa531Smrg	    break;
110264fa531Smrg
111264fa531Smrg	case 5:
112264fa531Smrg	    x1 = size - phase % size;
113264fa531Smrg	    y1 = size;
114264fa531Smrg	    x2 = 0;
115264fa531Smrg	    y2 = 0;
116264fa531Smrg	    break;
117264fa531Smrg
118264fa531Smrg	case 6:
119264fa531Smrg	    x1 = 0;
120264fa531Smrg	    y1 = size;
121264fa531Smrg	    x2 = phase % size;
122264fa531Smrg	    y2 = 0;
123264fa531Smrg	    break;
124264fa531Smrg
125264fa531Smrg	case 7:
126264fa531Smrg	    x1 = 0;
127264fa531Smrg	    y1 = size - phase % size;
128264fa531Smrg	    x2 = size;
129264fa531Smrg	    y2 = 0;
130264fa531Smrg	    break;
131264fa531Smrg	} /* end switch */
132264fa531Smrg
133264fa531Smrg	segments[i].x1 = x + x1;
134264fa531Smrg	segments[i].y1 = y + y1;
135264fa531Smrg	segments[i].x2 = x + x2;
136264fa531Smrg	segments[i].y2 = y + y2;
137264fa531Smrg
138264fa531Smrg	/* Change square to draw segment in */
139264fa531Smrg	rows++;
140264fa531Smrg	y += size;
141264fa531Smrg	if (y >= HEIGHT - size - half || rows == MAXROWS) {
142264fa531Smrg	    /* Go to next column */
143264fa531Smrg	    rows = 0;
144264fa531Smrg	    y = half;
145264fa531Smrg	    x += size;
146264fa531Smrg	    if (x >= WIDTH - size - half) {
147264fa531Smrg		x = half;
148264fa531Smrg	    }
149264fa531Smrg	}
150264fa531Smrg
151264fa531Smrg	/* Increment phase */
152264fa531Smrg	phase += phaseinc;
153264fa531Smrg	if (phase >= size8) phase -= size8;
154264fa531Smrg
155264fa531Smrg    }
156264fa531Smrg
157264fa531Smrg    gcv.cap_style = CapNotLast;
158264fa531Smrg
159264fa531Smrg    if(ddashed) {
160264fa531Smrg	XChangeGC(xp->d, xp->ddfggc, GCCapStyle, &gcv);
161264fa531Smrg	XChangeGC(xp->d, xp->ddbggc, GCCapStyle, &gcv);
162264fa531Smrg    } else {
163264fa531Smrg	XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
164264fa531Smrg	XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
165264fa531Smrg    }
166264fa531Smrg}
167264fa531Smrg
168264fa531Smrgint
169533545b5SmrgInitSegments(XParms xp, Parms p, int64_t reps)
170264fa531Smrg{
171264fa531Smrg    GenerateSegments(xp, p, False);
172264fa531Smrg    return reps;
173264fa531Smrg}
174264fa531Smrg
175264fa531Smrgint
176533545b5SmrgInitDashedSegments(XParms xp, Parms p, int64_t reps)
177264fa531Smrg{
178264fa531Smrg    char dashes[2];
179264fa531Smrg
180264fa531Smrg    GenerateSegments(xp, p, False);
181264fa531Smrg
182264fa531Smrg    /* Modify GCs to draw dashed */
183264fa531Smrg    XSetLineAttributes
184264fa531Smrg	(xp->d, xp->bggc, 0, LineOnOffDash, CapNotLast, JoinMiter);
185264fa531Smrg    XSetLineAttributes
186264fa531Smrg	(xp->d, xp->fggc, 0, LineOnOffDash, CapNotLast, JoinMiter);
187264fa531Smrg    dashes[0] = 3;   dashes[1] = 2;
188264fa531Smrg    XSetDashes(xp->d, xp->fggc, 0, dashes, 2);
189264fa531Smrg    XSetDashes(xp->d, xp->bggc, 0, dashes, 2);
190264fa531Smrg    return reps;
191264fa531Smrg}
192264fa531Smrg
193264fa531Smrgint
194533545b5SmrgInitDoubleDashedSegments(XParms xp, Parms p, int64_t reps)
195264fa531Smrg{
196264fa531Smrg    char dashes[2];
197264fa531Smrg
198264fa531Smrg    GenerateSegments(xp, p, True);
199264fa531Smrg
200264fa531Smrg    /* Modify GCs to draw dashed */
201264fa531Smrg    XSetLineAttributes
202264fa531Smrg	(xp->d, xp->ddbggc, 0, LineDoubleDash, CapNotLast, JoinMiter);
203264fa531Smrg    XSetLineAttributes
204264fa531Smrg	(xp->d, xp->ddfggc, 0, LineDoubleDash, CapNotLast, JoinMiter);
205264fa531Smrg    dashes[0] = 3;   dashes[1] = 2;
206264fa531Smrg    XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2);
207264fa531Smrg    XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2);
208264fa531Smrg    return reps;
209264fa531Smrg}
210264fa531Smrg
211264fa531Smrgint
212533545b5SmrgInitHorizSegments(XParms xp, Parms p, int64_t reps)
213264fa531Smrg{
214264fa531Smrg    int     size;
215264fa531Smrg    int     half;
216264fa531Smrg    int     i;
217264fa531Smrg    int     rows;       /* Number of rows filled in current column      */
218264fa531Smrg    int     x, y;	/* base of square to draw in			*/
219264fa531Smrg    int     y1;		/* y position inside square			*/
220264fa531Smrg    int     inc;
221264fa531Smrg    XGCValues   gcv;
222264fa531Smrg
223264fa531Smrg    pgc = xp->fggc;
224264fa531Smrg
225264fa531Smrg    size = p->special;
226264fa531Smrg    half = (size + 19) / 20;
227264fa531Smrg
228264fa531Smrg    segments = (XSegment *)malloc((p->objects) * sizeof(XSegment));
229264fa531Smrg
230264fa531Smrg    x = half;
231264fa531Smrg    y = half;
232264fa531Smrg    y1 = 0;
233264fa531Smrg    rows = 0;
234264fa531Smrg    inc = size / p->objects;
235264fa531Smrg    if (inc == 0) inc = 1;
236264fa531Smrg
237264fa531Smrg    for (i = 0; i != p->objects; i++) {
238264fa531Smrg	if (i % 2) {
239264fa531Smrg	    segments[i].x1 = x + size;
240264fa531Smrg	    segments[i].x2 = x;
241264fa531Smrg	    segments[i].y1 = y + size - y1;
242264fa531Smrg	    segments[i].y2 = y + size - y1;
243264fa531Smrg	    y1 += inc;
244264fa531Smrg	    if (y1 >= size) y1 -= size;
245264fa531Smrg	} else {
246264fa531Smrg	    segments[i].x1 = x;
247264fa531Smrg	    segments[i].x2 = x + size;
248264fa531Smrg	    segments[i].y1 = y + y1;
249264fa531Smrg	    segments[i].y2 = y + y1;
250264fa531Smrg	}
251264fa531Smrg	rows++;
252264fa531Smrg	y += size;
253264fa531Smrg	if (y >= HEIGHT - size - half || rows == MAXROWS) {
254264fa531Smrg	    rows = 0;
255264fa531Smrg	    y = half;
256264fa531Smrg	    x += size;
257264fa531Smrg	    if (x >= WIDTH - size - half)
258264fa531Smrg		x = half;
259264fa531Smrg	}
260264fa531Smrg    }
261264fa531Smrg    gcv.cap_style = CapNotLast;
262264fa531Smrg    XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
263264fa531Smrg    XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
264264fa531Smrg    return reps;
265264fa531Smrg}
266264fa531Smrg
267264fa531Smrgint
268533545b5SmrgInitWideHorizSegments(XParms xp, Parms p, int64_t reps)
269264fa531Smrg{
270264fa531Smrg    int size;
271264fa531Smrg
272264fa531Smrg    (void)InitHorizSegments(xp, p, reps);
273264fa531Smrg
274264fa531Smrg    size = p->special;
275264fa531Smrg    XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10),
276264fa531Smrg	LineSolid, CapRound, JoinRound);
277264fa531Smrg    XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10),
278264fa531Smrg	LineSolid, CapRound, JoinRound);
279264fa531Smrg
280264fa531Smrg    return reps;
281264fa531Smrg}
282264fa531Smrg
283264fa531Smrg
284264fa531Smrgint
285533545b5SmrgInitVertSegments(XParms xp, Parms p, int64_t reps)
286264fa531Smrg{
287264fa531Smrg    int     size;
288264fa531Smrg    int     half;
289264fa531Smrg    int     i;
290264fa531Smrg    int     rows;       /* Number of rows filled in current column      */
291264fa531Smrg    int     x, y;	/* base of square to draw in			*/
292264fa531Smrg    int     x1;		/* x position inside square			*/
293264fa531Smrg    int     inc;
294264fa531Smrg    XGCValues   gcv;
295264fa531Smrg
296264fa531Smrg    pgc = xp->fggc;
297264fa531Smrg
298264fa531Smrg    size = p->special;
299264fa531Smrg    half = (size + 19) / 20;
300264fa531Smrg
301264fa531Smrg    segments = (XSegment *)malloc((p->objects) * sizeof(XSegment));
302264fa531Smrg
303264fa531Smrg    x = half;
304264fa531Smrg    y = half;
305264fa531Smrg    x1 = 0;
306264fa531Smrg    rows = 0;
307264fa531Smrg    inc = size / p->objects;
308264fa531Smrg    if (inc == 0) inc = 1;
309264fa531Smrg
310264fa531Smrg    for (i = 0; i != p->objects; i++) {
311264fa531Smrg	if (i % 2) {
312264fa531Smrg	    segments[i].x1 = x + size - x1;
313264fa531Smrg	    segments[i].x2 = x + size - x1;
314264fa531Smrg	    segments[i].y1 = y + size;
315264fa531Smrg	    segments[i].y2 = y;
316264fa531Smrg	    x1 += inc;
317264fa531Smrg	    if (x1 >= size) x1 -= size;
318264fa531Smrg	} else {
319264fa531Smrg	    segments[i].x1 = x + x1;
320264fa531Smrg	    segments[i].x2 = x + x1;
321264fa531Smrg	    segments[i].y1 = y;
322264fa531Smrg	    segments[i].y2 = y + size;
323264fa531Smrg	}
324264fa531Smrg	rows++;
325264fa531Smrg	y += size;
326264fa531Smrg	if (y >= HEIGHT - size - half || rows == MAXROWS) {
327264fa531Smrg	    /* Go to next column */
328264fa531Smrg	    rows = 0;
329264fa531Smrg	    y = half;
330264fa531Smrg	    x += size;
331264fa531Smrg	    if (x >= WIDTH - size - half) {
332264fa531Smrg		x = half;
333264fa531Smrg	    }
334264fa531Smrg	}
335264fa531Smrg    }
336264fa531Smrg    gcv.cap_style = CapNotLast;
337264fa531Smrg    XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
338264fa531Smrg    XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
339264fa531Smrg    return reps;
340264fa531Smrg}
341264fa531Smrg
342264fa531Smrgint
343533545b5SmrgInitWideVertSegments(XParms xp, Parms p, int64_t reps)
344264fa531Smrg{
345264fa531Smrg    int size;
346264fa531Smrg
347264fa531Smrg    (void)InitVertSegments(xp, p, reps);
348264fa531Smrg
349264fa531Smrg    size = p->special;
350264fa531Smrg    XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10),
351264fa531Smrg	LineSolid, CapRound, JoinRound);
352264fa531Smrg    XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10),
353264fa531Smrg	LineSolid, CapRound, JoinRound);
354264fa531Smrg
355264fa531Smrg    return reps;
356264fa531Smrg}
357264fa531Smrg
358264fa531Smrg
359264fa531Smrgvoid
360533545b5SmrgDoSegments(XParms xp, Parms p, int64_t reps)
361264fa531Smrg{
362264fa531Smrg    int i;
363264fa531Smrg
364264fa531Smrg    for (i = 0; i != reps; i++) {
365264fa531Smrg        XDrawSegments(xp->d, xp->w, pgc, segments, p->objects);
366264fa531Smrg        if (pgc == xp->ddbggc)
367264fa531Smrg            pgc = xp->ddfggc;
368264fa531Smrg        else if(pgc == xp->ddfggc)
369264fa531Smrg            pgc = xp->ddbggc;
370264fa531Smrg        else if (pgc == xp->bggc)
371264fa531Smrg            pgc = xp->fggc;
372264fa531Smrg        else
373264fa531Smrg            pgc = xp->bggc;
374264fa531Smrg	CheckAbort ();
375264fa531Smrg    }
376264fa531Smrg}
377264fa531Smrg
378264fa531Smrgvoid
379264fa531SmrgEndSegments(XParms xp, Parms p)
380264fa531Smrg{
381264fa531Smrg    free(segments);
382264fa531Smrg}
383264fa531Smrg
384