(board, tag, bounds)
| 80 | }; |
| 81 | |
| 82 | function place(board, tag, bounds) { |
| 83 | var perimeter = [{x: 0, y: 0}, {x: size[0], y: size[1]}], |
| 84 | startX = tag.x, |
| 85 | startY = tag.y, |
| 86 | maxDelta = Math.sqrt(size[0] * size[0] + size[1] * size[1]), |
| 87 | s = spiral(size), |
| 88 | dt = Math.random() < .5 ? 1 : -1, |
| 89 | t = -dt, |
| 90 | dxdy, |
| 91 | dx, |
| 92 | dy; |
| 93 | |
| 94 | while (dxdy = s(t += dt)) { |
| 95 | dx = ~~dxdy[0]; |
| 96 | dy = ~~dxdy[1]; |
| 97 | |
| 98 | if (Math.min(dx, dy) > maxDelta) break; |
| 99 | |
| 100 | tag.x = startX + dx; |
| 101 | tag.y = startY + dy; |
| 102 | |
| 103 | if (tag.x + tag.x0 < 0 || tag.y + tag.y0 < 0 || |
| 104 | tag.x + tag.x1 > size[0] || tag.y + tag.y1 > size[1]) continue; |
| 105 | // TODO only check for collisions within current bounds. |
| 106 | if (!bounds || !cloudCollide(tag, board, size[0])) { |
| 107 | if (!bounds || collideRects(tag, bounds)) { |
| 108 | var sprite = tag.sprite, |
| 109 | w = tag.width >> 5, |
| 110 | sw = size[0] >> 5, |
| 111 | lx = tag.x - (w << 4), |
| 112 | sx = lx & 0x7f, |
| 113 | msx = 32 - sx, |
| 114 | h = tag.y1 - tag.y0, |
| 115 | x = (tag.y + tag.y0) * sw + (lx >> 5), |
| 116 | last; |
| 117 | for (var j = 0; j < h; j++) { |
| 118 | last = 0; |
| 119 | for (var i = 0; i <= w; i++) { |
| 120 | board[x + i] |= (last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0); |
| 121 | } |
| 122 | x += sw; |
| 123 | } |
| 124 | delete tag.sprite; |
| 125 | return true; |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | return false; |
| 130 | } |
| 131 | |
| 132 | cloud.words = function(x) { |
| 133 | if (!arguments.length) return words; |
no test coverage detected