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

📄 qregion_unix.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    int top;                    // Top of non-overlapping band    int 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.data();    r2 = reg2->rects.data();    r1End = r1 + reg1->numRects;    r2End = r2 + reg2->numRects;    QVector<QRect> oldRects = dest.rects;    dest.numRects = 0;    /*     * 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 realloc() at the end of this function eventually.     */    dest.rects.resize(qMax(reg1->numRects,reg2->numRects) * 2);    /*     * 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.top() < reg2->extents.top())        ybot = reg1->extents.top() - 1;    else        ybot = reg2->extents.top() - 1;    /*     * 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 = dest.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->top() == r1->top())            ++r1BandEnd;        r2BandEnd = r2;        while (r2BandEnd != r2End && r2BandEnd->top() == r2->top())            ++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->top() < r2->top()) {            top = qMax(r1->top(), ybot + 1);            bot = qMin(r1->bottom(), r2->top() - 1);            if (nonOverlap1Func != 0 && bot >= top)                (*nonOverlap1Func)(dest, r1, r1BandEnd, top, bot);            ytop = r2->top();        } else if (r2->top() < r1->top()) {            top = qMax(r2->top(), ybot + 1);            bot = qMin(r2->bottom(), r1->top() - 1);            if (nonOverlap2Func != 0 && bot >= top)                (*nonOverlap2Func)(dest, r2, r2BandEnd, top, bot);            ytop = r1->top();        } else {            ytop = r1->top();        }        /*         * 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 (dest.numRects != curBand)            prevBand = miCoalesce(dest, prevBand, curBand);        /*         * Now see if we've hit an intersecting band. The two bands only         * intersect if ybot >= ytop         */        ybot = qMin(r1->bottom(), r2->bottom());        curBand = dest.numRects;        if (ybot >= ytop)            (*overlapFunc)(dest, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);        if (dest.numRects != curBand)            prevBand = miCoalesce(dest, prevBand, curBand);        /*         * If we've finished with a band (y2 == ybot) we skip forward         * in the region to the next band.         */        if (r1->bottom() == ybot)            r1 = r1BandEnd;        if (r2->bottom() == ybot)            r2 = r2BandEnd;    } while (r1 != r1End && r2 != r2End);    /*     * Deal with whichever region still has rectangles left.     */    curBand = dest.numRects;    if (r1 != r1End) {        if (nonOverlap1Func != 0) {            do {                r1BandEnd = r1;                while (r1BandEnd < r1End && r1BandEnd->top() == r1->top())                    ++r1BandEnd;                (*nonOverlap1Func)(dest, r1, r1BandEnd, qMax(r1->top(), ybot + 1), r1->bottom());                r1 = r1BandEnd;            } while (r1 != r1End);        }    } else if ((r2 != r2End) && (nonOverlap2Func != 0)) {        do {            r2BandEnd = r2;            while (r2BandEnd < r2End && r2BandEnd->top() == r2->top())                 ++r2BandEnd;            (*nonOverlap2Func)(dest, r2, r2BandEnd, qMax(r2->top(), ybot + 1), r2->bottom());            r2 = r2BandEnd;        } while (r2 != r2End);    }    if (dest.numRects != curBand)        (void)miCoalesce(dest, 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.     *     * 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 (qMax(4, dest.numRects) < (dest.rects.size() >> 1))        dest.rects.resize(dest.numRects);}/*====================================================================== *          Region 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: *      dest.numRects is incremented and the final rectangles overwritten *      with the rectangles we're passed. * *----------------------------------------------------------------------- */static void miUnionNonO(register QRegionPrivate &dest, register const QRect *r, const QRect *rEnd,                        register int y1, register int y2){    register QRect *pNextRect;    pNextRect = dest.rects.data() + dest.numRects;    Q_ASSERT(y1 <= y2);    while (r != rEnd) {        Q_ASSERT(r->left() <= r->right());        MEMCHECK(dest, pNextRect, dest.rects)        pNextRect->setCoords(r->left(), y1, r->right(), y2);        dest.numRects++;        ++pNextRect;        ++r;    }}/*- *----------------------------------------------------------------------- * 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 dest.rects and dest.numRects will *      be changed. * *----------------------------------------------------------------------- */static void miUnionO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End,                     register const QRect *r2, const QRect *r2End, register int y1, register int y2){    register QRect *pNextRect;    pNextRect = dest.rects.data() + dest.numRects;#define MERGERECT(r)             \    if ((dest.numRects != 0) &&  \        (pNextRect[-1].top() == y1) &&  \        (pNextRect[-1].bottom() == y2) &&  \        (pNextRect[-1].right() >= r->left()-1)) { \        if (pNextRect[-1].right() < r->right()) { \            pNextRect[-1].setRight(r->right());  \            dest.updateInnerRect(pNextRect[-1]); \            Q_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \        }  \    } else { \        MEMCHECK(dest, pNextRect, dest.rects)  \        pNextRect->setCoords(r->left(), y1, r->right(), y2); \        dest.updateInnerRect(*pNextRect); \        dest.numRects++;  \        pNextRect++;  \    }  \    r++;    Q_ASSERT(y1 <= y2);    while (r1 != r1End && r2 != r2End) {        if (r1->left() < r2->left()) {            MERGERECT(r1)        } else {            MERGERECT(r2)        }    }    if (r1 != r1End) {        do {            MERGERECT(r1)        } while (r1 != r1End);    } else {        while (r2 != r2End) {            MERGERECT(r2)        }    }}static void UnionRegion(const QRegionPrivate *reg1, const QRegionPrivate *reg2, QRegionPrivate &dest){    Q_ASSERT(!isEmpty(reg1) && !isEmpty(reg2));    Q_ASSERT(!reg1->contains(*reg2));    Q_ASSERT(!reg2->contains(*reg1));    Q_ASSERT(!EqualRegion(reg1, reg2));    Q_ASSERT(!reg1->canAppend(reg2));    Q_ASSERT(!reg2->canAppend(reg1));    if (reg1->innerArea > reg2->innerArea) {        dest.innerArea = reg1->innerArea;        dest.innerRect = reg1->innerRect;    } else {        dest.innerArea = reg2->innerArea;        dest.innerRect = reg2->innerRect;    }    miRegionOp(dest, reg1, reg2, miUnionO, miUnionNonO, miUnionNonO);    dest.extents.setCoords(qMin(reg1->extents.left(), reg2->extents.left()),                           qMin(reg1->extents.top(), reg2->extents.top()),                           qMax(reg1->extents.right(), reg2->extents.right()),                           qMax(reg1->extents.bottom(), reg2->extents.bottom()));}/*====================================================================== *        Region Subtraction *====================================================================*//*- *----------------------------------------------------------------------- * miSubtractNonO -- *      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: *      dest may be affected. * *----------------------------------------------------------------------- */static void miSubtractNonO1(register QRegionPrivate &dest, register const QRect *r,                            const QRect *rEnd, register int y1, register int y2){    register QRect *pNextRect;    pNextRect = dest.rects.data() + dest.numRects;    Q_ASSERT(y1<=y2);    while (r != rEnd) {        Q_ASSERT(r->left() <= r->right());        MEMCHECK(dest, pNextRect, dest.rects)        pNextRect->setCoords(r->left(), y1, r->right(), y2);        ++dest.numRects;        ++pNextRect;        ++r;    }}/*- *----------------------------------------------------------------------- * miSubtractO -- *      Overlapping band subtraction. x1 is the left-most point not yet *      checked. * * Results: *      None. * * Side Effects: *      dest may have rectangles added to it. * *----------------------------------------------------------------------- */static void miSubtractO(register QRegionPrivate &dest, register const QRect *r1, const QRect *r1End,                        register const QRect *r2, const QRect *r2End, register int y1, register int y2){    register QRect *pNextRect;    register int x1;    x1 = r1->left();    Q_ASSERT(y1 <= y2);    pNextRect = dest.rects.data() + dest.numRects;    while (r1 != r1End && r2 != r2End) {        if (r2->right() < x1) {            /*             * Subtrahend missed the boat: go to next subtrahend.             */            ++r2;        } else if (r2->left() <= x1) {            /*             * Subtrahend precedes minuend: nuke left edge of minuend.             */            x1 = r2->right() + 1;            if (x1 > r1->right()) {                /*                 * Minuend completely covered: advance to next minuend and

⌨️ 快捷键说明

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