diff --git a/src/core/annotation.js b/src/core/annotation.js index 3d4cd539d..690ecace3 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -3511,8 +3511,8 @@ class FreeTextAnnotation extends MarkupAnnotation { const { xref } = params; this.data.annotationType = AnnotationType.FREETEXT; this.setDefaultAppearance(params); - if (!this.appearance && this._isOffscreenCanvasSupported) { + const strokeAlpha = params.dict.get("CA"); const fakeUnicodeFont = new FakeUnicodeFont(xref, "sans-serif"); const fontData = this.data.defaultAppearanceData; this.appearance = fakeUnicodeFont.createAppearance( @@ -3520,7 +3520,8 @@ class FreeTextAnnotation extends MarkupAnnotation { this.rectangle, this.rotation, fontData.fontSize || 10, - fontData.fontColor + fontData.fontColor, + strokeAlpha ); this._streams.push(this.appearance, FakeUnicodeFont.toUnicodeStream); } else if (!this._isOffscreenCanvasSupported) { diff --git a/src/core/default_appearance.js b/src/core/default_appearance.js index 43858e9f5..e886d3184 100644 --- a/src/core/default_appearance.js +++ b/src/core/default_appearance.js @@ -264,7 +264,7 @@ endcmap CMapName currentdict /CMap defineresource pop end end`; return this.resources; } - createAppearance(text, rect, rotation, fontSize, bgColor) { + createAppearance(text, rect, rotation, fontSize, bgColor, strokeAlpha) { const ctx = this._createContext(); const lines = []; let maxWidth = -Infinity; @@ -321,6 +321,23 @@ endcmap CMapName currentdict /CMap defineresource pop end end`; `/${this.fontName.name} ${numberToString(newFontSize)} Tf`, ]; + const { resources } = this; + strokeAlpha = + typeof strokeAlpha === "number" && strokeAlpha >= 0 && strokeAlpha <= 1 + ? strokeAlpha + : 1; + + if (strokeAlpha !== 1) { + buffer.push("/R0 gs"); + const extGState = new Dict(this.xref); + const r0 = new Dict(this.xref); + r0.set("ca", strokeAlpha); + r0.set("CA", strokeAlpha); + r0.set("Type", Name.get("ExtGState")); + extGState.set("R0", r0); + resources.set("ExtGState", extGState); + } + const vShift = numberToString(lineHeight); for (const line of lines) { buffer.push(`0 -${vShift} Td <${stringToUTF16HexString(line)}> Tj`); @@ -333,7 +350,7 @@ endcmap CMapName currentdict /CMap defineresource pop end end`; appearanceStreamDict.set("Type", Name.get("XObject")); appearanceStreamDict.set("BBox", [0, 0, w, h]); appearanceStreamDict.set("Length", appearance.length); - appearanceStreamDict.set("Resources", this.resources); + appearanceStreamDict.set("Resources", resources); if (rotation) { const matrix = getRotationMatrix(rotation, w, h); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 1a8ec3ce6..73ddec55f 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -572,3 +572,4 @@ !bug1811694.pdf !bug1811510.pdf !bug1815476.pdf +!issue16021.pdf diff --git a/test/pdfs/issue16021.pdf b/test/pdfs/issue16021.pdf new file mode 100755 index 000000000..3dab9349f Binary files /dev/null and b/test/pdfs/issue16021.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 2021bbef2..75e67684c 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -7349,5 +7349,12 @@ "value": "bar" } } + }, + { + "id": "issue16021", + "file": "pdfs/issue16021.pdf", + "md5": "78a12254cac90ba5219a4c5555ea35ed", + "rounds": 1, + "type": "eq" } ]