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

📄 region.c

📁 linux下的一款播放器
💻 C
📖 第 1 页 / 共 4 页
字号:
 *      second, the overlapFunc is called to process the entire band. It *      is responsible for clipping the rectangles in the band, though *      this function provides the boundaries. *      At the end of each band, the new region is coalesced, if possible, *      to reduce the number of rectangles in the region. * *----------------------------------------------------------------------- *//* static void*/static void miRegionOp(    register _HXRegion  newReg,                 /* Place to store result */    _HXRegion           reg1,                   /* First region in operation */    _HXRegion           reg2,                   /* 2d region in operation */    overlapFunc         fpOverlapFunc,            /* Function to call for over-                                                 * lapping bands */    nonOverlapFunc      nonOverlap1Func,        /* Function to call for non-                                                 * overlapping bands in region                                                 * 1 */    nonOverlapFunc     nonOverlap2Func         /* Function to call for non-                                                 * overlapping bands in region                                                 * 2 */    ){    register HXBoxPtr   r1;                     /* Pointer into first region */    register HXBoxPtr   r2;                     /* Pointer into 2d region */    HXBoxPtr            r1End;                  /* End of 1st region */    HXBoxPtr            r2End;                  /* End of 2d region */    register short      ybot;                   /* Bottom of intersection */    register short      ytop;                   /* Top of intersection */    HXBoxPtr            oldRects;               /* Old rects for newReg */    int                 prevBand;               /* Index of start of                                                 * previous band in newReg */    int                 curBand;                /* Index of start of current                                                 * band in newReg */    register HXBoxPtr   r1BandEnd;              /* End of current band in r1 */    register HXBoxPtr   r2BandEnd;              /* End of current band in r2 */    short               top;                    /* Top of non-overlapping                                                 * band */    short               bot;                    /* Bottom of non-overlapping                                                 * band */        /*     * Initialization:     *  set r1, r2, r1End and r2End appropriately, preserve the important     * parts of the destination region until the end in case it's one of     * the two source regions, then mark the "new" region empty, allocating     * another array of rectangles for it to use.     */    r1 = reg1->rects;    r2 = reg2->rects;    r1End = r1 + reg1->numRects;    r2End = r2 + reg2->numRects;        oldRects = newReg->rects;        EMPTY_REGION(newReg);    /*     * Allocate a reasonable number of rectangles for the new region. The idea     * is to allocate enough so the individual functions don't need to     * reallocate and copy the array, which is time consuming, yet we don't     * have to worry about using too much memory. I hope to be able to     * nuke the Xrealloc() at the end of this function eventually.     */    newReg->size = max(reg1->numRects,reg2->numRects) * 2;    if (! (newReg->rects = (HXBoxPtr)           malloc ((unsigned) (sizeof(HXBOX) * newReg->size)))) {        newReg->size = 0;        return;    }        /*     * Initialize ybot and ytop.     * In the upcoming loop, ybot and ytop serve different functions depending     * on whether the band being handled is an overlapping or non-overlapping     * band.     *  In the case of a non-overlapping band (only one of the regions     * has points in the band), ybot is the bottom of the most recent     * intersection and thus clips the top of the rectangles in that band.     * ytop is the top of the next intersection between the two regions and     * serves to clip the bottom of the rectangles in the current band.     *  For an overlapping band (where the two regions intersect), ytop clips     * the top of the rectangles of both regions and ybot clips the bottoms.     */    if (reg1->extents.y1 < reg2->extents.y1)        ybot = reg1->extents.y1;    else        ybot = reg2->extents.y1;        /*     * prevBand serves to mark the start of the previous band so rectangles     * can be coalesced into larger rectangles. qv. miCoalesce, above.     * In the beginning, there is no previous band, so prevBand == curBand     * (curBand is set later on, of course, but the first band will always     * start at index 0). prevBand and curBand must be indices because of     * the possible expansion, and resultant moving, of the new region's     * array of rectangles.     */    prevBand = 0;        do    {        curBand = newReg->numRects;        /*         * This algorithm proceeds one source-band (as opposed to a         * destination band, which is determined by where the two regions         * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the         * rectangle after the last one in the current band for their         * respective regions.         */        r1BandEnd = r1;        while ((r1BandEnd != r1End) && (r1BandEnd->y1 == r1->y1))        {            r1BandEnd++;        }                r2BandEnd = r2;        while ((r2BandEnd != r2End) && (r2BandEnd->y1 == r2->y1))        {            r2BandEnd++;        }                /*         * First handle the band that doesn't intersect, if any.         *         * Note that attention is restricted to one band in the         * non-intersecting region at once, so if a region has n         * bands between the current position and the next place it overlaps         * the other, this entire loop will be passed through n times.         */        if (r1->y1 < r2->y1)        {            top = max(r1->y1,ybot);            bot = min(r1->y2,r2->y1);            if ((top != bot) && (nonOverlap1Func != NULL))            {                (*nonOverlap1Func)(newReg, r1, r1BandEnd, top, bot);            }            ytop = r2->y1;        }        else if (r2->y1 < r1->y1)        {            top = max(r2->y1,ybot);            bot = min(r2->y2,r1->y1);            if ((top != bot) && (nonOverlap2Func != NULL ))            {                (* nonOverlap2Func) (newReg, r2, r2BandEnd, top, bot);            }            ytop = r1->y1;        }        else        {            ytop = r1->y1;        }        /*         * If any rectangles got added to the region, try and coalesce them         * with rectangles from the previous band. Note we could just do         * this test in miCoalesce, but some machines incur a not         * inconsiderable cost for function calls, so...         */        if (newReg->numRects != curBand)        {            prevBand = miCoalesce (newReg, prevBand, curBand);        }        /*         * Now see if we've hit an intersecting band. The two bands only         * intersect if ybot > ytop         */        ybot = min(r1->y2, r2->y2);        curBand = newReg->numRects;        if (ybot > ytop)        {            (* fpOverlapFunc) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);        }                if (newReg->numRects != curBand)        {            prevBand = miCoalesce (newReg, prevBand, curBand);        }        /*         * If we've finished with a band (y2 == ybot) we skip forward         * in the region to the next band.         */        if (r1->y2 == ybot)        {            r1 = r1BandEnd;        }        if (r2->y2 == ybot)        {            r2 = r2BandEnd;        }    } while ((r1 != r1End) && (r2 != r2End));    /*     * Deal with whichever region still has rectangles left.     */    curBand = newReg->numRects;    if (r1 != r1End)    {        if (nonOverlap1Func != NULL)        {            do            {                r1BandEnd = r1;                while ((r1BandEnd < r1End) && (r1BandEnd->y1 == r1->y1))                {                    r1BandEnd++;                }                (* nonOverlap1Func) (newReg, r1, r1BandEnd,                                     max(r1->y1,ybot), r1->y2);                r1 = r1BandEnd;            } while (r1 != r1End);        }    }    else if ((r2 != r2End) && (nonOverlap2Func != NULL))    {        do        {            r2BandEnd = r2;            while ((r2BandEnd < r2End) && (r2BandEnd->y1 == r2->y1))            {                 r2BandEnd++;            }            (* nonOverlap2Func) (newReg, r2, r2BandEnd,                                max(r2->y1,ybot), r2->y2);            r2 = r2BandEnd;        } while (r2 != r2End);    }    if (newReg->numRects != curBand)    {        (void) miCoalesce (newReg, prevBand, curBand);    }    /*     * A bit of cleanup. To keep regions from growing without bound,     * we shrink the array of rectangles to match the new number of     * rectangles in the region. This never goes to 0, however...     *     * Only do this stuff if the number of rectangles allocated is more than     * twice the number of rectangles in the region (a simple optimization...).     */    if (newReg->numRects < (newReg->size >> 1))    {        if (REGION_NOT_EMPTY(newReg))        {            HXBoxPtr prev_rects = newReg->rects;            newReg->size = newReg->numRects;            newReg->rects = (HXBoxPtr) realloc ((char *) newReg->rects,                                   (unsigned) (sizeof(HXBOX) * newReg->size));            if (! newReg->rects)                newReg->rects = prev_rects;        }        else        {            /*             * No point in doing the extra work involved in an Xrealloc if             * the region is empty             */            newReg->size = 1;            free((char *) newReg->rects);            newReg->rects = (HXBoxPtr) malloc(sizeof(HXBOX));        }    }    free ((char *) oldRects);    return;}/*====================================================================== *          _HXRegion Union *====================================================================*//*- *----------------------------------------------------------------------- * miUnionNonO -- *      Handle a non-overlapping band for the union operation. Just *      Adds the rectangles into the region. Doesn't have to check for *      subsumption or anything. * * Results: *      None. * * Side Effects: *      pReg->numRects is incremented and the final rectangles overwritten *      with the rectangles we're passed. * *----------------------------------------------------------------------- *//* static void*/static intmiUnionNonO( register _HXRegion  pReg,             register HXBoxPtr   r,             HXBoxPtr            rEnd,             register short      y1,             register short      y2             ){    register HXBoxPtr   pNextRect;    pNextRect = &pReg->rects[pReg->numRects];    /* assert(y1 < y2); */    while (r != rEnd)    {        /* assert(r->x1 < r->x2); */        MEMCHECK(pReg, pNextRect, pReg->rects);        pNextRect->x1 = r->x1;        pNextRect->y1 = y1;        pNextRect->x2 = r->x2;        pNextRect->y2 = y2;        pReg->numRects += 1;        pNextRect++;        /* assert(pReg->numRects<=pReg->size); */        r++;    }    return 0;}/*- *----------------------------------------------------------------------- * miUnionO -- *      Handle an overlapping band for the union operation. Picks the *      left-most rectangle each time and merges it into the region. * * Results: *      None. * * Side Effects: *      Rectangles are overwritten in pReg->rects and pReg->numRects will *      be changed. * *----------------------------------------------------------------------- *//* static void*/static int miUnionO( register _HXRegion  pReg,                     register HXBoxPtr   r1,                     HXBoxPtr            r1End,                     register HXBoxPtr   r2,                     HXBoxPtr            r2End,                     register short      y1,                     register short      y2                     ){    register HXBoxPtr   pNextRect;        pNextRect = &pReg->rects[pReg->numRects];#define MERGERECT(r) \    if ((pReg->numRects != 0) &&  \        (pNextRect[-1].y1 == y1) &&  \        (pNextRect[-1].y2 == y2) &&  \        (pNextRect[-1].x2 >= r->x1))  \    {  \        if (pNextRect[-1].x2 < r->x2)  \        {  \            pNextRect[-1].x2 = r->x2;  \            /* assert(pNextRect[-1].x1<pNextRect[-1].x2); */ \        }  \    }  \    else  \    {  \        MEMCHECK(pReg, pNextRect, pReg->rects);  \        pNextRect->y1 = y1;  \        pNextRect->y2 = y2;  \        pNextRect->x1 = r->x1;  \        pNextRect->x2 = r->x2;  \        pReg->numRects += 1;  \        pNextRect += 1;  \    }  \    /* assert(pReg->numRects<=pReg->size); */ \    r++;        /* assert (y1<y2); */    while ((r1 != r1End) && (r2 != r2End))    {        if (r1->x1 < r2->x1)        {            MERGERECT(r1);        }        else        {            MERGERECT(r2);        }    }        if (r1 != r1End)    {        do        {            MERGERECT(r1);        } while (r1 != r1End);    }    else while (r2 != r2End)    {        MERGERECT(r2);    }    return 0;   /* lint */}int HXUnionRegion(_HXRegion reg1, _HXRegion reg2, _HXRegion newReg){    /*  checks all the simple cases */    /*     * _HXRegion 1 and 2 are the same or region 1 is empty     */    if ( (reg1 == reg2) || (!(reg1->numRects)) )    {        if (newReg != reg2)            miRegionCopy(newReg, reg2);        return 1;    }    /*     * if nothing to union (region 2 empty)     */    if (!(reg2->numRects))    {        if (newReg != reg1)            miRegionCopy(newReg, reg1);        return 1;    }    /*     * _HXRegion 1 completely subsumes region 2     */    if ((reg1->numRects == 1) &&         (reg1->extents.x1 <= reg2->extents.x1) &&        (reg1->extents.y1 <= reg2->extents.y1) &&        (reg1->extents.x2 >= reg2->extents.x2) &&        (reg1->extents.y2 >= reg2->extents.y2))    {        if (newReg != reg1)            miRegionCopy(newReg, reg1);        return 1;    }    /*

⌨️ 快捷键说明

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