Apply proper formatting to polyfill.c

svn path=/trunk/; revision=66645
This commit is contained in:
Timo Kreuzer 2015-03-10 00:11:43 +00:00
parent fe4dc5d9d5
commit 42587dd1d3

View file

@ -18,31 +18,31 @@
*/ */
typedef struct _tagFILL_EDGE typedef struct _tagFILL_EDGE
{ {
/* Basic line information */ /* Basic line information */
int FromX; int FromX;
int FromY; int FromY;
int ToX; int ToX;
int ToY; int ToY;
int dx; int dx;
int dy; int dy;
int absdx, absdy; int absdx, absdy;
int x, y; int x, y;
int xmajor; int xmajor;
/* Active Edge List information */ /* Active Edge List information */
int XIntercept[2]; int XIntercept[2];
int Error; int Error;
int ErrorMax; int ErrorMax;
int XDirection, YDirection; int XDirection, YDirection;
/* The next edge in the active Edge List */ /* The next edge in the active Edge List */
struct _tagFILL_EDGE * pNext; struct _tagFILL_EDGE * pNext;
} FILL_EDGE; } FILL_EDGE;
typedef struct _FILL_EDGE_LIST typedef struct _FILL_EDGE_LIST
{ {
int Count; int Count;
FILL_EDGE** Edges; FILL_EDGE** Edges;
} FILL_EDGE_LIST; } FILL_EDGE_LIST;
#if 0 #if 0
@ -50,19 +50,19 @@ static
void void
DEBUG_PRINT_ACTIVE_EDGELIST ( FILL_EDGE* list ) DEBUG_PRINT_ACTIVE_EDGELIST ( FILL_EDGE* list )
{ {
FILL_EDGE* pThis = list; FILL_EDGE* pThis = list;
if (0 == list) if (0 == list)
{ {
DPRINT1("List is NULL\n"); DPRINT1("List is NULL\n");
return; return;
} }
while(0 != pThis) while(0 != pThis)
{ {
//DPRINT1("EDGE: (%d, %d) to (%d, %d)\n", pThis->FromX, pThis->FromY, pThis->ToX, pThis->ToY); //DPRINT1("EDGE: (%d, %d) to (%d, %d)\n", pThis->FromX, pThis->FromY, pThis->ToX, pThis->ToY);
DPRINT1("EDGE: [%d,%d]\n", pThis->XIntercept[0], pThis->XIntercept[1] ); DPRINT1("EDGE: [%d,%d]\n", pThis->XIntercept[0], pThis->XIntercept[1] );
pThis = pThis->pNext; pThis = pThis->pNext;
} }
} }
#else #else
#define DEBUG_PRINT_ACTIVE_EDGELIST(x) #define DEBUG_PRINT_ACTIVE_EDGELIST(x)
@ -76,20 +76,23 @@ void
FASTCALL FASTCALL
POLYGONFILL_DestroyEdgeList(FILL_EDGE_LIST* list) POLYGONFILL_DestroyEdgeList(FILL_EDGE_LIST* list)
{ {
int i; int i;
if ( list )
{ if (list)
if ( list->Edges )
{ {
for ( i = 0; i < list->Count; i++ ) if (list->Edges)
{ {
if ( list->Edges[i] ) for (i = 0; i < list->Count; i++)
EngFreeMem ( list->Edges[i] ); {
} if (list->Edges[i])
EngFreeMem ( list->Edges ); EngFreeMem(list->Edges[i]);
}
EngFreeMem(list->Edges);
}
EngFreeMem(list);
} }
EngFreeMem ( list );
}
} }
/* /*
@ -100,57 +103,57 @@ FILL_EDGE*
FASTCALL FASTCALL
POLYGONFILL_MakeEdge(POINT From, POINT To) POLYGONFILL_MakeEdge(POINT From, POINT To)
{ {
FILL_EDGE* rc = (FILL_EDGE*)EngAllocMem(FL_ZERO_MEMORY, sizeof(FILL_EDGE), FILL_EDGE_ALLOC_TAG); FILL_EDGE* rc = (FILL_EDGE*)EngAllocMem(FL_ZERO_MEMORY, sizeof(FILL_EDGE), FILL_EDGE_ALLOC_TAG);
if (0 == rc) if (0 == rc)
return NULL; return NULL;
//DPRINT1("Making Edge: (%d, %d) to (%d, %d)\n", From.x, From.y, To.x, To.y); //DPRINT1("Making Edge: (%d, %d) to (%d, %d)\n", From.x, From.y, To.x, To.y);
// Now fill the struct. // Now fill the struct.
if ( To.y < From.y ) if ( To.y < From.y )
{ {
rc->FromX = To.x; rc->FromX = To.x;
rc->FromY = To.y; rc->FromY = To.y;
rc->ToX = From.x; rc->ToX = From.x;
rc->ToY = From.y; rc->ToY = From.y;
rc->YDirection = -1; rc->YDirection = -1;
// Lines that go up get walked backwards, so need to be offset // Lines that go up get walked backwards, so need to be offset
// by -1 in order to make the walk identically on a pixel-level // by -1 in order to make the walk identically on a pixel-level
rc->Error = -1; rc->Error = -1;
} }
else else
{ {
rc->FromX = From.x; rc->FromX = From.x;
rc->FromY = From.y; rc->FromY = From.y;
rc->ToX = To.x; rc->ToX = To.x;
rc->ToY = To.y; rc->ToY = To.y;
rc->YDirection = 1; rc->YDirection = 1;
rc->Error = 0; rc->Error = 0;
} }
rc->x = rc->FromX; rc->x = rc->FromX;
rc->y = rc->FromY; rc->y = rc->FromY;
rc->dx = rc->ToX - rc->FromX; rc->dx = rc->ToX - rc->FromX;
rc->dy = rc->ToY - rc->FromY; rc->dy = rc->ToY - rc->FromY;
rc->absdx = abs(rc->dx); rc->absdx = abs(rc->dx);
rc->absdy = abs(rc->dy); rc->absdy = abs(rc->dy);
rc->xmajor = rc->absdx > rc->absdy; rc->xmajor = rc->absdx > rc->absdy;
rc->ErrorMax = max(rc->absdx,rc->absdy); rc->ErrorMax = max(rc->absdx,rc->absdy);
rc->Error += rc->ErrorMax / 2; rc->Error += rc->ErrorMax / 2;
rc->XDirection = (rc->dx < 0)?(-1):(1); rc->XDirection = (rc->dx < 0)?(-1):(1);
rc->pNext = 0; rc->pNext = 0;
//DPRINT("MakeEdge (%i,%i)->(%i,%i) d=(%i,%i) dir=(%i,%i) err=%i max=%i\n", //DPRINT("MakeEdge (%i,%i)->(%i,%i) d=(%i,%i) dir=(%i,%i) err=%i max=%i\n",
// From.x, From.y, To.x, To.y, rc->dx, rc->dy, rc->XDirection, rc->YDirection, rc->Error, rc->ErrorMax ); // From.x, From.y, To.x, To.y, rc->dx, rc->dy, rc->XDirection, rc->YDirection, rc->Error, rc->ErrorMax );
return rc; return rc;
} }
/* /*
** My Edge comparison routine. ** My Edge comparison routine.
@ -171,10 +174,10 @@ INT
FASTCALL FASTCALL
FILL_EDGE_Compare(FILL_EDGE* Edge1, FILL_EDGE* Edge2) FILL_EDGE_Compare(FILL_EDGE* Edge1, FILL_EDGE* Edge2)
{ {
int e1 = Edge1->XIntercept[0] + Edge1->XIntercept[1]; int e1 = Edge1->XIntercept[0] + Edge1->XIntercept[1];
int e2 = Edge2->XIntercept[0] + Edge2->XIntercept[1]; int e2 = Edge2->XIntercept[0] + Edge2->XIntercept[1];
return e1 - e2; return e1 - e2;
} }
@ -186,39 +189,41 @@ void
FASTCALL FASTCALL
POLYGONFILL_ActiveListInsert(FILL_EDGE** activehead, FILL_EDGE* NewEdge ) POLYGONFILL_ActiveListInsert(FILL_EDGE** activehead, FILL_EDGE* NewEdge )
{ {
FILL_EDGE *pPrev, *pThis; FILL_EDGE *pPrev, *pThis;
//DPRINT1("In POLYGONFILL_ActiveListInsert()\n"); //DPRINT1("In POLYGONFILL_ActiveListInsert()\n");
ASSERT ( activehead && NewEdge ); ASSERT(activehead && NewEdge);
if ( !*activehead )
{
NewEdge->pNext = NULL;
*activehead = NewEdge;
return;
}
/*
** First lets check to see if we have a new smallest value.
*/
if (FILL_EDGE_Compare(NewEdge, *activehead) <= 0)
{
NewEdge->pNext = *activehead;
*activehead = NewEdge;
return;
}
/*
** Ok, now scan to the next spot to put this item.
*/
pThis = *activehead;
pPrev = NULL;
while ( pThis && FILL_EDGE_Compare(pThis, NewEdge) < 0 )
{
pPrev = pThis;
pThis = pThis->pNext;
}
ASSERT(pPrev); if (!*activehead)
NewEdge->pNext = pPrev->pNext; {
pPrev->pNext = NewEdge; NewEdge->pNext = NULL;
//DEBUG_PRINT_ACTIVE_EDGELIST(*activehead); *activehead = NewEdge;
return;
}
/*
** First lets check to see if we have a new smallest value.
*/
if (FILL_EDGE_Compare(NewEdge, *activehead) <= 0)
{
NewEdge->pNext = *activehead;
*activehead = NewEdge;
return;
}
/*
** Ok, now scan to the next spot to put this item.
*/
pThis = *activehead;
pPrev = NULL;
while ( pThis && FILL_EDGE_Compare(pThis, NewEdge) < 0 )
{
pPrev = pThis;
pThis = pThis->pNext;
}
ASSERT(pPrev);
NewEdge->pNext = pPrev->pNext;
pPrev->pNext = NewEdge;
//DEBUG_PRINT_ACTIVE_EDGELIST(*activehead);
} }
/* /*
@ -229,50 +234,50 @@ FILL_EDGE_LIST*
FASTCALL FASTCALL
POLYGONFILL_MakeEdgeList(PPOINT Points, int Count) POLYGONFILL_MakeEdgeList(PPOINT Points, int Count)
{ {
int CurPt = 0; int CurPt = 0;
FILL_EDGE_LIST* list = 0; FILL_EDGE_LIST* list = 0;
FILL_EDGE* e = 0; FILL_EDGE* e = 0;
if ( 0 == Points || 2 > Count ) if (0 == Points || 2 > Count)
return 0; return 0;
list = (FILL_EDGE_LIST*)EngAllocMem(FL_ZERO_MEMORY, sizeof(FILL_EDGE_LIST), FILL_EDGE_ALLOC_TAG); list = (FILL_EDGE_LIST*)EngAllocMem(FL_ZERO_MEMORY, sizeof(FILL_EDGE_LIST), FILL_EDGE_ALLOC_TAG);
if ( 0 == list ) if ( 0 == list )
goto fail; goto fail;
list->Count = 0; list->Count = 0;
list->Edges = (FILL_EDGE**)EngAllocMem(FL_ZERO_MEMORY, Count*sizeof(FILL_EDGE*), FILL_EDGE_ALLOC_TAG); list->Edges = (FILL_EDGE**)EngAllocMem(FL_ZERO_MEMORY, Count*sizeof(FILL_EDGE*), FILL_EDGE_ALLOC_TAG);
if ( !list->Edges ) if ( !list->Edges )
goto fail; goto fail;
memset ( list->Edges, 0, Count * sizeof(FILL_EDGE*) ); memset(list->Edges, 0, Count * sizeof(FILL_EDGE*));
for ( CurPt = 1; CurPt < Count; ++CurPt ) for (CurPt = 1; CurPt < Count; ++CurPt)
{ {
e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[CurPt] ); e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[CurPt] );
if (!e)
goto fail;
// If a straight horizontal line - who cares?
if (!e->absdy)
EngFreeMem(e);
else
list->Edges[list->Count++] = e;
}
e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[0] );
if ( !e ) if ( !e )
goto fail; goto fail;
// If a straight horizontal line - who cares? if (!e->absdy)
if ( !e->absdy ) EngFreeMem(e);
EngFreeMem ( e );
else else
list->Edges[list->Count++] = e; list->Edges[list->Count++] = e;
} return list;
e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[0] );
if ( !e )
goto fail;
if ( !e->absdy )
EngFreeMem ( e );
else
list->Edges[list->Count++] = e;
return list;
fail: fail:
DPRINT1("Out Of MEMORY!!\n"); DPRINT1("Out Of MEMORY!!\n");
POLYGONFILL_DestroyEdgeList ( list ); POLYGONFILL_DestroyEdgeList ( list );
return 0; return 0;
} }
@ -287,63 +292,63 @@ void
FASTCALL FASTCALL
POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline) POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline)
{ {
if ( 0 == pEdge->dy ) if (0 == pEdge->dy)
return; return;
ASSERT ( pEdge->FromY <= Scanline && pEdge->ToY > Scanline ); ASSERT(pEdge->FromY <= Scanline && pEdge->ToY > Scanline);
if ( pEdge->xmajor ) if (pEdge->xmajor)
{
int steps;
ASSERT ( pEdge->y == Scanline );
// Now shoot to end of scanline collision
steps = (pEdge->ErrorMax-pEdge->Error-1)/pEdge->absdy;
if ( steps )
{ {
// Record first collision with scanline int steps;
int x1 = pEdge->x;
pEdge->x += steps * pEdge->XDirection; ASSERT(pEdge->y == Scanline);
pEdge->Error += steps * pEdge->absdy;
ASSERT ( pEdge->Error < pEdge->ErrorMax ); // Now shoot to end of scanline collision
pEdge->XIntercept[0] = min(x1,pEdge->x); steps = (pEdge->ErrorMax-pEdge->Error-1)/pEdge->absdy;
pEdge->XIntercept[1] = max(x1,pEdge->x); if (steps)
{
// Record first collision with scanline
int x1 = pEdge->x;
pEdge->x += steps * pEdge->XDirection;
pEdge->Error += steps * pEdge->absdy;
ASSERT ( pEdge->Error < pEdge->ErrorMax );
pEdge->XIntercept[0] = min(x1,pEdge->x);
pEdge->XIntercept[1] = max(x1,pEdge->x);
}
else
{
pEdge->XIntercept[0] = pEdge->x;
pEdge->XIntercept[1] = pEdge->x;
}
// We should require exactly 1 step to step onto next scanline...
ASSERT((pEdge->ErrorMax-pEdge->Error-1) / pEdge->absdy == 0);
pEdge->x += pEdge->XDirection;
pEdge->Error += pEdge->absdy;
ASSERT(pEdge->Error >= pEdge->ErrorMax);
// Now step onto next scanline...
pEdge->Error -= pEdge->absdx;
pEdge->y++;
} }
else else // Then this is a y-major line
{ {
pEdge->XIntercept[0] = pEdge->x; pEdge->XIntercept[0] = pEdge->x;
pEdge->XIntercept[1] = pEdge->x; pEdge->XIntercept[1] = pEdge->x;
pEdge->Error += pEdge->absdx;
pEdge->y++;
if (pEdge->Error >= pEdge->ErrorMax)
{
pEdge->Error -= pEdge->ErrorMax;
pEdge->x += pEdge->XDirection;
ASSERT ( pEdge->Error < pEdge->ErrorMax );
}
} }
// We should require exactly 1 step to step onto next scanline... //DPRINT("Line (%d, %d) to (%d, %d) intersects scanline %d at (%d,%d)\n",
ASSERT ( (pEdge->ErrorMax-pEdge->Error-1) / pEdge->absdy == 0 ); // pEdge->FromX, pEdge->FromY, pEdge->ToX, pEdge->ToY, Scanline, pEdge->XIntercept[0], pEdge->XIntercept[1] );
pEdge->x += pEdge->XDirection;
pEdge->Error += pEdge->absdy;
ASSERT ( pEdge->Error >= pEdge->ErrorMax );
// Now step onto next scanline...
pEdge->Error -= pEdge->absdx;
pEdge->y++;
}
else // Then this is a y-major line
{
pEdge->XIntercept[0] = pEdge->x;
pEdge->XIntercept[1] = pEdge->x;
pEdge->Error += pEdge->absdx;
pEdge->y++;
if ( pEdge->Error >= pEdge->ErrorMax )
{
pEdge->Error -= pEdge->ErrorMax;
pEdge->x += pEdge->XDirection;
ASSERT ( pEdge->Error < pEdge->ErrorMax );
}
}
//DPRINT("Line (%d, %d) to (%d, %d) intersects scanline %d at (%d,%d)\n",
// pEdge->FromX, pEdge->FromY, pEdge->ToX, pEdge->ToY, Scanline, pEdge->XIntercept[0], pEdge->XIntercept[1] );
} }
/* /*
@ -352,22 +357,25 @@ POLYGONFILL_UpdateScanline(FILL_EDGE* pEdge, int Scanline)
static static
void void
APIENTRY APIENTRY
POLYGONFILL_BuildActiveList ( int Scanline, FILL_EDGE_LIST* list, FILL_EDGE** ActiveHead ) POLYGONFILL_BuildActiveList(
int Scanline,
FILL_EDGE_LIST* list,
FILL_EDGE** ActiveHead)
{ {
int i; int i;
ASSERT ( list && ActiveHead ); ASSERT(list && ActiveHead);
*ActiveHead = 0; *ActiveHead = 0;
for ( i = 0; i < list->Count; i++ ) for (i = 0; i < list->Count; i++)
{
FILL_EDGE* pEdge = list->Edges[i];
ASSERT(pEdge);
if ( pEdge->FromY <= Scanline && pEdge->ToY > Scanline )
{ {
POLYGONFILL_UpdateScanline ( pEdge, Scanline ); FILL_EDGE* pEdge = list->Edges[i];
POLYGONFILL_ActiveListInsert ( ActiveHead, pEdge ); ASSERT(pEdge);
if (pEdge->FromY <= Scanline && pEdge->ToY > Scanline)
{
POLYGONFILL_UpdateScanline(pEdge, Scanline);
POLYGONFILL_ActiveListInsert(ActiveHead, pEdge);
}
} }
}
} }
/* /*
@ -378,140 +386,141 @@ static
void void
APIENTRY APIENTRY
POLYGONFILL_FillScanLineAlternate( POLYGONFILL_FillScanLineAlternate(
PDC dc, PDC dc,
int ScanLine, int ScanLine,
FILL_EDGE* ActiveHead, FILL_EDGE* ActiveHead,
SURFACE *psurf, SURFACE *psurf,
BRUSHOBJ *BrushObj, BRUSHOBJ *BrushObj,
MIX RopMode ) MIX RopMode )
{ {
FILL_EDGE *pLeft, *pRight; FILL_EDGE *pLeft, *pRight;
if ( !ActiveHead ) if (!ActiveHead)
return; return;
pLeft = ActiveHead; pLeft = ActiveHead;
pRight = pLeft->pNext; pRight = pLeft->pNext;
ASSERT(pRight); ASSERT(pRight);
while ( NULL != pRight ) while (NULL != pRight)
{
int x1 = pLeft->XIntercept[0];
int x2 = pRight->XIntercept[1];
if ( x2 > x1 )
{ {
RECTL BoundRect; int x1 = pLeft->XIntercept[0];
BoundRect.top = ScanLine; int x2 = pRight->XIntercept[1];
BoundRect.bottom = ScanLine + 1; if (x2 > x1)
BoundRect.left = x1; {
BoundRect.right = x2; RECTL BoundRect;
BoundRect.top = ScanLine;
BoundRect.bottom = ScanLine + 1;
BoundRect.left = x1;
BoundRect.right = x2;
//DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); //DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
IntEngLineTo(&psurf->SurfObj, IntEngLineTo(&psurf->SurfObj,
&dc->co.ClipObj, &dc->co.ClipObj,
BrushObj, BrushObj,
x1, x1,
ScanLine, ScanLine,
x2, x2,
ScanLine, ScanLine,
&BoundRect, // Bounding rectangle &BoundRect, // Bounding rectangle
RopMode); // MIX RopMode); // MIX
}
pLeft = pRight->pNext;
pRight = pLeft ? pLeft->pNext : NULL;
} }
pLeft = pRight->pNext;
pRight = pLeft ? pLeft->pNext : NULL;
}
} }
static static
void void
APIENTRY APIENTRY
POLYGONFILL_FillScanLineWinding( POLYGONFILL_FillScanLineWinding(
PDC dc, PDC dc,
int ScanLine, int ScanLine,
FILL_EDGE* ActiveHead, FILL_EDGE* ActiveHead,
SURFACE *psurf, SURFACE *psurf,
BRUSHOBJ *BrushObj, BRUSHOBJ *BrushObj,
MIX RopMode ) MIX RopMode )
{ {
FILL_EDGE *pLeft, *pRight; FILL_EDGE *pLeft, *pRight;
int x1, x2, winding = 0; int x1, x2, winding = 0;
RECTL BoundRect; RECTL BoundRect;
if ( !ActiveHead ) if (!ActiveHead)
return; return;
BoundRect.top = ScanLine; BoundRect.top = ScanLine;
BoundRect.bottom = ScanLine + 1; BoundRect.bottom = ScanLine + 1;
pLeft = ActiveHead; pLeft = ActiveHead;
winding = pLeft->YDirection; winding = pLeft->YDirection;
pRight = pLeft->pNext; pRight = pLeft->pNext;
ASSERT(pRight); ASSERT(pRight);
// Setup first line... // Setup first line...
x1 = pLeft->XIntercept[0]; x1 = pLeft->XIntercept[0];
x2 = pRight->XIntercept[1]; x2 = pRight->XIntercept[1];
pLeft = pRight;
pRight = pLeft->pNext;
winding += pLeft->YDirection;
while ( NULL != pRight )
{
int newx1 = pLeft->XIntercept[0];
int newx2 = pRight->XIntercept[1];
if ( winding )
{
// Check and see if this new line touches the previous...
if ( (newx1 >= x1 && newx1 <= x2)
|| (newx2 >= x1 && newx2 <= x2)
|| (x1 >= newx1 && x1 <= newx2)
|| (x2 >= newx2 && x2 <= newx2)
)
{
// Yup, just tack it on to our existing line
x1 = min(x1,newx1);
x2 = max(x2,newx2);
}
else
{
// Nope - render the old line..
BoundRect.left = x1;
BoundRect.right = x2;
//DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
IntEngLineTo(&psurf->SurfObj,
&dc->co.ClipObj,
BrushObj,
x1,
ScanLine,
x2,
ScanLine,
&BoundRect, // Bounding rectangle
RopMode); // MIX
x1 = newx1;
x2 = newx2;
}
}
pLeft = pRight; pLeft = pRight;
pRight = pLeft->pNext; pRight = pLeft->pNext;
winding += pLeft->YDirection; winding += pLeft->YDirection;
}
// There will always be a line left-over, render it now...
BoundRect.left = x1;
BoundRect.right = x2;
//DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine); while ( NULL != pRight )
IntEngLineTo(&psurf->SurfObj, {
&dc->co.ClipObj, int newx1 = pLeft->XIntercept[0];
BrushObj, int newx2 = pRight->XIntercept[1];
x1, if ( winding )
ScanLine, {
x2, // Check and see if this new line touches the previous...
ScanLine, if ((newx1 >= x1 && newx1 <= x2) ||
&BoundRect, // Bounding rectangle (newx2 >= x1 && newx2 <= x2) ||
RopMode); // MIX (x1 >= newx1 && x1 <= newx2) ||
(x2 >= newx2 && x2 <= newx2))
{
// Yup, just tack it on to our existing line
x1 = min(x1,newx1);
x2 = max(x2,newx2);
}
else
{
// Nope - render the old line..
BoundRect.left = x1;
BoundRect.right = x2;
//DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
IntEngLineTo(&psurf->SurfObj,
&dc->co.ClipObj,
BrushObj,
x1,
ScanLine,
x2,
ScanLine,
&BoundRect, // Bounding rectangle
RopMode); // MIX
x1 = newx1;
x2 = newx2;
}
}
pLeft = pRight;
pRight = pLeft->pNext;
winding += pLeft->YDirection;
}
// There will always be a line left-over, render it now...
BoundRect.left = x1;
BoundRect.right = x2;
//DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
IntEngLineTo(&psurf->SurfObj,
&dc->co.ClipObj,
BrushObj,
x1,
ScanLine,
x2,
ScanLine,
&BoundRect, // Bounding rectangle
RopMode); // MIX
} }
// When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and // When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
@ -526,54 +535,54 @@ POLYGONFILL_FillScanLineWinding(
BOOL BOOL
APIENTRY APIENTRY
FillPolygon( FillPolygon(
PDC dc,
SURFACE *psurf,
BRUSHOBJ *BrushObj,
MIX RopMode,
CONST PPOINT Points,
int Count,
RECTL BoundRect )
{
FILL_EDGE_LIST *list = 0;
FILL_EDGE *ActiveHead = 0;
int ScanLine;
PDC_ATTR pdcattr = dc->pdcattr;
void
(APIENTRY *FillScanLine)(
PDC dc, PDC dc,
int ScanLine,
FILL_EDGE* ActiveHead,
SURFACE *psurf, SURFACE *psurf,
BRUSHOBJ *BrushObj, BRUSHOBJ *BrushObj,
MIX RopMode ); MIX RopMode,
CONST PPOINT Points,
int Count,
RECTL BoundRect )
{
FILL_EDGE_LIST *list = 0;
FILL_EDGE *ActiveHead = 0;
int ScanLine;
PDC_ATTR pdcattr = dc->pdcattr;
void
(APIENTRY *FillScanLine)(
PDC dc,
int ScanLine,
FILL_EDGE* ActiveHead,
SURFACE *psurf,
BRUSHOBJ *BrushObj,
MIX RopMode);
//DPRINT("FillPolygon\n"); //DPRINT("FillPolygon\n");
/* Create Edge List. */ /* Create Edge List. */
list = POLYGONFILL_MakeEdgeList(Points, Count); list = POLYGONFILL_MakeEdgeList(Points, Count);
/* DEBUG_PRINT_EDGELIST(list); */ /* DEBUG_PRINT_EDGELIST(list); */
if (NULL == list) if (NULL == list)
return FALSE; return FALSE;
if ( WINDING == pdcattr->jFillMode ) if (WINDING == pdcattr->jFillMode)
FillScanLine = POLYGONFILL_FillScanLineWinding; FillScanLine = POLYGONFILL_FillScanLineWinding;
else /* Default */ else /* Default */
FillScanLine = POLYGONFILL_FillScanLineAlternate; FillScanLine = POLYGONFILL_FillScanLineAlternate;
/* For each Scanline from BoundRect.bottom to BoundRect.top, /* For each Scanline from BoundRect.bottom to BoundRect.top,
* determine line segments to draw * determine line segments to draw
*/ */
for ( ScanLine = BoundRect.top; ScanLine < BoundRect.bottom; ++ScanLine ) for (ScanLine = BoundRect.top; ScanLine < BoundRect.bottom; ++ScanLine)
{ {
POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead); POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead);
//DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead); //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);
FillScanLine ( dc, ScanLine, ActiveHead, psurf, BrushObj, RopMode ); FillScanLine(dc, ScanLine, ActiveHead, psurf, BrushObj, RopMode);
} }
/* Free Edge List. If any are left. */ /* Free Edge List. If any are left. */
POLYGONFILL_DestroyEdgeList(list); POLYGONFILL_DestroyEdgeList(list);
return TRUE; return TRUE;
} }
BOOL FASTCALL BOOL FASTCALL
@ -600,23 +609,24 @@ IntFillPolygon(
return FALSE; return FALSE;
/* For each Scanline from DestRect.top to DestRect.bottom, determine line segments to draw */ /* For each Scanline from DestRect.top to DestRect.bottom, determine line segments to draw */
for ( ScanLine = DestRect.top; ScanLine < DestRect.bottom; ++ScanLine ) for (ScanLine = DestRect.top; ScanLine < DestRect.bottom; ++ScanLine)
{ {
POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead); POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead);
//DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead); //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);
if ( !ActiveHead ) if (!ActiveHead)
return FALSE; return FALSE;
pLeft = ActiveHead; pLeft = ActiveHead;
pRight = pLeft->pNext; pRight = pLeft->pNext;
ASSERT(pRight); ASSERT(pRight);
while ( NULL != pRight ) while (NULL != pRight)
{ {
int x1 = pLeft->XIntercept[0]; int x1 = pLeft->XIntercept[0];
int x2 = pRight->XIntercept[1]; int x2 = pRight->XIntercept[1];
if ( x2 > x1 )
if (x2 > x1)
{ {
RECTL LineRect; RECTL LineRect;
LineRect.top = ScanLine; LineRect.top = ScanLine;
@ -625,17 +635,18 @@ IntFillPolygon(
LineRect.right = x2; LineRect.right = x2;
IntEngBitBlt(&psurf->SurfObj, IntEngBitBlt(&psurf->SurfObj,
NULL, NULL,
NULL, NULL,
&dc->co.ClipObj, &dc->co.ClipObj,
NULL, NULL,
&LineRect, &LineRect,
NULL, NULL,
NULL, NULL,
BrushObj, BrushObj,
BrushOrigin, BrushOrigin,
ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY)); ROP4_FROM_INDEX(R3_OPINDEX_PATCOPY));
} }
pLeft = pRight->pNext; pLeft = pRight->pNext;
pRight = pLeft ? pLeft->pNext : NULL; pRight = pLeft ? pLeft->pNext : NULL;
} }