File: DrawSL.c

package info (click to toggle)
acm4 4.7-18
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 4,776 kB
  • ctags: 1,621
  • sloc: ansic: 16,777; makefile: 364; sh: 31
file content (131 lines) | stat: -rw-r--r-- 2,792 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <Alib.h>
#include <stdio.h>

static ColorSegment *CSOverflow () {

	fprintf (stderr, "Color Segment pool overflow\n");
	return (ColorSegment *) NULL;

}

#define mallocCS(w)	( (w->curPool) ? \
	((w->CSTop1 == w->CSSize1) ? \
	CSOverflow() : &(w->csPool1[(w->CSTop1)++])) : \
	((w->CSTop0 == w->CSSize0) ? \
	CSOverflow() : &(w->csPool0[(w->CSTop0)++])) )

#define freeLastCS(w)    ( (w->curPool) ? -- (w->CSTop1) : -- (w->CSTop0) )


/*
 * DrawScanLine : draw a line segment.  Successive calls on the same scan line
 *		must be ordered by x0 value.
 */

void DrawScanLine (w, y, x0, x1, color)
AWindow		*w;
int		y, x0, x1;
Color		color; {

	register ColorSegment	*p;
	register int		lastx;

#ifdef DEBUG
	printf ("DrawScanLine (w, %d, %d, %d, %d)\n", y, x0, x1, color);
#endif

	if (w->scanLine[y].count == 0) {

/*
 *  This is the first segment on this scan line.
 */

		if ((p = mallocCS(w)) != (ColorSegment *) NULL) {
			p->x = x0;
			p->length = x1 - x0 + 1;
			p->color = color;
			w->scanLine[y].head = w->scanLine[y].tail = p;
			w->scanLine[y].count = 1;
		}

	}

/*
 *  The scan line wasn't empty.  Check the previous scan line entry for
 *  any overlap with this one.
 */

	else {
		p = w->scanLine[y].tail;
		lastx = p->x + p->length - 1;

		if (lastx >= x0) {

/*
 *  The segments overlap.
 *
 *  If the overlapping segments have the same color, then simply
 *  extend the previous segment's length.
 */

			if (p->color == color)
				p->length = x1 - p->x + 1;

/*
 *  The overlapping segment's colors are different.  Shorten the previous
 *  segment and allocate an entry for the current one.  If the shortened
 *  segment is eliminated, use it to store this segment's information.
 */

			else {
			    if ((p->length = x0 - p->x) > 0) {
				if ((p = mallocCS(w)) != (ColorSegment *) NULL) {
					++ w->scanLine[y].count;
					w->scanLine[y].tail = p;
				}
			    }

/*
 *  If the shortened segment's length went to zero, we may need to merge
 *  this segment with the last one.
 */

			    if (((p-1)->color == color) &&
				(w->scanLine[y].count > 1)) {
				freeLastCS (w);
				p = w->scanLine[y].tail = p-1;
				-- w->scanLine[y].count;
				p->length = x1 - p->x + 1;
			    }
			    else {
			    	p->x = x0;
			    	p->length = x1 - x0 + 1;
			    	p->color = color;
			    }
			}
		}

/*
 *  The segments do not overlap.
 *
 *  If the segments are adjacent and the colors are the same, extend the
 *  last segment.
 *
 *  Otehrwise, create a new segment and append it to this line.
 */

		else if ((lastx == x0 - 1) && (p->color == color))

			p->length = x1 - p->x + 1;

		else if ((p = mallocCS(w)) != (ColorSegment *) NULL) {
			++ w->scanLine[y].count;
			w->scanLine[y].tail = p;
			p->x = x0;
			p->length = x1 - x0 + 1;
			p->color = color;
		}

	}		

}