From a25895bf72bd52b09e455c58e65c391c5067b555 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Tue, 7 Feb 2023 21:16:14 +0100 Subject: [PATCH] [Annotation] Take into account the stroke alpha for a FreeText without appearance --- src/core/annotation.js | 5 +++-- src/core/default_appearance.js | 21 +++++++++++++++++++-- test/pdfs/.gitignore | 1 + test/pdfs/issue16021.pdf | Bin 0 -> 5865 bytes test/test_manifest.json | 7 +++++++ 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100755 test/pdfs/issue16021.pdf 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 0000000000000000000000000000000000000000..3dab9349f3dfbe3c3075f14cb36a3c9da073662e GIT binary patch literal 5865 zcmeHLZEPGz8MYlKO}4g_(o$NaO2efNHu2re?APsG&zGFNI|Nil2R&ECqE&mP+CDvlFDfSA*%BEhyDpdfgnm#-r4(F z+ZTi-$}g|%x!sw0zn=GyE|nXx=h4Cx6m3 z5XGZNj8FxSAu8Y@6qZGN2xe6z%2dJ!(G(H|3TyOeJl<_u22+7rUSLCP+DMtYZJ1fj zDVD)v(k{#wtuhjD)-jE|?%EEbd_0cR`GRXYI9Nl}scEk$IjZ<1sN69#kZ%q|<4E42pw^L|BxSAw?8KVJMkW;z#kYWtf#I2wYWPwxkBpl$cyfv&SOW;ku48J& zZf@@FT+Y}%otqxd<);6l<^FN=iBpfPeiZ$v?Jm-Bv6};=YFlfVm0itoD~>tS&5>@d zr)Ov^-Obf;1n8tDbgeK!;c(q=F$~F)DV{)ryvCvF>FLh1zwJWVpDyh>a-Z^4)l3y=~v@Zt=^1eW|1KzP5{RZtra2p%;CvLNcbS8JerHr~$FDdA9&HQ%17) znAK+CKH}YbASGdI!Jcha2o;*)BptgnXji642;hf*nes4(BQPGt8K?&BwyRJ+rsdWw zjhkhA-qB5{Cn%h8+l7)rq?#q>kT>D9C9vxkJoE?j!%jQYgVt2fj~FI>8I_J*2S{>(S#lKS$)DdV1> z>#2tydT6O_TiaVd`S@y!Jh7D24|1)NX(WOt=5wxBu$j?n zDD@mRgNg00lr;Ug>7txDo3{o6*MIPG0OgH=z@(HRnNrf6%O5=Hm=h-tsrt#|dc+9q zk8`m~v{Eb;p(0SFSg^{`%0NJa_kbCNdp3;&$lKx`9|$Da0y>h(qNMGZNDh&p4rdn9 z9ip-*i%LJ@2~RPhnDRj?MI}DUN9yMw5NAgs<`^^4@l?8I4xR=AbFN#8V!XJx7+MrU zwlj+%<_IP{=J_D(2$oM+u2u=88fTB$uEkX> zH4IthkQZY}w~M%+?{q18TiQ#oSn*ez_lJMSx zS9A*-LXu77%n35hA`JCrQCgYdgpm*4UFNLL>b-iKA6H$>M zX}Tf@#hIKQ)D#j4=ESg+lSEzABDAj8C+pJ-kwgI(V_r9%{}!$_GBsT>%+8PRJXH^? zHw&i~UKF_Trtp^7$@)OAW{@ACnJpum0(T3pEx0y?z@|2DRo50=n?hhyo42a#e+C!V z>@}bP9tbQ#C()vp@wJJ!?bI5Lni#246RgYG*r#1kN!Hh$-Mli|_oOWD;C8(B&R5iX zpL^$y2hTl!?{9wH4h`_{q&r_~;f#;HxUDl%vuh;($s1nGR^17WWcpvf^hSBOfA|-r z^T1v3GT}*>7ojVM7vQ!?WJ zmy+2)!-z@?@&yQ}b>s`f>b!pc?iW9j`t0_Ri|_6-C?T)x zJokkIUwpb9=$I=v?s%XDEIvAhQn^9M)Oiao7DKp3T%ajN8v$#N5F#Uvpt00k!oumj4SwOz!tyzR8^H#zt=j#(b1I%LG00X<`45||e2&Wy>RLu&Q z^*Sf$idZv-dQ(x>MS4|C2<0PvELz=#C=@9qB1uw00)he$MUWJhLJDA(N}yiPdB(x1 zGhliaq>>O5Ym!kf#8t4-r0o<8m`@`Sg0>yQbgCc|P|*Z1nE-kJ<%>%3MU{rG&Wj8X zX&}TV>);)Mw+M3_4*~;KwIoR)3DIy!0*f`CFe0tZCius4!4kvL0Zbv-9FKb!s+K7C zIgZs#Lm2`pWD;52pvo~CmLN9r6sbk{RdpC{MFGPt~|RV(A9@}+xHC3o_g`}^;>U!|C