Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public function floodFill(fx:Int, fy:Int, fc:Int):Void {
- // Slightly better than Jeash/NME/OpenFL version, but still some strange code.
- // At least it doesn't spam thousands of Point allocations.
- var wasCanvas = isCanvas();
- lock();
- var q:Array<Int> = [fx | (fy << 16)], // queue
- c:Int = 1, // length of queue
- d:Uint8ClampedArray = qImageData.data,
- zr:Int, zg:Int, zb:Int, za:Int, // start color
- fr:Int, fg:Int, fb:Int, fa:Int, // fill color
- x:Int, y:Int, p:Int, // x, y, pointer/swap variable
- o:Array<Array<Int>> = [], // inspection history array (width>>5 x height cells)
- r:Array<Int>, // row for init of above array
- w:Int = width, h:Int = height;
- // Retrieve RGBA of starting pixel:
- p = (fy * width + fx) << 4;
- zr = d[p]; zg = d[p + 1]; zb = d[p + 2]; za = d[p + 3];
- // Split target color into RGBA:
- fa = (fc >>> 24);
- fr = (fc >> 16) & 255;
- fg = (fc >> 8) & 255;
- fb = fc & 255;
- // Create history array:
- y = -1; while (++y < h) {
- o.push(r = []);
- x = 0; while (x < w) {
- r.push(0);
- x += 32;
- }
- }
- //
- while (c > 0) {
- p = q[--c]; // does the side matter?
- x = p & 0xffff;
- y = p >>> 16;
- // out of bounds (how did this happen...)?
- if (x < 0 || y < 0 || x >= w || y >= h) continue;
- // skip if cell was already inspected:
- if (((o[y][x >> 5] >> (x & 31)) & 1) != 0) continue;
- // mark cell as inspected:
- o[y][x >> 5] |= 1 << (x & 31);
- // find offset for imageData:
- p = (y * width + x) << 2;
- // if it matches source color, set it to destination color and try to expand:
- if (d[p] == zr && d[p + 1] == zg && d[p + 2] == zb && d[p + 3] == za) {
- d[p] = fr; d[p + 1] = fg; d[p + 2] = fb; d[p + 3] = fa;
- // attempt to expand in all directions if locations have not been inspected yet:
- if ((p = x + 1) < w && (((o[y][p >> 5] >> (p & 31)) & 1) == 0)) q[c++] = (y << 16) | p;
- if (x > 0 && (((o[y][(p = x - 1) >> 5] >> (p & 31)) & 1) == 0)) q[c++] = (y << 16) | p;
- if ((p = y + 1) < h && (((o[p][x >> 5] >> (x & 31)) & 1) == 0)) q[c++] = (p << 16) | x;
- if (y > 0 && (((o[(p = y - 1)][x >> 5] >> (x & 31)) & 1) == 0)) q[c++] = (p << 16) | x;
- }
- }
- qSync |= SY_CHANGE | SY_IMDATA;
- if (wasCanvas) unlock();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement