ReactOS  0.4.15-dev-1201-gb2cf5a4
polyfill.c File Reference
#include <win32k.h>
#include <debug.h>
Include dependency graph for polyfill.c:

Go to the source code of this file.

Classes

struct  _tagFILL_EDGE
 
struct  _FILL_EDGE_LIST
 

Macros

#define NDEBUG
 
#define FILL_EDGE_ALLOC_TAG   0x45465044
 
#define DEBUG_PRINT_ACTIVE_EDGELIST(x)
 

Typedefs

typedef struct _tagFILL_EDGE FILL_EDGE
 
typedef struct _FILL_EDGE_LIST FILL_EDGE_LIST
 

Functions

static void FASTCALL POLYGONFILL_DestroyEdgeList (FILL_EDGE_LIST *list)
 
static FILL_EDGE *FASTCALL POLYGONFILL_MakeEdge (POINT From, POINT To)
 
static INT FASTCALL FILL_EDGE_Compare (FILL_EDGE *Edge1, FILL_EDGE *Edge2)
 
static void FASTCALL POLYGONFILL_ActiveListInsert (FILL_EDGE **activehead, FILL_EDGE *NewEdge)
 
static FILL_EDGE_LIST *FASTCALL POLYGONFILL_MakeEdgeList (PPOINT Points, int Count)
 
static void FASTCALL POLYGONFILL_UpdateScanline (FILL_EDGE *pEdge, int Scanline)
 
static void APIENTRY POLYGONFILL_BuildActiveList (int Scanline, FILL_EDGE_LIST *list, FILL_EDGE **ActiveHead)
 
static void APIENTRY POLYGONFILL_FillScanLineAlternate (PDC dc, int ScanLine, FILL_EDGE *ActiveHead, SURFACE *psurf, BRUSHOBJ *BrushObj, MIX RopMode)
 
static void APIENTRY POLYGONFILL_FillScanLineWinding (PDC dc, int ScanLine, FILL_EDGE *ActiveHead, SURFACE *psurf, BRUSHOBJ *BrushObj, MIX RopMode)
 
BOOL APIENTRY FillPolygon (PDC dc, SURFACE *psurf, BRUSHOBJ *BrushObj, MIX RopMode, CONST PPOINT Points, int Count, RECTL BoundRect)
 
BOOL FASTCALL IntFillPolygon (PDC dc, SURFACE *psurf, BRUSHOBJ *BrushObj, CONST PPOINT Points, int Count, RECTL DestRect, POINTL *BrushOrigin)
 

Macro Definition Documentation

◆ DEBUG_PRINT_ACTIVE_EDGELIST

#define DEBUG_PRINT_ACTIVE_EDGELIST (   x)

Definition at line 68 of file polyfill.c.

◆ FILL_EDGE_ALLOC_TAG

#define FILL_EDGE_ALLOC_TAG   0x45465044

Definition at line 14 of file polyfill.c.

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file polyfill.c.

Typedef Documentation

◆ FILL_EDGE

◆ FILL_EDGE_LIST

Function Documentation

◆ FILL_EDGE_Compare()

static INT FASTCALL FILL_EDGE_Compare ( FILL_EDGE Edge1,
FILL_EDGE Edge2 
)
static

Definition at line 176 of file polyfill.c.

177 {
178  int e1 = Edge1->XIntercept[0] + Edge1->XIntercept[1];
179  int e2 = Edge2->XIntercept[0] + Edge2->XIntercept[1];
180 
181  return e1 - e2;
182 }
int XIntercept[2]
Definition: polytest.cpp:186

Referenced by POLYGONFILL_ActiveListInsert().

◆ FillPolygon()

BOOL APIENTRY FillPolygon ( PDC  dc,
SURFACE psurf,
BRUSHOBJ BrushObj,
MIX  RopMode,
CONST PPOINT  Points,
int  Count,
RECTL  BoundRect 
)

Definition at line 538 of file polyfill.c.

546 {
547  FILL_EDGE_LIST *list = 0;
548  FILL_EDGE *ActiveHead = 0;
549  int ScanLine;
550  PDC_ATTR pdcattr = dc->pdcattr;
551  void
552  (APIENTRY *FillScanLine)(
553  PDC dc,
554  int ScanLine,
555  FILL_EDGE* ActiveHead,
556  SURFACE *psurf,
557  BRUSHOBJ *BrushObj,
558  MIX RopMode);
559 
560  //DPRINT("FillPolygon\n");
561 
562  /* Create Edge List. */
564  /* DEBUG_PRINT_EDGELIST(list); */
565  if (NULL == list)
566  return FALSE;
567 
568  if (WINDING == pdcattr->jFillMode)
569  FillScanLine = POLYGONFILL_FillScanLineWinding;
570  else /* Default */
571  FillScanLine = POLYGONFILL_FillScanLineAlternate;
572 
573  /* For each Scanline from BoundRect.bottom to BoundRect.top,
574  * determine line segments to draw
575  */
576  for (ScanLine = BoundRect.top; ScanLine < BoundRect.bottom; ++ScanLine)
577  {
578  POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead);
579  //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);
580  FillScanLine(dc, ScanLine, ActiveHead, psurf, BrushObj, RopMode);
581  }
582 
583  /* Free Edge List. If any are left. */
585 
586  return TRUE;
587 }
#define WINDING
Definition: constants.h:279
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
ULONG MIX
Definition: winddi.h:129
#define TRUE
Definition: types.h:120
static FILL_EDGE_LIST *FASTCALL POLYGONFILL_MakeEdgeList(PPOINT Points, int Count)
Definition: polyfill.c:236
long bottom
Definition: polytest.cpp:53
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
static void APIENTRY POLYGONFILL_BuildActiveList(int Scanline, FILL_EDGE_LIST *list, FILL_EDGE **ActiveHead)
Definition: polyfill.c:361
#define FALSE
Definition: types.h:117
long top
Definition: polytest.cpp:53
smooth NULL
Definition: ftsmooth.c:416
static void APIENTRY POLYGONFILL_FillScanLineAlternate(PDC dc, int ScanLine, FILL_EDGE *ActiveHead, SURFACE *psurf, BRUSHOBJ *BrushObj, MIX RopMode)
Definition: polyfill.c:389
Definition: polytest.cpp:40
static void FASTCALL POLYGONFILL_DestroyEdgeList(FILL_EDGE_LIST *list)
Definition: polyfill.c:77
BYTE jFillMode
Definition: ntgdihdl.h:313
Definition: _list.h:228
static const WCHAR dc[]
static void APIENTRY POLYGONFILL_FillScanLineWinding(PDC dc, int ScanLine, FILL_EDGE *ActiveHead, SURFACE *psurf, BRUSHOBJ *BrushObj, MIX RopMode)
Definition: polyfill.c:437
#define APIENTRY
Definition: api.h:79

◆ IntFillPolygon()

BOOL FASTCALL IntFillPolygon ( PDC  dc,
SURFACE psurf,
BRUSHOBJ BrushObj,
CONST PPOINT  Points,
int  Count,
RECTL  DestRect,
POINTL BrushOrigin 
)

Definition at line 590 of file polyfill.c.

