Skip to content

Instantly share code, notes, and snippets.

@laserbat
Created July 16, 2011 13:12
Show Gist options
  • Save laserbat/1086350 to your computer and use it in GitHub Desktop.
Save laserbat/1086350 to your computer and use it in GitHub Desktop.
function floodFillScanline(x, y, width, height, diagonal, test, paint) {
// xMin, xMax, y, down[true] / up[false], extendLeft, extendRight
var ranges = [[x, x, y, null, true, true]];
paint(x, y);
while(ranges.length) {
var r = ranges.pop();
var down = r[3] === true;
var up = r[3] === false;
// extendLeft
var minX = r[0];
var y = r[2];
if(r[4]) {
while(minX>0 && test(minX-1, y)) {
minX–;
paint(minX, y);
}
}
var maxX = r[1];
// extendRight
if(r[5]) {
while(maxX<width-1 && test(maxX+1, y)) {
maxX++;
paint(maxX, y);
}
}
if(diagonal) {
// extend range looked at for next lines
if(minX>0) minX&#8211;;
if(maxX<width-1) maxX++;
}
else {
// extend range ignored from previous line
r[0]--;
r[1]++;
}
function addNextLine(newY, isNext, downwards) {
var rMinX = minX;
var inRange = false;
for(var x=minX; x<=maxX; x++) {
// skip testing, if testing previous line within previous range
var empty = (isNext || (x<r[0] || x>r[1])) && test(x, newY);
if(!inRange && empty) {
rMinX = x;
inRange = true;
}
else if(inRange && !empty) {
ranges.push([rMinX, x-1, newY, downwards, rMinX==minX, false]);
inRange = false;
}
if(inRange) {
paint(x, newY);
}
// skip
if(!isNext && x==r[0]) {
x = r[1];
}
}
if(inRange) {
ranges.push([rMinX, x-1, newY, downwards, rMinX==minX, true]);
}
}
if(y<height)
addNextLine(y+1, !up, true);
if(y>0)
addNextLine(y-1, !down, false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment