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

📄 winrgn.c

📁 MinGUI 可视化程序代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 *
 * Side Effects:
 *      Rectangles are overwritten in region->rects and region->numRects will
 *      be changed.
 *
 */
static void  REGION_UnionO(TREGION *region, const TClipRect  *r1, const TClipRect  *r1End,
                           const TClipRect  *r2, const TClipRect  *r2End, int top, int bottom)
{
    TClipRect  *newcliprect;
    
#define MERGERECT(r) \
    if ((region->head) &&  \
        (region->tail->rc.top == top) &&  \
        (region->tail->rc.bottom == bottom) &&  \
        (region->tail->rc.right >= r->rc.left))  \
    {  \
        if (region->tail->rc.right < r->rc.right)  \
        {  \
            region->tail->rc.right = r->rc.right;  \
        }  \
    }  \
    else  \
    {  \
        NEWCLIPRECT(region, newcliprect);  \
        newcliprect->rc.top = top;  \
        newcliprect->rc.bottom = bottom;  \
        newcliprect->rc.left = r->rc.left;  \
        newcliprect->rc.right = r->rc.right;  \
    }  \
    r = r->next;
    
    while ((r1 != r1End) && (r2 != r2End))
    {
        if (r1->rc.left < r2->rc.left)
        {
            MERGERECT(r1);
        }
        else
        {
            MERGERECT(r2);
        }
    }
    
    if (r1 != r1End)
    {
        do {
            MERGERECT(r1);
        } while (r1 != r1End);
    }
    else while (r2 != r2End)
    {
        MERGERECT(r2);
    }
}

/***********************************************************************
 *             Region Subtraction
 ***********************************************************************/

/***********************************************************************
 *             REGION_SubtractNonO1
 *
 *      Deal with non-overlapping band for subtraction. Any parts from
 *      region 2 we discard. Anything from region 1 we add to the region.
 *
 * Results:
 *      None.
 *
 * Side Effects:
 *      region may be affected.
 *
 */
static void REGION_SubtractNonO1 (TREGION *region, const TClipRect  *r, const TClipRect  *rEnd,
                        int top, int bottom)
{
    TClipRect  *newcliprect;
        
    while (r != rEnd) {
        NEWCLIPRECT(region, newcliprect);
        newcliprect->rc.left = r->rc.left;
        newcliprect->rc.top = top;
        newcliprect->rc.right = r->rc.right;
        newcliprect->rc.bottom = bottom;
        r = r->next;
    }
}


/***********************************************************************
 *             REGION_SubtractO
 *
 *      Overlapping band subtraction. x1 is the left-most point not yet
 *      checked.
 *
 * Results:
 *      None.
 *
 * Side Effects:
 *      region may have rectangles added to it.
 *
 */
