ReactOS  0.4.14-dev-52-g6116262
polytest.cpp
Go to the documentation of this file.
1 // this is a little 'sandbox' application I put together that duplicates
2 // the 'guts' of the Polygon algorithm. It allows for quick turn-around
3 // in testing the algorithm to see what effect your changes have.
4 //
5 // Royce3
6 
7 // the stuff immediately following is support so that the sandbox code
8 // is nearly identical to the real thing.
9 // search for the _tagFILL_EDGE struct to find the beginning of the
10 // real stuff.
11 
12 #include <memory.h>
13 #include <malloc.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <conio.h>
17 #include <assert.h>
18 
19 #define FASTCALL
20 #define INT int
21 #define CLIPOBJ int
22 #define SURFOBJ int
23 #define PBRUSHOBJ int
24 #define MIX char
25 #define BOOL bool
26 #define TRUE true
27 #define FALSE false
28 #define CONST const
29 #define MmCopyFromCaller memmove
30 #define ALTERNATE 0
31 #define WINDING 1
32 
33 #define ASSERT assert
34 
35 typedef struct W
36 {
38 } W;
39 
40 typedef struct DC
41 {
43  W w;
44 } DC, *PDC;
45 
46 typedef struct tagPOINT
47 {
48  long x, y;
49 } POINT, *PPOINT, *LPPOINT;
50 
51 typedef struct RECTL
52 {
53  long left, top, right, bottom;
54 } RECTL, *PRECTL;
55 
56 #define EngFreeMem free
57 
58 #define FL_ZERO_MEMORY 1
59 
60 #define DPRINT1 printf("%i:",__LINE__);printf
61 inline void DPRINT(...){}
62 
63 #define SCREENX 25
64 #define SCREENY 15
66 
67 #define EDGE_CHAR '*'
68 #define FILL_CHAR 'o'
69 
70 void* EngAllocMem ( int zero, unsigned long size, int tag=0 )
71 {
72  void* p = malloc ( size );
73  if ( zero )
74  memset ( p, 0, size );
75  return p;
76 }
77 
78 template <class T>
79 inline T MIN ( T a, T b )
80 {
81  return a < b ? a : b;
82 }
83 
84 template <class T>
85 inline T MAX ( T a, T b )
86 {
87  return a > b ? a : b;
88 }
89 
90 template <class T>
91 inline T abs ( T t )
92 {
93  return t < 0 ? -t : t;
94 }
95 
96 void putpixel ( int x, int y, char c )
97 {
98  ASSERT( x >= 0 && x < SCREENX && y >= 0 && y < SCREENY );
99  if ( screen[y][x] == c )
100  return;
101  if ( screen[y][x] == ' ' )
102  screen[y][x] = c;
103  else
104  screen[y][x] = '#';
105 }
106 
108  SURFOBJ*,
109  CLIPOBJ,
110  PBRUSHOBJ,
111  int x1, int y1, int x2, int y2,
112  RECTL*,
113  MIX mix )
114 {
115  int dx = x2 - x1;
116  int dy = y2 - y1;
117  int absdx = abs(dx);
118  int absdy = abs(dy);
119  int EMax = MAX(absdx,absdy);
120  int E = EMax/2;
121  int xinc = dx < 0 ? -1 : 1,
122  yinc = dy < 0 ? -1 : 1;
123  if ( !dy )
124  {
125  while ( x1 != x2 )
126  {
127  putpixel ( x1, y1, mix );
128  x1 += xinc;
129  }
130  return;
131  }
132  if ( !dx )
133  {
134  while ( y1 != y2 )
135  {
136  putpixel ( x1, y1, mix );
137  y1 += yinc;
138  }
139  return;
140  }
141  for ( int i = 0; i < EMax; i++ )
142  {
143  putpixel ( x1, y1, mix );
144  if ( absdy > absdx )
145  {
146  y1 += yinc;
147  E += absdx;
148  if ( E >= EMax )
149  {
150  E -= absdy;
151  x1 += xinc;
152  }
153  }
154  else
155  {
156  x1 += xinc;
157  E += absdy;
158  if ( E >= EMax )
159  {
160  E -= absdx;
161  y1 += yinc;
162  }
163  }
164  }
165 }
166 
167 #define FILL_EDGE_ALLOC_TAG 0x45465044
168 
169 /*
170 ** This struct is used for book keeping during polygon filling routines.
171 */
172 typedef struct _tagFILL_EDGE
173 {
174  /*Basic line information*/
175  int FromX;
176  int FromY;
177  int ToX;
178  int ToY;
179  int dx;
180  int dy;
181  int absdx, absdy;
182  int x, y;
183  int xmajor;
184 
185  /*Active Edge List information*/
186  int XIntercept[2];
187  int Error;
188  int ErrorMax;
190 
191  /* The next edge in the active Edge List*/
193 } FILL_EDGE;
194 
195 typedef struct _FILL_EDGE_LIST
196 {
197  int Count;
200 
201 #if 0
202 static
203 void
205 {
206  FILL_EDGE* pThis = list;
207  if (0 == list)
208  {
209  DPRINT1("List is NULL\n");
210  return;
211  }
212 
213  while(0 != pThis)
214  {
215  //DPRINT1("EDGE: (%d, %d) to (%d, %d)\n", pThis->FromX, pThis->FromY, pThis->ToX, pThis->ToY);
216  DPRINT1("EDGE: [%d,%d]\n", pThis->XIntercept[0], pThis->XIntercept[1] );
217  pThis = pThis->pNext;
218  }
219 }
220 #else
221 #define DEBUG_PRINT_ACTIVE_EDGELIST(x)
222 #endif
223 
224 /*
225 ** Hide memory clean up.
226 */
227 static
228 void
229 FASTCALL
231 {
232  int i;
233  if ( list )
234  {
235  if ( list->Edges )
236  {
237  for ( i = 0; i < list->Count; i++ )
238  {
239  if ( list->Edges[i] )
240  EngFreeMem ( list->Edges[i] );
241  }
242  EngFreeMem ( list->Edges );
243  }
244  EngFreeMem ( list );
245  }
246 }
247 
248 /*
249 ** This makes and initiaizes an Edge struct for a line between two points.
250 */
251 static
252 FILL_EDGE*
253 FASTCALL
255 {
257 
258  if (0 == rc)
259  return NULL;
260 
261  //DPRINT1("Making Edge: (%d, %d) to (%d, %d)\n", From.x, From.y, To.x, To.y);
262  //Now Fill the struct.
263  if ( To.y < From.y )
264  {
265  rc->FromX = To.x;
266  rc->FromY = To.y;
267  rc->ToX = From.x;
268  rc->ToY = From.y;
269  rc->YDirection = -1;
270 
271  // lines that go up get walked backwards, so need to be offset
272  // by -1 in order to make the walk identically on a pixel-level
273  rc->Error = -1;
274  }
275  else
276  {
277  rc->FromX = From.x;
278  rc->FromY = From.y;
279  rc->ToX = To.x;
280  rc->ToY = To.y;
281  rc->YDirection = 1;
282 
283  rc->Error = 0;
284  }
285 
286  rc->x = rc->FromX;
287  rc->y = rc->FromY;
288  rc->dx = rc->ToX - rc->FromX;
289  rc->dy = rc->ToY - rc->FromY;
290  rc->absdx = abs(rc->dx);
291  rc->absdy = abs(rc->dy);
292 
293  rc->xmajor = rc->absdx > rc->absdy;
294 
295  rc->ErrorMax = MAX(rc->absdx,rc->absdy);
296 
297  rc->Error += rc->ErrorMax / 2;
298 
299  rc->XDirection = (rc->dx < 0)?(-1):(1);
300 
301  rc->pNext = 0;
302 
303  DPRINT("MakeEdge (%i,%i)->(%i,%i) d=(%i,%i) dir=(%i,%i) err=%i max=%i\n",
304  From.x, From.y, To.x, To.y, rc->dx, rc->dy, rc->XDirection, rc->YDirection, rc->Error, rc->ErrorMax );
305 
306  return rc;
307 }
308 /*
309 ** My Edge comparison routine.
310 ** This is for scan converting polygon fill.
311 ** First sort by MinY, then Minx, then slope.
312 **
313 ** This comparison will help us determine which
314 ** lines will become active first when scanning from
315 ** top (min y) to bottom (max y).
316 **
317 ** Return Value Meaning
318 ** Negative integer element1 < element2
319 ** Zero element1 = element2
320 ** Positive integer element1 > element2
321 */
322 static
323 INT
324 FASTCALL
326 {
327  int e1 = Edge1->XIntercept[0] + Edge1->XIntercept[1];
328  int e2 = Edge2->XIntercept[0] + Edge2->XIntercept[1];
329 
330  return e1 - e2;
331 }
332 
333 
334 /*
335 ** Insert an edge into a list keeping the list in order.
336 */
337 static
338 void
339 FASTCALL
341 {
342  FILL_EDGE *pPrev, *pThis;
343  //DPRINT1("In POLYGONFILL_ActiveListInsert()\n");
344  ASSERT ( activehead && NewEdge );
345  if ( !*activehead )
346  {
347  NewEdge->pNext = NULL;
348  *activehead = NewEdge;
349  return;
350  }
351  /*
352  ** First lets check to see if we have a new smallest value.
353  */
354  if (FILL_EDGE_Compare(NewEdge, *activehead) <= 0)
355  {
356  NewEdge->pNext = *activehead;
357  *activehead = NewEdge;
358  return;
359  }
360  /*
361  ** Ok, now scan to the next spot to put this item.
362  */
363  pThis = *activehead;
364  pPrev = NULL;
365  while ( pThis && FILL_EDGE_Compare(pThis, NewEdge) < 0 )
366  {
367  pPrev = pThis;
368  pThis = pThis->pNext;
369  }
370 
371  ASSERT(pPrev);
372  NewEdge->pNext = pPrev->pNext;
373  pPrev->pNext = NewEdge;
374  //DEBUG_PRINT_ACTIVE_EDGELIST(*activehead);
375 }
376 
377 /*
378 ** Create a list of edges for a list of points.
379 */
380 static
382 FASTCALL
384 {
385  int CurPt = 0;
386  FILL_EDGE_LIST* list = 0;
387  FILL_EDGE* e = 0;
388 
389  if ( 0 == Points || 2 > Count )
390  return 0;
391 
393  if ( 0 == list )
394  goto fail;
395  list->Count = 0;
397  if ( !list->Edges )
398  goto fail;
399  memset ( list->Edges, 0, Count * sizeof(FILL_EDGE*) );
400 
401  for ( CurPt = 1; CurPt < Count; ++CurPt )
402  {
403  e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[CurPt] );
404  if ( !e )
405  goto fail;
406  // if a straight horizontal line - who cares?
407  if ( !e->absdy )
408  EngFreeMem ( e );
409  else
410  list->Edges[list->Count++] = e;
411  }
412  e = POLYGONFILL_MakeEdge ( Points[CurPt-1], Points[0] );
413  if ( !e )
414  goto fail;
415  if ( !e->absdy )
416  EngFreeMem ( e );
417  else
418  list->Edges[list->Count++] = e;
419  return list;
420 
421 fail:
422  DPRINT1("Out Of MEMORY!!\n");
424  return 0;
425 }
426 
427 
428 /*
429 ** This slow routine uses the data stored in the edge list to
430 ** calculate the x intercepts for each line in the edge list
431 ** for scanline Scanline.
432 **TODO: Get rid of this floating point arithmetic
433 */
434 static
435 void
436 FASTCALL
438 {
439  if ( 0 == pEdge->dy )
440  return;
441 
442  ASSERT ( pEdge->FromY <= Scanline && pEdge->ToY > Scanline );
443 
444  if ( pEdge->xmajor )
445  {
446  int steps;
447 
448  ASSERT ( pEdge->y == Scanline );
449 
450  // now shoot to end of scanline collision
451  steps = (pEdge->ErrorMax-pEdge->Error-1)/pEdge->absdy;
452  if ( steps )
453  {
454  // record first collision with scanline
455  int x1 = pEdge->x;
456  pEdge->x += steps * pEdge->XDirection;
457  pEdge->Error += steps * pEdge->absdy;
458  ASSERT ( pEdge->Error < pEdge->ErrorMax );
459  pEdge->XIntercept[0] = MIN(x1,pEdge->x);
460  pEdge->XIntercept[1] = MAX(x1,pEdge->x);
461  }
462  else
463  {
464  pEdge->XIntercept[0] = pEdge->x;
465  pEdge->XIntercept[1] = pEdge->x;
466  }
467 
468  // we should require exactly 1 step to step onto next scanline...
469  ASSERT ( (pEdge->ErrorMax-pEdge->Error-1) / pEdge->absdy == 0 );
470  pEdge->x += pEdge->XDirection;
471  pEdge->Error += pEdge->absdy;
472  ASSERT ( pEdge->Error >= pEdge->ErrorMax );
473 
474  // now step onto next scanline...
475  pEdge->Error -= pEdge->absdx;
476  pEdge->y++;
477  }
478  else // then this is a y-major line
479  {
480  pEdge->XIntercept[0] = pEdge->x;
481  pEdge->XIntercept[1] = pEdge->x;
482 
483  pEdge->Error += pEdge->absdx;
484  pEdge->y++;
485 
486  if ( pEdge->Error >= pEdge->ErrorMax )
487  {
488  pEdge->Error -= pEdge->ErrorMax;
489  pEdge->x += pEdge->XDirection;
490  ASSERT ( pEdge->Error < pEdge->ErrorMax );
491  }
492  }
493 
494  DPRINT("Line (%d, %d) to (%d, %d) intersects scanline %d at (%d,%d)\n",
495  pEdge->FromX, pEdge->FromY, pEdge->ToX, pEdge->ToY, Scanline, pEdge->XIntercept[0], pEdge->XIntercept[1] );
496 }
497 
498 /*
499 ** This method updates the Active edge collection for the scanline Scanline.
500 */
501 static
502 void
504 {
505  int i;
506 
507  ASSERT ( list && ActiveHead );
508  *ActiveHead = 0;
509  for ( i = 0; i < list->Count; i++ )
510  {
511  FILL_EDGE* pEdge = list->Edges[i];
512  ASSERT(pEdge);
513  if ( pEdge->FromY <= Scanline && pEdge->ToY > Scanline )
514  {
515  POLYGONFILL_UpdateScanline ( pEdge, Scanline );
516  POLYGONFILL_ActiveListInsert ( ActiveHead, pEdge );
517  }
518  }
519 }
520 
521 /*
522 ** This method fills the portion of the polygon that intersects with the scanline
523 ** Scanline.
524 */
525 static
526 void
528  PDC dc,
529  int ScanLine,
530  FILL_EDGE* ActiveHead,
531  SURFOBJ *SurfObj,
532  PBRUSHOBJ BrushObj,
533  MIX RopMode )
534 {
535  FILL_EDGE *pLeft, *pRight;
536 
537  if ( !ActiveHead )
538  return;
539 
540  pLeft = ActiveHead;
541  pRight = pLeft->pNext;
542  ASSERT(pRight);
543 
544  while ( NULL != pRight )
545  {
546  int x1 = pLeft->XIntercept[0];
547  int x2 = pRight->XIntercept[1];
548  if ( x2 > x1 )
549  {
550  RECTL BoundRect;
551  BoundRect.top = ScanLine;
552  BoundRect.bottom = ScanLine + 1;
553  BoundRect.left = x1;
554  BoundRect.right = x2;
555 
556  DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
557  IntEngLineTo( SurfObj,
558  dc->CombinedClip,
559  BrushObj,
560  x1,
561  ScanLine,
562  x2,
563  ScanLine,
564  &BoundRect, // Bounding rectangle
565  RopMode); // MIX
566  }
567  pLeft = pRight->pNext;
568  pRight = pLeft ? pLeft->pNext : NULL;
569  }
570 }
571 
572 static
573 void
575  PDC dc,
576  int ScanLine,
577  FILL_EDGE* ActiveHead,
578  SURFOBJ *SurfObj,
579  PBRUSHOBJ BrushObj,
580  MIX RopMode )
581 {
582  FILL_EDGE *pLeft, *pRight;
583  int x1, x2, winding = 0;
584  RECTL BoundRect;
585 
586  if ( !ActiveHead )
587  return;
588 
589  BoundRect.top = ScanLine;
590  BoundRect.bottom = ScanLine + 1;
591 
592  pLeft = ActiveHead;
593  winding = pLeft->YDirection;
594  pRight = pLeft->pNext;
595  ASSERT(pRight);
596 
597  // setup first line...
598  x1 = pLeft->XIntercept[0];
599  x2 = pRight->XIntercept[1];
600 
601  pLeft = pRight;
602  pRight = pLeft->pNext;
603  winding += pLeft->YDirection;
604 
605  while ( NULL != pRight )
606  {
607  int newx1 = pLeft->XIntercept[0];
608  int newx2 = pRight->XIntercept[1];
609  if ( winding )
610  {
611  // check and see if this new line touches the previous...
612  if ( (newx1 >= x1 && newx1 <= x2)
613  || (newx2 >= x1 && newx2 <= x2)
614  || (x1 >= newx1 && x1 <= newx2)
615  || (x2 >= newx2 && x2 <= newx2)
616  )
617  {
618  // yup, just tack it on to our existing line
619  x1 = MIN(x1,newx1);
620  x2 = MAX(x2,newx2);
621  }
622  else
623  {
624  // nope - render the old line..
625  BoundRect.left = x1;
626  BoundRect.right = x2;
627 
628  DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
629  IntEngLineTo( SurfObj,
630  dc->CombinedClip,
631  BrushObj,
632  x1,
633  ScanLine,
634  x2,
635  ScanLine,
636  &BoundRect, // Bounding rectangle
637  RopMode); // MIX
638 
639  x1 = newx1;
640  x2 = newx2;
641  }
642  }
643  pLeft = pRight;
644  pRight = pLeft->pNext;
645  winding += pLeft->YDirection;
646  }
647  // there will always be a line left-over, render it now...
648  BoundRect.left = x1;
649  BoundRect.right = x2;
650 
651  DPRINT("Fill Line (%d, %d) to (%d, %d)\n",x1, ScanLine, x2, ScanLine);
652  IntEngLineTo( SurfObj,
653  dc->CombinedClip,
654  BrushObj,
655  x1,
656  ScanLine,
657  x2,
658  ScanLine,
659  &BoundRect, // Bounding rectangle
660  RopMode); // MIX
661 }
662 
663 //When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
664 //even-numbered polygon sides on each scan line. That is, GDI fills the area between the
665 //first and second side, between the third and fourth side, and so on.
666 
667 //WINDING Selects winding mode (fills any region with a nonzero winding value).
668 //When the fill mode is WINDING, GDI fills any region that has a nonzero winding value.
669 //This value is defined as the number of times a pen used to draw the polygon would go around the region.
670 //The direction of each edge of the polygon is important.
671 
672 BOOL
674  PDC dc,
675  SURFOBJ *SurfObj,
676  PBRUSHOBJ BrushObj,
677  MIX RopMode,
678  CONST PPOINT Points,
679  int Count,
680  RECTL BoundRect )
681 {
682  FILL_EDGE_LIST *list = 0;
683  FILL_EDGE *ActiveHead = 0;
684  int ScanLine;
685 
686  void
687  (*FillScanLine)(
688  PDC dc,
689  int ScanLine,
690  FILL_EDGE* ActiveHead,
691  SURFOBJ *SurfObj,
692  PBRUSHOBJ BrushObj,
693  MIX RopMode );
694 
695  DPRINT("FillPolygon\n");
696 
697  /* Create Edge List. */
699  /* DEBUG_PRINT_EDGELIST(list); */
700  if (NULL == list)
701  return FALSE;
702 
703  if ( WINDING == dc->w.polyFillMode )
704  FillScanLine = POLYGONFILL_FillScanLineWinding;
705  else /* default */
706  FillScanLine = POLYGONFILL_FillScanLineAlternate;
707 
708  /* For each Scanline from BoundRect.bottom to BoundRect.top,
709  * determine line segments to draw
710  */
711  for ( ScanLine = BoundRect.top; ScanLine < BoundRect.bottom; ++ScanLine )
712  {
713  POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead);
714  //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);
715  FillScanLine ( dc, ScanLine, ActiveHead, SurfObj, BrushObj, RopMode );
716  }
717 
718  /* Free Edge List. If any are left. */
720 
721  return TRUE;
722 }
723 
724 
725 
726 
727 
728 // this is highly hacked from W32kPolygon...
729 BOOL
730 Polygon ( CONST PPOINT UnsafePoints, int Count, int polyFillMode )
731 {
732  BOOL ret;
733  RECTL DestRect;
734  int CurrentPoint;
735  PPOINT Points;
736  SURFOBJ* SurfObj = 0;
737  DC dc;
738  PBRUSHOBJ OutBrushObj = 0;
739 
740  dc.CombinedClip = 0;
741  dc.w.polyFillMode = polyFillMode;
742 
743  DPRINT1("In W32kPolygon()\n");
744 
745  if ( NULL == UnsafePoints || Count < 2)
746  {
747  DPRINT1("ERROR_INVALID_PARAMETER\n");
748  return FALSE;
749  }
750 
751  /* Copy points from userspace to kernelspace */
752  Points = (PPOINT)EngAllocMem(0, Count * sizeof(POINT));
753  if (NULL == Points)
754  {
755  DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
756  return FALSE;
757  }
758  MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT));
759  if ( memcmp ( Points, UnsafePoints, Count * sizeof(POINT) ) )
760  {
761  free(Points);
762  return FALSE;
763  }
764 
765  DestRect.left = Points[0].x;
766  DestRect.right = Points[0].x;
767  DestRect.top = Points[0].y;
768  DestRect.bottom = Points[0].y;
769 
770  for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint)
771  {
772  DestRect.left = MIN(DestRect.left, Points[CurrentPoint].x);
773  DestRect.right = MAX(DestRect.right, Points[CurrentPoint].x);
774  DestRect.top = MIN(DestRect.top, Points[CurrentPoint].y);
775  DestRect.bottom = MAX(DestRect.bottom, Points[CurrentPoint].y);
776  }
777 
778  // Draw the Polygon Edges with the current pen
779  for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint)
780  {
781  POINT To, From; //, Next;
782 
783  /* Let CurrentPoint be i
784  * if i+1 > Count, Draw a line from Points[i] to Points[0]
785  * Draw a line from Points[i] to Points[i+1]
786  */
787  From = Points[CurrentPoint];
788  if ( CurrentPoint + 1 >= Count)
789  {
790  To = Points[0];
791  }
792  else
793  {
794  To = Points[CurrentPoint + 1];
795  }
796 
797  DPRINT1("Polygon Making line from (%ld,%ld) to (%ld,%ld)\n", From.x, From.y, To.x, To.y );
798  IntEngLineTo(SurfObj,
799  dc.CombinedClip,
800  OutBrushObj,
801  From.x,
802  From.y,
803  To.x,
804  To.y,
805  &DestRect,
806  EDGE_CHAR); /* MIX */
807  }
808  /* determine the fill mode to fill the polygon. */
809  ret = FillPolygon(&dc, SurfObj, OutBrushObj, FILL_CHAR, Points, Count, DestRect );
810  free(Points);
811 
812  return ret;
813 }
814 
815 
816 int main()
817 {
818  memset ( screen, ' ', sizeof(screen) );
819  POINT pts[] =
820  {
821 #if 0
822  { 0, 0 },
823  { 12, 4 },
824  { 4, 8 },
825 #elif 0
826  { 3, 0 },
827  { 0, 3 },
828  { 3, 6 },
829 #elif 0
830  { 1, 1 },
831  { 3, 1 },
832  { 3, 3 },
833  { 1, 3 }
834 #elif 0
835  { 0, 0 },
836  { 4, 0 },
837  { 4, 4 },
838  { 8, 4 },
839  { 8, 8 },
840  { 4, 8 },
841  { 4, 4 },
842  { 0, 4 },
843 #else
844  { 4, 12 },
845  { 12, 0 },
846  { 18, 12 },
847  { 4, 4 },
848  { 20, 4 }
849 #endif
850  };
851  const int pts_count = sizeof(pts)/sizeof(pts[0]);
852 
853  // use ALTERNATE or WINDING for 3rd param
854  Polygon ( pts, pts_count, ALTERNATE );
855 
856  // print out our "screen"
857  for ( int y = 0; y < SCREENY; y++ )
858  {
859  for ( int x = 0; x < SCREENX; x++ )
860  {
861  printf("%c", screen[y][x] );
862  }
863  printf("\n");
864  }
865  DPRINT1("Done!\n");
866  (void)_getch();
867 }
868 /* EOF */
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3706
struct DC * PDC
int polyFillMode
Definition: polytest.cpp:37
FILL_EDGE ** Edges
Definition: polytest.cpp:198
#define ALTERNATE
Definition: polytest.cpp:30
struct tagPOINT * LPPOINT
static void FASTCALL POLYGONFILL_ActiveListInsert(FILL_EDGE **activehead, FILL_EDGE *NewEdge)
Definition: polytest.cpp:340
T abs(T t)
Definition: polytest.cpp:91
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ULONG MIX
Definition: winddi.h:129
long y
Definition: polytest.cpp:48
struct RECTL * PRECTL
BOOL Polygon(CONST PPOINT UnsafePoints, int Count, int polyFillMode)
Definition: polytest.cpp:730
long x
Definition: polytest.cpp:48
#define EngFreeMem
Definition: polytest.cpp:56
GLint dy
Definition: linetemp.h:97
#define free
Definition: debug_ros.c:5
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
long bottom
Definition: polytest.cpp:53
GLdouble GLdouble t
Definition: gl.h:2047
Definition: ecma_167.h:138
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define MmCopyFromCaller
Definition: polytest.cpp:29
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
HDC dc
Definition: cylfrac.c:34
#define FILL_CHAR
Definition: polytest.cpp:68
#define SCREENY
Definition: polytest.cpp:64
struct tagPOINT * PPOINT
int XIntercept[2]
Definition: polytest.cpp:186
#define EDGE_CHAR
Definition: polytest.cpp:67
int32_t INT
Definition: typedefs.h:56
#define T
Definition: mbstring.h:31
BOOL FillPolygon(PDC dc, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, CONST PPOINT Points, int Count, RECTL BoundRect)
Definition: polytest.cpp:673
T MIN(T a, T b)
Definition: polytest.cpp:79
long right
Definition: polytest.cpp:53
#define DPRINT1
Definition: polytest.cpp:60
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 FILL_EDGE_LIST *FASTCALL POLYGONFILL_MakeEdgeList(PPOINT Points, int Count)
Definition: polytest.cpp:383
unsigned int BOOL
Definition: ntddk_ex.h:94
#define a
Definition: ke_i.h:78
#define e
Definition: ke_i.h:82
Definition: polytest.cpp:35
long top
Definition: polytest.cpp:53
#define ASSERT
Definition: polytest.cpp:33
static void POLYGONFILL_FillScanLineWinding(PDC dc, int ScanLine, FILL_EDGE *ActiveHead, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode)
Definition: polytest.cpp:574
struct _tagFILL_EDGE FILL_EDGE
static DWORD DWORD DWORD DWORD * steps
Definition: cursoricon.c:1521
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define FALSE
Definition: polytest.cpp:27
long left
Definition: polytest.cpp:53
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
Definition: polytest.cpp:40
GLsizeiptr size
Definition: glext.h:5919
if(!(yy_init))
Definition: macro.lex.yy.c:714
static void FASTCALL POLYGONFILL_DestroyEdgeList(FILL_EDGE_LIST *list)
Definition: polytest.cpp:230
CLIPOBJ CombinedClip
Definition: polytest.cpp:42
struct DC DC
const GLubyte * c
Definition: glext.h:8905
#define TRUE
Definition: polytest.cpp:26
static void FASTCALL POLYGONFILL_UpdateScanline(FILL_EDGE *pEdge, int Scanline)
Definition: polytest.cpp:437
struct W W
void IntEngLineTo(SURFOBJ *, CLIPOBJ, PBRUSHOBJ, int x1, int y1, int x2, int y2, RECTL *, MIX mix)
Definition: polytest.cpp:107
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
int ret
static double zero
Definition: j0_y0.c:96
#define FL_ZERO_MEMORY
Definition: polytest.cpp:58
#define FILL_EDGE_ALLOC_TAG
Definition: polytest.cpp:167
#define CONST
Definition: polytest.cpp:28
struct _FILL_EDGE_LIST FILL_EDGE_LIST
static FILL_EDGE *FASTCALL POLYGONFILL_MakeEdge(POINT From, POINT To)
Definition: polytest.cpp:254
Definition: _list.h:228
#define PBRUSHOBJ
Definition: polytest.cpp:23
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3706
T MAX(T a, T b)
Definition: polytest.cpp:85
char screen[SCREENY][SCREENX]
Definition: polytest.cpp:65
static void POLYGONFILL_FillScanLineAlternate(PDC dc, int ScanLine, FILL_EDGE *ActiveHead, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode)
Definition: polytest.cpp:527
#define FASTCALL
Definition: polytest.cpp:19
static const WCHAR E[]
Definition: oid.c:1253
struct _tagFILL_EDGE * pNext
Definition: polytest.cpp:192
static INT FASTCALL FILL_EDGE_Compare(FILL_EDGE *Edge1, FILL_EDGE *Edge2)
Definition: polytest.cpp:325
int main()
Definition: polytest.cpp:816
_In_ PATHOBJ _In_ CLIPOBJ _In_ BRUSHOBJ _In_ POINTL _In_ MIX mix
Definition: winddi.h:3591
#define DEBUG_PRINT_ACTIVE_EDGELIST(x)
Definition: polytest.cpp:221
#define list
Definition: rosglue.h:35
#define SCREENX
Definition: polytest.cpp:63
#define WINDING
Definition: polytest.cpp:31
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
void putpixel(int x, int y, char c)
Definition: polytest.cpp:96
static void POLYGONFILL_BuildActiveList(int Scanline, FILL_EDGE_LIST *list, FILL_EDGE **ActiveHead)
Definition: polytest.cpp:503
W w
Definition: polytest.cpp:43
#define c
Definition: ke_i.h:80
#define malloc
Definition: debug_ros.c:4
struct RECTL RECTL
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
int _getch()
Definition: getch.c:16
struct tagPOINT POINT
#define memset(x, y, z)
Definition: compat.h:39
#define printf
Definition: config.h:203