diff --git a/include/tools.bm b/include/tools.bm index 01b45bd..ba16767 100644 --- a/include/tools.bm +++ b/include/tools.bm @@ -145,99 +145,62 @@ sub filledcircle(x,y,r,col as long) wend end sub - -sub floodfill (x as integer, y as integer, fillcolor as long) - dim as integer leftx, rightx, currenty - dim as integer arrsize, stackptr - - ' Create a stack for storing coordinates - arrsize = 1000 ' Adjust based on expected complexity - redim stack(1 to arrsize, 1 to 2) as integer - stackptr = 0 - - ' Get the color at starting point - dim startcolor as long - startcolor = point(x, y) - - ' If starting on boundary color or fill color, exit - if startcolor = fillcolor then exit sub - - ' Push starting point to stack - stackptr = stackptr + 1 - stack(stackptr, 1) = x - stack(stackptr, 2) = y - - ' Process until stack is empty - do while stackptr > 0 - ' Pop a point from stack - x = stack(stackptr, 1) - y = stack(stackptr, 2) - stackptr = stackptr - 1 - - ' Skip if current point is not startcolor - if point(x, y) <> startcolor then _continue - - ' Find leftmost point on this scanline - leftx = x - do while leftx > 0 and point(leftx - 1, y) = startcolor - leftx = leftx - 1 - loop - - ' Find rightmost point on this scanline - rightx = x - do while rightx < _width - 1 and point(rightx + 1, y) = startcolor - rightx = rightx + 1 - loop - - ' Fill the scanline - line (leftx, y)-(rightx, y), fillcolor - - ' Check scanline above - currenty = y - 1 - if currenty >= 0 then - for x = leftx to rightx - if point(x, currenty) = startcolor then - ' Push seed point to stack - stackptr = stackptr + 1 - if stackptr > arrsize then - ' Resize stack if needed - arrsize = arrsize * 2 - redim _preserve stack(1 to arrsize, 1 to 2) as integer - end if - stack(stackptr, 1) = x - stack(stackptr, 2) = currenty - - ' Skip adjacent pixels of same color - do while x <= rightx and point(x, currenty) = startcolor - x = x + 1 - loop - x = x - 1 ' Adjust for loop increment - end if - next x - end if - - ' Check scanline below - currenty = y + 1 - if currenty < _height then - for x = leftx to rightx - if point(x, currenty) = startcolor then - ' Push seed point to stack - stackptr = stackptr + 1 - if stackptr > arrsize then - ' Resize stack if needed - arrsize = arrsize * 2 - redim _preserve stack(1 to arrsize, 1 to 2) as integer - end if - stack(stackptr, 1) = x - stack(stackptr, 2) = currenty - - ' Skip adjacent pixels of same color - do while x <= rightx and point(x, currenty) = startcolor - x = x + 1 - loop - x = x - 1 ' Adjust for loop increment - end if - next x - end if - loop -end sub + SUB FloodFill (startX, startY, fillColor~&) + ' We use a simple array as a stack for (x, y) pairs + ' For large images, you may need to increase this size + DIM stackX(2000) AS INTEGER + DIM stackY(2000) AS INTEGER + targetColor~&=point(startX,startY) + stackPtr = 1 + + stackX(stackPtr) = startX + stackY(stackPtr) = startY + + WHILE stackPtr > 0 + curX = stackX(stackPtr) + curY = stackY(stackPtr) + stackPtr = stackPtr - 1 + + ' Move to the left edge of the span + x = curX + WHILE POINT(x, curY) = targetColor~& AND x >= 0 + x = x - 1 + WEND + x = x + 1 + + spanAbove = 0 + spanBelow = 0 + + ' Process the span moving right + WHILE POINT(x, curY) = targetColor~& AND x < _WIDTH + PSET (x, curY), fillColor~& + + ' Check row above + IF curY > 0 THEN + IF spanAbove = 0 AND POINT(x, curY - 1) = targetColor~& THEN + stackPtr = stackPtr + 1 + stackX(stackPtr) = x + stackY(stackPtr) = curY - 1 + spanAbove = 1 + ELSEIF spanAbove = 1 AND POINT(x, curY - 1) <> targetColor~& THEN + spanAbove = 0 + END IF + END IF + + ' Check row below + IF curY < _HEIGHT - 1 THEN + IF spanBelow = 0 AND POINT(x, curY + 1) = targetColor~& THEN + stackPtr = stackPtr + 1 + stackX(stackPtr) = x + stackY(stackPtr) = curY + 1 + spanBelow = 1 + ELSEIF spanBelow = 1 AND POINT(x, curY + 1) <> targetColor~& THEN + spanBelow = 0 + END IF + END IF + + x = x + 1 + WEND + WEND + END SUB + diff --git a/pixler.bas b/pixler.bas index e8bae4f..b69973c 100644 --- a/pixler.bas +++ b/pixler.bas @@ -180,8 +180,8 @@ sub canvas if _mousex > boxX1 then ' Start Drawing Logic if state.tool = 9 and (mouseclicked or rmouseclicked) then - _dest layers(2).ihandle - _source layers(2).ihandle + _dest layers(1).ihandle + _source layers(1).ihandle if mouseclicked then floodfill canX,canY,state.fcolor else @@ -230,7 +230,7 @@ sub canvas thickline state.startX, canY, state.startX, state.startY, drawCol case 6 ' Filled Rect line (state.startX, state.startY)-(canX, canY), drawCol, bf - case 7, 8 ' Polygons[cite: 2] + case 7, 8 ' Polygons if pointCount > 0 then for p = 1 to pointCount - 1 thickline polypoints((p - 1) * 2), polypoints((p - 1) * 2 + 1), polypoints(p * 2), polypoints(p * 2 + 1), drawCol