| 140872 | } // Fetches a monochrome sprite bitmap for the specified text. |
| 140873 | // Load in batches for speed. |
| 140874 | function cloudSprite(contextAndRatio, d, data, di) { |
| 140875 | if (d.sprite) return; |
| 140876 | var c = contextAndRatio.context, ratio = contextAndRatio.ratio; |
| 140877 | c.clearRect(0, 0, (cw << 5) / ratio, ch / ratio); |
| 140878 | var x = 0, y = 0, maxh = 0, n = data.length, w, w32, h, i, j; |
| 140879 | --di; |
| 140880 | while(++di < n){ |
| 140881 | d = data[di]; |
| 140882 | c.save(); |
| 140883 | c.font = d.style + " " + d.weight + " " + ~~((d.size + 1) / ratio) + "px " + d.font; |
| 140884 | w = c.measureText(d.text + "m").width * ratio; |
| 140885 | h = d.size << 1; |
| 140886 | if (d.rotate) { |
| 140887 | var sr = Math.sin(d.rotate * cloudRadians), cr = Math.cos(d.rotate * cloudRadians), wcr = w * cr, wsr = w * sr, hcr = h * cr, hsr = h * sr; |
| 140888 | w = Math.max(Math.abs(wcr + hsr), Math.abs(wcr - hsr)) + 0x1f >> 5 << 5; |
| 140889 | h = ~~Math.max(Math.abs(wsr + hcr), Math.abs(wsr - hcr)); |
| 140890 | } else w = w + 0x1f >> 5 << 5; |
| 140891 | if (h > maxh) maxh = h; |
| 140892 | if (x + w >= cw << 5) { |
| 140893 | x = 0; |
| 140894 | y += maxh; |
| 140895 | maxh = 0; |
| 140896 | } |
| 140897 | if (y + h >= ch) break; |
| 140898 | c.translate((x + (w >> 1)) / ratio, (y + (h >> 1)) / ratio); |
| 140899 | if (d.rotate) c.rotate(d.rotate * cloudRadians); |
| 140900 | c.fillText(d.text, 0, 0); |
| 140901 | if (d.padding) { |
| 140902 | c.lineWidth = 2 * d.padding; |
| 140903 | c.strokeText(d.text, 0, 0); |
| 140904 | } |
| 140905 | c.restore(); |
| 140906 | d.width = w; |
| 140907 | d.height = h; |
| 140908 | d.xoff = x; |
| 140909 | d.yoff = y; |
| 140910 | d.x1 = w >> 1; |
| 140911 | d.y1 = h >> 1; |
| 140912 | d.x0 = -d.x1; |
| 140913 | d.y0 = -d.y1; |
| 140914 | d.hasText = true; |
| 140915 | x += w; |
| 140916 | } |
| 140917 | var pixels = c.getImageData(0, 0, (cw << 5) / ratio, ch / ratio).data, sprite = []; |
| 140918 | while(--di >= 0){ |
| 140919 | d = data[di]; |
| 140920 | if (!d.hasText) continue; |
| 140921 | w = d.width; |
| 140922 | w32 = w >> 5; |
| 140923 | h = d.y1 - d.y0; // Zero the buffer |
| 140924 | for(i = 0; i < h * w32; i++)sprite[i] = 0; |
| 140925 | x = d.xoff; |
| 140926 | if (x == null) return; |
| 140927 | y = d.yoff; |
| 140928 | var seen = 0, seenRow = -1; |
| 140929 | for(j = 0; j < h; j++){ |
| 140930 | for(i = 0; i < w; i++){ |
| 140931 | var k = w32 * j + (i >> 5), m = pixels[(y + j) * (cw << 5) + (x + i) << 2] ? 1 << 31 - i % 32 : 0; |