⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpolyreg.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
 * *     Just a simple insertion sort using *     pointers and back pointers to sort the Active *     Edge Table. * */static intInsertionSort(AET)    register EdgeTableEntry *AET;{    register EdgeTableEntry *pETEchase;    register EdgeTableEntry *pETEinsert;    register EdgeTableEntry *pETEchaseBackTMP;    register int changed = 0;    AET = AET->next;    while (AET)     {        pETEinsert = AET;        pETEchase = AET;        while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)            pETEchase = pETEchase->back;        AET = AET->next;        if (pETEchase != pETEinsert)         {            pETEchaseBackTMP = pETEchase->back;            pETEinsert->back->next = AET;            if (AET)                AET->back = pETEinsert->back;            pETEinsert->next = pETEchase;            pETEchase->back->next = pETEinsert;            pETEchase->back = pETEinsert;            pETEinsert->back = pETEchaseBackTMP;            changed = 1;        }    }    return(changed);}/* *     Clean up our act. */static voidFreeStorage(pSLLBlock)    register ScanLineListBlock   *pSLLBlock;{    register ScanLineListBlock   *tmpSLLBlock;    while (pSLLBlock)     {        tmpSLLBlock = pSLLBlock->next;        Xfree((char *)pSLLBlock);        pSLLBlock = tmpSLLBlock;    }}/* *     Create an array of rectangles from a list of points. *     If indeed these things (POINTS, RECTS) are the same, *     then this proc is still needed, because it allocates *     storage for the array, which was allocated on the *     stack by the calling procedure. * */static int PtsToRegion(numFullPtBlocks, iCurPtBlock, FirstPtBlock, reg)    register int  numFullPtBlocks, iCurPtBlock;    POINTBLOCK *FirstPtBlock;    REGION *reg;{    register BOX  *rects;    register XPoint *pts;    register POINTBLOCK *CurPtBlock;    register int i;    register BOX *extents;    register int numRects;     extents = &reg->extents;     numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;     if (!(reg->rects = (BOX *)Xrealloc((char *)reg->rects, 	    (unsigned) (sizeof(BOX) * numRects))))       return(0);     reg->size = numRects;    CurPtBlock = FirstPtBlock;    rects = reg->rects - 1;    numRects = 0;    extents->x1 = MAXSHORT,  extents->x2 = MINSHORT;     for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) {	/* the loop uses 2 points per iteration */	i = NUMPTSTOBUFFER >> 1;	if (!numFullPtBlocks)	    i = iCurPtBlock >> 1;	for (pts = CurPtBlock->pts; i--; pts += 2) {	    if (pts->x == pts[1].x)		continue;	    if (numRects && pts->x == rects->x1 && pts->y == rects->y2 &&		pts[1].x == rects->x2 &&		(numRects == 1 || rects[-1].y1 != rects->y1) &&		(!i || pts[2].y > pts[1].y)) {		rects->y2 = pts[1].y + 1;		continue;	    }	    numRects++;	    rects++;	    rects->x1 = pts->x;  rects->y1 = pts->y;	    rects->x2 = pts[1].x;  rects->y2 = pts[1].y + 1;	    if (rects->x1 < extents->x1)		extents->x1 = rects->x1;	    if (rects->x2 > extents->x2)		extents->x2 = rects->x2;        }	CurPtBlock = CurPtBlock->next;    }    if (numRects) {	extents->y1 = reg->rects->y1;	extents->y2 = rects->y2;    } else {	extents->x1 = 0;	extents->y1 = 0;	extents->x2 = 0;	extents->y2 = 0;    }    reg->numRects = numRects;     return(TRUE);}/* *     polytoregion * *     Scan converts a polygon by returning a run-length *     encoding of the resultant bitmap -- the run-length *     encoding is in the form of an array of rectangles. */Region XPolygonRegion(Pts, Count, rule)    int       Count;                 /* number of pts           */    XPoint     *Pts;		     /* the pts                 */    int	rule;			     /* winding rule */{    Region region;    register EdgeTableEntry *pAET;   /* Active Edge Table       */    register int y;                  /* current scanline        */    register int iPts = 0;           /* number of pts in buffer */    register EdgeTableEntry *pWETE;  /* Winding Edge Table Entry*/    register ScanLineList *pSLL;     /* current scanLineList    */    register XPoint *pts;             /* output buffer           */    EdgeTableEntry *pPrevAET;        /* ptr to previous AET     */    EdgeTable ET;                    /* header node for ET      */    EdgeTableEntry AET;              /* header node for AET     */    EdgeTableEntry *pETEs;           /* EdgeTableEntries pool   */    ScanLineListBlock SLLBlock;      /* header for scanlinelist */    int fixWAET = FALSE;    POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers    */    POINTBLOCK *tmpPtBlock;    int numFullPtBlocks = 0;     if (! (region = XCreateRegion())) return (Region) NULL;    /* special case a rectangle */    pts = Pts;    if (((Count == 4) ||	 ((Count == 5) && (pts[4].x == pts[0].x) && (pts[4].y == pts[0].y))) &&	(((pts[0].y == pts[1].y) &&	  (pts[1].x == pts[2].x) &&	  (pts[2].y == pts[3].y) &&	  (pts[3].x == pts[0].x)) ||	 ((pts[0].x == pts[1].x) &&	  (pts[1].y == pts[2].y) &&	  (pts[2].x == pts[3].x) &&	  (pts[3].y == pts[0].y)))) {	region->extents.x1 = min(pts[0].x, pts[2].x);	region->extents.y1 = min(pts[0].y, pts[2].y);	region->extents.x2 = max(pts[0].x, pts[2].x);	region->extents.y2 = max(pts[0].y, pts[2].y);	if ((region->extents.x1 != region->extents.x2) &&	    (region->extents.y1 != region->extents.y2)) {	    region->numRects = 1;	    *(region->rects) = region->extents;	}	return(region);    }    if (! (pETEs = (EdgeTableEntry *)	   Xmalloc((unsigned) (sizeof(EdgeTableEntry) * Count))))	return (Region) NULL;    pts = FirstPtBlock.pts;    CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock);    pSLL = ET.scanlines.next;    curPtBlock = &FirstPtBlock;     if (rule == EvenOddRule) {        /*         *  for each scanline         */        for (y = ET.ymin; y < ET.ymax; y++) {            /*             *  Add a new edge to the active edge table when we             *  get to the next edge.             */            if (pSLL != NULL && y == pSLL->scanline) {                loadAET(&AET, pSLL->edgelist);                pSLL = pSLL->next;            }            pPrevAET = &AET;            pAET = AET.next;             /*             *  for each active edge             */            while (pAET) {                pts->x = pAET->bres.minor_axis,  pts->y = y;                pts++, iPts++;                 /*                 *  send out the buffer                 */                if (iPts == NUMPTSTOBUFFER) {                    tmpPtBlock = (POINTBLOCK *)Xmalloc(sizeof(POINTBLOCK));                    curPtBlock->next = tmpPtBlock;                    curPtBlock = tmpPtBlock;                    pts = curPtBlock->pts;                    numFullPtBlocks++;                    iPts = 0;                }                EVALUATEEDGEEVENODD(pAET, pPrevAET, y);            }            (void) InsertionSort(&AET);        }    }    else {        /*         *  for each scanline         */        for (y = ET.ymin; y < ET.ymax; y++) {            /*             *  Add a new edge to the active edge table when we             *  get to the next edge.             */            if (pSLL != NULL && y == pSLL->scanline) {                loadAET(&AET, pSLL->edgelist);                computeWAET(&AET);                pSLL = pSLL->next;            }            pPrevAET = &AET;            pAET = AET.next;            pWETE = pAET;             /*             *  for each active edge             */            while (pAET) {                /*                 *  add to the buffer only those edges that                 *  are in the Winding active edge table.                 */                if (pWETE == pAET) {                    pts->x = pAET->bres.minor_axis,  pts->y = y;                    pts++, iPts++;                     /*                     *  send out the buffer                     */                    if (iPts == NUMPTSTOBUFFER) {                        tmpPtBlock = (POINTBLOCK *)Xmalloc(sizeof(POINTBLOCK));                        curPtBlock->next = tmpPtBlock;                        curPtBlock = tmpPtBlock;                        pts = curPtBlock->pts;                        numFullPtBlocks++;    iPts = 0;                    }                    pWETE = pWETE->nextWETE;                }                EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);            }             /*             *  recompute the winding active edge table if             *  we just resorted or have exited an edge.             */            if (InsertionSort(&AET) || fixWAET) {                computeWAET(&AET);                fixWAET = FALSE;            }        }    }    FreeStorage(SLLBlock.next);	    (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);    for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {	tmpPtBlock = curPtBlock->next;	Xfree((char *)curPtBlock);	curPtBlock = tmpPtBlock;    }    Xfree((char *)pETEs);    return(region);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -