Advertisement
YellowAfterlife

Haxe-OpenFL BitmapData.floodFill implementation

Aug 17th, 2013
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haxe 2.18 KB | None | 0 0
  1. public function floodFill(fx:Int, fy:Int, fc:Int):Void {
  2.     // Slightly better than Jeash/NME/OpenFL version, but still some strange code.
  3.     // At least it doesn't spam thousands of Point allocations.
  4.     var wasCanvas = isCanvas();
  5.     lock();
  6.     var q:Array<Int> = [fx | (fy << 16)], // queue
  7.         c:Int = 1, // length of queue
  8.         d:Uint8ClampedArray = qImageData.data,
  9.         zr:Int, zg:Int, zb:Int, za:Int, // start color
  10.         fr:Int, fg:Int, fb:Int, fa:Int, // fill color
  11.         x:Int, y:Int, p:Int, // x, y, pointer/swap variable
  12.         o:Array<Array<Int>> = [], // inspection history array (width>>5 x height cells)
  13.         r:Array<Int>, // row for init of above array
  14.         w:Int = width, h:Int = height;
  15.     // Retrieve RGBA of starting pixel:
  16.     p = (fy * width + fx) << 4;
  17.     zr = d[p]; zg = d[p + 1]; zb = d[p + 2]; za = d[p + 3];
  18.     // Split target color into RGBA:
  19.     fa = (fc >>> 24);
  20.     fr = (fc >> 16) & 255;
  21.     fg = (fc >> 8) & 255;
  22.     fb = fc & 255;
  23.     // Create history array:
  24.     y = -1; while (++y < h) {
  25.         o.push(r = []);
  26.         x = 0; while (x < w) {
  27.             r.push(0);
  28.             x += 32;
  29.         }
  30.     }
  31.     //
  32.     while (c > 0) {
  33.         p = q[--c]; // does the side matter?
  34.         x = p & 0xffff;
  35.         y = p >>> 16;
  36.         // out of bounds (how did this happen...)?
  37.         if (x < 0 || y < 0 || x >= w || y >= h) continue;
  38.         // skip if cell was already inspected:
  39.         if (((o[y][x >> 5] >> (x & 31)) & 1) != 0) continue;
  40.         // mark cell as inspected:
  41.         o[y][x >> 5] |= 1 << (x & 31);
  42.         // find offset for imageData:
  43.         p = (y * width + x) << 2;
  44.         // if it matches source color, set it to destination color and try to expand:
  45.         if (d[p] == zr && d[p + 1] == zg && d[p + 2] == zb && d[p + 3] == za) {
  46.             d[p] = fr; d[p + 1] = fg; d[p + 2] = fb; d[p + 3] = fa;
  47.             // attempt to expand in all directions if locations have not been inspected yet:
  48.             if ((p = x + 1) < w && (((o[y][p >> 5] >> (p & 31)) & 1) == 0)) q[c++] = (y << 16) | p;
  49.             if (x > 0 && (((o[y][(p = x - 1) >> 5] >> (p & 31)) & 1) == 0)) q[c++] = (y << 16) | p;
  50.             if ((p = y + 1) < h && (((o[p][x >> 5] >> (x & 31)) & 1) == 0)) q[c++] = (p << 16) | x;
  51.             if (y > 0 && (((o[(p = y - 1)][x >> 5] >> (x & 31)) & 1) == 0)) q[c++] = (p << 16) | x;
  52.         }
  53.     }
  54.     qSync |= SY_CHANGE | SY_IMDATA;
  55.     if (wasCanvas) unlock();
  56. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement