diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 6d61fea1d..05bf061df 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -20,7 +20,8 @@ stdFontMap, symbolsFonts, getTilingPatternIR, warn, Util, Promise, RefSetCache, isRef, TextRenderingMode, IdentityToUnicodeMap, OPS, UNSUPPORTED_FEATURES, NormalizedUnicodes, IDENTITY_MATRIX, - reverseIfRtl, createPromiseCapability, ToUnicodeMap, getFontType */ + reverseIfRtl, createPromiseCapability, ToUnicodeMap, getFontType, + isPDFFunction, PDFFunction */ 'use strict'; @@ -274,6 +275,22 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { subtype: smask.get('S').name, backdrop: smask.get('BC') }; + + // The SMask might have a alpha/luminosity value transfer function -- + // we will build a map of integer values in range 0..255 to be fast. + var transferObj = smask.get('TR'); + if (isPDFFunction(transferObj)) { + var transferFn = PDFFunction.parse(this.xref, transferObj); + var transferMap = new Uint8Array(256); + var tmp = new Float32Array(1); + for (var i = 0; i < 255; i++) { + tmp[0] = i / 255; + transferFn(tmp, 0, tmp, 0); + transferMap[i] = (tmp[0] * 255) | 0; + } + smaskOptions.transferMap = transferMap; + } + return this.buildFormXObject(resources, smaskContent, smaskOptions, operatorList, task, stateManager.state.clone()); }, diff --git a/src/display/canvas.js b/src/display/canvas.js index 0ffe01de2..b704f8f06 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -632,27 +632,29 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } } - function composeSMaskAlpha(maskData, layerData) { + function composeSMaskAlpha(maskData, layerData, transferMap) { var length = maskData.length; var scale = 1 / 255; for (var i = 3; i < length; i += 4) { - var alpha = maskData[i]; + var alpha = transferMap ? transferMap[maskData[i]] : maskData[i]; layerData[i] = (layerData[i] * alpha * scale) | 0; } } - function composeSMaskLuminosity(maskData, layerData) { + function composeSMaskLuminosity(maskData, layerData, transferMap) { 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.11 .... - layerData[i] = (layerData[i] * y) >> 16; + layerData[i] = transferMap ? + (layerData[i] * transferMap[y >> 8]) >> 8 : + (layerData[i] * y) >> 16; } } function genericComposeSMask(maskCtx, layerCtx, width, height, - subtype, backdrop) { + subtype, backdrop, transferMap) { var hasBackdrop = !!backdrop; var r0 = hasBackdrop ? backdrop[0] : 0; var g0 = hasBackdrop ? backdrop[1] : 0; @@ -676,7 +678,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { if (hasBackdrop) { composeSMaskBackdrop(maskData.data, r0, g0, b0); } - composeFn(maskData.data, layerData.data); + composeFn(maskData.data, layerData.data, transferMap); maskCtx.putImageData(layerData, 0, row); } @@ -690,7 +692,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { smask.offsetX, smask.offsetY); var backdrop = smask.backdrop || null; - if (WebGLUtils.isEnabled) { + if (!smask.transferMap && WebGLUtils.isEnabled) { var composed = WebGLUtils.composeSMask(layerCtx.canvas, mask, {subtype: smask.subtype, backdrop: backdrop}); ctx.setTransform(1, 0, 0, 1, 0, 0); @@ -698,7 +700,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { return; } genericComposeSMask(maskCtx, layerCtx, mask.width, mask.height, - smask.subtype, backdrop); + smask.subtype, backdrop, smask.transferMap); ctx.drawImage(mask, 0, 0); } @@ -1749,7 +1751,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { scaleX: scaleX, scaleY: scaleY, subtype: group.smask.subtype, - backdrop: group.smask.backdrop + backdrop: group.smask.backdrop, + transferMap: group.smask.transferMap || null }); } else { // Setup the current ctx so when the group is popped we draw it at the diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 38a33eb86..d6062dc85 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -172,6 +172,7 @@ !issue5334.pdf !bug1186827.pdf !issue215.pdf +!issue5044.pdf !issue1512r.pdf !issue2128r.pdf !issue5540.pdf diff --git a/test/pdfs/issue5044.pdf b/test/pdfs/issue5044.pdf new file mode 100644 index 000000000..ed45dbc91 Binary files /dev/null and b/test/pdfs/issue5044.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 7e907db39..7d923c30e 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -430,6 +430,13 @@ "link": false, "type": "eq" }, + { "id": "issue5044", + "file": "pdfs/issue5044.pdf", + "md5": "44788cd31dcb4a2495ded34a84c4a765", + "rounds": 1, + "link": false, + "type": "eq" + }, { "id": "bug1186827", "file": "pdfs/bug1186827.pdf", "md5": "6c5526ae1a9d66cb517153001afc196e",