size_t ZGRgnRep_HRGN::Decompose(DecomposeProc iProc, void* iRefcon) { RECT bounds; int regionType = ::GetRgnBox(fHRGN, &bounds); if (regionType == NULLREGION) return 0 ; if (regionType == SIMPLEREGION) { iProc(sRectPOD(bounds.left, bounds.top, bounds.right, bounds.bottom), iRefcon); return 1; } if (regionType == COMPLEXREGION) { size_t regionLength = ::GetRegionData(fHRGN, 0, nullptr); std::vector<char> rawStorage(regionLength); RGNDATA* regionData = reinterpret_cast<RGNDATA*>(&rawStorage[0]); ::GetRegionData(fHRGN, regionLength, regionData); RECT* rectArray = (RECT*)(regionData->Buffer); size_t callbacksMade = 0; for (size_t x = 0; x < regionData->rdh.nCount; ++x) { ++callbacksMade; if (iProc(sRectPOD(rectArray[x].left, rectArray[x].top, rectArray[x].right, rectArray[x].bottom), iRefcon)) break; } return callbacksMade; } ZDebugStopf(1, ("ZGRgnRep_HRGN::Decompose, unknown region type")); return 0; }
static void spDecompose( int iMaxDim, int iBaseDim, const PixmapRegName& iPRN, vector<PixmapRegName>& ioPRNs) { vector<ZRectPOD> theRects; // Quantized region. { ZBigRegionAccumulator quant; const int q = iBaseDim; const ZBigRegion theRgn = spRegion(iPRN.f0); const ZRectPOD theBounds = theRgn.Bounds(); const vector<ZRectPOD> decomposed = spDecompose(theRgn); foreachv (const ZRectPOD& theRect, decomposed) { const ZRectPOD current = sRectPOD( (L(theRect) / q) * q, (T(theRect) / q) * q, (R(theRect + q - 1) / q) * q, (B(theRect + q - 1) / q) * q); quant.Include(theBounds & current); } quant.Get().Decompose(theRects); } // We have a list of rectangles within the source. // Now let's break up any that are too big. vector<ZRectPOD> smallRects; foreachv (const ZRectPOD& theRect, theRects) { for (int theTop = T(theRect); theTop < B(theRect); /*no inc*/) { const int theBottom = sMin(theTop + iMaxDim, B(theRect)); for (int theLeft = L(theRect); theLeft < R(theRect); /*no inc*/) { const int theRight = sMin(theLeft + iMaxDim, R(theRect)); smallRects.push_back(sRectPOD(theLeft, theTop, theRight, theBottom)); theLeft = theRight; } theTop = theBottom; } } // Append chunks to ioPRNs foreachv (const ZRectPOD& theRect, smallRects) { ioPRNs.push_back( PixmapRegName(ZDCPixmap(iPRN.f0, theRect), iPRN.f1 - LT(theRect), iPRN.f2)); }
ZRectPOD ZGRgnRep_HRGN::Bounds() { RECT theRECT; ::GetRgnBox(fHRGN, &theRECT); return sRectPOD(theRECT.left, theRECT.top, theRECT.right, theRECT.bottom); }
ZRectPOD ZGRgn::Bounds() const { if (fRep) return fRep->Bounds(); return sRectPOD(0, 0, 0, 0); }
ZGRgn::ZGRgn(ZCoord iLeft, ZCoord iTop, ZCoord iRight, ZCoord iBottom) : fRep(spMake(sRectPOD(iLeft, iTop, iRight, iBottom))) {}
ZDCPixmap GetPixmap() { return ZDCPixmap(fPixmap, sRectPOD(fUsedX, fUsedY)); }