static bool sCheckPixel(const ZRef<ZDCCanvas>& inCanvas, ZDCState& ioState, ZCoord inLocationH, ZCoord inLocationV, const ZRGBColor& inSeedColor, const ZDCRgn& inMaskRgn) { if (inMaskRgn.Contains(inLocationH, inLocationV)) { // We've already visited this pixel. return false; } if (inCanvas->GetPixel(ioState, inLocationH, inLocationV) != inSeedColor) { // This pixel is not the seed color. return false; } return true; }
static ZDCRgn sCalcFloodFillRgn(const ZRef<ZDCCanvas>& inCanvas, ZDCState& ioState, ZPoint inSeedLocation) { ZDCRgn theMaskRgn; ZRGBColor theSeedColor = inCanvas->GetPixel(ioState, inSeedLocation.h, inSeedLocation.v); ZRect theBounds = ioState.fClip.Bounds() + (ioState.fClipOrigin - ioState.fOrigin); vector<ZPoint> theStack; theStack.push_back(inSeedLocation); while (theStack.size()) { ZPoint theLocation = theStack.back(); theStack.pop_back(); if (::sCheckPixel(inCanvas, ioState, theLocation.h, theLocation.v, theSeedColor, theMaskRgn)) { // Find left and right boundaries ZCoord left = theLocation.h; while ((left > theBounds.left) && ::sCheckPixel(inCanvas, ioState, left - 1, theLocation.v, theSeedColor, theMaskRgn)) { --left; } ZCoord right = theLocation.h; while ((right < theBounds.right) && ::sCheckPixel(inCanvas, ioState, right, theLocation.v, theSeedColor, theMaskRgn)) { ++right; } theMaskRgn |= ZRect(left, theLocation.v, right, theLocation.v + 1); // Do the line above ZCoord currentY = theLocation.v - 1; ZCoord currentX; if (currentY >= theBounds.top) { currentX = left; while (currentX < right) { while ((currentX < right) && !sCheckPixel(inCanvas, ioState, currentX, currentY, theSeedColor, theMaskRgn)) { ++currentX; } if (currentX < right) { while ((currentX < right) && sCheckPixel(inCanvas, ioState, currentX, currentY, theSeedColor, theMaskRgn)) { ++currentX; } theStack.push_back(ZPoint(currentX - 1, currentY)); } } } // Do the line below currentY = theLocation.v + 1; if (currentY < theBounds.bottom) { currentX = left; while (currentX < right) { while ((currentX < right) && !sCheckPixel(inCanvas, ioState, currentX, currentY, theSeedColor, theMaskRgn)) { ++currentX; } if (currentX < right) { while ((currentX < right) && sCheckPixel(inCanvas, ioState, currentX, currentY, theSeedColor, theMaskRgn)) { ++currentX; } theStack.push_back(ZPoint(currentX - 1, currentY)); } } } } } return theMaskRgn; }