diff --git a/src/core/annotation.js b/src/core/annotation.js index 5fe3d865476209..0ecfec4cf41541 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -200,7 +200,10 @@ function getQuadPoints(dict, rect) { // The quadpoints should be ignored if any coordinate in the array // lies outside the region specified by the rectangle. - if (x < rect[0] || x > rect[2] || y < rect[1] || y > rect[3]) { + if ( + rect !== null && + (x < rect[0] || x > rect[2] || y < rect[1] || y > rect[3]) + ) { return null; } quadPointsLists[i].push({ x, y }); @@ -1854,11 +1857,70 @@ class HighlightAnnotation extends MarkupAnnotation { this.data.annotationType = AnnotationType.HIGHLIGHT; - const quadPoints = getQuadPoints(parameters.dict, this.rectangle); + const quadPoints = getQuadPoints(parameters.dict, null); if (quadPoints) { this.data.quadPoints = quadPoints; + if (!this.appearance) { + // Default color is yellow + const color = parameters.dict.getArray("C") || [1, 1, 0]; + this._setDefaultAppearance(parameters.xref, color); + } } } + + _setDefaultAppearance(xref, color) { + let minX = Number.MAX_VALUE; + let minY = Number.MAX_VALUE; + let maxX = Number.MIN_VALUE; + let maxY = Number.MIN_VALUE; + + const buffer = [`q ${color[0]} ${color[1]} ${color[2]} rg`]; + for (const points of this.data.quadPoints) { + [minX, maxX, minY, maxY] = points.reduce( + ([mX, MX, mY, MY], point) => { + return [ + Math.min(mX, point.x), + Math.max(MX, point.x), + Math.min(mY, point.y), + Math.max(MY, point.y), + ]; + }, + [minX, maxX, minY, maxY] + ); + buffer.push(`${points[0].x} ${points[0].y} m`); + buffer.push(`${points[1].x} ${points[1].y} l`); + buffer.push(`${points[3].x} ${points[3].y} l`); + buffer.push(`${points[2].x} ${points[2].y} l`); + buffer.push("f"); + } + buffer.push("Q"); + + const formDict = new Dict(xref); + const appearanceStreamDict = new Dict(xref); + appearanceStreamDict.set("Subtype", Name.get("Form")); + + const appearanceStream = new StringStream(buffer.join(" ")); + appearanceStream.dict = appearanceStreamDict; + formDict.set("Fm0", appearanceStream); + + const gsDict = new Dict(xref); + gsDict.set("BM", Name.get("Multiply")); + + const stateDict = new Dict(xref); + stateDict.set("GS0", gsDict); + + const resources = new Dict(xref); + resources.set("ExtGState", stateDict); + resources.set("XObject", formDict); + + const appearanceDict = new Dict(xref); + appearanceDict.set("Resources", resources); + const bbox = (this.data.rect = [minX, minY, maxX, maxY]); + appearanceDict.set("BBox", bbox); + + this.appearance = new StringStream("/GS0 gs /Fm0 Do"); + this.appearance.dict = appearanceDict; + } } class UnderlineAnnotation extends MarkupAnnotation { diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 3da0e6caba35d9..135c9996b2aaf9 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -40,6 +40,7 @@ !issue7403.pdf !issue7406.pdf !issue7426.pdf +!bug1538111.pdf !issue7439.pdf !issue7446.pdf !issue7492.pdf diff --git a/test/pdfs/bug1538111.pdf b/test/pdfs/bug1538111.pdf new file mode 100644 index 00000000000000..671a8b8ad4f583 Binary files /dev/null and b/test/pdfs/bug1538111.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 27337835903a1d..62311fc41ec45c 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -990,6 +990,12 @@ "lastPage": 1, "type": "eq" }, + { "id": "bug1538111", + "file": "pdfs/bug1538111.pdf", + "md5": "e2cd397bf67eddb1f5f642f2eaba661d", + "rounds": 1, + "type": "eq" + }, { "id": "issue5509", "file": "pdfs/issue5509.pdf", "md5": "1975ef8db7355b1d691bc79d0749574b",