static void REGION_SubtractO (TREGION *region, const TClipRect  *r1, const TClipRect  *r1End,
                        const TClipRect  *r2, const TClipRect  *r2End, int top, int bottom)
{
    TClipRect  *newcliprect;
    int left;
    
    left = r1->rc.left;
    while ((r1 != r1End) && (r2 != r2End)) {
        if (r2->rc.right <= left) {
            /*
             * Subtrahend missed the boat: go to next subtrahend.
             */
            r2 = r2->next;
        }
        else if (r2->rc.left <= left)
        {
            /*
             * Subtrahend preceeds minuend: nuke left edge of minuend.
             */
            left = r2->rc.right;
            if (left >= r1->rc.right)
            {
                /*
                 * Minuend completely covered: advance to next minuend and
                 * reset left fence to edge of new minuend.
                 */
                r1 = r1->next;
                if (r1 != r1End)
                    left = r1->rc.left;
            }
            else
            {
                /*
                 * Subtrahend now used up since it doesn't extend beyond
                 * minuend
                 */
                r2 = r2->next;
            }
        }
        else if (r2->rc.left < r1->rc.right)
        {
            /*
             * Left part of subtrahend covers part of minuend: add uncovered
             * part of minuend to region and skip to next subtrahend.
             */
            NEWCLIPRECT(region, newcliprect);
            newcliprect->rc.left = left;
            newcliprect->rc.top = top;
            newcliprect->rc.right = r2->rc.left;
            newcliprect->rc.bottom = bottom;
            left = r2->rc.right;
            if (left >= r1->rc.right)
            {
                /*
                 * Minuend used up: advance to new...
                 */
                r1 = r1->next;
                if (r1 != r1End)
                    left = r1->rc.left;
            }
            else
            {
                /*
                 * Subtrahend used up
                 */
                r2 = r2->next;
            }
        }
        else
        {
            /*
             * Minuend used up: add any remaining piece before advancing.
             */
            if (r1->rc.right > left)
            {
                NEWCLIPRECT(region, newcliprect);
                newcliprect->rc.left = left;
                newcliprect->rc.top = top;
                newcliprect->rc.right = r1->rc.right;
                newcliprect->rc.bottom = bottom;
            }
            r1 = r1->next;
            if (r1 != r1End)
                left = r1->rc.left;
        }
    }

    /*
     * Add remaining minuend rectangles to region.
     */
    while (r1 != r1End)
    {
        NEWCLIPRECT(region, newcliprect);
        newcliprect->rc.left = left;
        newcliprect->rc.top = top;
        newcliprect->rc.right = r1->rc.right;
        newcliprect->rc.bottom = bottom;
        r1 = r1->next;
        if (r1 != r1End)
            left = r1->rc.left;
    }
}

/***********************************************************************
 *             IntersectRegion
 */
void RegionIntersect(TREGION *dst, const TREGION *src1, const TREGION *src2)
{
    /* check for trivial reject */
    if ( (!(src1->head)) || (!(src2->head))  ||  (!IsRectOverlap(&src1->rcBound, &src2->rcBound)))
    {  ClearRegion (dst);
    }
    else
    {  REGION_RegionOp (dst, src1, src2, REGION_IntersectO, NULL, NULL);
       REGION_SetExtents(dst);
       dst->type = (dst->head) ? COMPLEXREGION : NULLREGION ;
    }
}

/***********************************************************************
 *             SubtractRegion
 *
 *      Subtract rgnS from rgnM and leave the result in rgnD.
 *      S stands for subtrahend, M for minuend and D for difference.
 *
 * Results:
 *      true.
 *
 * Side Effects:
 *      regD is overwritten.
 *
 */
void RegionSubtract (TREGION *rgnD, const TREGION *rgnM, const TREGION *rgnS)
{
    /* check for trivial reject */
    if ( (!(rgnM->head)) || (!(rgnS->head))  || (!IsRectOverlap(&rgnM->rcBound, &rgnS->rcBound)) )
    {  RegionCopy (rgnD, rgnM);
    }
    else
    {   REGION_RegionOp (rgnD, rgnM, rgnS, REGION_SubtractO,REGION_SubtractNonO1, NULL);

        REGION_SetExtents (rgnD);
        rgnD->type = (rgnD->head) ? COMPLEXREGION : NULLREGION;
    }
}    
/***********************************************************************
 *             UnionRegion
 */