598 {
599  FILL_EDGE_LIST *list = 0;
600  FILL_EDGE *ActiveHead = 0;
601  FILL_EDGE *pLeft, *pRight;
602  int ScanLine;
603 
604  //DPRINT("IntFillPolygon\n");
605 
606  /* Create Edge List. */
608  /* DEBUG_PRINT_EDGELIST(list); */
609  if (NULL == list)
610  return FALSE;
611 
612  /* For each Scanline from DestRect.top to DestRect.bottom, determine line segments to draw */
613  for (ScanLine = DestRect.top; ScanLine < DestRect.bottom; ++ScanLine)
614  {
615  POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead);
616  //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);
617 
618  if (!ActiveHead)
619  {
621  return FALSE;
622  }
623 
624  pLeft = ActiveHead;
625  pRight = pLeft->pNext;
626  ASSERT(pRight);
627 
628  while (NULL != pRight)
629  {
630  int x1 = pLeft->XIntercept[0];
631  int x2 = pRight->XIntercept[1];
632 
633  if (x2 > x1)
634  {
635  RECTL LineRect;
636  LineRect.top = ScanLine;
637  LineRect.bottom = ScanLine + 1;
638  LineRect.left = x1;
639  LineRect.right = x2;
640 
641  IntEngBitBlt(&psurf->SurfObj,
642  NULL,
643  NULL,
644  (CLIPOBJ *)&dc->co,
645  NULL,
646  &LineRect,
647  NULL,
648  NULL,
649  BrushObj,
650  BrushOrigin,
652  }
653 
654  pLeft = pRight->pNext;
655  pRight = pLeft ? pLeft->pNext : NULL;
656  }
657  }
658 
659  /* Free Edge List. If any are left. */
661 
662  return TRUE;
663 }
#define TRUE
Definition: types.h:120
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
static FILL_EDGE_LIST *FASTCALL POLYGONFILL_MakeEdgeList(PPOINT Points, int Count)
Definition: polyfill.c:236
long bottom
Definition: polytest.cpp:53
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
static void APIENTRY POLYGONFILL_BuildActiveList(int Scanline, FILL_EDGE_LIST *list, FILL_EDGE **ActiveHead)
Definition: polyfill.c:361
int XIntercept[2]
Definition: polytest.cpp:186
long right
Definition: polytest.cpp:53
#define FALSE
Definition: types.h:117
long top
Definition: polytest.cpp:53
SURFOBJ SurfObj
Definition: surface.h:8
smooth NULL
Definition: ftsmooth.c:416
long left
Definition: polytest.cpp:53
static void FASTCALL POLYGONFILL_DestroyEdgeList(FILL_EDGE_LIST *list)
Definition: polyfill.c:77
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: _list.h:228
struct _tagFILL_EDGE * pNext
Definition: polytest.cpp:192
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
static const WCHAR dc[]
#define ROP4_FROM_INDEX(index)
Definition: inteng.h:42
BOOL APIENTRY IntEngBitBlt(SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 Rop4)
Definition: bitblt.c:604

Referenced by IntGdiPolygon().

◆ POLYGONFILL_ActiveListInsert()

static void FASTCALL POLYGONFILL_ActiveListInsert ( FILL_EDGE **  activehead,
FILL_EDGE NewEdge 
)
static

Definition at line 191 of file polyfill.c.

192 {
193  FILL_EDGE *pPrev, *pThis;
194  //DPRINT1("In POLYGONFILL_ActiveListInsert()\n");
195  ASSERT(activehead && NewEdge);
196 
197  if (!*activehead)
198  {
199  NewEdge->pNext = NULL;
200  *activehead = NewEdge;
201  return;
202  }
203  /*
204  ** First lets check to see if we have a new smallest value.
205  */
206  if (FILL_EDGE_Compare(NewEdge, *activehead) <= 0)
207  {
208  NewEdge->pNext = *activehead;
209  *activehead = NewEdge;
210  return;
211  }
212 
213  /*
214  ** Ok, now scan to the next spot to put this item.
215  */
216  pThis = *activehead;
217  pPrev = NULL;
218  while ( pThis && FILL_EDGE_Compare(pThis, NewEdge) < 0 )
219  {
220  pPrev = pThis;
221  pThis = pThis->pNext;
222  }
223 
224  ASSERT(pPrev);
225  NewEdge->pNext = pPrev->pNext;
226  pPrev->pNext = NewEdge;
227  //DEBUG_PRINT_ACTIVE_EDGELIST(*activehead);
228 }
smooth NULL
Definition: ftsmooth.c:416
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _tagFILL_EDGE * pNext
Definition: polytest.cpp:192
static INT FASTCALL FILL_EDGE_Compare(FILL_EDGE *Edge1, FILL_EDGE *Edge2)
Definition: polyfill.c:176

Referenced by POLYGONFILL_BuildActiveList().

◆ POLYGONFILL_BuildActiveList()

static void APIENTRY POLYGONFILL_BuildActiveList ( int  Scanline,
FILL_EDGE_LIST list,
FILL_EDGE **  ActiveHead 
)
static

Definition at line 361 of file polyfill.c.

365 {
366  int i;
367 
368  ASSERT(list && ActiveHead);
369  *ActiveHead = 0;
370  for (i = 0; i < list->Count; i++)
371  {
372  FILL_EDGE* pEdge = list->Edges[i];
373  ASSERT(pEdge);
374  if (pEdge->FromY <= Scanline && pEdge->ToY > Scanline)
375  {
376  POLYGONFILL_UpdateScanline(pEdge, Scanline);
377  POLYGONFILL_ActiveListInsert(ActiveHead, pEdge);
378  }
379  }
380 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void FASTCALL POLYGONFILL_UpdateScanline(FILL_EDGE *pEdge, int Scanline)
Definition: polyfill.c:294
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static void FASTCALL POLYGONFILL_ActiveListInsert(FILL_EDGE **activehead, FILL_EDGE *NewEdge)
Definition: polyfill.c:191
Definition: _list.h:228

Referenced by FillPolygon(), and IntFillPolygon().

◆ POLYGONFILL_DestroyEdgeList()

static void FASTCALL POLYGONFILL_DestroyEdgeList ( FILL_EDGE_LIST list)
static

Definition at line 77 of file polyfill.c.

78 {
79  int i;
80 
81  if (list)
82  {
83  if (list->Edges)
84  {
85  for (i = 0; i < list->Count; i++)
86  {
88  if (list->Edges[i])
89  EngFreeMem(list->Edges[i]);
90  }
91 
92  EngFreeMem(list->Edges);
93  }
94 
96  }
97 }
#define EngFreeMem
Definition: polytest.cpp:56
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: _list.h:228
#define __WARNING_USING_UNINIT_VAR
Definition: suppress.h:31
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28

Referenced by FillPolygon(), IntFillPolygon(), and POLYGONFILL_MakeEdgeList().

◆ POLYGONFILL_FillScanLineAlternate()

static void APIENTRY POLYGONFILL_FillScanLineAlternate ( PDC  dc,
int  ScanLine,
FILL_EDGE ActiveHead,
SURFACE psurf,
BRUSHOBJ BrushObj,
MIX  RopMode 
)
static

Definition at line 389 of file polyfill.c.

396 {
397  FILL_EDGE *pLeft, *pRight;
398 
399  if (!ActiveHead)
400  return;
401 
402  pLeft = ActiveHead;
403  pRight = pLeft->pNext;
404  ASSERT(pRight);
405 
406  while (NULL != pRight)
407  {
408  int x1 = pLeft->XIntercept[0];
409  int x2 = pRight->XIntercept[1];
410  if (x2 > x1)
411  {
412  RECTL BoundRect;
413  BoundRect.top = ScanLine;
414  BoundRect.bottom = ScanLine + 1;
415  BoundRect.left = x1;
416  BoundRect.right = x2;
417 
418  //DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
419  IntEngLineTo(&psurf->SurfObj,
420  (CLIPOBJ *)&dc->co,
421  BrushObj,
422  x1,
423  ScanLine,
424  x2,
425  ScanLine,
426  &BoundRect, // Bounding rectangle
427  RopMode); // MIX
428  }
429  pLeft = pRight->pNext;
430  pRight = pLeft ? pLeft->pNext : NULL;
431  }
432 }
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
long bottom
Definition: polytest.cpp:53
int XIntercept[2]
Definition: polytest.cpp:186
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
SURFOBJ SurfObj
Definition: surface.h:8
smooth NULL
Definition: ftsmooth.c:416
long left
Definition: polytest.cpp:53
void IntEngLineTo(SURFOBJ *, CLIPOBJ, PBRUSHOBJ, int x1, int y1, int x2, int y2, RECTL *, MIX mix)
Definition: polytest.cpp:107
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _tagFILL_EDGE * pNext
Definition: polytest.cpp:192
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
static const WCHAR dc[]

Referenced by FillPolygon().

◆ POLYGONFILL_FillScanLineWinding()

static void APIENTRY POLYGONFILL_FillScanLineWinding ( PDC  dc,
int  ScanLine,
FILL_EDGE ActiveHead,
SURFACE psurf,
BRUSHOBJ BrushObj,
MIX  RopMode 
)
static

Definition at line 437 of file polyfill.c.

444 {
445  FILL_EDGE *pLeft, *pRight;
446  int x1, x2, winding = 0;
447  RECTL BoundRect;
448 
449  if (!ActiveHead)
450  return;
451 
452  BoundRect.top = ScanLine;
453  BoundRect.bottom = ScanLine + 1;
454 
455  pLeft = ActiveHead;
456  winding = pLeft->YDirection;
457  pRight = pLeft->pNext;
458  ASSERT(pRight);
459 
460  // Setup first line...
461  x1 = pLeft->XIntercept[0];
462  x2 = pRight->XIntercept[1];
463 
464  pLeft = pRight;
465  pRight = pLeft->pNext;
466  winding += pLeft->YDirection;
467 
468  while ( NULL != pRight )
469  {
470  int newx1 = pLeft->XIntercept[0];
471  int newx2 = pRight->XIntercept[1];
472  if ( winding )
473  {
474  // Check and see if this new line touches the previous...
475  if ((newx1 >= x1 && newx1 <= x2) ||
476  (newx2 >= x1 && newx2 <= x2) ||
477  (x1 >= newx1 && x1 <= newx2) ||
478  (x2 >= newx2 && x2 <= newx2))
479  {
480  // Yup, just tack it on to our existing line
481  x1 = min(x1,newx1);
482  x2 = max(x2,newx2);
483  }
484  else
485  {
486  // Nope - render the old line..
487  BoundRect.left = x1;
488  BoundRect.right = x2;
489 
490  //DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
491  IntEngLineTo(&psurf->SurfObj,
492  (CLIPOBJ *)&dc->co,
493  BrushObj,
494  x1,
495  ScanLine,
496  x2,
497  ScanLine,
498  &BoundRect, // Bounding rectangle
499  RopMode); // MIX
500 
501  x1 = newx1;
502  x2 = newx2;
503  }
504  }
505 
506  pLeft = pRight;
507  pRight = pLeft->pNext;
508  winding += pLeft->YDirection;
509  }
510 
511  // There will always be a line left-over, render it now...
512  BoundRect.left = x1;
513  BoundRect.right = x2;
514 
515  //DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
516  IntEngLineTo(&psurf->SurfObj,
517  (CLIPOBJ *)&dc->co,
518  BrushObj,
519  x1,
520  ScanLine,
521  x2,
522  ScanLine,
523  &BoundRect, // Bounding rectangle
524  RopMode); // MIX
525 }
#define max(a, b)
Definition: svc.c:63
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
long bottom
Definition: polytest.cpp:53
int XIntercept[2]
Definition: polytest.cpp:186
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
SURFOBJ SurfObj
Definition: surface.h:8
smooth NULL
Definition: ftsmooth.c:416
long left
Definition: polytest.cpp:53
void IntEngLineTo(SURFOBJ *, CLIPOBJ, PBRUSHOBJ, int x1, int y1, int x2, int y2, RECTL *, MIX mix)
Definition: polytest.cpp:107
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _tagFILL_EDGE * pNext
Definition: polytest.cpp:192
#define min(a, b)
Definition: monoChain.cc:55
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
static const WCHAR dc[]

Referenced by FillPolygon().

◆ POLYGONFILL_MakeEdge()

static FILL_EDGE* FASTCALL POLYGONFILL_MakeEdge ( POINT  From,
POINT  To 
)
static

Definition at line 105 of file polyfill.c.

106 {
108 
109  if (0 == rc)
110  return NULL;
111 
112  //DPRINT1("Making Edge: (%d, %d) to (%d, %d)\n", From.x, From.y, To.x, To.y);
113  // Now fill the struct.
114  if ( To.y < From.y )
115  {
116  rc->FromX = To.x;
117  rc->FromY = To.y;
118  rc->ToX = From.x;
119  rc->ToY = From.y;
120  rc->YDirection = -1;
121 
122  // Lines that go up get walked backwards, so need to be offset
123  // by -1 in order to make the walk identically on a pixel-level
124  rc->Error = -1;
125  }
126  else
127  {
128  rc->FromX = From.x;
129  rc->FromY = From.y;
130  rc->ToX = To.x;
131  rc->ToY = To.y;
132  rc->YDirection = 1;
133 
134  rc->Error = 0;
135  }
136 
137  rc->x = rc->FromX;
138  rc->y = rc->FromY;
139  rc->dx = rc->ToX - rc->FromX;
140  rc->dy = rc->ToY - rc->FromY;
141  rc->absdx = abs(rc->dx);
142  rc->absdy = abs(rc->dy);
143 
144  rc->xmajor = rc->absdx > rc->absdy;
145 
146  rc->ErrorMax = max(rc->absdx,rc->absdy);
147 
148  rc->Error += rc->ErrorMax / 2;
149 
150  rc->XDirection = (rc->dx < 0)?(-1):(1);
151 
152  rc->pNext = 0;
153 
154  //DPRINT("MakeEdge (%i,%i)->(%i,%i) d=(%i,%i) dir=(%i,%i) err=%i max=%i\n",
155  // From.x, From.y, To.x, To.y, rc->dx, rc->dy, rc->XDirection, rc->YDirection, rc->Error, rc->ErrorMax );
156 
157  return rc;
158 }
#define abs(i)
Definition: fconv.c:206
#define max(a, b)
Definition: svc.c:63
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
smooth NULL
Definition: ftsmooth.c:416
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
#define FL_ZERO_MEMORY
Definition: polytest.cpp:58
struct _tagFILL_EDGE * pNext
Definition: polytest.cpp:192
#define FILL_EDGE_ALLOC_TAG
Definition: polyfill.c:14

Referenced by POLYGONFILL_MakeEdgeList().

◆ POLYGONFILL_MakeEdgeList()

static FILL_EDGE_LIST* FASTCALL POLYGONFILL_MakeEdgeList ( PPOINT  Points,
int  Count 
)
static

Definition at line 236 of file polyfill.c.

237 {
238  int CurPt = 0;
239  FILL_EDGE_LIST* list = 0;
240  FILL_EDGE* e = 0;
241 
242  if (0 == Points || 2 > Count)
243  return 0;
244 
246  if ( 0 == list )
247  goto fail;
248  list->Count = 0;
250  if ( !list->Edges )
251  goto fail;
252 
253  memset(list->Edges, 0, Count * sizeof(FILL_EDGE*));
254 
255  for (CurPt = 1; CurPt < Count; ++CurPt)
256  {
257  e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[CurPt] );
258  if (!e)
259  goto fail;
260 
261  // If a straight horizontal line - who cares?
262  if (!e->absdy)
263  EngFreeMem(e);
264  else
265  list->Edges[list->Count++] = e;
266  }
267  e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[0] );
268  if ( !e )
269  goto fail;
270 
271  if (!e->absdy)
272  EngFreeMem(e);
273  else
274  list->Edges[list->Count++] = e;
275  return list;
276 
277 fail:
278 
279  DPRINT1("Out Of MEMORY!!\n");
281  return 0;
282 }
#define EngFreeMem
Definition: polytest.cpp:56
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
#define e
Definition: ke_i.h:82
static void FASTCALL POLYGONFILL_DestroyEdgeList(FILL_EDGE_LIST *list)
Definition: polyfill.c:77
static FILL_EDGE *FASTCALL POLYGONFILL_MakeEdge(POINT From, POINT To)
Definition: polyfill.c:105
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
#define FL_ZERO_MEMORY
Definition: polytest.cpp:58
Definition: _list.h:228
#define list
Definition: rosglue.h:35
#define DPRINT1
Definition: precomp.h:8
#define memset(x, y, z)
Definition: compat.h:39
#define FILL_EDGE_ALLOC_TAG
Definition: polyfill.c:14

