From a6447f2ca2e50d148caed3fec6bcc171e3843244 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Thu, 27 May 2021 10:06:13 +0200 Subject: [PATCH] Support strokeAlpha/fillAlpha when creating a fallback appearance stream (issue 6810) This fixes the colours, by respecting the strokeAlpha/fillAlpha-values, for a couple of Annotations in the PDF document from issue 13447.[1] --- [1] Some of the annotations still won't render at all, when compared with Adobe Reader, but that could/should probably be handled separately. --- src/core/annotation.js | 52 +++++++++++++++++++++++++++++++++++++-- test/pdfs/.gitignore | 1 + test/pdfs/issue13447.pdf | Bin 0 -> 24084 bytes test/test_manifest.json | 13 ++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 test/pdfs/issue13447.pdf diff --git a/src/core/annotation.js b/src/core/annotation.js index 9ade49e82..67530d32b 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -1070,6 +1070,8 @@ class MarkupAnnotation extends Annotation { strokeColor, fillColor, blendMode, + strokeAlpha, + fillAlpha, pointsCallback, }) { let minX = Number.MAX_VALUE; @@ -1124,6 +1126,12 @@ class MarkupAnnotation extends Annotation { if (blendMode) { gsDict.set("BM", Name.get(blendMode)); } + if (typeof strokeAlpha === "number") { + gsDict.set("CA", strokeAlpha); + } + if (typeof fillAlpha === "number") { + gsDict.set("ca", fillAlpha); + } const stateDict = new Dict(xref); stateDict.set("GS0", gsDict); @@ -2400,6 +2408,19 @@ class LineAnnotation extends MarkupAnnotation { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; + const strokeAlpha = parameters.dict.get("CA"); + + // The default fill color is transparent. Setting the fill colour is + // necessary if/when we want to add support for non-default line endings. + let fillColor = null, + interiorColor = parameters.dict.getArray("IC"); + if (interiorColor) { + interiorColor = getRgbColor(interiorColor); + fillColor = interiorColor + ? Array.from(interiorColor).map(c => c / 255) + : null; + } + const fillAlpha = fillColor ? strokeAlpha : null; const borderWidth = this.borderStyle.width; @@ -2418,6 +2439,9 @@ class LineAnnotation extends MarkupAnnotation { xref: parameters.xref, extra: `${borderWidth} w`, strokeColor, + fillColor, + strokeAlpha, + fillAlpha, pointsCallback: (buffer, points) => { buffer.push( `${lineCoordinates[0]} ${lineCoordinates[1]} m`, @@ -2447,22 +2471,26 @@ class SquareAnnotation extends MarkupAnnotation { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; + const strokeAlpha = parameters.dict.get("CA"); // The default fill color is transparent. - let fillColor = null; - let interiorColor = parameters.dict.getArray("IC"); + let fillColor = null, + interiorColor = parameters.dict.getArray("IC"); if (interiorColor) { interiorColor = getRgbColor(interiorColor); fillColor = interiorColor ? Array.from(interiorColor).map(c => c / 255) : null; } + const fillAlpha = fillColor ? strokeAlpha : null; this._setDefaultAppearance({ xref: parameters.xref, extra: `${this.borderStyle.width} w`, strokeColor, fillColor, + strokeAlpha, + fillAlpha, pointsCallback: (buffer, points) => { const x = points[2].x + this.borderStyle.width / 2; const y = points[2].y + this.borderStyle.width / 2; @@ -2492,6 +2520,7 @@ class CircleAnnotation extends MarkupAnnotation { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; + const strokeAlpha = parameters.dict.get("CA"); // The default fill color is transparent. let fillColor = null; @@ -2502,6 +2531,7 @@ class CircleAnnotation extends MarkupAnnotation { ? Array.from(interiorColor).map(c => c / 255) : null; } + const fillAlpha = fillColor ? strokeAlpha : null; // Circles are approximated by Bézier curves with four segments since // there is no circle primitive in the PDF specification. For the control @@ -2513,6 +2543,8 @@ class CircleAnnotation extends MarkupAnnotation { extra: `${this.borderStyle.width} w`, strokeColor, fillColor, + strokeAlpha, + fillAlpha, pointsCallback: (buffer, points) => { const x0 = points[0].x + this.borderStyle.width / 2; const y0 = points[0].y - this.borderStyle.width / 2; @@ -2569,6 +2601,7 @@ class PolylineAnnotation extends MarkupAnnotation { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; + const strokeAlpha = parameters.dict.get("CA"); const borderWidth = this.borderStyle.width || 1; @@ -2576,6 +2609,7 @@ class PolylineAnnotation extends MarkupAnnotation { xref: parameters.xref, extra: `${borderWidth} w`, strokeColor, + strokeAlpha, pointsCallback: (buffer, points) => { const vertices = this.data.vertices; for (let i = 0, ii = vertices.length; i < ii; i++) { @@ -2639,6 +2673,7 @@ class InkAnnotation extends MarkupAnnotation { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; + const strokeAlpha = parameters.dict.get("CA"); const borderWidth = this.borderStyle.width || 1; @@ -2646,6 +2681,7 @@ class InkAnnotation extends MarkupAnnotation { xref: parameters.xref, extra: `${borderWidth} w`, strokeColor, + strokeAlpha, pointsCallback: (buffer, points) => { // According to the specification, see "12.5.6.13 Ink Annotations": // When drawn, the points shall be connected by straight lines or @@ -2681,10 +2717,13 @@ class HighlightAnnotation extends MarkupAnnotation { const fillColor = this.color ? Array.from(this.color).map(c => c / 255) : [1, 1, 0]; + const fillAlpha = parameters.dict.get("CA"); + this._setDefaultAppearance({ xref: parameters.xref, fillColor, blendMode: "Multiply", + fillAlpha, pointsCallback: (buffer, points) => { buffer.push( `${points[0].x} ${points[0].y} m`, @@ -2718,10 +2757,13 @@ class UnderlineAnnotation extends MarkupAnnotation { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; + const strokeAlpha = parameters.dict.get("CA"); + this._setDefaultAppearance({ xref: parameters.xref, extra: "[] 0 d 1 w", strokeColor, + strokeAlpha, pointsCallback: (buffer, points) => { buffer.push( `${points[2].x} ${points[2].y} m`, @@ -2754,10 +2796,13 @@ class SquigglyAnnotation extends MarkupAnnotation { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; + const strokeAlpha = parameters.dict.get("CA"); + this._setDefaultAppearance({ xref: parameters.xref, extra: "[] 0 d 1 w", strokeColor, + strokeAlpha, pointsCallback: (buffer, points) => { const dy = (points[0].y - points[2].y) / 6; let shift = dy; @@ -2797,10 +2842,13 @@ class StrikeOutAnnotation extends MarkupAnnotation { const strokeColor = this.color ? Array.from(this.color).map(c => c / 255) : [0, 0, 0]; + const strokeAlpha = parameters.dict.get("CA"); + this._setDefaultAppearance({ xref: parameters.xref, extra: "[] 0 d 1 w", strokeColor, + strokeAlpha, pointsCallback: (buffer, points) => { buffer.push( `${(points[0].x + points[2].x) / 2} ` + diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 1abd53fd2..2e056d1f5 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -124,6 +124,7 @@ !bug1068432.pdf !issue12295.pdf !bug1146106.pdf +!issue13447.pdf !bug1245391_reduced.pdf !bug1252420.pdf !bug1513120_reduced.pdf diff --git a/test/pdfs/issue13447.pdf b/test/pdfs/issue13447.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1b2559842de12ef572da29ec90f6894c65f56e03 GIT binary patch literal 24084 zcmdsf2|SeF*Em{eA{AP+n6!~F&+JpEtSLo^q+~FbVn&S6A{A0f^{r@68!eQO(w>wk zmG&Ycl?p9ND%Jno=b0H}_kDlw@AH28D`w7f?z#8ed(S!d+;i@IM%tK~>tcE=(#Z0c zckYuIWC~f}HlIu~Fd*rh3j+M?L;ZPVjHGWDvW zSE8%3k9x|*>H(Y0*Qta(_n4?b;_*EQUdiYyKJs+wDUb}iiBEvLFLdA5gsf#SA;iy@ zyoeVN=p*18YGQg6%?U;ZZUT=`G9dVYhML|&q5n92{ovqWy<8V0oA>Kki zUrnOWxDZcnlY#)_B?H~Pd461d0ChdMLashkuMaey+;Nj^EFHv+PI3vl8p@fjW7d!e4yx*ms4#;BMc6-~YknFa%43zJONG95>yP%#RFO2=q)76a3vut!rUqfwo>OitqS z1t3M1CLlvV&1O@{6g?W7LgT4_ zc1CNj^tnn=a5hu9>+0)ky>U5h<%b<%KYTRiURtq{uDmKDGU7$dn%Vd5Pv4%I{xxUr zz;6S6_nzWCU3`7XH9waD@8xYLcgvcg8?w(Mf8@4B$L>Wl{Kw?1?6Xc~njv%B6!t)M z*F&%G?(L~Gq`O|Qd;gly$5XrSnH6h!sN!_qUZ3t%A~kNV&Ye|VX&$9?5kt$& z|LGdZVj_FVVCk`ub!u;wWOZthRJ)$l=Q2gXw9p|_&OH2#?daRjS6$EQds>h&A!KJg zCHl}PjjLW6*{{~UF?vir^lbN@rFx zwY-yR;bcXb!kK)z5q0SF0Dj6Y50=b4RAJ>A3Bq>d`PV9X1Or z|VsT598G;#dYb%x3E;r`v3FIGn6%l6_eyLZrR#=Fty0tSyf??3LnV%)-zUd3{w zN3H#M#-6i(z=+V5mfeEKeC9@&?=bfpz%5F!VwZ7Rx``5p0tHtS1gP2UTJ~0VrosMt3m~6CIwY5Ys zFbc+^w52pHwo?o+hSK{f49z>#-RPfT&9_f>LLc`9q2%cTVLPi%b2g+kqIHMc%7+i` zg{3`NAAOq?5FiNtyJnNs;bc-VCfY62m>gKq*s#|HW7yHgnL}kY8bB+uGe*Y{A&o^P zQ!yH*|P|YxnEd=CW zt)H!mMe`auEeukOOAAAj5X=8R!ocWI7#JKd2w;8bAQLo*rLxF0uof7Kfwk!zaVWH= zvk!YrAf_|O7>k9+CtEr6&w9;>0joPtu*C}I9f?8PQ_qlE z8=6>v7G5Ak*d?n!Bn!a7gB+2ws6l85i5;{Ko+yWgiw_%LSip(tobIEE@e=U4zT{50 z2~uoJPdSKCEBj_k{(`^DOT;=3(xRXgTD_SRJqiY@iVr{ddJGge?2OhkC^TxL*0(?P z(m~ly1Ym7=e0Lv|J%NF@@(F}&kh6$S28D`?2EjFg*lckhfT1QhCXRqa4+FZ2dJ6d` zh}~eK8fXLrMhQ@K0$`z)jSAZ#DieY{xDQNaa`c#xhyphXHN}F^4^%=!Ya2j7jUX_c zKnHdXl>|G7AU2hNaKDQR=`0N4SY#@M#}OYi7ILv6uS66BBa9%>L4*U}n*xa+;2r-; z@Cp`eZ;*w;{XBqBN)E9HoDvWf{0bBo6GQlZ5>2N1CQe15UK&~M%YZeSr&`|qJTPq9tIvQHvr+qIK=o9 z5Sy4O5f0LS;$mzxN1`$`eBK)&aAc7dw3)kWBKy+zqe<*ivSj>y_M_wcEET3uWItdE zFa{M|NhC<^EEb@yon9A03B&3l1wVTYo_3uNQKZO zs0UqSatYx^5Uw6LD|CpuQ(@gh#qh68#2_kz>gI3|Psme4ng@0X0kFphiw6WWK;tS2 zY7Nr>wcthr0-@mFgTmmp0M~0seB(6`01J-}p!z^Hf+4L=O;QIEb^1F!FpSc% zD^AQaE`kuY0gH*I4tDNLv_tFMqKrxH);hl^OZj6+{!uU&&m__yf&{`rg{g+=gaj5! z=dy8Up&10m6DbNF1n$fd-+5<^L6Pc{v~;u{p`GmGZLaH&NlsIXB-77s6uR#Z@Hw08#=M1&y#35Ef7OM*dw z2m=}o9-;_C01^yZP$d|Ab;a8O5dj+|!iWHZrX37y6OoYNTti_5h-g@P6baYx2mu5J ze5pp>M1Ta-$Qxi9c>{d{qbX`f1c+$b!r(Su%$pd%X%N5=^CkvF7%+(9(V>HzCgA`9 zQZxiW(13Fa=Zpy6=psOZp-E~33<5+LJfQd5H#&z2&bOt4?2_~)+sswEJ;sA08ty0 z@I?t45g@@ZBs~QT0z??-oP;;ny&#|?3~o5Y{Sg6(M!e9_Icy3zVQp>v85q{qS-Tb+ z|2DEegy$wP*X_pjn=~iA1~f^0N<0KRIQ+SQXC3sntpOcJaOrTQ3XD1!G>{+UfkA49 z393zPz6KB_Fxb5!2N5rh!TL@3s~{i*2DexMbcn%)N=!olA{qc_lG+G>z+h-;5@SSw z1k*?Z7zBtguqkFqXb3=pp+ZIr?++dJnFt^-RB*~A9Ebo326R?L0~iE|FyPEK(hxw0 z7}yiTDG`DL*kU6@Cx!a#${rg*thw5D1_%QqN_`=SJxm2T4Voqy4i74fuq8XKdNS(|)e87seawUci!E@LYBcF{133wE6 zM5BVn2!vQV0w5}aQDLVfA;7@pK*I=8L=1*ej3Xd14z{V_7m0BMB*ww64^~exj(|FW zgUu@J!^CtVNJQ5z4&NtA=m|PZ1=dLlF35QaFIbIDGRc!4Xg+PO1-( z3qp_>2T2St$>KT*s1rCE;gE{xM39KCJsfO*AF)t#h5rRIm6s6==~f1Muh*wIjxfKjC^Effv(3S=1(?f#11k{lkx`Lpdpr&XgDE zj;yXO-0Xu%6YzzOJQUFd+l68YLY|)knGV4TgqhCugCm5K0(`i>)9k@#At*T%@M$cC zTwfpeN$BPR8R)EdTn`_<7aT-^VvD>SeLUc@D4h=XU{F28JyTsKm{im(nM%QVMX^;P zjE)K+#sYl&g@OPG$8-HB6I`*VY^cMR>lFx5S>ytT5OqT$8Mv4wDg_4}(Dgt`kDDAd zFyq4&R>YjXqYr-)KhQ_~fCLYKPgFCEkS)HO5aKr*?E`{%h%;&afDNC3K%t2@HvnhF ziYo%(?j+I8#vZ^p5H%We19_-(jiV^drZ~XzA4+aZ`D*P6l8x4$H-CoY3zr~?#1SQs z9HMXkLLQ}Lu*t5XQ3fe!c42%vC4;(z(6uLux)=yar-Tvm=^%_~YfNKsKym&PVZ_)h zIAqtBFg8i0h-I%GVI+=gH(vezcfyE?MpRlD(cpu4HxtIj;gpt1v4@Nf58?Cuzxfy0 zEL5M^mj0W%>5waHTAr}BB6|loR6Aso;agMt*JL-;D0>*pSsSt^vW$fNv-k1i1y1J$ z+Y0=+d>cC{@nds9^V_h5bP&WwOGs&I2^mZ_vV>stDRd^8$w4W|jw~UR0)AVwgcz9X zwuG-qY@-vxCt8Lj(cXV4e6XQwYRe%$3iHuK_*#yql>E`r6iaSbL0T3D&UhL+#~$Fv z^%akj=#%9rbRUMbFh{`F7 z&xwx_{9ZbixpzbV*L!0GC4%1{R|~=xe|!0DXTyf&#Y?~aIv10umv;P_(9Gx0PQ9}R z3lx^hr26G2^A#0RdJH}AJNVM2`m&_p{_`s4bi4Ji->bwyQ|^xm{xf0QpTOD^7xtVh ze0R1WYLT7esUgcX&)iPGa@+CoT!+!Fr6sX8N^>9e-+7cz9WN6ew8v}rdzRqMLnmUi_ChO{lUm(X>F35JM(hY&D?V_`%}_Ns-nN2C|Y{{Lj8xEmyCwg z-Os#O+)%%?*d;#x#QnPEM!#Q`uinsKqdZ0X(&rRQKg+q_oC@=FpGJ)Tc*>|o{(H@s z5yNO+J~j!*8*I-R-R!Y+VrtbbzJZOqOzz>}wc+nhxmspvE1H~~eDAcA3v*|t=7{gl z?-bPqT&mW;wC&R4>Yy3pz0)t$={&HG3S+Mx^S@d2@{rEi zi|K|#tA%y1Yr1J%{*`)v$nggQPJgVp^TjlGh~eWCOJ*w+?0LI9ESLWM>pge5lRMJ# zqNZy;@>H^Z$4Pq8W7_3qgH5)}@w?a*{y6039FdzEy!Ly>08}yn0W&p`+Lx#M{(IT-=js!xgTo3=)O?@GI)&W{^Z(=R6qgdSQznsa z=AIOPCQZ}jp9QNDhOZ)*(oMLlX~hR~N|iqr4V2|Hs0Y1Q{Z@G?phh-7#p#fl0_}8J z+_X}!pzZd4U33=Qb?7HF)#*7gBW=g=ujEYgkaa&srzAJ%l+K?NrgiJwJ)bq}H@WNX za6C*JXI5~;GmiF9snXrWU1x#qld6;qzUPNCi5K78%=BKEJV?Fxz3c1SThA2a@2DQC z?K`uK!Ni{EYOlNVw46=D4u=%VI5XRJ3qYOp_NL%OSxTBmb}|-T;Ba|)v5hK z5xIx|%=WpUrGwgJSCNgWVQu&+ctsS2Lim z!Uaawd`T%pCnmimFcQks~3jn zzSA~cER(We>OGlk_Xo>U=r&)R3YVyFEbO}`(9C6JX0C44tF&n$G6tp2Nn`A{tqHu~ zbuimwMUZUlkxPc92D3{a%o7ZqFt29A<4X;GJ;RQkFdRZYHNkJ|s|(Ne21j7Ymz;}z z0)or7KkSwnuvh z%Dtz37tye3H7?1D+4a6Ukwfq4sMl{+|F}?RNJjFkoZDR1hjr?o6=Lf9>Uk^ocl|N0 zztQY|`m4L-h4$4eOpjD|%CudvYE!=zdsjqn+O)xTwNrR((#Bh|RqH?NL=U};y(^d$ z7wY7YVjU;D;P6lCpoZIb%m&$e)UBN<%Z^&+cy#vz z&;HM%re$2U8cYng#KH%hzFHg4_@7SYN@gZUQqkOwj*xBJL9)AxWIgc|w zv)783x@%b>ReANll{F8VzCCSwXnI%O2!4Ubh+^&28MdouoO4`xYLBbw>2tyCi{^Uo zYM1pb_+fK!{veaSeN9R}oL=P?ytYf9Q@MJx)6X3w4WYkO5sZCd{JUmC_=)-HuPi^t zPOo(8k@!Mu8R?14#GsUIh^gR|^1@{0d46NmR$6g2(!Y9+&dOF=9W6J_BmAGhxBa3N zTzPWck#`_aQw^=x0y`Y|OgpTlfyj7M!+m@u8R zthPLU_=sogG3z^(+V&yWjnuvzR4~yFGylRh7uG}vle7jU9KE%6O7C&me>4uO#-=)W zaz{C^4X&O%U_0P(go(!redQreGqtzHeDo;zS$=rq$htDl?#CoW;i?&jt7XdSD2kkU zu8zrvm#!GG#AQ}P{E01^e|$IX+N~n|!I<`2&RurLi1G5(zAubkr5^kkm8N+%z4~ah zWk~j3g#@wy*^FV>h<*vhgJHxxWD_gV(u(A@|K9z zj_bFcRZMt)|6~fSfANEf{jK->+`qi&`SQ%i*{VawQ#WtB`*HDpihAB0rv6CfG53Fl z-dUmeN2}De-j`lGlRTC2!+KbdjJHdua}T#kA&PgGuf5TQTeYJ4jm0dTtS>1%`PezP zU6)nOOeC=uKOO7zXvYy7`do*Z^Y8Sds-@;TxW7@=)DQPNzHnd}cDX=1dv3%@`OLi< z+)+hkiDNOsnsZpnRiDVAX`tn6~Kya(RxQgmlS zs>6}u3a8Ss{rv_{=ka>ZpeJwG-am52tq11Uw)3La6wi1TonFuGInz|@iLGkrlrh^b z+V4N+YrfmpoHy9#)SM?I-{s~be@O1LV*VTBcK3M+ddn$QG;EYj*r@tx=e4&u7d`M;dtqX!fDzsOtseYaf z4U?~|U3U0d!Ul`2w@c+W^c^*8)n=xZF{XR9GASg(sVX>y|KR$KY^5g$GxzkV*yTJ- z>-xlJ`LasCgVy(GFyKzwZi5b_0W4v$$w}03~t0kwxD!apC_#A z`;t>9F8@92(4iw&z8zb7HM?j>^xmh1cUR~42^v^rsp0s{PTPF`^t$nZe7(5do4d=T zkH1FWXR|gaiMF|~R?VhGq=nB`@k*V|cH8WFfxWxrpn7Mj>8C*D2WM-xe3*0L{KL3i zs$X4|#+RhL@E&dzT(%?BX!*BlryFBdZZ`P!V#}}KUx~vNQyK3o7X-yQrrb2|ryo$_ z=+fQdL6_id#;;{vAJ2DL2^Prup~4oOu~X!S+AT71s4qxlzq+o`x8M8aJ3ofgw@xQ* zXRlhjV?hyZu(scn@=g3TIX1!8U46>77|%-azaGI?Fi5H{UIi*LJbwFx%LPgKQx~wd zYH37!7O5<7m78X4S+U;Wi(b%Kw^=g={74R3^NAF4ZFM+5X=Adi?}DGFx+Ml6XKxB4 zDy_Q8Qe|KNZ7W|VWFB?9dEWls_3S6VZ@nJ9|8nK(ey=jB+<6N}dnKIZ)-KVulXnb! zz0frC`{}qv8b>bN@ce8&)T3W*?X{=2N&U2vel0n3{^`fQYT9qMt=jj?Ry`}J_cz&$ z(xTo@hFv$z_;czX)|IAAMcNbz5F#?ncI9=lUl%B0fbG-tTpL$1}@8 z!ov5mo|@{17iJBJA6Rqbn%q~na%JAvH3w=__4XP}jfwoeal(k6@)hY3PpjP=J!8w? z#fNC5_21rQRRd+xojt}$8^dMk^#>|paA5KlAD?>jL|4Q2>F1wjt=1k;@ir#bdH98% zw|Dp}#w|p+~TcvPKeA+7Zt*5>}vDMRHpVs)coqyQR-vrjZ}VC zoZVB)NZS8UUR5h*_0hoxwj36&xiQCQxW=Cm!((T3(|l%DdnF=>^fAA;@xDUx+Z(Su zM#pZ8y0zg*(Dko=zrT;n-b(wtb6fl_VZOze588`KJ%(OBe{#(ht3L{8Jnt$u4(rS43wpNs_k*uP*EuLA zI_0ijx@YZ>xay7U2eZTG?H_V*o?WO-K}yC*^V?JIYuZzFv-0Isi=qzc&50f}PAkK* z^!eePrvst_v?2ra_V`}xm(M6qj@0=yCp&+(R`0Fr1(i?xA1bek^IDL9>*1F1kr7I+ z^SsAdpgn;7yMD{I%GNHOz?avybQ(EjXwHWNzvr;F=a1WF_*#XQ@$lwp`jU0-b}`9=z6Iob_wX`HCSSwW=^eXeQLy;vQ)T{|rTI6;Z=alE z6=(4xSH-i>!q-}igmUc>0Ww9C?i&y;f2msZw5bn`%p7ATM){qZ`f~jrO}oz&cb3)2 z&mOBzTd#Hr-s*6ydfS@?7o8Qf6+iXR`$)dE^7gUtlgno5d1=<4+emd${52@qj-~$7 z`OU=veN3JFl6XfG42PWMIIH@Hku2pdCl*BLkgj0wE;#(~?tXB?ox>$lzIpVn>X|KH zcaQVNZqj|zwc+cIUCB+VIbC@qe%_w_YLUanZ*|(yptafWYvKv2uDtpEQeK)Lf3xFW zpZv|G1IyRMO`zx8xiEcZ0RN{VrD!*_3rm}4HaZ4(4 zp8CAqFmFVaLZC(bGp(ii4_42-o#WK2Y`4L{GwdJ-$HMu+Yg`8XjAL)h7*IdQ$aeI) zqw^xC4~)EG7hWQ>HLD=f)z>0Kamfj_=Qr2h{iU&E+2$z~O1BPZ?OJfRBy{sWgF()! zK7(t|pWlAWRlFbLA%cl0T%IFMS=0TYMwe z7roN1{FC)$R=W9X=iL^=#vgq?_08}bTQ;Vv9nFj#tadg*-^p-n_MJl6y6lCQwe^DE z-Rf62xzcpNuwvueqe&YJ4*rRAd*3g{){moKOrPc%Y2hvCvpvv6)-*$7w(=zRuDOT5 zP1zJynSQ)WKdl88@%JmAf8wQ$`?||x{zBL7z6E(3_Lmi<9X=O^t(o1wp{$p}=s@N7(M_JIvNThEx<&A)ZC_CT{MsMcq%HdmT04`|Bs*!(bqho<2i3>lEeiK7P|V+!j3+S2 zcqEyOr(td3JqtJnV(6#g<4=DQpEZ8*hCDUZ`h4ChC|} zb9m}Uk`LTYTLM8+Il%b09ni5!&A5b&aA0zLKkJfW_yAeigr!$XvF zw6&!=9umOwBvIf@5ec&2q91tgGTb#Ldy^CCyAPugY%0m zo>AaTQ?qiA?*y4dKT>UQkjOTB#%8xDM}?OcH7|#;kytjRg&WK*_@gr6RDH8@R3_4z zX0&X$BG>#G9Zo7Ydq#&F#x0()(VO9#*2kbB9c=cD4Ob_dJ!8TFh!)S-E!$;rT8;~w z-E#ama3QQ&eehlYWUrd=f>GhxL5pV?+{bQKj)uWK)Mn4%l6UiY!)VMF{l(w{dh;=b z_tc;xE=_rXHyO3ykHLmh_RY#MXmFIH`7>sV@xz#OxR%qb9Fu~KF8YzkAI7B8TC~eV z$3>c#W5N0N7SCGf0_af-S)+o=NcBS)!1eLv1(0y-ZOQi(z-bl27F(K z2Zu#-XEV5-Tn`?P$>H)i?rt<1&)wa~fX4NtFeyAP#^bQ*Y)>AI!s9TRJa-O<#b9%J tJR`8cwgLg1tHBK;EG9mSc}V-gtOW|W0Ycm!P~oKj@DliuX4dAU{|9r;J=_2Q literal 0 HcmV?d00001 diff --git a/test/test_manifest.json b/test/test_manifest.json index 2bc7d078d..46119fb6d 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -115,6 +115,19 @@ "type": "eq", "about": "Causes cmap to be created with invalid glyph ids." }, + { "id": "issue13447-eq", + "file": "pdfs/issue13447.pdf", + "md5": "a729709950d69ec1cfc516bf559e995d", + "rounds": 1, + "type": "eq" + }, + { "id": "issue13447-annotations", + "file": "pdfs/issue13447.pdf", + "md5": "a729709950d69ec1cfc516bf559e995d", + "rounds": 1, + "type": "eq", + "annotations": true + }, { "id": "bug946506", "file": "pdfs/bug946506.pdf", "md5": "c28911b5c31bdc337c2ce404c5971cfc",