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;
}
}
}
|