Пример #1
0
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;
	}
Пример #2
0
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;
	}