do_segs.c revision c9e4df9b
11.7Ssimonb/*****************************************************************************
21.1SjoergCopyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
31.1Sjoerg
41.1Sjoerg                        All Rights Reserved
51.1Sjoerg
61.1SjoergPermission to use, copy, modify, and distribute this software and its
71.1Sjoergdocumentation for any purpose and without fee is hereby granted,
81.1Sjoergprovided that the above copyright notice appear in all copies and that
91.1Sjoergboth that copyright notice and this permission notice appear in
101.1Sjoergsupporting documentation, and that the name of Digital not be
111.1Sjoergused in advertising or publicity pertaining to distribution of the
121.1Sjoergsoftware without specific, written prior permission.
131.1Sjoerg
141.1SjoergDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
151.1SjoergALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
161.1SjoergDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
171.1SjoergANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
181.1SjoergWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
191.1SjoergARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
201.1SjoergSOFTWARE.
211.1Sjoerg
221.1Sjoerg******************************************************************************/
231.1Sjoerg
241.1Sjoerg#include "x11perf.h"
251.1Sjoerg
261.1Sjoergstatic XSegment *segments;
271.1Sjoergstatic GC       pgc;
281.1Sjoerg
291.1Sjoergstatic void
301.1SjoergGenerateSegments(XParms xp, Parms p, Bool ddashed)
311.6Skamil{
321.1Sjoerg    int     size;
331.1Sjoerg    int     half;
341.1Sjoerg    int     i;
351.5Sabhinav    int     rows;	    /* Number of rows filled in current column      */
361.1Sjoerg    int     x, y;	    /* base of square to draw in		    */
371.4Sjoerg    int     x1=0, y1=0, x2=0, y2=0; /* offsets into square		    */
381.1Sjoerg    int     phase;	    /* how far into 0..8*size we are		    */
391.1Sjoerg    int     phaseinc;       /* how much to increment phase at each segment  */
401.1Sjoerg    int     size8;	    /* 8 * size					    */
411.5Sabhinav    XGCValues   gcv;
421.1Sjoerg
431.1Sjoerg    if(ddashed)
441.7Ssimonb	pgc = xp->ddfggc;
451.1Sjoerg    else
461.1Sjoerg	pgc = xp->fggc;
471.4Sjoerg
481.4Sjoerg
491.4Sjoerg    size = p->special;
501.4Sjoerg    size8 = 8 * size;
511.6Skamil    half = (size + 19) / 20;
521.4Sjoerg
531.4Sjoerg    segments = malloc((p->objects) * sizeof(XSegment));
541.4Sjoerg
551.1Sjoerg    /* All this x, x1, etc. stuff is to create a pattern that
561.1Sjoerg	(1) scans down the screen vertically, with each new segment going
571.1Sjoerg	    into a square of size^2.
581.1Sjoerg
591.1Sjoerg	(2) rotates the endpoints clockwise around the square
601.1Sjoerg
611.1Sjoerg	(3) rotates by ``large'' steps if we aren't going to paint enough
621.1Sjoerg	    segments to get full coverage
631.1Sjoerg
641.1Sjoerg	(4) uses CapNotLast so we can create segments of length 1 that
651.1Sjoerg	    nonetheless have a distinct direction
661.1Sjoerg    */
671.1Sjoerg
681.1Sjoerg    x     = half;  y     = half;
691.1Sjoerg    phase = 0;
701.1Sjoerg    phaseinc = size8 / p->objects;
711.1Sjoerg    if (phaseinc == 0) phaseinc = 1;
721.2Swiz    rows = 0;
731.1Sjoerg
741.1Sjoerg    for (i = 0; i != p->objects; i++) {
751.1Sjoerg	switch (phase / size) {
761.1Sjoerg	case 0:
771.1Sjoerg	    x1 = 0;
781.1Sjoerg	    y1 = 0;
791.1Sjoerg	    x2 = size;
801.1Sjoerg	    y2 = phase;
811.1Sjoerg	    break;
821.1Sjoerg
831.1Sjoerg	case 1:
841.1Sjoerg	    x1 = phase % size;
851.1Sjoerg	    y1 = 0;
861.1Sjoerg	    x2 = size;
871.1Sjoerg	    y2 = size;
881.1Sjoerg	    break;
891.1Sjoerg
901.4Sjoerg	case 2:
911.4Sjoerg	    x1 = size;
921.4Sjoerg	    y1 = 0;
931.4Sjoerg	    x2 = size - phase % size;
941.4Sjoerg	    y2 = size;
951.4Sjoerg	    break;
961.4Sjoerg
971.4Sjoerg	case 3:
981.4Sjoerg	    x1 = size;
991.4Sjoerg	    y1 = phase % size;
1001.4Sjoerg	    x2 = 0;
1011.4Sjoerg	    y2 = size;
1021.4Sjoerg	    break;
1031.4Sjoerg
1041.4Sjoerg	case 4:
1051.4Sjoerg	    x1 = size;
1061.4Sjoerg	    y1 = size;
1071.4Sjoerg	    x2 = 0;
1081.4Sjoerg	    y2 = size - phase % size;
1091.1Sjoerg	    break;
1101.1Sjoerg
1111.1Sjoerg	case 5:
1121.2Swiz	    x1 = size - phase % size;
1131.1Sjoerg	    y1 = size;
1141.1Sjoerg	    x2 = 0;
1151.1Sjoerg	    y2 = 0;
1161.1Sjoerg	    break;
1171.1Sjoerg
1181.1Sjoerg	case 6:
1191.1Sjoerg	    x1 = 0;
1201.1Sjoerg	    y1 = size;
1211.1Sjoerg	    x2 = phase % size;
1221.1Sjoerg	    y2 = 0;
1231.1Sjoerg	    break;
1241.1Sjoerg
1251.1Sjoerg	case 7:
1261.1Sjoerg	    x1 = 0;
1271.1Sjoerg	    y1 = size - phase % size;
1281.2Swiz	    x2 = size;
1291.1Sjoerg	    y2 = 0;
1301.1Sjoerg	    break;
1311.1Sjoerg	} /* end switch */
1321.1Sjoerg
1331.2Swiz	segments[i].x1 = x + x1;
1341.1Sjoerg	segments[i].y1 = y + y1;
1351.1Sjoerg	segments[i].x2 = x + x2;
1361.1Sjoerg	segments[i].y2 = y + y2;
1371.1Sjoerg
1381.1Sjoerg	/* Change square to draw segment in */
1391.1Sjoerg	rows++;
1401.1Sjoerg	y += size;
1411.1Sjoerg	if (y >= HEIGHT - size - half || rows == MAXROWS) {
1421.1Sjoerg	    /* Go to next column */
1431.1Sjoerg	    rows = 0;
1441.1Sjoerg	    y = half;
1451.1Sjoerg	    x += size;
1461.1Sjoerg	    if (x >= WIDTH - size - half) {
1471.3Swiz		x = half;
148	    }
149	}
150
151	/* Increment phase */
152	phase += phaseinc;
153	if (phase >= size8) phase -= size8;
154
155    }
156
157    gcv.cap_style = CapNotLast;
158
159    if(ddashed) {
160	XChangeGC(xp->d, xp->ddfggc, GCCapStyle, &gcv);
161	XChangeGC(xp->d, xp->ddbggc, GCCapStyle, &gcv);
162    } else {
163	XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
164	XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
165    }
166}
167
168int
169InitSegments(XParms xp, Parms p, int64_t reps)
170{
171    GenerateSegments(xp, p, False);
172    return reps;
173}
174
175int
176InitDashedSegments(XParms xp, Parms p, int64_t reps)
177{
178    char dashes[2];
179
180    GenerateSegments(xp, p, False);
181
182    /* Modify GCs to draw dashed */
183    XSetLineAttributes
184	(xp->d, xp->bggc, 0, LineOnOffDash, CapNotLast, JoinMiter);
185    XSetLineAttributes
186	(xp->d, xp->fggc, 0, LineOnOffDash, CapNotLast, JoinMiter);
187    dashes[0] = 3;   dashes[1] = 2;
188    XSetDashes(xp->d, xp->fggc, 0, dashes, 2);
189    XSetDashes(xp->d, xp->bggc, 0, dashes, 2);
190    return reps;
191}
192
193int
194InitDoubleDashedSegments(XParms xp, Parms p, int64_t reps)
195{
196    char dashes[2];
197
198    GenerateSegments(xp, p, True);
199
200    /* Modify GCs to draw dashed */
201    XSetLineAttributes
202	(xp->d, xp->ddbggc, 0, LineDoubleDash, CapNotLast, JoinMiter);
203    XSetLineAttributes
204	(xp->d, xp->ddfggc, 0, LineDoubleDash, CapNotLast, JoinMiter);
205    dashes[0] = 3;   dashes[1] = 2;
206    XSetDashes(xp->d, xp->ddfggc, 0, dashes, 2);
207    XSetDashes(xp->d, xp->ddbggc, 0, dashes, 2);
208    return reps;
209}
210
211int
212InitHorizSegments(XParms xp, Parms p, int64_t reps)
213{
214    int     size;
215    int     half;
216    int     i;
217    int     rows;       /* Number of rows filled in current column      */
218    int     x, y;	/* base of square to draw in			*/
219    int     y1;		/* y position inside square			*/
220    int     inc;
221    XGCValues   gcv;
222
223    pgc = xp->fggc;
224
225    size = p->special;
226    half = (size + 19) / 20;
227
228    segments = malloc((p->objects) * sizeof(XSegment));
229
230    x = half;
231    y = half;
232    y1 = 0;
233    rows = 0;
234    inc = size / p->objects;
235    if (inc == 0) inc = 1;
236
237    for (i = 0; i != p->objects; i++) {
238	if (i % 2) {
239	    segments[i].x1 = x + size;
240	    segments[i].x2 = x;
241	    segments[i].y1 = y + size - y1;
242	    segments[i].y2 = y + size - y1;
243	    y1 += inc;
244	    if (y1 >= size) y1 -= size;
245	} else {
246	    segments[i].x1 = x;
247	    segments[i].x2 = x + size;
248	    segments[i].y1 = y + y1;
249	    segments[i].y2 = y + y1;
250	}
251	rows++;
252	y += size;
253	if (y >= HEIGHT - size - half || rows == MAXROWS) {
254	    rows = 0;
255	    y = half;
256	    x += size;
257	    if (x >= WIDTH - size - half)
258		x = half;
259	}
260    }
261    gcv.cap_style = CapNotLast;
262    XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
263    XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
264    return reps;
265}
266
267int
268InitWideHorizSegments(XParms xp, Parms p, int64_t reps)
269{
270    int size;
271
272    (void)InitHorizSegments(xp, p, reps);
273
274    size = p->special;
275    XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10),
276	LineSolid, CapRound, JoinRound);
277    XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10),
278	LineSolid, CapRound, JoinRound);
279
280    return reps;
281}
282
283
284int
285InitVertSegments(XParms xp, Parms p, int64_t reps)
286{
287    int     size;
288    int     half;
289    int     i;
290    int     rows;       /* Number of rows filled in current column      */
291    int     x, y;	/* base of square to draw in			*/
292    int     x1;		/* x position inside square			*/
293    int     inc;
294    XGCValues   gcv;
295
296    pgc = xp->fggc;
297
298    size = p->special;
299    half = (size + 19) / 20;
300
301    segments = malloc((p->objects) * sizeof(XSegment));
302
303    x = half;
304    y = half;
305    x1 = 0;
306    rows = 0;
307    inc = size / p->objects;
308    if (inc == 0) inc = 1;
309
310    for (i = 0; i != p->objects; i++) {
311	if (i % 2) {
312	    segments[i].x1 = x + size - x1;
313	    segments[i].x2 = x + size - x1;
314	    segments[i].y1 = y + size;
315	    segments[i].y2 = y;
316	    x1 += inc;
317	    if (x1 >= size) x1 -= size;
318	} else {
319	    segments[i].x1 = x + x1;
320	    segments[i].x2 = x + x1;
321	    segments[i].y1 = y;
322	    segments[i].y2 = y + size;
323	}
324	rows++;
325	y += size;
326	if (y >= HEIGHT - size - half || rows == MAXROWS) {
327	    /* Go to next column */
328	    rows = 0;
329	    y = half;
330	    x += size;
331	    if (x >= WIDTH - size - half) {
332		x = half;
333	    }
334	}
335    }
336    gcv.cap_style = CapNotLast;
337    XChangeGC(xp->d, xp->fggc, GCCapStyle, &gcv);
338    XChangeGC(xp->d, xp->bggc, GCCapStyle, &gcv);
339    return reps;
340}
341
342int
343InitWideVertSegments(XParms xp, Parms p, int64_t reps)
344{
345    int size;
346
347    (void)InitVertSegments(xp, p, reps);
348
349    size = p->special;
350    XSetLineAttributes(xp->d, xp->bggc, (int) ((size + 9) / 10),
351	LineSolid, CapRound, JoinRound);
352    XSetLineAttributes(xp->d, xp->fggc, (int) ((size + 9) / 10),
353	LineSolid, CapRound, JoinRound);
354
355    return reps;
356}
357
358
359void
360DoSegments(XParms xp, Parms p, int64_t reps)
361{
362    int i;
363
364    for (i = 0; i != reps; i++) {
365        XDrawSegments(xp->d, xp->w, pgc, segments, p->objects);
366        if (pgc == xp->ddbggc)
367            pgc = xp->ddfggc;
368        else if(pgc == xp->ddfggc)
369            pgc = xp->ddbggc;
370        else if (pgc == xp->bggc)
371            pgc = xp->fggc;
372        else
373            pgc = xp->bggc;
374	CheckAbort ();
375    }
376}
377
378void
379EndSegments(XParms xp, Parms p)
380{
381    free(segments);
382}
383
384