93 #define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
102 incr1 = -2 * dx + 2 * (dy) * m1; \
103 incr2 = -2 * dx + 2 * (dy) * m; \
104 d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
108 incr1 = 2 * dx - 2 * (dy) * m1; \
109 incr2 = 2 * dx - 2 * (dy) * m; \
110 d = -2 * m * (dy) + 2 * dx; \
115 #define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
153 #define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
154 BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \
155 bres.m, bres.m1, bres.incr1, bres.incr2)
157 #define BRESINCRPGONSTRUCT(bres) \
158 BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2)
211 #define COUNTERCLOCKWISE -1
213 typedef struct _EdgeTableEntry {
216 struct _EdgeTableEntry *next;
217 struct _EdgeTableEntry *back;
218 struct _EdgeTableEntry *nextWETE;
223 typedef struct _ScanLineList{
225 EdgeTableEntry *edgelist;
226 struct _ScanLineList *next;
233 ScanLineList scanlines;
242 #define SLLSPERBLOCK 25
244 typedef struct _ScanLineListBlock {
245 ScanLineList SLLs[SLLSPERBLOCK];
246 struct _ScanLineListBlock *next;
264 #define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
265 if (pAET->ymax == y) { \
266 pPrevAET->next = pAET->next; \
267 pAET = pPrevAET->next; \
270 pAET->back = pPrevAET; \
273 BRESINCRPGONSTRUCT(pAET->bres); \
287 #define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
288 if (pAET->ymax == y) { \
289 pPrevAET->next = pAET->next; \
290 pAET = pPrevAET->next; \
292 pAET->back = pPrevAET; \
295 BRESINCRPGONSTRUCT(pAET->bres); \
301 #define LARGE_COORDINATE 1000000
302 #define SMALL_COORDINATE -LARGE_COORDINATE
305 static void InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE,
int scanline,
306 ScanLineListBlock **SLLBlock,
int *iSLLBlock)
313 EdgeTableEntry *start, *prev;
314 ScanLineList *pSLL, *pPrevSLL;
315 ScanLineListBlock *tmpSLLBlock;
320 pPrevSLL = &ET->scanlines;
321 pSLL = pPrevSLL->next;
322 while (pSLL && (pSLL->scanline < scanline)) {
330 if ((!pSLL) || (pSLL->scanline > scanline)) {
331 if (*iSLLBlock > SLLSPERBLOCK-1) {
332 tmpSLLBlock =
new ScanLineListBlock;
333 (*SLLBlock)->next = tmpSLLBlock;
334 tmpSLLBlock->next = (ScanLineListBlock *)0;
335 *SLLBlock = tmpSLLBlock;
338 pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
340 pSLL->next = pPrevSLL->next;
341 pSLL->edgelist = (EdgeTableEntry *)0;
342 pPrevSLL->next = pSLL;
344 pSLL->scanline = scanline;
349 prev = (EdgeTableEntry *)0;
350 start = pSLL->edgelist;
351 while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) {
360 pSLL->edgelist = ETE;
365 static void CreateETandAET(
int count, TPoint *pts, EdgeTable *ET, EdgeTableEntry *AET,
366 EdgeTableEntry *pETEs, ScanLineListBlock *pSLLBlock)
388 TPoint *top, *bottom;
389 TPoint *PrevPt, *CurrPt;
393 if (count < 2)
return;
398 AET->next = (EdgeTableEntry *)0;
399 AET->back = (EdgeTableEntry *)0;
400 AET->nextWETE = (EdgeTableEntry *)0;
401 AET->bres.minor_axis = SMALL_COORDINATE;
406 ET->scanlines.next = (ScanLineList *)0;
407 ET->ymax = SMALL_COORDINATE;
408 ET->ymin = LARGE_COORDINATE;
409 pSLLBlock->next = (ScanLineListBlock *)0;
411 PrevPt = &pts[count-1];
424 if (PrevPt->fY > CurrPt->fY) {
425 bottom = PrevPt, top = CurrPt;
426 pETEs->ClockWise = 0;
428 bottom = CurrPt, top = PrevPt;
429 pETEs->ClockWise = 1;
435 if (bottom->fY != top->fY) {
436 pETEs->ymax = bottom->fY-1;
441 dy = bottom->fY - top->fY;
442 BRESINITPGONSTRUCT(dy, top->fX, bottom->fX, pETEs->bres);
444 InsertEdgeInET(ET, pETEs, top->fY, &pSLLBlock, &iSLLBlock);
446 if (PrevPt->fY > ET->ymax) ET->ymax = PrevPt->fY;
447 if (PrevPt->fY < ET->ymin) ET->ymin = PrevPt->fY;
455 static void loadAET(EdgeTableEntry *AET, EdgeTableEntry *ETEs)
461 EdgeTableEntry *pPrevAET;
467 while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis)) {
476 ETEs->back = pPrevAET;
477 pPrevAET->next = ETEs;
485 static int InsertionSort(EdgeTableEntry * AET)
493 EdgeTableEntry *pETEchase;
494 EdgeTableEntry *pETEinsert;
495 EdgeTableEntry *pETEchaseBackTMP;
502 while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis) {
503 pETEchase = pETEchase->back;
507 if (pETEchase != pETEinsert) {
508 pETEchaseBackTMP = pETEchase->back;
509 pETEinsert->back->next = AET;
511 AET->back = pETEinsert->back;
513 pETEinsert->next = pETEchase;
514 pETEchase->back->next = pETEinsert;
515 pETEchase->back = pETEinsert;
516 pETEinsert->back = pETEchaseBackTMP;
524 static void FreeStorage(ScanLineListBlock *pSLLBlock)
528 ScanLineListBlock *tmpSLLBlock;
531 tmpSLLBlock = pSLLBlock->next;
533 pSLLBlock = tmpSLLBlock;