Bug Summary

File:src/PolyReg.c
Location:line 447, column 13
Description:Assigned value is garbage or undefined

Annotated Source Code

1/************************************************************************
2
3Copyright 1987, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25
26Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28 All Rights Reserved
29
30Permission to use, copy, modify, and distribute this software and its
31documentation for any purpose and without fee is hereby granted,
32provided that the above copyright notice appear in all copies and that
33both that copyright notice and this permission notice appear in
34supporting documentation, and that the name of Digital not be
35used in advertising or publicity pertaining to distribution of the
36software without specific, written prior permission.
37
38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44SOFTWARE.
45
46************************************************************************/
47
48#define LARGE_COORDINATE1000000 1000000
49#define SMALL_COORDINATE-1000000 -LARGE_COORDINATE1000000
50
51#ifdef HAVE_CONFIG_H1
52#include <config.h>
53#endif
54#include "Xlibint.h"
55#include "Xutil.h"
56#include <X11/Xregion.h>
57#include "poly.h"
58
59/*
60 * InsertEdgeInET
61 *
62 * Insert the given edge into the edge table.
63 * First we must find the correct bucket in the
64 * Edge table, then find the right slot in the
65 * bucket. Finally, we can insert it.
66 *
67 */
68static void
69InsertEdgeInET(
70 EdgeTable *ET,
71 EdgeTableEntry *ETE,
72 int scanline,
73 ScanLineListBlock **SLLBlock,
74 int *iSLLBlock)
75{
76 register EdgeTableEntry *start, *prev;
77 register ScanLineList *pSLL, *pPrevSLL;
78 ScanLineListBlock *tmpSLLBlock;
79
80 /*
81 * find the right bucket to put the edge into
82 */
83 pPrevSLL = &ET->scanlines;
84 pSLL = pPrevSLL->next;
85 while (pSLL && (pSLL->scanline < scanline))
86 {
87 pPrevSLL = pSLL;
88 pSLL = pSLL->next;
89 }
90
91 /*
92 * reassign pSLL (pointer to ScanLineList) if necessary
93 */
94 if ((!pSLL) || (pSLL->scanline > scanline))
95 {
96 if (*iSLLBlock > SLLSPERBLOCK25-1)
97 {
98 tmpSLLBlock = Xmalloc(sizeof(ScanLineListBlock))malloc(((sizeof(ScanLineListBlock)) == 0 ? 1 : (sizeof(ScanLineListBlock
))))
;
99 (*SLLBlock)->next = tmpSLLBlock;
100 tmpSLLBlock->next = (ScanLineListBlock *)NULL((void*)0);
101 *SLLBlock = tmpSLLBlock;
102 *iSLLBlock = 0;
103 }
104 pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
105
106 pSLL->next = pPrevSLL->next;
107 pSLL->edgelist = (EdgeTableEntry *)NULL((void*)0);
108 pPrevSLL->next = pSLL;
109 }
110 pSLL->scanline = scanline;
111
112 /*
113 * now insert the edge in the right bucket
114 */
115 prev = (EdgeTableEntry *)NULL((void*)0);
116 start = pSLL->edgelist;
117 while (start && (start->bres.minor_axis < ETE->bres.minor_axis))
118 {
119 prev = start;
120 start = start->next;
121 }
122 ETE->next = start;
123
124 if (prev)
125 prev->next = ETE;
126 else
127 pSLL->edgelist = ETE;
128}
129
130/*
131 * CreateEdgeTable
132 *
133 * This routine creates the edge table for
134 * scan converting polygons.
135 * The Edge Table (ET) looks like:
136 *
137 * EdgeTable
138 * --------
139 * | ymax | ScanLineLists
140 * |scanline|-->------------>-------------->...
141 * -------- |scanline| |scanline|
142 * |edgelist| |edgelist|
143 * --------- ---------
144 * | |
145 * | |
146 * V V
147 * list of ETEs list of ETEs
148 *
149 * where ETE is an EdgeTableEntry data structure,
150 * and there is one ScanLineList per scanline at
151 * which an edge is initially entered.
152 *
153 */
154
155static void
156CreateETandAET(
157 register int count,
158 register XPoint *pts,
159 EdgeTable *ET,
160 EdgeTableEntry *AET,
161 register EdgeTableEntry *pETEs,
162 ScanLineListBlock *pSLLBlock)
163{
164 register XPoint *top, *bottom;
165 register XPoint *PrevPt, *CurrPt;
166 int iSLLBlock = 0;
167 int dy;
168
169 if (count < 2) return;
170
171 /*
172 * initialize the Active Edge Table
173 */
174 AET->next = (EdgeTableEntry *)NULL((void*)0);
175 AET->back = (EdgeTableEntry *)NULL((void*)0);
176 AET->nextWETE = (EdgeTableEntry *)NULL((void*)0);
177 AET->bres.minor_axis = SMALL_COORDINATE-1000000;
178
179 /*
180 * initialize the Edge Table.
181 */
182 ET->scanlines.next = (ScanLineList *)NULL((void*)0);
183 ET->ymax = SMALL_COORDINATE-1000000;
184 ET->ymin = LARGE_COORDINATE1000000;
185 pSLLBlock->next = (ScanLineListBlock *)NULL((void*)0);
186
187 PrevPt = &pts[count-1];
188
189 /*
190 * for each vertex in the array of points.
191 * In this loop we are dealing with two vertices at
192 * a time -- these make up one edge of the polygon.
193 */
194 while (count--)
195 {
196 CurrPt = pts++;
197
198 /*
199 * find out which point is above and which is below.
200 */
201 if (PrevPt->y > CurrPt->y)
202 {
203 bottom = PrevPt, top = CurrPt;
204 pETEs->ClockWise = 0;
205 }
206 else
207 {
208 bottom = CurrPt, top = PrevPt;
209 pETEs->ClockWise = 1;
210 }
211
212 /*
213 * don't add horizontal edges to the Edge table.
214 */
215 if (bottom->y != top->y)
216 {
217 pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */
218
219 /*
220 * initialize integer edge algorithm
221 */
222 dy = bottom->y - top->y;
223 BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres){ int dx; if ((dy) != 0) { pETEs->bres.minor_axis = (top->
x); dx = (bottom->x) - pETEs->bres.minor_axis; if (dx <
0) { pETEs->bres.m = dx / (dy); pETEs->bres.m1 = pETEs
->bres.m - 1; pETEs->bres.incr1 = -2 * dx + 2 * (dy) * pETEs
->bres.m1; pETEs->bres.incr2 = -2 * dx + 2 * (dy) * pETEs
->bres.m; pETEs->bres.d = 2 * pETEs->bres.m * (dy) -
2 * dx - 2 * (dy); } else { pETEs->bres.m = dx / (dy); pETEs
->bres.m1 = pETEs->bres.m + 1; pETEs->bres.incr1 = 2
* dx - 2 * (dy) * pETEs->bres.m1; pETEs->bres.incr2 = 2
* dx - 2 * (dy) * pETEs->bres.m; pETEs->bres.d = -2 * pETEs
->bres.m * (dy) + 2 * dx; } } }
;
224
225 InsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock);
226
227 if (PrevPt->y > ET->ymax)
228 ET->ymax = PrevPt->y;
229 if (PrevPt->y < ET->ymin)
230 ET->ymin = PrevPt->y;
231 pETEs++;
232 }
233
234 PrevPt = CurrPt;
235 }
236}
237
238/*
239 * loadAET
240 *
241 * This routine moves EdgeTableEntries from the
242 * EdgeTable into the Active Edge Table,
243 * leaving them sorted by smaller x coordinate.
244 *
245 */
246
247static void
248loadAET(
249 register EdgeTableEntry *AET,
250 register EdgeTableEntry *ETEs)
251{
252 register EdgeTableEntry *pPrevAET;
253 register EdgeTableEntry *tmp;
254
255 pPrevAET = AET;
256 AET = AET->next;
257 while (ETEs)
258 {
259 while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis))
260 {
261 pPrevAET = AET;
262 AET = AET->next;
263 }
264 tmp = ETEs->next;
265 ETEs->next = AET;
266 if (AET)
267 AET->back = ETEs;
268 ETEs->back = pPrevAET;
269 pPrevAET->next = ETEs;
270 pPrevAET = ETEs;
271
272 ETEs = tmp;
273 }
274}
275
276/*
277 * computeWAET
278 *
279 * This routine links the AET by the
280 * nextWETE (winding EdgeTableEntry) link for
281 * use by the winding number rule. The final
282 * Active Edge Table (AET) might look something
283 * like:
284 *
285 * AET
286 * ---------- --------- ---------
287 * |ymax | |ymax | |ymax |
288 * | ... | |... | |... |
289 * |next |->|next |->|next |->...
290 * |nextWETE| |nextWETE| |nextWETE|
291 * --------- --------- ^--------
292 * | | |
293 * V-------------------> V---> ...
294 *
295 */
296static void
297computeWAET(
298 register EdgeTableEntry *AET)
299{
300 register EdgeTableEntry *pWETE;
301 register int inside = 1;
302 register int isInside = 0;
303
304 AET->nextWETE = (EdgeTableEntry *)NULL((void*)0);
305 pWETE = AET;
306 AET = AET->next;
307 while (AET)
308 {
309 if (AET->ClockWise)
310 isInside++;
311 else
312 isInside--;
313
314 if ((!inside && !isInside) ||
315 ( inside && isInside))
316 {
317 pWETE->nextWETE = AET;
318 pWETE = AET;
319 inside = !inside;
320 }
321 AET = AET->next;
322 }
323 pWETE->nextWETE = (EdgeTableEntry *)NULL((void*)0);
324}
325
326/*
327 * InsertionSort
328 *
329 * Just a simple insertion sort using
330 * pointers and back pointers to sort the Active
331 * Edge Table.
332 *
333 */
334
335static int
336InsertionSort(
337 register EdgeTableEntry *AET)
338{
339 register EdgeTableEntry *pETEchase;
340 register EdgeTableEntry *pETEinsert;
341 register EdgeTableEntry *pETEchaseBackTMP;
342 register int changed = 0;
343
344 AET = AET->next;
345 while (AET)
346 {
347 pETEinsert = AET;
348 pETEchase = AET;
349 while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)
350 pETEchase = pETEchase->back;
351
352 AET = AET->next;
353 if (pETEchase != pETEinsert)
354 {
355 pETEchaseBackTMP = pETEchase->back;
356 pETEinsert->back->next = AET;
357 if (AET)
358 AET->back = pETEinsert->back;
359 pETEinsert->next = pETEchase;
360 pETEchase->back->next = pETEinsert;
361 pETEchase->back = pETEinsert;
362 pETEinsert->back = pETEchaseBackTMP;
363 changed = 1;
364 }
365 }
366 return(changed);
367}
368
369/*
370 * Clean up our act.
371 */
372static void
373FreeStorage(
374 register ScanLineListBlock *pSLLBlock)
375{
376 register ScanLineListBlock *tmpSLLBlock;
377
378 while (pSLLBlock)
379 {
380 tmpSLLBlock = pSLLBlock->next;
381 Xfree(pSLLBlock)free((pSLLBlock));
382 pSLLBlock = tmpSLLBlock;
383 }
384}
385
386/*
387 * Create an array of rectangles from a list of points.
388 * If indeed these things (POINTS, RECTS) are the same,
389 * then this proc is still needed, because it allocates
390 * storage for the array, which was allocated on the
391 * stack by the calling procedure.
392 *
393 */
394static int PtsToRegion(
395 register int numFullPtBlocks,
396 register int iCurPtBlock,
397 POINTBLOCK *FirstPtBlock,
398 REGION *reg)
399{
400 register BOX *rects;
401 register XPoint *pts;
402 register POINTBLOCK *CurPtBlock;
403 register int i;
404 register BOX *extents;
405 register int numRects;
406 BOX *prevRects = reg->rects;
407
408 extents = &reg->extents;
409
410 numRects = ((numFullPtBlocks * NUMPTSTOBUFFER200) + iCurPtBlock) >> 1;
411
412 if (!(reg->rects = Xrealloc(reg->rects, sizeof(BOX) * numRects)realloc((reg->rects), ((sizeof(BOX) * numRects) == 0 ? 1 :
(sizeof(BOX) * numRects)))
)) {
13
Within the expansion of the macro 'Xrealloc':
14
Assuming is not null
15
Taking false branch
413 Xfree(prevRects)free((prevRects));
414 return(0);
415 }
416
417 reg->size = numRects;
418 CurPtBlock = FirstPtBlock;
419 rects = reg->rects - 1;
420 numRects = 0;
421 extents->x1 = MAXSHORT32767, extents->x2 = MINSHORT-32767;
422
423 for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) {
16
Loop condition is true. Entering loop body
424 /* the loop uses 2 points per iteration */
425 i = NUMPTSTOBUFFER200 >> 1;
426 if (!numFullPtBlocks)
17
Taking true branch
427 i = iCurPtBlock >> 1;
428 for (pts = CurPtBlock->pts; i--; pts += 2) {
18
Loop condition is false. Execution continues on line 447
429 if (pts->x == pts[1].x)
430 continue;
431 if (numRects && pts->x == rects->x1 && pts->y == rects->y2 &&
432 pts[1].x == rects->x2 &&
433 (numRects == 1 || rects[-1].y1 != rects->y1) &&
434 (i && pts[2].y > pts[1].y)) {
435 rects->y2 = pts[1].y + 1;
436 continue;
437 }
438 numRects++;
439 rects++;
440 rects->x1 = pts->x; rects->y1 = pts->y;
441 rects->x2 = pts[1].x; rects->y2 = pts[1].y + 1;
442 if (rects->x1 < extents->x1)
443 extents->x1 = rects->x1;
444 if (rects->x2 > extents->x2)
445 extents->x2 = rects->x2;
446 }
447 CurPtBlock = CurPtBlock->next;
19
Assigned value is garbage or undefined
448 }
449
450 if (numRects) {
451 extents->y1 = reg->rects->y1;
452 extents->y2 = rects->y2;
453 } else {
454 extents->x1 = 0;
455 extents->y1 = 0;
456 extents->x2 = 0;
457 extents->y2 = 0;
458 }
459 reg->numRects = numRects;
460
461 return(TRUE1);
462}
463
464/*
465 * polytoregion
466 *
467 * Scan converts a polygon by returning a run-length
468 * encoding of the resultant bitmap -- the run-length
469 * encoding is in the form of an array of rectangles.
470 */
471Region
472XPolygonRegion(
473 XPoint *Pts, /* the pts */
474 int Count, /* number of pts */
475 int rule) /* winding rule */
476{
477 Region region;
478 register EdgeTableEntry *pAET; /* Active Edge Table */
479 register int y; /* current scanline */
480 register int iPts = 0; /* number of pts in buffer */
481 register EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/
482 register ScanLineList *pSLL; /* current scanLineList */
483 register XPoint *pts; /* output buffer */
484 EdgeTableEntry *pPrevAET; /* ptr to previous AET */
485 EdgeTable ET; /* header node for ET */
486 EdgeTableEntry AET; /* header node for AET */
487 EdgeTableEntry *pETEs; /* EdgeTableEntries pool */
488 ScanLineListBlock SLLBlock; /* header for scanlinelist */
489 int fixWAET = FALSE0;
490 POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */
491 POINTBLOCK *tmpPtBlock;
492 int numFullPtBlocks = 0;
493
494 if (! (region = XCreateRegion())) return (Region) NULL((void*)0);
1
Assuming 'region' is not null
2
Taking false branch
495
496 /* special case a rectangle */
497 pts = Pts;
498 if (((Count == 4) ||
3
Assuming 'Count' is not equal to 4
499 ((Count == 5) && (pts[4].x == pts[0].x) && (pts[4].y == pts[0].y))) &&
4
Assuming 'Count' is not equal to 5
500 (((pts[0].y == pts[1].y) &&
501 (pts[1].x == pts[2].x) &&
502 (pts[2].y == pts[3].y) &&
503 (pts[3].x == pts[0].x)) ||
504 ((pts[0].x == pts[1].x) &&
505 (pts[1].y == pts[2].y) &&
506 (pts[2].x == pts[3].x) &&
507 (pts[3].y == pts[0].y)))) {
508 region->extents.x1 = min(pts[0].x, pts[2].x)(((pts[0].x) < (pts[2].x)) ? (pts[0].x) : (pts[2].x));
509 region->extents.y1 = min(pts[0].y, pts[2].y)(((pts[0].y) < (pts[2].y)) ? (pts[0].y) : (pts[2].y));
510 region->extents.x2 = max(pts[0].x, pts[2].x)(((pts[0].x) > (pts[2].x)) ? (pts[0].x) : (pts[2].x));
511 region->extents.y2 = max(pts[0].y, pts[2].y)(((pts[0].y) > (pts[2].y)) ? (pts[0].y) : (pts[2].y));
512 if ((region->extents.x1 != region->extents.x2) &&
513 (region->extents.y1 != region->extents.y2)) {
514 region->numRects = 1;
515 *(region->rects) = region->extents;
516 }
517 return(region);
518 }
519
520 if (Count < 2) return region;
5
Assuming 'Count' is >= 2
6
Taking false branch
521
522 if (! (pETEs = Xmalloc(sizeof(EdgeTableEntry) * Count)malloc(((sizeof(EdgeTableEntry) * Count) == 0 ? 1 : (sizeof(EdgeTableEntry
) * Count)))
)) {
7
Assuming 'pETEs' is not null
8
Taking false branch
523 XDestroyRegion(region);
524 return (Region) NULL((void*)0);
525 }
526
527 pts = FirstPtBlock.pts;
528 CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock);
529 pSLL = ET.scanlines.next;
530 curPtBlock = &FirstPtBlock;
531
532 if (rule == EvenOddRule0) {
9
Assuming 'rule' is not equal to 0
10
Taking false branch
533 /*
534 * for each scanline
535 */
536 for (y = ET.ymin; y < ET.ymax; y++) {
537 /*
538 * Add a new edge to the active edge table when we
539 * get to the next edge.
540 */
541 if (pSLL != NULL((void*)0) && y == pSLL->scanline) {
542 loadAET(&AET, pSLL->edgelist);
543 pSLL = pSLL->next;
544 }
545 pPrevAET = &AET;
546 pAET = AET.next;
547
548 /*
549 * for each active edge
550 */
551 while (pAET) {
552 pts->x = pAET->bres.minor_axis, pts->y = y;
553 pts++, iPts++;
554
555 /*
556 * send out the buffer
557 */
558 if (iPts == NUMPTSTOBUFFER200) {
559 tmpPtBlock = Xmalloc(sizeof(POINTBLOCK))malloc(((sizeof(POINTBLOCK)) == 0 ? 1 : (sizeof(POINTBLOCK)))
)
;
560 curPtBlock->next = tmpPtBlock;
561 curPtBlock = tmpPtBlock;
562 pts = curPtBlock->pts;
563 numFullPtBlocks++;
564 iPts = 0;
565 }
566 EVALUATEEDGEEVENODD(pAET, pPrevAET, y){ if (pAET->ymax == y) { pPrevAET->next = pAET->next
; pAET = pPrevAET->next; if (pAET) pAET->back = pPrevAET
; } else { { if (pAET->bres.m1 > 0) { if (pAET->bres
.d > 0) { pAET->bres.minor_axis += pAET->bres.m1; pAET
->bres.d += pAET->bres.incr1; } else { pAET->bres.minor_axis
+= pAET->bres.m; pAET->bres.d += pAET->bres.incr2; }
} else { if (pAET->bres.d >= 0) { pAET->bres.minor_axis
+= pAET->bres.m1; pAET->bres.d += pAET->bres.incr1;
} else { pAET->bres.minor_axis += pAET->bres.m; pAET->
bres.d += pAET->bres.incr2; } } }; pPrevAET = pAET; pAET =
pAET->next; } }
;
567 }
568 (void) InsertionSort(&AET);
569 }
570 }
571 else {
572 /*
573 * for each scanline
574 */
575 for (y = ET.ymin; y < ET.ymax; y++) {
11
Loop condition is false. Execution continues on line 626
576 /*
577 * Add a new edge to the active edge table when we
578 * get to the next edge.
579 */
580 if (pSLL != NULL((void*)0) && y == pSLL->scanline) {
581 loadAET(&AET, pSLL->edgelist);
582 computeWAET(&AET);
583 pSLL = pSLL->next;
584 }
585 pPrevAET = &AET;
586 pAET = AET.next;
587 pWETE = pAET;
588
589 /*
590 * for each active edge
591 */
592 while (pAET) {
593 /*
594 * add to the buffer only those edges that
595 * are in the Winding active edge table.
596 */
597 if (pWETE == pAET) {
598 pts->x = pAET->bres.minor_axis, pts->y = y;
599 pts++, iPts++;
600
601 /*
602 * send out the buffer
603 */
604 if (iPts == NUMPTSTOBUFFER200) {
605 tmpPtBlock = Xmalloc(sizeof(POINTBLOCK))malloc(((sizeof(POINTBLOCK)) == 0 ? 1 : (sizeof(POINTBLOCK)))
)
;
606 curPtBlock->next = tmpPtBlock;
607 curPtBlock = tmpPtBlock;
608 pts = curPtBlock->pts;
609 numFullPtBlocks++; iPts = 0;
610 }
611 pWETE = pWETE->nextWETE;
612 }
613 EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET){ if (pAET->ymax == y) { pPrevAET->next = pAET->next
; pAET = pPrevAET->next; fixWAET = 1; if (pAET) pAET->back
= pPrevAET; } else { { if (pAET->bres.m1 > 0) { if (pAET
->bres.d > 0) { pAET->bres.minor_axis += pAET->bres
.m1; pAET->bres.d += pAET->bres.incr1; } else { pAET->
bres.minor_axis += pAET->bres.m; pAET->bres.d += pAET->
bres.incr2; } } else { if (pAET->bres.d >= 0) { pAET->
bres.minor_axis += pAET->bres.m1; pAET->bres.d += pAET->
bres.incr1; } else { pAET->bres.minor_axis += pAET->bres
.m; pAET->bres.d += pAET->bres.incr2; } } }; pPrevAET =
pAET; pAET = pAET->next; } }
;
614 }
615
616 /*
617 * recompute the winding active edge table if
618 * we just resorted or have exited an edge.
619 */
620 if (InsertionSort(&AET) || fixWAET) {
621 computeWAET(&AET);
622 fixWAET = FALSE0;
623 }
624 }
625 }
626 FreeStorage(SLLBlock.next);
627 (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
12
Calling 'PtsToRegion'
628 for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
629 tmpPtBlock = curPtBlock->next;
630 Xfree(curPtBlock)free((curPtBlock));
631 curPtBlock = tmpPtBlock;
632 }
633 Xfree(pETEs)free((pETEs));
634 return(region);
635}