Referenced by FillPolygon(), and IntFillPolygon().

◆ POLYGONFILL_UpdateScanline()

static void FASTCALL POLYGONFILL_UpdateScanline ( FILL_EDGE pEdge,
int  Scanline 
)
static

Definition at line 294 of file polyfill.c.

295 {
296  if (0 == pEdge->dy)
297  return;
298 
299  ASSERT(pEdge->FromY <= Scanline && pEdge->ToY > Scanline);
300 
301  if (pEdge->xmajor)
302  {
303  int steps;
304 
305  ASSERT(pEdge->y == Scanline);
306 
307  // Now shoot to end of scanline collision
308  steps = (pEdge->ErrorMax-pEdge->Error-1)/pEdge->absdy;
309  if (steps)
310  {
311  // Record first collision with scanline
312  int x1 = pEdge->x;
313  pEdge->x += steps * pEdge->XDirection;
314  pEdge->Error += steps * pEdge->absdy;
315  ASSERT ( pEdge->Error < pEdge->ErrorMax );
316  pEdge->XIntercept[0] = min(x1,pEdge->x);
317  pEdge->XIntercept[1] = max(x1,pEdge->x);
318  }
319  else
320  {
321  pEdge->XIntercept[0] = pEdge->x;
322  pEdge->XIntercept[1] = pEdge->x;
323  }
324 
325  // We should require exactly 1 step to step onto next scanline...
326  ASSERT((pEdge->ErrorMax-pEdge->Error-1) / pEdge->absdy == 0);
327  pEdge->x += pEdge->XDirection;
328  pEdge->Error += pEdge->absdy;
329  ASSERT(pEdge->Error >= pEdge->ErrorMax);
330 
331  // Now step onto next scanline...
332  pEdge->Error -= pEdge->absdx;
333  pEdge->y++;
334  }
335  else // Then this is a y-major line
336  {
337  pEdge->XIntercept[0] = pEdge->x;
338  pEdge->XIntercept[1] = pEdge->x;
339 
340  pEdge->Error += pEdge->absdx;
341  pEdge->y++;
342 
343  if (pEdge->Error >= pEdge->ErrorMax)
344  {
345  pEdge->Error -= pEdge->ErrorMax;
346  pEdge->x += pEdge->XDirection;
347  ASSERT ( pEdge->Error < pEdge->ErrorMax );
348  }
349  }
350 
351  //DPRINT("Line (%d, %d) to (%d, %d) intersects scanline %d at (%d,%d)\n",
352  // pEdge->FromX, pEdge->FromY, pEdge->ToX, pEdge->ToY, Scanline, pEdge->XIntercept[0], pEdge->XIntercept[1] );
353 }
#define max(a, b)
Definition: svc.c:63
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
int XIntercept[2]
Definition: polytest.cpp:186
static DWORD DWORD DWORD DWORD * steps
Definition: cursoricon.c:1638
if(!(yy_init))
Definition: macro.lex.yy.c:714
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define min(a, b)
Definition: monoChain.cc:55

Referenced by POLYGONFILL_BuildActiveList().