unsafe void LinearFloodFill4(ref int x, ref int y) { //offset the pointer to the point passed in byte *p = (byte *)(scan0 + (CoordsToIndex(ref x, ref y))); //cache some bitmap and fill info in local variables for a little extra speed 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 byte *ptr = p; //the pointer to the current location int pxIdx = (bitmapWidth * y) + x; while (true) { ptr[0] = byteFillColor[0]; //fill with the color ptr[1] = byteFillColor[1]; ptr[2] = byteFillColor[2]; pixelsChecked[pxIdx] = true; lFillLoc--; //de-increment counter ptr -= bitmapPixelFormatSize; //de-increment pointer pxIdx--; if (lFillLoc <= 0 || !CheckPixel(ref ptr) || (pixelsChecked[pxIdx])) { break; //exit loop if we're at edge of bitmap or color area } } lFillLoc++; //FIND RIGHT EDGE OF COLOR AREA int rFillLoc = x; //the location to check/fill on the left ptr = p; pxIdx = (bitmapWidth * y) + x; while (true) { ptr[0] = byteFillColor[0]; //fill with the color ptr[1] = byteFillColor[1]; ptr[2] = byteFillColor[2]; pixelsChecked[pxIdx] = true; rFillLoc++; //increment counter ptr += bitmapPixelFormatSize; //increment pointer pxIdx++; if (rFillLoc >= bitmapWidth || !CheckPixel(ref ptr) || (pixelsChecked[pxIdx])) { break; //exit loop if we're at edge of bitmap or color area } } rFillLoc--; for (int xx = lFillLoc; xx <= rFillLoc; xx++) { pts.Add(new Point(xx, y)); } FloodFillRange r = new FloodFillRange(lFillLoc, rFillLoc, y); ranges.Enqueue(ref r); }
/// <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) { //***Find Left Edge of fill area int lFillLoc = x; //the location to check/fill on the left int idx = CoordsToIndex(ref x, ref y); //the index of the current location while (true) { //**fill with the fillValue gridCells[idx] = true; //**de-increment lFillLoc--; //de-increment counter idx -= 1; //de-increment index //**exit loop if we're at edge of fill area if (lFillLoc <= 0 || (gridCells[idx]) || !CheckCell(ref idx)) { break; } } lFillLoc++; //***Find Right Edge of free area int rFillLoc = x; //the location to check/fill on the right idx = CoordsToIndex(ref x, ref y); while (true) { //**fill with the fillValue gridCells[idx] = true; //**increment rFillLoc++; //increment counter idx += 1; //increment index //**exit loop if we're at edge of fill area if (rFillLoc >= gridWidth || gridCells[idx] || !CheckCell(ref idx)) { break; } } rFillLoc--; //add range to queue FloodFillRange r = new FloodFillRange(lFillLoc, rFillLoc, y); ranges.Enqueue(ref r); }
/// <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); }