X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/77ffb5937e89927b621128789401db8921fe580f..c08ebc627546d8f1a3c69c989d21d587c851f9a9:/src/generic/regiong.cpp diff --git a/src/generic/regiong.cpp b/src/generic/regiong.cpp index 3027f4a213..99fd7cb8b8 100644 --- a/src/generic/regiong.cpp +++ b/src/generic/regiong.cpp @@ -6,7 +6,7 @@ // Created: 2004/04/12 // RCS-ID: $Id$ // Copyright: (c) 2004 David Elliott -// Licence: wxWidgets licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #include "wx/generic/region.h" @@ -49,17 +49,17 @@ public: register int x, register int y); static bool XIntersectRegion( - Region reg1, - Region reg2, /* source regions */ - register Region newReg); /* destination Region */ + Region reg1, + Region reg2, /* source regions */ + register Region newReg); /* destination Region */ static bool XUnionRegion( - Region reg1, - Region reg2, /* source regions */ - Region newReg); /* destination Region */ + Region reg1, + Region reg2, /* source regions */ + Region newReg); /* destination Region */ static bool XSubtractRegion( - Region regM, - Region regS, - register Region regD); + Region regM, + Region regS, + register Region regD); static bool XXorRegion(Region sra, Region srb, Region dr); static bool XEmptyRegion( Region r); @@ -68,87 +68,87 @@ public: Region pRegion, int x, int y); static wxRegionContain XRectInRegion( - register Region region, + register Region region, int rx, int ry, unsigned int rwidth, unsigned int rheight); protected: static Region XCreateRegion(void); static void miSetExtents ( - Region pReg); + Region pReg); static bool XDestroyRegion(Region r); static int miIntersectO ( - register Region pReg, - register BoxPtr r1, - BoxPtr r1End, - register BoxPtr r2, - BoxPtr r2End, - wxCoord y1, - wxCoord y2); + register Region pReg, + register BoxPtr r1, + BoxPtr r1End, + register BoxPtr r2, + BoxPtr r2End, + wxCoord y1, + wxCoord y2); static void miRegionCopy( register Region dstrgn, register Region rgn); static int miCoalesce( - register Region pReg, /* Region to coalesce */ - int prevStart, /* Index of start of previous band */ - int curStart); /* Index of start of current band */ + register Region pReg, /* Region to coalesce */ + int prevStart, /* Index of start of previous band */ + int curStart); /* Index of start of current band */ static void miRegionOp( - register Region newReg, /* Place to store result */ - Region reg1, /* First region in operation */ - Region reg2, /* 2d region in operation */ - int (*overlapFunc)( + register Region newReg, /* Place to store result */ + Region reg1, /* First region in operation */ + Region reg2, /* 2d region in operation */ + int (*overlapFunc)( register Region pReg, register BoxPtr r1, BoxPtr r1End, register BoxPtr r2, BoxPtr r2End, - wxCoord y1, - wxCoord y2), /* Function to call for over- - * lapping bands */ - int (*nonOverlap1Func)( + wxCoord y1, + wxCoord y2), /* Function to call for over- + * lapping bands */ + int (*nonOverlap1Func)( register Region pReg, register BoxPtr r, BoxPtr rEnd, - register wxCoord y1, - register wxCoord y2), /* Function to call for non- - * overlapping bands in region - * 1 */ - int (*nonOverlap2Func)( + register wxCoord y1, + register wxCoord y2), /* Function to call for non- + * overlapping bands in region + * 1 */ + int (*nonOverlap2Func)( register Region pReg, register BoxPtr r, BoxPtr rEnd, - register wxCoord y1, - register wxCoord y2)); /* Function to call for non- - * overlapping bands in region - * 2 */ + register wxCoord y1, + register wxCoord y2)); /* Function to call for non- + * overlapping bands in region + * 2 */ static int miUnionNonO ( - register Region pReg, - register BoxPtr r, - BoxPtr rEnd, - register wxCoord y1, - register wxCoord y2); + register Region pReg, + register BoxPtr r, + BoxPtr rEnd, + register wxCoord y1, + register wxCoord y2); static int miUnionO ( - register Region pReg, - register BoxPtr r1, - BoxPtr r1End, - register BoxPtr r2, - BoxPtr r2End, - register wxCoord y1, - register wxCoord y2); + register Region pReg, + register BoxPtr r1, + BoxPtr r1End, + register BoxPtr r2, + BoxPtr r2End, + register wxCoord y1, + register wxCoord y2); static int miSubtractNonO1 ( - register Region pReg, - register BoxPtr r, - BoxPtr rEnd, - register wxCoord y1, - register wxCoord y2); + register Region pReg, + register BoxPtr r, + BoxPtr rEnd, + register wxCoord y1, + register wxCoord y2); static int miSubtractO ( - register Region pReg, - register BoxPtr r1, - BoxPtr r1End, - register BoxPtr r2, - BoxPtr r2End, - register wxCoord y1, - register wxCoord y2); + register Region pReg, + register BoxPtr r1, + BoxPtr r1End, + register BoxPtr r2, + BoxPtr r2End, + register wxCoord y1, + register wxCoord y2); protected: long size; long numRects; @@ -291,7 +291,7 @@ bool wxRegionGeneric::Union(const wxRect& rect) /* XUnionRectWithRegion */ { if (!rect.width || !rect.height) - return false; + return false; AllocExclusive(); REGION region(rect); @@ -307,7 +307,7 @@ bool wxRegionGeneric::Union(const wxRegionGeneric& region) bool wxRegionGeneric::Intersect(const wxRect& rect) { if (!rect.width || !rect.height) - return false; + return false; AllocExclusive(); REGION region(rect); @@ -323,7 +323,7 @@ bool wxRegionGeneric::Intersect(const wxRegionGeneric& region) bool wxRegionGeneric::Subtract(const wxRect& rect) { if (!rect.width || !rect.height) - return false; + return false; AllocExclusive(); REGION region(rect); @@ -338,7 +338,7 @@ bool wxRegionGeneric::Subtract(const wxRegionGeneric& region) bool wxRegionGeneric::Xor(const wxRect& rect) { if (!rect.width || !rect.height) - return false; + return false; AllocExclusive(); REGION region(rect); @@ -373,28 +373,28 @@ wxRegionContain wxRegionGeneric::Contains(long x, long y) const wxASSERT(m_refData); return REGION::XPointInRegion(M_REGIONDATA,x,y)?wxInRegion:wxOutRegion; } - + // Does the region contain the point pt? wxRegionContain wxRegionGeneric::Contains(const wxPoint& pt) const { wxASSERT(m_refData); return REGION::XPointInRegion(M_REGIONDATA,pt.x,pt.y)?wxInRegion:wxOutRegion; } - + // Does the region contain the rectangle (x, y, w, h)? wxRegionContain wxRegionGeneric::Contains(long x, long y, long w, long h) const { wxASSERT(m_refData); return REGION::XRectInRegion(M_REGIONDATA,x,y,w,h); } - + // Does the region contain the rectangle rect? wxRegionContain wxRegionGeneric::Contains(const wxRect& rect) const { wxASSERT(m_refData); return REGION::XRectInRegion(M_REGIONDATA,rect.x,rect.y,rect.width,rect.height); } - + // ======================================================================== // wxRegionIteratorGeneric // ======================================================================== @@ -443,7 +443,7 @@ wxRegionIteratorGeneric wxRegionIteratorGeneric::operator++(int) wxRect wxRegionIteratorGeneric::GetRect() const { - wxASSERT(m_refData); + wxASSERT(m_region.m_refData); const Box *box = M_REGIONDATA_OF(m_region)->GetBox(m_current); wxASSERT(box); return wxRect @@ -456,7 +456,7 @@ wxRect wxRegionIteratorGeneric::GetRect() const long wxRegionIteratorGeneric::GetX() const { - wxASSERT(m_refData); + wxASSERT(m_region.m_refData); const Box *box = M_REGIONDATA_OF(m_region)->GetBox(m_current); wxASSERT(box); return box->x1; @@ -464,7 +464,7 @@ long wxRegionIteratorGeneric::GetX() const long wxRegionIteratorGeneric::GetY() const { - wxASSERT(m_refData); + wxASSERT(m_region.m_refData); const Box *box = M_REGIONDATA_OF(m_region)->GetBox(m_current); wxASSERT(box); return box->y1; @@ -472,7 +472,7 @@ long wxRegionIteratorGeneric::GetY() const long wxRegionIteratorGeneric::GetW() const { - wxASSERT(m_refData); + wxASSERT(m_region.m_refData); const Box *box = M_REGIONDATA_OF(m_region)->GetBox(m_current); wxASSERT(box); return box->x2 - box->x1; @@ -480,7 +480,7 @@ long wxRegionIteratorGeneric::GetW() const long wxRegionIteratorGeneric::GetH() const { - wxASSERT(m_refData); + wxASSERT(m_region.m_refData); const Box *box = M_REGIONDATA_OF(m_region)->GetBox(m_current); wxASSERT(box); return box->y2 - box->y1; @@ -524,13 +524,13 @@ Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. All Rights Reserved -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in +both that copyright notice and this permission notice appear in supporting documentation, and that the name of Digital not be used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. +software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL @@ -544,13 +544,13 @@ SOFTWARE. /* 1 if two BOXs overlap. * 0 if two BOXs do not overlap. - * Remember, x2 and y2 are not in the region + * Remember, x2 and y2 are not in the region */ #define EXTENTCHECK(r1, r2) \ - ((r1)->x2 > (r2)->x1 && \ - (r1)->x1 < (r2)->x2 && \ - (r1)->y2 > (r2)->y1 && \ - (r1)->y1 < (r2)->y2) + ((r1)->x2 > (r2)->x1 && \ + (r1)->x1 < (r2)->x2 && \ + (r1)->y2 > (r2)->y1 && \ + (r1)->y1 < (r2)->y2) /* * Check to see if there is enough memory in the present region. @@ -602,17 +602,17 @@ SOFTWARE. * the y-x-banding that's so nice to have... */ -/* Create a new empty region */ +/* Create a new empty region */ Region REGION:: XCreateRegion(void) { Region temp; if (! (temp = new REGION)) - return (Region) NULL; + return (Region) NULL; if (! (temp->rects = ( BOX * )malloc( (unsigned) sizeof( BOX )))) { - free((char *) temp); - return (Region) NULL; + free((char *) temp); + return (Region) NULL; } temp->numRects = 0; temp->extents.x1 = 0; @@ -638,33 +638,32 @@ XClipBox( /*- *----------------------------------------------------------------------- * miSetExtents -- - * Reset the extents of a region to what they should be. Called by - * miSubtract and miIntersect b/c they can't figure it out along the - * way or do so easily, as miUnion can. + * Reset the extents of a region to what they should be. Called by + * miSubtract and miIntersect b/c they can't figure it out along the + * way or do so easily, as miUnion can. * * Results: - * None. + * None. * * Side Effects: - * The region's 'extents' structure is overwritten. + * The region's 'extents' structure is overwritten. * *----------------------------------------------------------------------- */ void REGION:: -miSetExtents ( - Region pReg) +miSetExtents (Region pReg) { - register BoxPtr pBox, - pBoxEnd, - pExtents; + register BoxPtr pBox, + pBoxEnd, + pExtents; if (pReg->numRects == 0) { - pReg->extents.x1 = 0; - pReg->extents.y1 = 0; - pReg->extents.x2 = 0; - pReg->extents.y2 = 0; - return; + pReg->extents.x1 = 0; + pReg->extents.y1 = 0; + pReg->extents.x2 = 0; + pReg->extents.y2 = 0; + return; } pExtents = &pReg->extents; @@ -686,15 +685,15 @@ miSetExtents ( assert(pExtents->y1 < pExtents->y2); while (pBox <= pBoxEnd) { - if (pBox->x1 < pExtents->x1) - { - pExtents->x1 = pBox->x1; - } - if (pBox->x2 > pExtents->x2) - { - pExtents->x2 = pBox->x2; - } - pBox++; + if (pBox->x1 < pExtents->x1) + { + pExtents->x1 = pBox->x1; + } + if (pBox->x2 > pExtents->x2) + { + pExtents->x2 = pBox->x2; + } + pBox++; } assert(pExtents->x1 < pExtents->x2); } @@ -727,11 +726,11 @@ XOffsetRegion( while(nbox--) { - pbox->x1 += x; - pbox->x2 += x; - pbox->y1 += y; - pbox->y2 += y; - pbox++; + pbox->x1 += x; + pbox->x2 += x; + pbox->y1 += y; + pbox->y2 += y; + pbox++; } pRegion->extents.x1 += x; pRegion->extents.x2 += x; @@ -741,100 +740,100 @@ XOffsetRegion( } /*====================================================================== - * Region Intersection + * Region Intersection *====================================================================*/ /*- *----------------------------------------------------------------------- * miIntersectO -- - * Handle an overlapping band for miIntersect. + * Handle an overlapping band for miIntersect. * * Results: - * None. + * None. * * Side Effects: - * Rectangles may be added to the region. + * Rectangles may be added to the region. * *----------------------------------------------------------------------- */ /* static void*/ int REGION:: miIntersectO ( - register Region pReg, - register BoxPtr r1, - BoxPtr r1End, - register BoxPtr r2, - BoxPtr r2End, - wxCoord y1, - wxCoord y2) + register Region pReg, + register BoxPtr r1, + BoxPtr r1End, + register BoxPtr r2, + BoxPtr r2End, + wxCoord y1, + wxCoord y2) { - register wxCoord x1; - register wxCoord x2; - register BoxPtr pNextRect; + register wxCoord x1; + register wxCoord x2; + register BoxPtr pNextRect; pNextRect = &pReg->rects[pReg->numRects]; while ((r1 != r1End) && (r2 != r2End)) { - x1 = wxMax(r1->x1,r2->x1); - x2 = wxMin(r1->x2,r2->x2); - - /* - * If there's any overlap between the two rectangles, add that - * overlap to the new region. - * There's no need to check for subsumption because the only way - * such a need could arise is if some region has two rectangles - * right next to each other. Since that should never happen... - */ - if (x1 < x2) - { - assert(y1rects); - pNextRect->x1 = x1; - pNextRect->y1 = y1; - pNextRect->x2 = x2; - pNextRect->y2 = y2; - pReg->numRects += 1; - pNextRect++; - assert(pReg->numRects <= pReg->size); - } - - /* - * Need to advance the pointers. Shift the one that extends - * to the right the least, since the other still has a chance to - * overlap with that region's next rectangle, if you see what I mean. - */ - if (r1->x2 < r2->x2) - { - r1++; - } - else if (r2->x2 < r1->x2) - { - r2++; - } - else - { - r1++; - r2++; - } + x1 = wxMax(r1->x1,r2->x1); + x2 = wxMin(r1->x2,r2->x2); + + /* + * If there's any overlap between the two rectangles, add that + * overlap to the new region. + * There's no need to check for subsumption because the only way + * such a need could arise is if some region has two rectangles + * right next to each other. Since that should never happen... + */ + if (x1 < x2) + { + assert(y1rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + assert(pReg->numRects <= pReg->size); + } + + /* + * Need to advance the pointers. Shift the one that extends + * to the right the least, since the other still has a chance to + * overlap with that region's next rectangle, if you see what I mean. + */ + if (r1->x2 < r2->x2) + { + r1++; + } + else if (r2->x2 < r1->x2) + { + r2++; + } + else + { + r1++; + r2++; + } } - return 0; /* lint */ + return 0; /* lint */ } bool REGION:: XIntersectRegion( - Region reg1, - Region reg2, /* source regions */ - register Region newReg) /* destination Region */ + Region reg1, + Region reg2, /* source regions */ + register Region newReg) /* destination Region */ { /* check for trivial reject */ if ( (!(reg1->numRects)) || (!(reg2->numRects)) || - (!EXTENTCHECK(®1->extents, ®2->extents))) + (!EXTENTCHECK(®1->extents, ®2->extents))) newReg->numRects = 0; else - miRegionOp (newReg, reg1, reg2, - miIntersectO, NULL, NULL); - + miRegionOp (newReg, reg1, reg2, + miIntersectO, NULL, NULL); + /* * Can't alter newReg's extents before we call miRegionOp because * it might be one of the source regions and miRegionOp depends @@ -853,69 +852,70 @@ miRegionCopy( { if (dstrgn != rgn) /* don't want to copy to itself */ - { + { if (dstrgn->size < rgn->numRects) { if (dstrgn->rects) { - BOX *prevRects = dstrgn->rects; - + BOX *prevRects = dstrgn->rects; + if (! (dstrgn->rects = (BOX *) - realloc((char *) dstrgn->rects, - (unsigned) rgn->numRects * (sizeof(BOX))))) { - free(prevRects); - return; - } + realloc((char *) dstrgn->rects, + (unsigned) rgn->numRects * (sizeof(BOX))))) + { + free(prevRects); + return; + } } dstrgn->size = rgn->numRects; - } + } dstrgn->numRects = rgn->numRects; dstrgn->extents.x1 = rgn->extents.x1; dstrgn->extents.y1 = rgn->extents.y1; dstrgn->extents.x2 = rgn->extents.x2; dstrgn->extents.y2 = rgn->extents.y2; - memcpy((char *) dstrgn->rects, (char *) rgn->rects, - (int) (rgn->numRects * sizeof(BOX))); + memcpy((char *) dstrgn->rects, (char *) rgn->rects, + (int) (rgn->numRects * sizeof(BOX))); } } /*====================================================================== - * Generic Region Operator + * Generic Region Operator *====================================================================*/ /*- *----------------------------------------------------------------------- * miCoalesce -- - * Attempt to merge the boxes in the current band with those in the - * previous one. Used only by miRegionOp. + * Attempt to merge the boxes in the current band with those in the + * previous one. Used only by miRegionOp. * * Results: - * The new index for the previous band. + * The new index for the previous band. * * Side Effects: - * If coalescing takes place: - * - rectangles in the previous band will have their y2 fields - * altered. - * - pReg->numRects will be decreased. + * If coalescing takes place: + * - rectangles in the previous band will have their y2 fields + * altered. + * - pReg->numRects will be decreased. * *----------------------------------------------------------------------- */ /* static int*/ int REGION:: miCoalesce( - register Region pReg, /* Region to coalesce */ - int prevStart, /* Index of start of previous band */ - int curStart) /* Index of start of current band */ + register Region pReg, /* Region to coalesce */ + int prevStart, /* Index of start of previous band */ + int curStart) /* Index of start of current band */ { - register BoxPtr pPrevBox; /* Current box in previous band */ - register BoxPtr pCurBox; /* Current box in current band */ - register BoxPtr pRegEnd; /* End of region */ - int curNumRects; /* Number of rectangles in current - * band */ - int prevNumRects; /* Number of rectangles in previous - * band */ - int bandY1; /* Y1 coordinate for current band */ + register BoxPtr pPrevBox; /* Current box in previous band */ + register BoxPtr pCurBox; /* Current box in current band */ + register BoxPtr pRegEnd; /* End of region */ + int curNumRects; /* Number of rectangles in current + * band */ + int prevNumRects; /* Number of rectangles in previous + * band */ + int bandY1; /* Y1 coordinate for current band */ pRegEnd = &pReg->rects[pReg->numRects]; @@ -930,98 +930,99 @@ miCoalesce( pCurBox = &pReg->rects[curStart]; bandY1 = pCurBox->y1; for (curNumRects = 0; - (pCurBox != pRegEnd) && (pCurBox->y1 == bandY1); - curNumRects++) + (pCurBox != pRegEnd) && (pCurBox->y1 == bandY1); + curNumRects++) { - pCurBox++; + pCurBox++; } - + if (pCurBox != pRegEnd) { - /* - * If more than one band was added, we have to find the start - * of the last band added so the next coalescing job can start - * at the right place... (given when multiple bands are added, - * this may be pointless -- see above). - */ - pRegEnd--; - while (pRegEnd[-1].y1 == pRegEnd->y1) - { - pRegEnd--; - } - curStart = pRegEnd - pReg->rects; - pRegEnd = pReg->rects + pReg->numRects; + /* + * If more than one band was added, we have to find the start + * of the last band added so the next coalescing job can start + * at the right place... (given when multiple bands are added, + * this may be pointless -- see above). + */ + pRegEnd--; + while (pRegEnd[-1].y1 == pRegEnd->y1) + { + pRegEnd--; + } + curStart = pRegEnd - pReg->rects; + pRegEnd = pReg->rects + pReg->numRects; } - - if ((curNumRects == prevNumRects) && (curNumRects != 0)) { - pCurBox -= curNumRects; - /* - * The bands may only be coalesced if the bottom of the previous - * matches the top scanline of the current. - */ - if (pPrevBox->y2 == pCurBox->y1) - { - /* - * Make sure the bands have boxes in the same places. This - * assumes that boxes have been added in such a way that they - * cover the most area possible. I.e. two boxes in a band must - * have some horizontal space between them. - */ - do - { - if ((pPrevBox->x1 != pCurBox->x1) || - (pPrevBox->x2 != pCurBox->x2)) - { - /* - * The bands don't line up so they can't be coalesced. - */ - return (curStart); - } - pPrevBox++; - pCurBox++; - prevNumRects -= 1; - } while (prevNumRects != 0); - - pReg->numRects -= curNumRects; - pCurBox -= curNumRects; - pPrevBox -= curNumRects; - - /* - * The bands may be merged, so set the bottom y of each box - * in the previous band to that of the corresponding box in - * the current band. - */ - do - { - pPrevBox->y2 = pCurBox->y2; - pPrevBox++; - pCurBox++; - curNumRects -= 1; - } while (curNumRects != 0); - - /* - * If only one band was added to the region, we have to backup - * curStart to the start of the previous band. - * - * If more than one band was added to the region, copy the - * other bands down. The assumption here is that the other bands - * came from the same region as the current one and no further - * coalescing can be done on them since it's all been done - * already... curStart is already in the right place. - */ - if (pCurBox == pRegEnd) - { - curStart = prevStart; - } - else - { - do - { - *pPrevBox++ = *pCurBox++; - } while (pCurBox != pRegEnd); - } - - } + + if ((curNumRects == prevNumRects) && (curNumRects != 0)) + { + pCurBox -= curNumRects; + /* + * The bands may only be coalesced if the bottom of the previous + * matches the top scanline of the current. + */ + if (pPrevBox->y2 == pCurBox->y1) + { + /* + * Make sure the bands have boxes in the same places. This + * assumes that boxes have been added in such a way that they + * cover the most area possible. I.e. two boxes in a band must + * have some horizontal space between them. + */ + do + { + if ((pPrevBox->x1 != pCurBox->x1) || + (pPrevBox->x2 != pCurBox->x2)) + { + /* + * The bands don't line up so they can't be coalesced. + */ + return (curStart); + } + pPrevBox++; + pCurBox++; + prevNumRects -= 1; + } while (prevNumRects != 0); + + pReg->numRects -= curNumRects; + pCurBox -= curNumRects; + pPrevBox -= curNumRects; + + /* + * The bands may be merged, so set the bottom y of each box + * in the previous band to that of the corresponding box in + * the current band. + */ + do + { + pPrevBox->y2 = pCurBox->y2; + pPrevBox++; + pCurBox++; + curNumRects -= 1; + } while (curNumRects != 0); + + /* + * If only one band was added to the region, we have to backup + * curStart to the start of the previous band. + * + * If more than one band was added to the region, copy the + * other bands down. The assumption here is that the other bands + * came from the same region as the current one and no further + * coalescing can be done on them since it's all been done + * already... curStart is already in the right place. + */ + if (pCurBox == pRegEnd) + { + curStart = prevStart; + } + else + { + do + { + *pPrevBox++ = *pCurBox++; + } while (pCurBox != pRegEnd); + } + + } } return (curStart); } @@ -1029,82 +1030,82 @@ miCoalesce( /*- *----------------------------------------------------------------------- * miRegionOp -- - * Apply an operation to two regions. Called by miUnion, miInverse, - * miSubtract, miIntersect... + * Apply an operation to two regions. Called by miUnion, miInverse, + * miSubtract, miIntersect... * * Results: - * None. + * None. * * Side Effects: - * The new region is overwritten. + * The new region is overwritten. * * Notes: - * The idea behind this function is to view the two regions as sets. - * Together they cover a rectangle of area that this function divides - * into horizontal bands where points are covered only by one region - * or by both. For the first case, the nonOverlapFunc is called with - * each the band and the band's upper and lower extents. For the - * 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. + * The idea behind this function is to view the two regions as sets. + * Together they cover a rectangle of area that this function divides + * into horizontal bands where points are covered only by one region + * or by both. For the first case, the nonOverlapFunc is called with + * each the band and the band's upper and lower extents. For the + * 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*/ void REGION:: miRegionOp( - register Region newReg, /* Place to store result */ - Region reg1, /* First region in operation */ - Region reg2, /* 2d region in operation */ - int (*overlapFunc)( + register Region newReg, /* Place to store result */ + Region reg1, /* First region in operation */ + Region reg2, /* 2d region in operation */ + int (*overlapFunc)( register Region pReg, register BoxPtr r1, BoxPtr r1End, register BoxPtr r2, BoxPtr r2End, wxCoord y1, - wxCoord y2), /* Function to call for over- - * lapping bands */ - int (*nonOverlap1Func)( + wxCoord y2), /* Function to call for over- + * lapping bands */ + int (*nonOverlap1Func)( register Region pReg, register BoxPtr r, BoxPtr rEnd, register wxCoord y1, - register wxCoord y2), /* Function to call for non- - * overlapping bands in region - * 1 */ - int (*nonOverlap2Func)( + register wxCoord y2), /* Function to call for non- + * overlapping bands in region + * 1 */ + int (*nonOverlap2Func)( register Region pReg, register BoxPtr r, BoxPtr rEnd, register wxCoord y1, - register wxCoord y2)) /* Function to call for non- - * overlapping bands in region - * 2 */ + register wxCoord y2)) /* Function to call for non- + * overlapping bands in region + * 2 */ { - register BoxPtr r1; /* Pointer into first region */ - register BoxPtr r2; /* Pointer into 2d region */ - BoxPtr r1End; /* End of 1st region */ - BoxPtr r2End; /* End of 2d region */ - register wxCoord ybot; /* Bottom of intersection */ - register wxCoord ytop; /* Top of intersection */ - BoxPtr 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 BoxPtr r1BandEnd; /* End of current band in r1 */ - register BoxPtr r2BandEnd; /* End of current band in r2 */ - wxCoord top; /* Top of non-overlapping - * band */ - wxCoord bot; /* Bottom of non-overlapping - * band */ - + register BoxPtr r1; /* Pointer into first region */ + register BoxPtr r2; /* Pointer into 2d region */ + BoxPtr r1End; /* End of 1st region */ + BoxPtr r2End; /* End of 2d region */ + register wxCoord ybot; /* Bottom of intersection */ + register wxCoord ytop; /* Top of intersection */ + BoxPtr 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 BoxPtr r1BandEnd; /* End of current band in r1 */ + register BoxPtr r2BandEnd; /* End of current band in r2 */ + wxCoord top; /* Top of non-overlapping + * band */ + wxCoord bot; /* Bottom of non-overlapping + * band */ + /* * Initialization: - * set r1, r2, r1End and r2End appropriately, preserve the important + * 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. @@ -1113,9 +1114,9 @@ miRegionOp( r2 = reg2->rects; r1End = r1 + reg1->numRects; r2End = r2 + reg2->numRects; - + oldRects = newReg->rects; - + EMPTY_REGION(newReg); /* @@ -1128,29 +1129,29 @@ miRegionOp( newReg->size = wxMax(reg1->numRects,reg2->numRects) * 2; if (! (newReg->rects = (BoxPtr) - malloc ((unsigned) (sizeof(BoxRec) * newReg->size)))) { - newReg->size = 0; - return; + malloc ((unsigned) (sizeof(BoxRec) * 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 + * 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 + * 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; + ybot = reg1->extents.y1; else - ybot = reg2->extents.y1; - + 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. @@ -1161,107 +1162,107 @@ miRegionOp( * 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 = wxMax(r1->y1,ybot); - bot = wxMin(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 = wxMax(r2->y1,ybot); - bot = wxMin(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 = wxMin(r1->y2, r2->y2); - curBand = newReg->numRects; - if (ybot > ytop) - { - (* overlapFunc) (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; - } + 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 = wxMax(r1->y1,ybot); + bot = wxMin(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 = wxMax(r2->y1,ybot); + bot = wxMin(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 = wxMin(r1->y2, r2->y2); + curBand = newReg->numRects; + if (ybot > ytop) + { + (* overlapFunc) (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)); /* @@ -1270,39 +1271,39 @@ miRegionOp( curBand = newReg->numRects; if (r1 != r1End) { - if (nonOverlap1Func != NULL) - { - do - { - r1BandEnd = r1; - while ((r1BandEnd < r1End) && (r1BandEnd->y1 == r1->y1)) - { - r1BandEnd++; - } - (* nonOverlap1Func) (newReg, r1, r1BandEnd, - wxMax(r1->y1,ybot), r1->y2); - r1 = r1BandEnd; - } while (r1 != r1End); - } + if (nonOverlap1Func != NULL) + { + do + { + r1BandEnd = r1; + while ((r1BandEnd < r1End) && (r1BandEnd->y1 == r1->y1)) + { + r1BandEnd++; + } + (* nonOverlap1Func) (newReg, r1, r1BandEnd, + wxMax(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, - wxMax(r2->y1,ybot), r2->y2); - r2 = r2BandEnd; - } while (r2 != r2End); + do + { + r2BandEnd = r2; + while ((r2BandEnd < r2End) && (r2BandEnd->y1 == r2->y1)) + { + r2BandEnd++; + } + (* nonOverlap2Func) (newReg, r2, r2BandEnd, + wxMax(r2->y1,ybot), r2->y2); + r2 = r2BandEnd; + } while (r2 != r2End); } if (newReg->numRects != curBand) { - (void) miCoalesce (newReg, prevBand, curBand); + (void) miCoalesce (newReg, prevBand, curBand); } /* @@ -1315,60 +1316,60 @@ miRegionOp( */ if (newReg->numRects < (newReg->size >> 1)) { - if (REGION_NOT_EMPTY(newReg)) - { - BoxPtr prev_rects = newReg->rects; - newReg->size = newReg->numRects; - newReg->rects = (BoxPtr) realloc ((char *) newReg->rects, - (unsigned) (sizeof(BoxRec) * newReg->size)); - if (! newReg->rects) - newReg->rects = prev_rects; - } - else - { - /* - * No point in doing the extra work involved in an realloc if - * the region is empty - */ - newReg->size = 1; - free((char *) newReg->rects); - newReg->rects = (BoxPtr) malloc(sizeof(BoxRec)); - } + if (REGION_NOT_EMPTY(newReg)) + { + BoxPtr prev_rects = newReg->rects; + newReg->size = newReg->numRects; + newReg->rects = (BoxPtr) realloc ((char *) newReg->rects, + (unsigned) (sizeof(BoxRec) * newReg->size)); + if (! newReg->rects) + newReg->rects = prev_rects; + } + else + { + /* + * No point in doing the extra work involved in an realloc if + * the region is empty + */ + newReg->size = 1; + free((char *) newReg->rects); + newReg->rects = (BoxPtr) malloc(sizeof(BoxRec)); + } } free ((char *) oldRects); return; } /*====================================================================== - * Region Union + * 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. + * 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. + * None. * * Side Effects: - * pReg->numRects is incremented and the final rectangles overwritten - * with the rectangles we're passed. + * pReg->numRects is incremented and the final rectangles overwritten + * with the rectangles we're passed. * *----------------------------------------------------------------------- */ /* static void*/ int REGION:: miUnionNonO ( - register Region pReg, - register BoxPtr r, - BoxPtr rEnd, - register wxCoord y1, - register wxCoord y2) + register Region pReg, + register BoxPtr r, + BoxPtr rEnd, + register wxCoord y1, + register wxCoord y2) { - register BoxPtr pNextRect; + register BoxPtr pNextRect; pNextRect = &pReg->rects[pReg->numRects]; @@ -1376,34 +1377,34 @@ miUnionNonO ( 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++; + 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; /* lint */ + return 0; /* lint */ } /*- *----------------------------------------------------------------------- * miUnionO -- - * Handle an overlapping band for the union operation. Picks the - * left-most rectangle each time and merges it into the region. + * Handle an overlapping band for the union operation. Picks the + * left-most rectangle each time and merges it into the region. * * Results: - * None. + * None. * * Side Effects: - * Rectangles are overwritten in pReg->rects and pReg->numRects will - * be changed. + * Rectangles are overwritten in pReg->rects and pReg->numRects will + * be changed. * *----------------------------------------------------------------------- */ @@ -1411,75 +1412,75 @@ miUnionNonO ( /* static void*/ int REGION:: miUnionO ( - register Region pReg, - register BoxPtr r1, - BoxPtr r1End, - register BoxPtr r2, - BoxPtr r2End, - register wxCoord y1, - register wxCoord y2) + register Region pReg, + register BoxPtr r1, + BoxPtr r1End, + register BoxPtr r2, + BoxPtr r2End, + register wxCoord y1, + register wxCoord y2) { - register BoxPtr pNextRect; - + register BoxPtr 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)) \ + (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].x1x2) \ + { \ + pNextRect[-1].x2 = r->x2; \ + assert(pNextRect[-1].x1rects); \ - pNextRect->y1 = y1; \ - pNextRect->y2 = y2; \ - pNextRect->x1 = r->x1; \ - pNextRect->x2 = r->x2; \ - pReg->numRects += 1; \ + 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 (y1x1 < r2->x1) - { - MERGERECT(r1); - } - else - { - MERGERECT(r2); - } + if (r1->x1 < r2->x1) + { + MERGERECT(r1); + } + else + { + MERGERECT(r2); + } } - + if (r1 != r1End) { - do - { - MERGERECT(r1); - } while (r1 != r1End); + do + { + MERGERECT(r1); + } while (r1 != r1End); } else while (r2 != r2End) { - MERGERECT(r2); + MERGERECT(r2); } - return 0; /* lint */ + return 0; /* lint */ } bool REGION:: XUnionRegion( - Region reg1, - Region reg2, /* source regions */ - Region newReg) /* destination Region */ + Region reg1, + Region reg2, /* source regions */ + Region newReg) /* destination Region */ { /* checks all the simple cases */ @@ -1506,11 +1507,11 @@ XUnionRegion( /* * Region 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 ((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); @@ -1520,19 +1521,19 @@ XUnionRegion( /* * Region 2 completely subsumes region 1 */ - if ((reg2->numRects == 1) && - (reg2->extents.x1 <= reg1->extents.x1) && - (reg2->extents.y1 <= reg1->extents.y1) && - (reg2->extents.x2 >= reg1->extents.x2) && - (reg2->extents.y2 >= reg1->extents.y2)) + if ((reg2->numRects == 1) && + (reg2->extents.x1 <= reg1->extents.x1) && + (reg2->extents.y1 <= reg1->extents.y1) && + (reg2->extents.x2 >= reg1->extents.x2) && + (reg2->extents.y2 >= reg1->extents.y2)) { if (newReg != reg2) miRegionCopy(newReg, reg2); return 1; } - miRegionOp (newReg, reg1, reg2, miUnionO, - miUnionNonO, miUnionNonO); + miRegionOp (newReg, reg1, reg2, miUnionO, + miUnionNonO, miUnionNonO); newReg->extents.x1 = wxMin(reg1->extents.x1, reg2->extents.x1); newReg->extents.y1 = wxMin(reg1->extents.y1, reg2->extents.y1); @@ -1543,178 +1544,178 @@ XUnionRegion( } /*====================================================================== - * Region Subtraction + * 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. + * 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. + * None. * * Side Effects: - * pReg may be affected. + * pReg may be affected. * *----------------------------------------------------------------------- */ /* static void*/ int REGION:: miSubtractNonO1 ( - register Region pReg, - register BoxPtr r, - BoxPtr rEnd, - register wxCoord y1, - register wxCoord y2) + register Region pReg, + register BoxPtr r, + BoxPtr rEnd, + register wxCoord y1, + register wxCoord y2) { - register BoxPtr pNextRect; - + register BoxPtr pNextRect; + pNextRect = &pReg->rects[pReg->numRects]; - + assert(y1x1x2); - 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++; + assert(r->x1x2); + 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; /* lint */ + return 0; /* lint */ } /*- *----------------------------------------------------------------------- * miSubtractO -- - * Overlapping band subtraction. x1 is the left-most point not yet - * checked. + * Overlapping band subtraction. x1 is the left-most point not yet + * checked. * * Results: - * None. + * None. * * Side Effects: - * pReg may have rectangles added to it. + * pReg may have rectangles added to it. * *----------------------------------------------------------------------- */ /* static void*/ int REGION:: miSubtractO ( - register Region pReg, - register BoxPtr r1, - BoxPtr r1End, - register BoxPtr r2, - BoxPtr r2End, - register wxCoord y1, - register wxCoord y2) + register Region pReg, + register BoxPtr r1, + BoxPtr r1End, + register BoxPtr r2, + BoxPtr r2End, + register wxCoord y1, + register wxCoord y2) { - register BoxPtr pNextRect; - register int x1; - + register BoxPtr pNextRect; + register int x1; + x1 = r1->x1; - + assert(y1rects[pReg->numRects]; while ((r1 != r1End) && (r2 != r2End)) { - if (r2->x2 <= x1) - { - /* - * Subtrahend missed the boat: go to next subtrahend. - */ - r2++; - } - else if (r2->x1 <= x1) - { - /* - * Subtrahend preceeds minuend: nuke left edge of minuend. - */ - x1 = r2->x2; - if (x1 >= r1->x2) - { - /* - * Minuend completely covered: advance to next minuend and - * reset left fence to edge of new minuend. - */ - r1++; - if (r1 != r1End) - x1 = r1->x1; - } - else - { - /* - * Subtrahend now used up since it doesn't extend beyond - * minuend - */ - r2++; - } - } - else if (r2->x1 < r1->x2) - { - /* - * Left part of subtrahend covers part of minuend: add uncovered - * part of minuend to region and skip to next subtrahend. - */ - assert(x1x1); - MEMCHECK(pReg, pNextRect, pReg->rects); - pNextRect->x1 = x1; - pNextRect->y1 = y1; - pNextRect->x2 = r2->x1; - pNextRect->y2 = y2; - pReg->numRects += 1; - pNextRect++; - - assert(pReg->numRects<=pReg->size); - - x1 = r2->x2; - if (x1 >= r1->x2) - { - /* - * Minuend used up: advance to new... - */ - r1++; - if (r1 != r1End) - x1 = r1->x1; - } - else - { - /* - * Subtrahend used up - */ - r2++; - } - } - else - { - /* - * Minuend used up: add any remaining piece before advancing. - */ - if (r1->x2 > x1) - { - MEMCHECK(pReg, pNextRect, pReg->rects); - pNextRect->x1 = x1; - pNextRect->y1 = y1; - pNextRect->x2 = r1->x2; - pNextRect->y2 = y2; - pReg->numRects += 1; - pNextRect++; - assert(pReg->numRects<=pReg->size); - } - r1++; - if (r1 != r1End) - x1 = r1->x1; - } + if (r2->x2 <= x1) + { + /* + * Subtrahend missed the boat: go to next subtrahend. + */ + r2++; + } + else if (r2->x1 <= x1) + { + /* + * Subtrahend preceeds minuend: nuke left edge of minuend. + */ + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend completely covered: advance to next minuend and + * reset left fence to edge of new minuend. + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend now used up since it doesn't extend beyond + * minuend + */ + r2++; + } + } + else if (r2->x1 < r1->x2) + { + /* + * Left part of subtrahend covers part of minuend: add uncovered + * part of minuend to region and skip to next subtrahend. + */ + assert(x1x1); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r2->x1; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend used up: advance to new... + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend used up + */ + r2++; + } + } + else + { + /* + * Minuend used up: add any remaining piece before advancing. + */ + if (r1->x2 > x1) + { + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + assert(pReg->numRects<=pReg->size); + } + r1++; + if (r1 != r1End) + x1 = r1->x1; + } } /* @@ -1722,57 +1723,57 @@ miSubtractO ( */ while (r1 != r1End) { - assert(x1x2); - MEMCHECK(pReg, pNextRect, pReg->rects); - pNextRect->x1 = x1; - pNextRect->y1 = y1; - pNextRect->x2 = r1->x2; - pNextRect->y2 = y2; - pReg->numRects += 1; - pNextRect++; - - assert(pReg->numRects<=pReg->size); - - r1++; - if (r1 != r1End) - { - x1 = r1->x1; - } + assert(x1x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + assert(pReg->numRects<=pReg->size); + + r1++; + if (r1 != r1End) + { + x1 = r1->x1; + } } - return 0; /* lint */ + return 0; /* lint */ } - + /*- *----------------------------------------------------------------------- * miSubtract -- - * Subtract regS from regM and leave the result in regD. - * S stands for subtrahend, M for minuend and D for difference. + * Subtract regS from regM and leave the result in regD. + * S stands for subtrahend, M for minuend and D for difference. * * Results: - * true. + * true. * * Side Effects: - * regD is overwritten. + * regD is overwritten. * *----------------------------------------------------------------------- */ bool REGION:: XSubtractRegion( - Region regM, - Region regS, - register Region regD) + Region regM, + Region regS, + register Region regD) { /* check for trivial reject */ if ( (!(regM->numRects)) || (!(regS->numRects)) || - (!EXTENTCHECK(®M->extents, ®S->extents)) ) + (!EXTENTCHECK(®M->extents, ®S->extents)) ) { - miRegionCopy(regD, regM); + miRegionCopy(regD, regM); return true; } - - miRegionOp (regD, regM, regS, miSubtractO, - miSubtractNonO1, NULL); + + miRegionOp (regD, regM, regS, miSubtractO, + miSubtractNonO1, NULL); /* * Can't alter newReg's extents before we call miRegionOp because @@ -1791,7 +1792,7 @@ XXorRegion(Region sra, Region srb, Region dr) Region tra, trb; if ((! (tra = XCreateRegion())) || (! (trb = XCreateRegion()))) - return 0; + return 0; (void) XSubtractRegion(sra,srb,tra); (void) XSubtractRegion(srb,sra,trb); (void) XUnionRegion(tra,trb,dr); @@ -1801,7 +1802,7 @@ XXorRegion(Region sra, Region srb, Region dr) } /* - * Check to see if the region is empty. Assumes a region is passed + * Check to see if the region is empty. Assumes a region is passed * as a parameter */ bool REGION:: @@ -1813,7 +1814,7 @@ XEmptyRegion( } /* - * Check to see if two regions are equal + * Check to see if two regions are equal */ bool REGION:: XEqualRegion(Region r1, Region r2) @@ -1827,10 +1828,10 @@ XEqualRegion(Region r1, Region r2) else if ( r1->extents.y1 != r2->extents.y1 ) return false; else if ( r1->extents.y2 != r2->extents.y2 ) return false; else for( i=0; i < r1->numRects; i++ ) { - if ( r1->rects[i].x1 != r2->rects[i].x1 ) return false; - else if ( r1->rects[i].x2 != r2->rects[i].x2 ) return false; - else if ( r1->rects[i].y1 != r2->rects[i].y1 ) return false; - else if ( r1->rects[i].y2 != r2->rects[i].y2 ) return false; + if ( r1->rects[i].x1 != r2->rects[i].x1 ) return false; + else if ( r1->rects[i].x2 != r2->rects[i].x2 ) return false; + else if ( r1->rects[i].y1 != r2->rects[i].y1 ) return false; + else if ( r1->rects[i].y2 != r2->rects[i].y2 ) return false; } return true; } @@ -1849,14 +1850,14 @@ XPointInRegion( for (i=0; inumRects; i++) { if (INBOX (pRegion->rects[i], x, y)) - return true; + return true; } return false; } wxRegionContain REGION:: XRectInRegion( - register Region region, + register Region region, int rx, int ry, unsigned int rwidth, unsigned int rheight) { @@ -1870,69 +1871,69 @@ XRectInRegion( prect->y1 = ry; prect->x2 = rwidth + rx; prect->y2 = rheight + ry; - + /* this is (just) a useful optimization */ if ((region->numRects == 0) || !EXTENTCHECK(®ion->extents, prect)) return(wxOutRegion); - partOut = FALSE; - partIn = FALSE; + partOut = false; + partIn = false; - /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */ + /* can stop when both partOut and partIn are true, or we reach prect->y2 */ for (pbox = region->rects, pboxEnd = pbox + region->numRects; - pbox < pboxEnd; - pbox++) + pbox < pboxEnd; + pbox++) { - if (pbox->y2 <= ry) - continue; /* getting up to speed or skipping remainder of band */ - - if (pbox->y1 > ry) - { - partOut = TRUE; /* missed part of rectangle above */ - if (partIn || (pbox->y1 >= prect->y2)) - break; - ry = pbox->y1; /* x guaranteed to be == prect->x1 */ - } - - if (pbox->x2 <= rx) - continue; /* not far enough over yet */ - - if (pbox->x1 > rx) - { - partOut = TRUE; /* missed part of rectangle to left */ - if (partIn) - break; - } - - if (pbox->x1 < prect->x2) - { - partIn = TRUE; /* definitely overlap */ - if (partOut) - break; - } - - if (pbox->x2 >= prect->x2) - { - ry = pbox->y2; /* finished with this band */ - if (ry >= prect->y2) - break; - rx = prect->x1; /* reset x out to left again */ - } else - { - /* - * Because boxes in a band are maximal width, if the first box - * to overlap the rectangle doesn't completely cover it in that - * band, the rectangle must be partially out, since some of it - * will be uncovered in that band. partIn will have been set true - * by now... - */ - break; - } + if (pbox->y2 <= ry) + continue; /* getting up to speed or skipping remainder of band */ + + if (pbox->y1 > ry) + { + partOut = true; /* missed part of rectangle above */ + if (partIn || (pbox->y1 >= prect->y2)) + break; + ry = pbox->y1; /* x guaranteed to be == prect->x1 */ + } + + if (pbox->x2 <= rx) + continue; /* not far enough over yet */ + + if (pbox->x1 > rx) + { + partOut = true; /* missed part of rectangle to left */ + if (partIn) + break; + } + + if (pbox->x1 < prect->x2) + { + partIn = true; /* definitely overlap */ + if (partOut) + break; + } + + if (pbox->x2 >= prect->x2) + { + ry = pbox->y2; /* finished with this band */ + if (ry >= prect->y2) + break; + rx = prect->x1; /* reset x out to left again */ + } else + { + /* + * Because boxes in a band are maximal width, if the first box + * to overlap the rectangle doesn't completely cover it in that + * band, the rectangle must be partially out, since some of it + * will be uncovered in that band. partIn will have been set true + * by now... + */ + break; + } } - return(partIn ? ((ry < prect->y2) ? wxPartRegion : wxInRegion) : - wxOutRegion); + return(partIn ? ((ry < prect->y2) ? wxPartRegion : wxInRegion) : + wxOutRegion); }