#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <X11/IntrinsicP.h>
#include <X11/Xmu/Xmu.h>
#define XmuMax(a, b) ((a) > (b) ? (a) : (b))
#define XmuMin(a, b) ((a) < (b) ? (a) : (b))
XmuArea *
XmuNewArea(int x1, int y1, int x2, int y2)
{
XmuArea *area;
area = (XmuArea *)XtMalloc(sizeof(XmuArea));
if (x2 > x1 && y2 > y1)
{
area->scanline = XmuNewScanline(y1, x1, x2);
area->scanline->next = XmuNewScanline(y2, 0, 0);
}
else
area->scanline = (XmuScanline *)NULL;
return (area);
}
XmuArea *
XmuAreaDup(XmuArea *area)
{
XmuArea *dst;
if (!area)
return ((XmuArea *)NULL);
dst = XmuCreateArea();
XmuAreaCopy(dst, area);
return (dst);
}
XmuArea *
XmuAreaCopy(XmuArea *dst, XmuArea *src)
{
XmuScanline *z, *p, *Z;
if (!dst || !src || dst == src)
return (dst);
z = p = dst->scanline;
Z = src->scanline;
while (1)
{
if (!Z)
{
if (z == dst->scanline)
{
XmuDestroyScanlineList(dst->scanline);
dst->scanline = (XmuScanline *)NULL;
}
else
{
XmuDestroyScanlineList(p->next);
p->next = (XmuScanline *)NULL;
}
return (dst);
}
if (z)
{
XmuScanlineCopy(z, Z);
z->y = Z->y;
}
else
{
z = XmuNewScanline(Z->y, 0, 0);
XmuScanlineCopy(z, Z);
if (p == dst->scanline && !dst->scanline)
p = dst->scanline = z;
else
p->next = z;
}
p = z;
z = z->next;
Z = Z->next;
}
return (dst);
}
XmuArea *
XmuAreaNot(XmuArea *area, int x1, int y1, int x2, int y2)
{
XmuScanline *z;
XmuArea *and;
if (!area)
return (area);
if (x1 > x2)
{
x1 ^= x2; x2 ^= x1; x1 ^= x2;
}
if (y1 > y2)
{
y1 ^= y2; y2 ^= y1; y1 ^= y2;
}
if (!area->scanline)
{
if ((area->scanline = XmuNewScanline(y1, x1, x2)) != NULL)
area->scanline->next = XmuNewScanline(y2, 0, 0);
return (area);
}
and = XmuNewArea(x1, y1, x2, y2);
XmuAreaAnd(area, and);
XmuDestroyArea(and);
z = area->scanline;
if (z->y != y1)
{
XmuScanline *q = XmuNewScanline(y1, x1, x2);
q->next = z;
area->scanline = q;
}
else
{
area->scanline = area->scanline->next;
XmuDestroyScanline(z);
XmuOptimizeArea(area);
if((z = area->scanline) == (XmuScanline *)NULL)
return (area);
}
while (1)
{
XmuScanlineNot(z, x1, x2);
if (!z->next)
{
z->next = XmuNewScanline(y2, 0, 0);
break;
}
if (z->next->y == y2)
{
XmuDestroyScanlineList(z->next);
z->next = XmuNewScanline(y2, 0, 0);
break;
}
z = z->next;
}
return (area);
}
XmuArea *
XmuAreaOrXor(XmuArea *dst, XmuArea *src, Bool or)
{
XmuScanline *z, *p, *Z, *P, *ins, *top;
if (!dst || !src)
return (dst);
if (dst == src)
{
if (or)
return (dst);
XmuDestroyScanlineList(dst->scanline);
dst->scanline = (XmuScanline *)NULL;
return (dst);
}
if (!XmuValidArea(src))
return (dst);
if (!XmuValidArea(dst))
{
XmuAreaCopy(dst, src);
return (dst);
}
p = z = dst->scanline;
P = Z = src->scanline;
ins = XmuNewScanline(dst->scanline->y, 0, 0);
top = XmuNewScanline(dst->scanline->y, 0, 0);
XmuScanlineCopy(ins, dst->scanline);
XmuScanlineCopy(top, dst->scanline);
while (1)
{
if (!Z)
break;
else if (Z->y < z->y)
{
XmuScanline *q = XmuNewScanline(Z->y, 0, 0);
XmuScanlineCopy(q, Z);
if (z == dst->scanline)
{
dst->scanline = p = q;
q->next = z;
}
else
{
p->next = q;
q->next = z;
if (Z->y >= p->y)
{
if (ins->y >= top->y
&& (p->y != P->y || !XmuScanlineEqu(p, P)
|| (ins->y <= P->y && !XmuScanlineEqu(ins, P))))
{
if (or)
XmuScanlineOr(q, ins);
else
XmuScanlineXor(q, ins);
}
else if (Z->y >= top->y
&& (top->y == p->y || top->y > ins->y
|| !XmuValidScanline(Z)
|| (p->y == P->y && XmuValidScanline(p)
&& XmuValidScanline(P))
|| XmuScanlineEqu(ins, top)))
{
if (or)
XmuScanlineOr(q, top);
else
XmuScanlineXor(q, top);
}
if (ins->y != p->y && p->y != P->y)
{
XmuScanlineCopy(ins, p);
ins->y = p->y;
}
}
if (!XmuValidScanline(p) || Z->y <= p->y)
{
XmuScanlineCopy(top, p);
top->y = p->y;
}
p = q;
}
P = Z;
Z = Z->next;
continue;
}
else if (Z->y == z->y)
{
if (top->y != z->y)
{
XmuScanlineCopy(top, z);
top->y = z->y;
}
if (or)
XmuScanlineOr(z, Z);
else
XmuScanlineXor(z, Z);
P = Z;
Z = Z->next;
}
else if (P != Z)
{
if (top->y == ins->y && top->y != z->y)
{
XmuScanlineCopy(top, z);
top->y = z->y;
}
if (ins->y != z->y)
{
XmuScanlineCopy(ins, z);
ins->y = z->y;
}
if (or)
XmuScanlineOr(z, P);
else
XmuScanlineXor(z, P);
}
else if (ins->y != z->y)
{
XmuScanlineCopy(ins, z);
ins->y = z->y;
}
p = z;
z = z->next;
if (!z)
{
while (Z)
{
p->next = XmuNewScanline(Z->y, 0, 0);
XmuScanlineCopy(p->next, Z);
p = p->next;
Z = Z->next;
}
break;
}
else if (ins->y > top->y && !XmuValidScanline(z)
&& XmuValidScanline(ins))
{
XmuScanlineCopy(top, ins);
top->y = ins->y;
}
}
XmuOptimizeArea(dst);
XmuDestroyScanline(ins);
XmuDestroyScanline(top);
return (dst);
}
XmuArea *
XmuAreaAnd(XmuArea *dst, XmuArea *src)
{
XmuScanline *z, *p, *Z, *P, *top;
if (!dst || !src || dst == src)
return (dst);
if (!XmuValidArea(dst) || !XmuValidArea(src))
{
XmuDestroyScanlineList(dst->scanline);
dst->scanline = (XmuScanline *)NULL;
return (dst);
}
z = p = dst->scanline;
Z = P = src->scanline;
top = XmuNewScanline(dst->scanline->y, 0, 0);
XmuScanlineCopy(top, dst->scanline);
while (z)
{
while (Z->next && Z->next->y < z->y)
{
P = Z;
Z = Z->next;
if (Z->y >= p->y)
{
XmuScanline *q = XmuNewScanline(Z->y, 0, 0);
XmuScanlineCopy(q, Z);
XmuScanlineAnd(q, top);
if (p->y != P->y)
{
XmuScanlineAnd(p, P);
p->y = XmuMax(p->y, P->y);
}
p->next = q;
q->next = z;
p = q;
}
}
if (!z->next)
{
z->y = XmuMax(z->y, Z->y);
break;
}
while (Z->y >= z->next->y)
{
if (z == dst->scanline)
{
p = dst->scanline = dst->scanline->next;
XmuDestroyScanline(z);
z = dst->scanline;
}
else
{
p->next = z->next;
XmuDestroyScanline(z);
z = p;
}
if (!z || !z->next)
{
XmuOptimizeArea(dst);
XmuDestroyScanline(top);
return (dst);
}
}
if (Z->y > p->y)
z->y = XmuMax(z->y, Z->y);
if (top->y != z->y)
{
XmuScanlineCopy(top, z);
top->y = z->y;
}
XmuScanlineAnd(z, Z);
p = z;
z = z->next;
}
XmuOptimizeArea(dst);
XmuDestroyScanline(top);
return (dst);
}
Bool
XmuValidArea(XmuArea *area)
{
XmuScanline *at;
if (!area || !area->scanline)
return (False);
at = area->scanline;
while (at)
{
if (XmuValidScanline(at))
return (True);
at = at->next;
}
return (False);
}
Bool
XmuValidScanline(XmuScanline *scanline)
{
XmuSegment *z;
if (!scanline)
return (False);
z = scanline->segment;
while (z)
{
if (XmuValidSegment(z))
return (True);
z = z->next;
}
return (False);
}
Bool
XmuScanlineEqu(XmuScanline *s1, XmuScanline *s2)
{
XmuSegment *z, *Z;
if ((!s1 && !s2) || s1 == s2)
return (True);
if (!s1 || !s2)
return (False);
z = s1->segment;
Z = s2->segment;
while (1)
{
if (!z && !Z)
return (True);
if (!z || !Z)
return (False);
if (!XmuSegmentEqu(z, Z))
return (False);
z = z->next;
Z = Z->next;
}
}
XmuSegment *
XmuNewSegment(int x1, int x2)
{
XmuSegment *segment;
if ((segment = (XmuSegment *)XtMalloc(sizeof(XmuSegment))) == NULL)
return (segment);
segment->x1 = x1;
segment->x2 = x2;
segment->next = (XmuSegment *)NULL;
return (segment);
}
void
XmuDestroySegmentList(XmuSegment *segment)
{
XmuSegment *z;
if (!segment)
return;
while (segment)
{
z = segment;
segment = segment->next;
XmuDestroySegment(z);
}
}
XmuScanline *
XmuScanlineCopy(XmuScanline *dst, XmuScanline *src)
{
XmuSegment *z, *p, *Z;
if (!dst || !src || dst == src)
return (dst);
z = p = dst->segment;
Z = src->segment;
while (1)
{
if (!Z)
{
if (z == dst->segment)
dst->segment = (XmuSegment *)NULL;
else
p->next = (XmuSegment *)NULL;
XmuDestroySegmentList(z);
return (dst);
}
if (z)
{
z->x1 = Z->x1;
z->x2 = Z->x2;
}
else
{
z = XmuNewSegment(Z->x1, Z->x2);
if (p == dst->segment && !dst->segment)
p = dst->segment = z;
else
p->next = z;
}
p = z;
z = z->next;
Z = Z->next;
}
}
Bool
XmuAppendSegment(XmuSegment *segment, XmuSegment *append)
{
if (!segment || !append)
return (False);
if (segment->next)
XmuDestroySegmentList(segment->next);
while (append)
{
if (XmuValidSegment(append))
{
if ((segment->next = XmuNewSegment(append->x1, append->x2)) == NULL)
return (False);
segment = segment->next;
}
append = append->next;
}
return (True);
}
XmuScanline *
XmuOptimizeScanline(XmuScanline *scanline)
{
XmuSegment *z, *p;
while (scanline->segment && !XmuValidSegment(scanline->segment))
{
XmuSegment *s = scanline->segment;
scanline->segment = scanline->segment->next;
XmuDestroySegment(s);
}
for (z = p = scanline->segment; z; p = z, z = z->next)
{
if (!XmuValidSegment(z))
{
p->next = z->next;
XmuDestroySegment(z);
z = p;
}
}
return (scanline);
}
XmuScanline *
XmuScanlineNot(XmuScanline *scanline, int minx, int maxx)
{
XmuSegment *z;
static XmuSegment x = { 0, 0, 0 };
static XmuScanline and = { 0, &x, 0 };
if (!scanline)
return (scanline);
XmuOptimizeScanline(scanline);
if (minx > maxx)
{
minx ^= maxx; maxx ^= minx; minx ^= maxx;
}
and.segment->x1 = minx;
and.segment->x2 = maxx;
XmuScanlineAnd(scanline, &and);
if (!scanline->segment)
{
scanline->segment = XmuNewSegment(minx, maxx);
return (scanline);
}
z = scanline->segment;
if (z->x1 != minx)
{
XmuSegment *q = XmuNewSegment(minx, z->x1);
q->next = z;
scanline->segment = q;
}
while (1)
{
z->x1 = z->x2;
if (!z->next)
{
z->x2 = maxx;
break;
}
z->x2 = z->next->x1;
if (z->next->x2 == maxx)
{
XmuDestroySegment(z->next);
z->next = (XmuSegment *)NULL;
break;
}
z = z->next;
}
return (scanline);
}
#ifndef notdef
XmuScanline *
XmuScanlineOrSegment(XmuScanline *dst, XmuSegment *src)
{
XmuSegment *z, *p, ins;
if (!src || !dst || !XmuValidSegment(src))
return (dst);
if (!dst->segment)
{
dst->segment = XmuNewSegment(src->x1, src->x2);
return (dst);
}
z = p = dst->segment;
ins.x1 = src->x1;
ins.x2 = src->x2;
while (1)
{
if (!z)
{
XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
if (p == dst->segment && z == p)
dst->segment = q;
else
p->next = q;
break;
}
else if (ins.x2 < z->x1)
{
XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
if (p == dst->segment && z == p)
{
q->next = dst->segment;
dst->segment = q;
}
else
{
p->next = q;
q->next = z;
}
break;
}
else if (ins.x2 <= z->x2)
{
z->x1 = XmuMin(z->x1, ins.x1);
break;
}
else if (ins.x1 <= z->x2)
{
ins.x1 = XmuMin(z->x1, ins.x1);
if (!z->next)
{
z->x1 = ins.x1;
z->x2 = ins.x2;
break;
}
else
{
if (z == dst->segment)
{
p = dst->segment = dst->segment->next;
XmuDestroySegment(z);
z = dst->segment;
continue;
}
else
{
p->next = z->next;
XmuDestroySegment(z);
z = p;
}
}
}
p = z;
z = z->next;
}
return (dst);
}
XmuScanline *
XmuScanlineAndSegment(XmuScanline *dst, XmuSegment *src)
{
XmuSegment *z, *p;
if (!dst || !src)
return (dst);
if (!XmuValidSegment(src))
{
XmuDestroySegmentList(dst->segment);
dst->segment = (XmuSegment *)NULL;
return (dst);
}
if (!dst->segment)
return (dst);
z = p = dst->segment;
while (z)
{
if (src->x2 <= z->x1 || src->x1 >= z->x2)
{
if (z == dst->segment)
{
p = dst->segment = dst->segment->next;
XmuDestroySegment(z);
z = dst->segment;
continue;
}
else
{
p->next = z->next;
XmuDestroySegment(z);
z = p;
}
}
else
{
z->x1 = XmuMax(z->x1, src->x1);
z->x2 = XmuMin(z->x2, src->x2);
}
p = z;
z = z->next;
}
return (dst);
}
XmuScanline *
XmuScanlineXorSegment(XmuScanline *dst, XmuSegment *src)
{
XmuSegment *p, *z, ins;
int tmp1, tmp2;
if (!dst || !src || !XmuValidSegment(src))
return (dst);
if (!dst->segment)
{
dst->segment = XmuNewSegment(src->x1, src->x2);
return (dst);
}
p = z = dst->segment;
ins.x1 = src->x1;
ins.x2 = src->x2;
while (1)
{
if (!XmuValidSegment((&ins)))
break;
if (!z || ins.x2 < z->x1)
{
XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
q->next = z;
if (z == dst->segment)
dst->segment = q;
else
p->next = q;
break;
}
else if (ins.x2 == z->x1)
{
z->x1 = ins.x1;
break;
}
else if (ins.x1 < z->x2)
{
if (ins.x1 < z->x1)
{
tmp1 = ins.x2;
tmp2 = z->x2;
ins.x2 = XmuMax(ins.x2, z->x2);
z->x2 = z->x1;
z->x1 = ins.x1;
ins.x1 = XmuMin(tmp1, tmp2);
}
else if (ins.x1 > z->x1)
{
tmp1 = ins.x1;
ins.x1 = XmuMin(ins.x2, z->x2);
ins.x2 = XmuMax(z->x2, ins.x2);
z->x2 = tmp1;
}
else
{
if (ins.x2 < z->x2)
{
z->x1 = ins.x2;
break;
}
else
{
ins.x1 = z->x2;
if (z == dst->segment)
p = dst->segment = dst->segment->next;
else
p->next = z->next;
XmuDestroySegment(z);
z = p;
continue;
}
}
}
else if (ins.x1 == z->x2)
{
ins.x1 = z->x1;
if (z == dst->segment)
p = dst->segment = dst->segment->next;
else
p->next = z->next;
XmuDestroySegment(z);
z = p;
continue;
}
p = z;
z = z->next;
}
return (dst);
}
#endif
XmuScanline *
XmuScanlineOr(XmuScanline *dst, XmuScanline *src)
{
XmuSegment *z, *p, *Z, ins;
if (!src || !src->segment || !dst || dst == src)
return (dst);
if (!dst->segment)
{
XmuScanlineCopy(dst, src);
return (dst);
}
z = p = dst->segment;
Z = src->segment;
ins.x1 = Z->x1;
ins.x2 = Z->x2;
while (1)
{
while (!XmuValidSegment((&ins)))
{
if ((Z = Z->next) == (XmuSegment *)NULL)
return (dst);
ins.x1 = Z->x1;
ins.x2 = Z->x2;
}
if (!z)
{
XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
if (p == dst->segment && z == p)
dst->segment = p = q;
else
{
p->next = q;
p = q;
}
Z = Z->next;
XmuAppendSegment(p, Z);
break;
}
else if (ins.x2 < z->x1)
{
XmuSegment *r = XmuNewSegment(ins.x1, ins.x2);
if (p == dst->segment && z == p)
{
r->next = dst->segment;
dst->segment = p = r;
}
else
{
p->next = r;
r->next = z;
p = r;
}
Z = Z->next;
if (!Z)
break;
else
{
ins.x1 = Z->x1;
ins.x2 = Z->x2;
continue;
}
}
else if (ins.x2 <= z->x2)
{
z->x1 = XmuMin(z->x1, ins.x1);
Z = Z->next;
if (!Z)
break;
else
{
ins.x1 = Z->x1;
ins.x2 = Z->x2;
continue;
}
}
else if (ins.x1 <= z->x2)
{
ins.x1 = XmuMin(z->x1, ins.x1);
if (!z->next)
{
z->x1 = ins.x1;
z->x2 = ins.x2;
p = z;
Z = Z->next;
XmuAppendSegment(p, Z);
break;
}
else
{
if (z == dst->segment)
{
p = dst->segment = dst->segment->next;
XmuDestroySegment(z);
z = p;
continue;
}
else
{
p->next = z->next;
XmuDestroySegment(z);
z = p;
}
}
}
p = z;
z = z->next;
}
return (dst);
}
XmuScanline *
XmuScanlineAnd(XmuScanline *dst, XmuScanline *src)
{
XmuSegment *z, *p, *Z;
if (!dst || !src || dst == src || !dst->segment) {
return (dst);
}
if (!src->segment)
{
XmuDestroySegmentList(dst->segment);
dst->segment = (XmuSegment *)NULL;
return (dst);
}
z = p = dst->segment;
Z = src->segment;
while (z)
{
while (!XmuValidSegment(Z) || Z->x2 <= z->x1)
{
Z = Z->next;
if (!Z)
{
if (z == dst->segment)
dst->segment = (XmuSegment *)NULL;
else
p->next = (XmuSegment *)0;
XmuDestroySegmentList(z);
return (dst);
}
}
if (Z->x1 >= z->x2)
{
if (z == dst->segment)
{
p = dst->segment = dst->segment->next;
XmuDestroySegment(z);
z = dst->segment;
}
else
{
p->next = z->next;
XmuDestroySegment(z);
z = p->next;
}
if (!z)
return (dst);
else
continue;
}
z->x1 = XmuMax(z->x1, Z->x1);
if (z->x2 > Z->x2)
{
if (Z->next)
{
XmuSegment *q = XmuNewSegment(Z->x2, z->x2);
q->next = z->next;
z->next = q;
}
z->x2 = Z->x2;
}
p = z;
z = z->next;
}
return (dst);
}
XmuScanline *
XmuScanlineXor(XmuScanline *dst, XmuScanline *src)
{
XmuSegment *z, *p, *Z, ins;
int tmp1, tmp2;
if (!src || !dst || !src->segment)
return (dst);
if (src == dst)
{
XmuDestroySegmentList(dst->segment);
dst->segment = (XmuSegment *)NULL;
return (dst);
}
if (!dst->segment)
{
XmuScanlineCopy(dst, src);
return (dst);
}
z = p = dst->segment;
Z = src->segment;
ins.x1 = Z->x1;
ins.x2 = Z->x2;
while (1)
{
while (!XmuValidSegment((&ins)))
{
if ((Z = Z->next) == (XmuSegment *)NULL)
return (dst);
ins.x1 = Z->x1;
ins.x2 = Z->x2;
}
if (!z)
{
XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
if (!dst->segment)
dst->segment = q;
else
p->next = q;
p = q;
Z = Z->next;
XmuAppendSegment(p, Z);
break;
}
else if (ins.x2 < z->x1)
{
XmuSegment *q = XmuNewSegment(ins.x1, ins.x2);
q->next = z;
if (z == dst->segment)
dst->segment = q;
else
p->next = q;
if ((Z = Z->next) == (XmuSegment *)NULL)
return (dst);
p = q;
ins.x1 = Z->x1;
ins.x2 = Z->x2;
continue;
}
else if (ins.x2 == z->x1)
{
z->x1 = ins.x1;
if ((Z = Z->next) == (XmuSegment *)NULL)
break;
ins.x1 = Z->x1;
ins.x2 = Z->x2;
continue;
}
else if (ins.x1 < z->x2)
{
if (ins.x1 == z->x1)
{
if (ins.x2 < z->x2)
{
z->x1 = ins.x2;
if ((Z = Z->next) == (XmuSegment *)NULL)
break;
ins.x1 = Z->x1;
ins.x2 = Z->x2;
continue;
}
else
{
ins.x1 = z->x2;
if (z == dst->segment)
p = dst->segment = dst->segment->next;
else
p->next = z->next;
XmuDestroySegment(z);
z = p;
continue;
}
}
else
{
if (Z->x2 < z->x2)
{
XmuSegment *q = XmuNewSegment(XmuMin(ins.x1, z->x1),
XmuMax(z->x1, ins.x1));
q->next = z;
if (z == dst->segment)
dst->segment = q;
else
p->next = q;
ins.x1 = z->x2;
z->x1 = ins.x2;
p = q;
continue;
}
else
{
tmp1 = ins.x2;
tmp2 = z->x2;
ins.x2 = XmuMax(ins.x2, z->x2);
z->x2 = XmuMax(z->x1, ins.x1);
z->x1 = XmuMin(ins.x1, z->x1);
ins.x1 = XmuMin(tmp1, tmp2);
}
}
}
else if (ins.x1 == z->x2)
{
ins.x1 = z->x1;
if (z == dst->segment)
p = dst->segment = dst->segment->next;
else
p->next = z->next;
XmuDestroySegment(z);
z = p;
continue;
}
p = z;
z = z->next;
}
return (dst);
}
XmuScanline *
XmuNewScanline(int y, int x1, int x2)
{
XmuScanline *scanline;
scanline = (XmuScanline *)XtMalloc(sizeof(XmuScanline));
scanline->y = y;
if (x1 < x2)
scanline->segment = XmuNewSegment(x1, x2);
else
scanline->segment = (XmuSegment *)NULL;
scanline->next = (XmuScanline *)NULL;
return (scanline);
}
void
XmuDestroyScanlineList(XmuScanline *scanline)
{
XmuScanline *z;
if (!scanline)
return;
while (scanline)
{
z = scanline;
scanline = scanline->next;
XmuDestroyScanline(z);
}
}
XmuArea *XmuOptimizeArea(XmuArea *area)
{
XmuScanline *pr, *at;
if (!area || !area->scanline)
return (area);
if (!area->scanline->next)
{
XmuDestroyScanlineList(area->scanline);
area->scanline = (XmuScanline *)0;
return (area);
}
pr = area->scanline;
at = area->scanline->next;
while (area->scanline && (!XmuValidScanline(area->scanline)
|| (area->scanline->next && area->scanline->y
>= area->scanline->next->y)))
{
area->scanline = area->scanline->next;
XmuDestroyScanline(pr);
pr = area->scanline;
if (pr)
at = pr->next;
}
for (; at; pr = at, at = at->next)
{
if (XmuScanlineEqu(at, pr)
|| (!XmuValidScanline(at) && !XmuValidScanline(pr))
|| (at->next && at->y >= at->next->y))
{
pr->next = at->next;
XmuDestroyScanline(at);
at = pr;
}
}
if (pr && XmuValidScanline(pr))
{
XmuDestroySegmentList(pr->segment);
pr->segment = (XmuSegment *)NULL;
}
if (area->scanline && !area->scanline->next)
{
XmuDestroyScanlineList(area->scanline);
area->scanline = (XmuScanline *)NULL;
}
return (area);
}