|
|
|
@ -601,49 +601,54 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
@@ -601,49 +601,54 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function composeSMaskBackdrop(bytes, r0, g0, b0) { |
|
|
|
|
var length = bytes.length; |
|
|
|
|
for (var i = 3; i < length; i += 4) { |
|
|
|
|
var alpha = bytes[i]; |
|
|
|
|
if (alpha === 0) { |
|
|
|
|
bytes[i - 3] = r0; |
|
|
|
|
bytes[i - 2] = g0; |
|
|
|
|
bytes[i - 1] = b0; |
|
|
|
|
} else if (alpha < 255) { |
|
|
|
|
var alpha_ = 255 - alpha; |
|
|
|
|
bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) >> 8; |
|
|
|
|
bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) >> 8; |
|
|
|
|
bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) >> 8; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function composeSMaskAlpha(maskData, layerData) { |
|
|
|
|
var length = maskData.length; |
|
|
|
|
var scale = 1 / 255; |
|
|
|
|
for (var i = 3; i < length; i += 4) { |
|
|
|
|
var alpha = maskData[i]; |
|
|
|
|
layerData[i] = (layerData[i] * alpha * scale) | 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function composeSMaskLuminosity(maskData, layerData) { |
|
|
|
|
var length = maskData.length; |
|
|
|
|
for (var i = 3; i < length; i += 4) { |
|
|
|
|
var y = ((maskData[i - 3] * 77) + // * 0.3 / 255 * 0x10000
|
|
|
|
|
(maskData[i - 2] * 152) + // * 0.59 ....
|
|
|
|
|
(maskData[i - 1] * 28)) | 0; // * 0.11 ....
|
|
|
|
|
layerData[i] = (layerData[i] * y) >> 16; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function genericComposeSMask(maskCtx, layerCtx, width, height, |
|
|
|
|
subtype, backdrop) { |
|
|
|
|
var addBackdropFn; |
|
|
|
|
if (backdrop) { |
|
|
|
|
addBackdropFn = function (r0, g0, b0, bytes) { |
|
|
|
|
var length = bytes.length; |
|
|
|
|
for (var i = 3; i < length; i += 4) { |
|
|
|
|
var alpha = bytes[i] / 255; |
|
|
|
|
if (alpha === 0) { |
|
|
|
|
bytes[i - 3] = r0; |
|
|
|
|
bytes[i - 2] = g0; |
|
|
|
|
bytes[i - 1] = b0; |
|
|
|
|
} else if (alpha < 1) { |
|
|
|
|
var alpha_ = 1 - alpha; |
|
|
|
|
bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) | 0; |
|
|
|
|
bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) | 0; |
|
|
|
|
bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) | 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}.bind(null, backdrop[0], backdrop[1], backdrop[2]); |
|
|
|
|
} else { |
|
|
|
|
addBackdropFn = function () {}; |
|
|
|
|
} |
|
|
|
|
var hasBackdrop = backdrop !== undefined; |
|
|
|
|
var r0 = hasBackdrop ? backdrop[0] : 0; |
|
|
|
|
var g0 = hasBackdrop ? backdrop[1] : 0; |
|
|
|
|
var b0 = hasBackdrop ? backdrop[2] : 0; |
|
|
|
|
|
|
|
|
|
var composeFn; |
|
|
|
|
if (subtype === 'Luminosity') { |
|
|
|
|
composeFn = function (maskDataBytes, layerDataBytes) { |
|
|
|
|
var length = maskDataBytes.length; |
|
|
|
|
for (var i = 3; i < length; i += 4) { |
|
|
|
|
var y = ((maskDataBytes[i - 3] * 77) + // * 0.3 / 255 * 0x10000
|
|
|
|
|
(maskDataBytes[i - 2] * 152) + // * 0.59 ....
|
|
|
|
|
(maskDataBytes[i - 1] * 28)) | 0; // * 0.11 ....
|
|
|
|
|
layerDataBytes[i] = (layerDataBytes[i] * y) >> 16; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
composeFn = composeSMaskLuminosity; |
|
|
|
|
} else { |
|
|
|
|
composeFn = function (maskDataBytes, layerDataBytes) { |
|
|
|
|
var length = maskDataBytes.length; |
|
|
|
|
for (var i = 3; i < length; i += 4) { |
|
|
|
|
var alpha = maskDataBytes[i]; |
|
|
|
|
layerDataBytes[i] = (layerDataBytes[i] * alpha / 255) | 0; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
composeFn = composeSMaskAlpha; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// processing image in chunks to save memory
|
|
|
|
@ -654,7 +659,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
@@ -654,7 +659,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|
|
|
|
var maskData = maskCtx.getImageData(0, row, width, chunkHeight); |
|
|
|
|
var layerData = layerCtx.getImageData(0, row, width, chunkHeight); |
|
|
|
|
|
|
|
|
|
addBackdropFn(maskData.data); |
|
|
|
|
if (hasBackdrop) { |
|
|
|
|
composeSMaskBackdrop(maskData.data, r0, g0, b0); |
|
|
|
|
} |
|
|
|
|
composeFn(maskData.data, layerData.data); |
|
|
|
|
|
|
|
|
|
maskCtx.putImageData(layerData, 0, row); |
|
|
|
|