ReactOS 0.4.15-dev-7788-g1ad9096
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
35typedef struct W
36{
38} W;
39
40typedef struct DC
41{
44} DC, *PDC;
45
46typedef struct tagPOINT
47{
48 long x, y;
50
51typedef struct RECTL
52{
55
56#define EngFreeMem free
57
58#define FL_ZERO_MEMORY 1
59
60#define DPRINT1 printf("%i:",__LINE__);printf
61inline void DPRINT(...){}
62
63#define SCREENX 25
64#define SCREENY 15
66
67#define EDGE_CHAR '*'
68#define FILL_CHAR 'o'
69
70void* 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
78template <class T>
79inline T MIN ( T a, T b )
80{
81 return a < b ? a : b;
82}
83
84template <class T>
85inline T MAX ( T a, T b )
86{
87 return a > b ? a : b;
88}
89
90template <class T>
91inline T abs ( T t )
92{
93 return t < 0 ? -t : t;
94}
95
96void 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*/
172typedef 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;
182 int x, y;
184
185 /*Active Edge List information*/
187 int Error;
190
191 /* The next edge in the active Edge List*/
194
195typedef struct _FILL_EDGE_LIST
196{
197 int Count;
200
201#if 0
202static
203void
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*/
227static
228void
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*/
251static
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*/
322static
323INT
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*/
337static
338void
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*/
380static
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
421fail:
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*/
434static
435void
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*/
501static
502void
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*/
525static
526void
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
572static
573void
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
672BOOL
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 */
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...
729BOOL
730Polygon ( 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
816int 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 */
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define MIN(x, y)
Definition: rdesktop.h:171
#define MAX(x, y)
Definition: rdesktop.h:175
Definition: list.h:37
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
static const WCHAR E[]
Definition: oid.c:1253
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
#define printf
Definition: freeldr.h:93
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
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
#define e
Definition: ke_i.h:82
#define a
Definition: ke_i.h:78
#define c
Definition: ke_i.h:80
#define b
Definition: ke_i.h:79
#define T
Definition: mbstring.h:31
GLint dy
Definition: linetemp.h:97
if(dx< 0)
Definition: linetemp.h:194
GLint dx
Definition: linetemp.h:97
static const WCHAR dc[]
static DWORD DWORD DWORD DWORD * steps
Definition: cursoricon.c:1638
int Count
Definition: noreturn.cpp:7
#define DEBUG_PRINT_ACTIVE_EDGELIST(x)
Definition: polytest.cpp:221
#define CONST
Definition: polytest.cpp:28
struct tagPOINT POINT
static FILL_EDGE *FASTCALL POLYGONFILL_MakeEdge(POINT From, POINT To)
Definition: polytest.cpp:254
struct RECTL * PRECTL
#define SCREENY
Definition: polytest.cpp:64
#define MmCopyFromCaller
Definition: polytest.cpp:29
#define EngFreeMem
Definition: polytest.cpp:56
static FILL_EDGE_LIST *FASTCALL POLYGONFILL_MakeEdgeList(PPOINT Points, int Count)
Definition: polytest.cpp:383
#define FASTCALL
Definition: polytest.cpp:19
void putpixel(int x, int y, char c)
Definition: polytest.cpp:96
BOOL Polygon(CONST PPOINT UnsafePoints, int Count, int polyFillMode)
Definition: polytest.cpp:730
static void POLYGONFILL_BuildActiveList(int Scanline, FILL_EDGE_LIST *list, FILL_EDGE **ActiveHead)
Definition: polytest.cpp:503
struct _FILL_EDGE_LIST FILL_EDGE_LIST
#define FILL_EDGE_ALLOC_TAG
Definition: polytest.cpp:167
struct _tagFILL_EDGE FILL_EDGE
static void FASTCALL POLYGONFILL_DestroyEdgeList(FILL_EDGE_LIST *list)
Definition: polytest.cpp:230
#define WINDING
Definition: polytest.cpp:31
#define FL_ZERO_MEMORY
Definition: polytest.cpp:58
static void FASTCALL POLYGONFILL_ActiveListInsert(FILL_EDGE **activehead, FILL_EDGE *NewEdge)
Definition: polytest.cpp:340
void IntEngLineTo(SURFOBJ *, CLIPOBJ, PBRUSHOBJ, int x1, int y1, int x2, int y2, RECTL *, MIX mix)
Definition: polytest.cpp:107
static void POLYGONFILL_FillScanLineAlternate(PDC dc, int ScanLine, FILL_EDGE *ActiveHead, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode)
Definition: polytest.cpp:527
#define TRUE
Definition: polytest.cpp:26
#define FALSE
Definition: polytest.cpp:27
void DPRINT(...)
Definition: polytest.cpp:61
#define EDGE_CHAR
Definition: polytest.cpp:67
#define PBRUSHOBJ
Definition: polytest.cpp:23
#define ALTERNATE
Definition: polytest.cpp:30
BOOL FillPolygon(PDC dc, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode, CONST PPOINT Points, int Count, RECTL BoundRect)
Definition: polytest.cpp:673
char screen[SCREENY][SCREENX]
Definition: polytest.cpp:65
static void FASTCALL POLYGONFILL_UpdateScanline(FILL_EDGE *pEdge, int Scanline)
Definition: polytest.cpp:437
#define DPRINT1
Definition: polytest.cpp:60
struct DC * PDC
static void POLYGONFILL_FillScanLineWinding(PDC dc, int ScanLine, FILL_EDGE *ActiveHead, SURFOBJ *SurfObj, PBRUSHOBJ BrushObj, MIX RopMode)
Definition: polytest.cpp:574
int main()
Definition: polytest.cpp:816
#define SCREENX
Definition: polytest.cpp:63
struct tagPOINT * LPPOINT
#define ASSERT
Definition: polytest.cpp:33
static INT FASTCALL FILL_EDGE_Compare(FILL_EDGE *Edge1, FILL_EDGE *Edge2)
Definition: polytest.cpp:325
struct tagPOINT * PPOINT
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
#define FILL_CHAR
Definition: polytest.cpp:68
#define list
Definition: rosglue.h:35
#define memset(x, y, z)
Definition: compat.h:39
int zero
Definition: sehframes.cpp:29
int _getch()
Definition: getch.c:16
Definition: polytest.cpp:41
W w
Definition: polytest.cpp:43
CLIPOBJ CombinedClip
Definition: polytest.cpp:42
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
Definition: polytest.cpp:36
int polyFillMode
Definition: polytest.cpp:37
FILL_EDGE ** Edges
Definition: polytest.cpp:198
struct _tagFILL_EDGE * pNext
Definition: polytest.cpp:192
int XIntercept[2]
Definition: polytest.cpp:186
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
Definition: ecma_167.h:138
int32_t INT
Definition: typedefs.h:58
int ret
_In_ PATHOBJ _In_ CLIPOBJ _In_ BRUSHOBJ _In_ POINTL _In_ MIX mix
Definition: winddi.h:3595
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3709
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3711
ULONG MIX
Definition: winddi.h:129