mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:23:07 +00:00
[WIN32K]
Apply proper formatting to polyfill.c svn path=/trunk/; revision=66645
This commit is contained in:
parent
fe4dc5d9d5
commit
42587dd1d3
1 changed files with 389 additions and 378 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue