diff --git a/src/display/canvas.js b/src/display/canvas.js index c9864ec70..40a2bc1df 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -191,6 +191,18 @@ function compileType3Glyph(imgData) { var points = new Uint8Array(width1 * (height + 1)); var POINT_TYPES = new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); + + // decodes bit-packed mask data + var lineSize = (width + 7) & ~7, data0 = imgData.data; + var data = new Uint8Array(lineSize * height), pos = 0, ii; + for (i = 0, ii = data0.length; i < ii; i++) { + var mask = 128, elem = data0[i]; + while (mask > 0) { + data[pos++] = (elem & mask) ? 0 : 255; + mask >>= 1; + } + } + // finding iteresting points: every point is located between mask pixels, // so there will be points of the (width + 1)x(height + 1) grid. Every point // will have flags assigned based on neighboring mask pixels: @@ -201,24 +213,25 @@ function compileType3Glyph(imgData) { // - outside corners: 1, 2, 4, 8; // - inside corners: 7, 11, 13, 14; // - and, intersections: 5, 10. - var pos = 3, data = imgData.data, lineSize = width * 4, count = 0; - if (data[3] !== 0) { + var count = 0; + pos = 0; + if (data[pos] !== 0) { points[0] = 1; ++count; } for (j = 1; j < width; j++) { - if (data[pos] !== data[pos + 4]) { + if (data[pos] !== data[pos + 1]) { points[j] = data[pos] ? 2 : 1; ++count; } - pos += 4; + pos++; } if (data[pos] !== 0) { points[j] = 2; ++count; } - pos += 4; for (i = 1; i < height; i++) { + pos = i * lineSize; j0 = i * width1; if (data[pos - lineSize] !== data[pos]) { points[j0] = data[pos] ? 1 : 8; @@ -228,37 +241,36 @@ function compileType3Glyph(imgData) { // array (in order 8-1-2-4, so we can use '>>2' to shift the column). var sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0); for (j = 1; j < width; j++) { - sum = (sum >> 2) + (data[pos + 4] ? 4 : 0) + - (data[pos - lineSize + 4] ? 8 : 0); + sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + + (data[pos - lineSize + 1] ? 8 : 0); if (POINT_TYPES[sum]) { points[j0 + j] = POINT_TYPES[sum]; ++count; } - pos += 4; + pos++; } if (data[pos - lineSize] !== data[pos]) { points[j0 + j] = data[pos] ? 2 : 4; ++count; } - pos += 4; if (count > POINT_TO_PROCESS_LIMIT) { return null; } } - pos -= lineSize; + pos = lineSize * (height - 1); j0 = i * width1; if (data[pos] !== 0) { points[j0] = 8; ++count; } for (j = 1; j < width; j++) { - if (data[pos] !== data[pos + 4]) { + if (data[pos] !== data[pos + 1]) { points[j0 + j] = data[pos] ? 4 : 8; ++count; } - pos += 4; + pos++; } if (data[pos] !== 0) { points[j0 + j] = 4;