예제 #1
0
        /// <summary>Removes and returns the <see cref="FloodFillRange"/> at the beginning of the queue.</summary>
        public FloodFillRange Dequeue()
        {
            FloodFillRange range = new FloodFillRange();

            if (size > 0)
            {
                range       = array[head];
                array[head] = new FloodFillRange();
                head++; //advance head position
                size--; //update size to exclude dequeued item
            }
            return(range);
        }
예제 #2
0
        /// <summary>
        /// Finds the furthermost left and right boundaries of the fill area
        /// on a given y coordinate, starting from a given x coordinate, filling as it goes.
        /// Adds the resulting horizontal range to the queue of floodfill ranges,
        /// to be processed in the main loop.
        /// </summary>
        /// <param name="x">The x coordinate to start from.</param>
        /// <param name="y">The y coordinate to check at.</param>
        void LinearFill(ref int x, ref int y)
        {
            //cache some bitmap and fill info in local variables for a little extra speed
            byte[] bitmapBits            = this.bitmapBits;
            bool[] pixelsChecked         = this.pixelsChecked;
            byte[] byteFillColor         = this.byteFillColor;
            int    bitmapPixelFormatSize = this.bitmapPixelFormatSize;
            int    bitmapWidth           = this.bitmapWidth;

            //***Find Left Edge of Color Area
            int lFillLoc = x;                               //the location to check/fill on the left
            int idx      = CoordsToByteIndex(ref x, ref y); //the byte index of the current location
            int pxIdx    = (bitmapWidth * y) + x;           //CoordsToPixelIndex(x,y);

            while (true)
            {
                //**fill with the color
                bitmapBits[idx]     = byteFillColor[0];
                bitmapBits[idx + 1] = byteFillColor[1];
                bitmapBits[idx + 2] = byteFillColor[2];
                //**indicate that this pixel has already been checked and filled
                pixelsChecked[pxIdx] = true;
                //**screen update for 'slow' fill
                if (slow)
                {
                    UpdateScreen(ref lFillLoc, ref y);
                }
                //**de-increment
                lFillLoc--;                   //de-increment counter
                pxIdx--;                      //de-increment pixel index
                idx -= bitmapPixelFormatSize; //de-increment byte index
                //**exit loop if we're at edge of bitmap or color area
                if (lFillLoc <= 0 || (pixelsChecked[pxIdx]) || !CheckPixel(ref idx))
                {
                    break;
                }
            }
            lFillLoc++;

            //***Find Right Edge of Color Area
            int rFillLoc = x; //the location to check/fill on the left

            idx   = CoordsToByteIndex(ref x, ref y);
            pxIdx = (bitmapWidth * y) + x;
            while (true)
            {
                //**fill with the color
                bitmapBits[idx]     = byteFillColor[0];
                bitmapBits[idx + 1] = byteFillColor[1];
                bitmapBits[idx + 2] = byteFillColor[2];
                //**indicate that this pixel has already been checked and filled
                pixelsChecked[pxIdx] = true;
                //**screen update for 'slow' fill
                if (slow)
                {
                    UpdateScreen(ref rFillLoc, ref y);
                }
                //**increment
                rFillLoc++;                   //increment counter
                pxIdx++;                      //increment pixel index
                idx += bitmapPixelFormatSize; //increment byte index
                //**exit loop if we're at edge of bitmap or color area
                if (rFillLoc >= bitmapWidth || pixelsChecked[pxIdx] || !CheckPixel(ref idx))
                {
                    break;
                }
            }
            rFillLoc--;

            //add range to queue
            FloodFillRange r = new FloodFillRange(lFillLoc, rFillLoc, y);

            ranges.Enqueue(ref r);
        }