diff --git a/src/canvas.js b/src/canvas.js index d40368a9e..474cc250f 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -33,6 +33,9 @@ var CanvasExtraState = (function canvasExtraState() { // Default fore and background colors this.fillColor = '#000000'; this.strokeColor = '#000000'; + // Note: fill alpha applies to all non-stroking operations + this.fillAlpha = 1; + this.strokeAlpha = 1; this.old = old; } @@ -211,6 +214,13 @@ var CanvasGraphics = (function canvasGraphics() { case 'Font': this.setFont(state[1], state[2]); break; + case 'CA': + this.current.strokeAlpha = state[1]; + break; + case 'ca': + this.current.fillAlpha = state[1]; + this.ctx.globalAlpha = state[1]; + break; } } }, @@ -259,9 +269,13 @@ var CanvasGraphics = (function canvasGraphics() { rectangle: function canvasGraphicsRectangle(x, y, width, height) { this.ctx.rect(x, y, width, height); }, - stroke: function canvasGraphicsStroke() { + stroke: function canvasGraphicsStroke(consumePath) { + consumePath = typeof consumePath !== 'undefined' ? consumePath : true; var ctx = this.ctx; var strokeColor = this.current.strokeColor; + // For stroke we want to temporarily change the global alpha to the + // stroking alpha. + ctx.globalAlpha = this.current.strokeAlpha; if (strokeColor && strokeColor.hasOwnProperty('type') && strokeColor.type === 'Pattern') { // for patterns, we transform to pattern space, calculate @@ -273,14 +287,17 @@ var CanvasGraphics = (function canvasGraphics() { } else { ctx.stroke(); } - - this.consumePath(); + if (consumePath) + this.consumePath(); + // Restore the global alpha to the fill alpha + ctx.globalAlpha = this.current.fillAlpha; }, closeStroke: function canvasGraphicsCloseStroke() { this.closePath(); this.stroke(); }, - fill: function canvasGraphicsFill() { + fill: function canvasGraphicsFill(consumePath) { + consumePath = typeof consumePath !== 'undefined' ? consumePath : true; var ctx = this.ctx; var fillColor = this.current.fillColor; @@ -293,8 +310,8 @@ var CanvasGraphics = (function canvasGraphics() { } else { ctx.fill(); } - - this.consumePath(); + if (consumePath) + this.consumePath(); }, eoFill: function canvasGraphicsEoFill() { var savedFillRule = this.setEOFillRule(); @@ -302,29 +319,8 @@ var CanvasGraphics = (function canvasGraphics() { this.restoreFillRule(savedFillRule); }, fillStroke: function canvasGraphicsFillStroke() { - var ctx = this.ctx; - - var fillColor = this.current.fillColor; - if (fillColor && fillColor.hasOwnProperty('type') && - fillColor.type === 'Pattern') { - ctx.save(); - ctx.fillStyle = fillColor.getPattern(ctx); - ctx.fill(); - ctx.restore(); - } else { - ctx.fill(); - } - - var strokeColor = this.current.strokeColor; - if (strokeColor && strokeColor.hasOwnProperty('type') && - strokeColor.type === 'Pattern') { - ctx.save(); - ctx.strokeStyle = strokeColor.getPattern(ctx); - ctx.stroke(); - ctx.restore(); - } else { - ctx.stroke(); - } + this.fill(false); + this.stroke(false); this.consumePath(); }, diff --git a/src/evaluator.js b/src/evaluator.js index 48e12c83d..b7a5ef583 100644 --- a/src/evaluator.js +++ b/src/evaluator.js @@ -405,6 +405,8 @@ var PartialEvaluator = (function partialEvaluator() { case 'D': case 'RI': case 'FL': + case 'CA': + case 'ca': gsStateObj.push([key, value]); break; case 'Font': @@ -428,8 +430,6 @@ var PartialEvaluator = (function partialEvaluator() { case 'SA': case 'BM': case 'SMask': - case 'CA': - case 'ca': case 'AIS': case 'TK': TODO('graphic state operator ' + key); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 49267e36f..443cb155a 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -13,3 +13,5 @@ !simpletype3font.pdf !sizes.pdf !close-path-bug.pdf +!alphatrans.pdf + diff --git a/test/pdfs/alphatrans.pdf b/test/pdfs/alphatrans.pdf new file mode 100644 index 000000000..6274ce3ac Binary files /dev/null and b/test/pdfs/alphatrans.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 4837dd2b7..25f609e8d 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -222,5 +222,11 @@ "file": "pdfs/close-path-bug.pdf", "rounds": 1, "type": "eq" + }, + { "id": "alphatrans", + "file": "pdfs/alphatrans.pdf", + "link": false, + "rounds": 1, + "type": "eq" } ]