From a67198895f210ed694e2ca3b8f2d4a0f5864d32c Mon Sep 17 00:00:00 2001
From: Yury Delendik <ydelendik@mozilla.com>
Date: Tue, 23 May 2017 10:57:26 -0500
Subject: [PATCH] Resets canvas 2d context to the default state.

---
 src/display/canvas.js        | 26 +++++++++++++++++++++-----
 test/pdfs/issue8047.pdf.link |  1 +
 test/test_manifest.json      |  8 ++++++++
 3 files changed, 30 insertions(+), 5 deletions(-)
 create mode 100644 test/pdfs/issue8047.pdf.link

diff --git a/src/display/canvas.js b/src/display/canvas.js
index 6093e6822..2490d18ef 100644
--- a/src/display/canvas.js
+++ b/src/display/canvas.js
@@ -354,7 +354,7 @@ function compileType3Glyph(imgData) {
 }
 
 var CanvasExtraState = (function CanvasExtraStateClosure() {
-  function CanvasExtraState(old) {
+  function CanvasExtraState() {
     // Are soft masks and alpha values shapes or opacities?
     this.alphaIsShape = false;
     this.fontSize = 0;
@@ -385,8 +385,6 @@ var CanvasExtraState = (function CanvasExtraStateClosure() {
     this.lineWidth = 1;
     this.activeSMask = null;
     this.resumeSMaskCtx = null; // nonclonable field (see the save method below)
-
-    this.old = old;
   }
 
   CanvasExtraState.prototype = {
@@ -609,6 +607,23 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
     }
   }
 
+  function resetCtxToDefault(ctx) {
+    ctx.strokeStyle = '#000000';
+    ctx.fillStyle = '#000000';
+    ctx.fillRule = 'nonzero';
+    ctx.globalAlpha = 1;
+    ctx.lineWidth = 1;
+    ctx.lineCap = 'butt';
+    ctx.lineJoin = 'miter';
+    ctx.miterLimit = 10;
+    ctx.globalCompositeOperation = 'source-over';
+    ctx.font = '10px sans-serif';
+    if (ctx.setLineDash !== undefined) {
+      ctx.setLineDash([]);
+      ctx.lineDashOffset = 0;
+    }
+  }
+
   function composeSMaskBackdrop(bytes, r0, g0, b0) {
     var length = bytes.length;
     for (var i = 3; i < length; i += 4) {
@@ -734,6 +749,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
       }
 
       this.ctx.save();
+      resetCtxToDefault(this.ctx);
       if (transform) {
         this.ctx.transform.apply(this.ctx, transform);
       }
@@ -1863,8 +1879,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
 
     beginAnnotations: function CanvasGraphics_beginAnnotations() {
       this.save();
-      this.current = new CanvasExtraState();
-
       if (this.baseTransform) {
         this.ctx.setTransform.apply(this.ctx, this.baseTransform);
       }
@@ -1877,6 +1891,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
     beginAnnotation: function CanvasGraphics_beginAnnotation(rect, transform,
                                                              matrix) {
       this.save();
+      resetCtxToDefault(this.ctx);
+      this.current = new CanvasExtraState();
 
       if (isArray(rect) && rect.length === 4) {
         var width = rect[2] - rect[0];
diff --git a/test/pdfs/issue8047.pdf.link b/test/pdfs/issue8047.pdf.link
new file mode 100644
index 000000000..57a220446
--- /dev/null
+++ b/test/pdfs/issue8047.pdf.link
@@ -0,0 +1 @@
+https://github.com/mozilla/pdf.js/files/762326/212241.6.pdf
diff --git a/test/test_manifest.json b/test/test_manifest.json
index 4de3ad4d4..f2d6428f9 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -2467,6 +2467,14 @@
       "rounds": 1,
       "type": "load"
     },
+    {  "id": "issue8047",
+       "file": "pdfs/issue8047.pdf",
+       "md5": "83f1b9f7e95caa8e2625390afd7c7276",
+       "rounds": 1,
+       "lastPage": 1,
+       "link": true,
+       "type": "eq"
+    },
     {  "id": "issue818",
       "file": "pdfs/issue818.pdf",
       "md5": "dd2f8a5bd65164ad74da2b45a6ca90cc",