void RegionUnion (TREGION *dst, const TREGION *src1, const TREGION *src2)
{   int boundLeft,boundRight;
    /*  checks all the simple cases */

    /*
     * Region 1 and 2 are the same or region 1 is empty
     */
    if ( (src1 == src2) || (!(src1->head)) )
    { if (dst != src2)
          RegionCopy (dst, src2);
       return;
    }

    /*
     * if nothing to union (region 2 empty)
     */
    if (!(src2->head))
    { if (dst != src1)
        RegionCopy (dst, src1);
       return;
    }

	
    /*
     * Region 1 completely subsumes region 2
     */
    if (src1->head == src1->tail && RectInRect(&src2->rcBound,&src1->rcBound) )
    {   if (dst != src1)
            RegionCopy (dst, src1);
        return;
    }

    /*
     * Region 2 completely subsumes region 1
     */
    if (src2->head == src2->tail && RectInRect(&src1->rcBound,&src2->rcBound) )
    {   if (dst != src2)
            RegionCopy(dst, src2);
        return;
    }

	boundLeft=min (src1->rcBound.left, src2->rcBound.left);
	boundRight=max (src1->rcBound.right, src2->rcBound.right);

    REGION_RegionOp (dst, src1, src2, REGION_UnionO, REGION_UnionNonO, REGION_UnionNonO);

    dst->rcBound.left = boundLeft;
    dst->rcBound.top = dst->head->rc.top;
    dst->rcBound.right = boundRight;
    dst->rcBound.bottom = dst->tail->rc.bottom;
    dst->type = (dst->head) ? COMPLEXREGION : NULLREGION ;
}

/* XorRegion */
void RegionXor (TREGION *dst, const TREGION *src1, const TREGION *src2)
{
    TREGION tmpa, tmpb;

    InitRegion(&tmpa, src1->heap);
    InitRegion(&tmpb, src2->heap);

    RegionSubtract(&tmpa, src1, src2);
    RegionSubtract(&tmpb, src2, src1);
    RegionUnion(dst, &tmpa, &tmpb);

    ClearRegion(&tmpa);
    ClearRegion(&tmpb);
}

/* Adds a rectangle to a region */
void RegionUnionRect (TREGION *region, const TRECT *rect)
{   if (!IsRectEmpty(rect))
    { TREGION my_region;
      TClipRect  my_cliprect;

      my_cliprect.rc = *rect;
      my_cliprect.next = NULL;
      my_cliprect.prev = NULL;

      my_region.type = SIMPLEREGION;
      my_region.rcBound = *rect;
      my_region.head = &my_cliprect;
      my_region.tail = &my_cliprect;
      my_region.heap = NULL;

      RegionUnion(region, region, &my_region);
    }
}

/* Intersect a rect with a region */
void RegionIntersectRect (TREGION *region, const TRECT* rect)
{   if(IsRegionEmpty(region)) return;
	if(!IsRectEmpty(rect) && IsRectOverlap(&region->rcBound,rect) )
    { if(!RectInRect(&region->rcBound,rect))
	  { TREGION my_region;
        TClipRect  my_cliprect;
        my_cliprect.rc = *rect;
        my_cliprect.next = NULL;
        my_cliprect.prev = NULL;
        my_region.type = SIMPLEREGION;
        my_region.rcBound = *rect;
        my_region.head = &my_cliprect;
        my_region.tail = &my_cliprect;
        my_region.heap = NULL;

        REGION_RegionOp(region, region, &my_region, REGION_IntersectO, NULL, NULL);
        REGION_SetExtents(region);
        region->type = (region->head) ? COMPLEXREGION : NULLREGION ;
	  }else return; 
    }
	else
	{ ClearRegion(region);
	}
}

void RegionSubtractRect(TREGION *region, const TRECT* rect)
{   if(!IsRegionEmpty(region) && !IsRectEmpty(rect) && IsRectOverlap(&region->rcBound,rect))
    { if(!RectInRect(&region->rcBound,rect))
	  { TREGION my_region;
        TClipRect  my_cliprect;
        my_cliprect.rc = *rect;
        my_cliprect.next = NULL;
        my_cliprect.prev = NULL;

        my_region.type = SIMPLEREGION;
        my_region.rcBound = *rect;
        my_region.head = &my_cliprect;
        my_region.tail = &my_cliprect;
        my_region.heap = NULL;
       
		REGION_RegionOp(region, region, &my_region, REGION_SubtractO,REGION_SubtractNonO1, NULL);
        REGION_SetExtents(region);
        region->type = (region->head) ? COMPLEXREGION : NULLREGION;
      }
      else
	  { ClearRegion(region);
	  }
    }  
}



⌨️ 快捷键说明

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