From 218e54ce7050ea2f95f40564a9425a9375719ac1 Mon Sep 17 00:00:00 2001 From: visionmercer <62051836+visionmercer@users.noreply.github.com> Date: Fri, 1 May 2026 13:58:36 +0200 Subject: [PATCH] buggy flood fill --- include/tools.bm | 102 ++++++++++++++++++++++++++++++++++++++++++++++- pixler.bas | 25 +++++++++--- 2 files changed, 120 insertions(+), 7 deletions(-) diff --git a/include/tools.bm b/include/tools.bm index e6f03fc..01b45bd 100644 --- a/include/tools.bm +++ b/include/tools.bm @@ -1,6 +1,6 @@ -sub filledPolygon (Points() as single, col as long) +sub filledPolygon (Points() as long, col as long) dim i as integer, j as integer dim x1 as single, y1 as single, x2 as single, y2 as single dim intersectX as single @@ -67,8 +67,9 @@ Sub polygon (pa() As Long,col as long) For i = 2 To UBound(pa) Step 2 thickLine pa(i - 2), pa(i - 1),pa(i), pa(i + 1),col Next i - thickLine pa(i - 1), pa(i - 2),pa(0), pa(1),col + thickLine pa(ubound(pa)-1), pa(ubound(pa)),pa(0), pa(1),col End Sub + sub thickcircle(x, y, r, col as long) if state.brushsize <= 1 then circle (x, y), r, col @@ -143,3 +144,100 @@ sub filledcircle(x,y,r,col as long) line (x-tx,y+ty)-(x+tx,y+ty),col 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 diff --git a/pixler.bas b/pixler.bas index 8827781..e8bae4f 100644 --- a/pixler.bas +++ b/pixler.bas @@ -179,6 +179,17 @@ sub canvas ' 4. Interaction Logic if _mousex > boxX1 then ' Start Drawing Logic + if state.tool = 9 and (mouseclicked or rmouseclicked) then + _dest layers(2).ihandle + _source layers(2).ihandle + if mouseclicked then + floodfill canX,canY,state.fcolor + else + floodfill canX,canY,state.bcolor + end if + _dest 0 + _source 0 + end if if state.tool = 7 or state.tool = 8 then if mouseclicked then polypoints(pointCount * 2) = canX @@ -238,16 +249,15 @@ sub canvas if commit then _dest layers(1).ihandle ' Final destination is always the drawing layer - if state.tool = 8 and pointCount > 2 then - redim finalP(pointCount * 2 - 1) as single + if (state.tool = 8 or state.tool=7) and pointCount > 2 then + redim finalP(pointCount * 2 - 1) as long for p = 0 to (pointCount * 2) - 1: finalP(p) = polypoints(p): next - filledPolygon finalP(), drawCol ' Using tools.bm sub[cite: 2] + if state.tool =8 then filledPolygon finalP(), drawCol else Polygon finalP(), drawCol else - ' Merge the preview into the drawing layer[cite: 1] + ' Merge the preview into the drawing layer _putimage , layers(2).ihandle, layers(1).ihandle end if - ' Clear preview layer[cite: 1] _dest layers(2).ihandle: cls , 0 state.isDrawing = 0 pointCount = 0 @@ -275,6 +285,11 @@ function icon (index as long) ' Draw a small filled shape for the filled polygon icon for fy = 10 to 20: line (10, fy)-(22, fy): next _dest 0 + icons(8) = _newimage(32, 32, 32): _dest icons(8) + ' Simple "Bucket" icon + line (8, 10)-(24, 10): line -(26, 22): line -(6, 22): line -(8, 10) + line (10, 8)-(22, 8) ' Handle + _dest 0 ' Fill the remaining slots with blank 32x32 images dim j as integer for j = 0 to 19