From 6819de2a172a23a79afdbbf9aa537ac9c228d195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 21 Mar 2021 17:54:33 +0100 Subject: [PATCH] gnujpdf - Linear colorspace gradients some test data --- lib/gnujpdf.jar | Bin 194468 -> 196102 bytes .../ffdec_lib/testdata/graphics/graphics.swf | Bin 108525 -> 108623 bytes .../graphics/graphics/DOMDocument.xml | 96 ++++++++++++------ .../graphics/graphics/META-INF/metadata.xml | 12 ++- .../graphics/graphics/bin/SymDepend.cache | Bin 385 -> 385 bytes libsrc/gnujpdf/src/gnu/jpdf/PDFGraphics.java | 2 +- 6 files changed, 76 insertions(+), 34 deletions(-) diff --git a/lib/gnujpdf.jar b/lib/gnujpdf.jar index dd0754ea614738fc807ee34dc705d163cc3eacc7..ebb26fc69da3d6cbd14dcf3dcb1db2accef22f1d 100644 GIT binary patch delta 37185 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¨+Ca@~S%%&ExDpjhlnZqi6;UhPRr5ygQ z=J%}7aqvAWY%awokysrGf2UeJ6Jd^OX@!eJNJj4pPiq<0KAf<$8tR*}RfVCXV6w$? zp;-F*v7&*tKvAfQzAa*Mouz6Z(m5%-9@UC7(VWg%!5{tRANRufiQ;wqvBkk3p=zHB zzShTvN-DUK+MrHqP^WCB+={eJ)u7J0U!A*ET_{3n4eBzsxA~wL4p&_`y=#2DxeW>{ zmZoE252!1#wAf68cdDzvijW0&qqkU1@Ev&Fq zUpt4{jc%Z0LspK>-QaMdXN9{{-N4ZJfPuQH!i(eTF|HxR7wMHn$V))usUEXQfbF?9 zG|1+%3VWxzd1lD&+Nf@AelAXbfX5PFc*nkpl+*!U+5kUW-98{SWNX8>j(avR`xb_5 z$bUupPBk5Jbw@=;JdxQql+J@9gCA2XGDDd>Dl+t_$l{l;_ywaPCqFAcYiWK?e$LV= zT#yvK?sCyOeCI~GhFgBQB73L0cV=m$+ES6ZQ(*(XQ8iR#m4>p7M%7r6!wvPW$PML& za+*3e@1Ty&Q3}aW}|wzB0F9;>XmAf_R4)#uKgK0-L7GgbEwf3t(UHIyKaq zUqb~f2(7drwBeVp_yvN{Hor}N+u8xe`Nj8#)yo4quuB~wF%_LcaH<*T-`6;S5Lr&> z26XNF)tfpe-_Q5&SMLPr4y*51?;{y!T5z2L&P{e|zDpM5Jsh*H^`_ER+~dRr58fyX z3Ld;u7UUhYRmKM~Q8%_##^zk-o$8~RrCI8e{B-ncb|@6;+^9aQC<$Tp*}I}N1c!Fu z6=>>}aF!8wRA?zpD)R+8hy{iFU)Jj0O6vczgZdw;B%#x=1_&fM0qx7AmNeZ!D5mMc zu@kTj>gy)#lFEZDUe1=vz=!i;C=_^K63g!H(mDzCx!-a@7?p)15#^x)W)JJBjAH$I#-iJDKX;sdTz~EUj~=;jeT~r%mn* zx&!I^+}ZS?dmKIP9#1bK{kl7sK5$QfIaMi?J6Cw_e9_vi7H!>yqQqS!`nik62zQAX z?=BTn-DP5yyIjn3Ys7N*BvJ3K78kfDi%sqtvCTb2yy%`PzH(2OVb2ZA0{2|p4ZTj5 zxaY|-cdZ=go-fC`7s^HMMRKXTUY_D!E7!T3W+~M9Vce=O8r`%iROYUv* zO?R{W%x#e0yNyP+dyCQ1eb6X$A2LeZhmF4OE@Qa6+nD4&YD{q-Gp4zZ8?)WLMveP~ zvC4fiY@FdfWvp|bHZF0WF|Kr!l)`@0Ic2UMviRWBTNsqjoS0{1$P_AE8lv(+rz z0=>{nQT6y60js?h>J%>(ceIBy)D>Q)y3xy4_j@^Nua~D@@IvY}ua)}9>!QB!x|uD! z9%i~%Zf1Jj&0?>Y+1=}79_0-%XM2OpT5qtq$~)3L%^PB#;|((}_J*5RdLztRypiTM zZ?w7F8)H82jWu8OjxzUo_g31eUcKGMTWxpo*4T5rQ|vX~srD(}8FttU+vj^{+IM(o z+wXYi*gtyO-)wZDV{kQ7VArP8HY(N@ZaTe%@D|>VO^5O6SSMKFO87n6;CkD6Ruw#D z9cVxPDr*(|Ha+PZs~X0xMMu(Ktp!LqG=rYD7UHW%bLmk8IP&Sg#dN>57*V$TXFTt= zmcRgRL8sF#)>7o9V)ycDYZ>y=aCfO;Ew?Ih+gKUG2WzZaTovc0(#$C$xVw*^o&)Hln*!W4r>)sEo1?W)0TIt#9;yJBnx*lit%EmbuzXYEin~; zwrmYjHvVYNIO`NRW*ku=>NLfsdB8*$OxiEYg1#oZd!w&ttiHtQVZ6`T9S z^;Y;?Bs-WNiw)L!h#=@>-Ar#-Yq7NHY&}T3t#v@A#M(m-Smy)lQeK(F7fAL`)&=ZR z<2>s^T=0h*f2|j+i>!;WK25>_u* zm!cQ(7l70b>oV?7V~V=f;_E&=W170j;_E(rW45}^;_E(Bjn`E>>k6dO)hWgq0pHZ= z#;F0{)D^~j>q@kO;cN`CHXxOwUNefVD5NJ>ePrZVSAnEF^@WjYZ3Ia(^3B=uI*YIF z4e0}=*anHwaSa(U>~S+LFY06+wK{-NmBzay5vGczatb$ZQupq0s1<*dXR}oYyMyLvyE=HI#uA%DtobQ70x_B-N5pGsFiLL@l{m=D@enV)1M&JOV0dxLyjTk^prLe=Ap)r(kd1dkc zv;ke836FPlyt~oiIAhEoxXa>9!Mzj*K?p+{0^THXKF-k?j&Ts|OXk1&7xN(>0~MVC z=ff_TRzHpBJ4U+TiV=>-;`I_jun+{=p!RbFdV@&=On#^VHeWi@#W1=wnAp28!`4pI z#!AL?qnATVoleN==CYCAL$ZugX>4)rm`1Lq=azMWMDHR5!lRLC?&9n z^#QQh4P&rYv4TA0DiP#0Gl_M%Lo8yHJH#SJ-XRt-@|rB-aD~6q^a7I@S0#qrkl$$f z6)i$7*dR{bY2qw>YNMG^k;dfYo2jY!_Ucq-W#&Q@$1`hTqnQnVMp}Y_h$YtdqNE>& z7~~y9OqgwSWFA5d@(!T}d52JgycjiE;yD0jhrz-3qL{f!sOM`jXu>`Ge}eq~0`B4e z3Gy+%XPbHXHe5shr@UwM!~Y-fJ{kZ2|MMT-C^HoI62Py8m0PlxplK16v?dESIx&V0 z_EsHc2^ZF@$JiQ<6&xa*iT+CcaR_}KncfAI>RpJv>x-$#yM#J08poQL5 zRPSx1v%ITmy>~5b@UEllz3b_A?*`i9-9-0$x6pgut)iuOn;7Wbj=zchsF>kBhCk4~ zSDfuVAs+Fb6fb+>r^Kh;)8ZHJ8QIc%0)Lg}IXTFCUas-}BG-E_$Q!*E zdLLqG@mDM@K2|4spQxL?Pt_w{5N>x>7}tU{U7d&- zkB`1?QWJg(3-iyO_3{4Bxv@4|`l2D2wW`!<>bngu|lq#__U9mr)+UP>ml zNy(y4xYWNqC5QT@dmWIYgraSEgaq9Uw23f<$%fW(t;9DMd+qX_08Wg>@$+g~R&pO2ixDz^QJsxum3&BsCG2 z6hspX>uxN#7$f{eniyXHCX&@0c-TnRlpfR~r6*;l^rDt2eKe#)BU$;zb{67R*1bp> zScayWVZK@mk*sn?f-Ah<<^D^KARgZZrqpYtT@GT8me!PkV9y}RNEuAIDMu!H1Jx63 z$}^7DY>Gz^Bks|_pJ>&@A_(K(P>WMXhl|@y83k%bgW55mHV9KZgj(a+IJL&)1hp|@ zjn;`%7SoOf^-OJW-)e(-WYY)_x_=UaRgX!cE9r1t;#f)ie$xM^t*eiXqKM*e-rg=v zM@&E93dcwIqXDdK#A;NuNUcShLfg{eIIPqShc!c>heJ` z(Ni!=xR1@Sqdv)|2xd4w2v&ic#%x9tO+HPItU_a}DNWYUC|PSN;yU>&8GOJc2|acy zarM~Io)T+b1lnM_X(g5p)1pnLik&v(Y=|soIv*qFK=G&0X-7^wrp|XdkV}GlGK7Ei zy5b@HpVoR0ciH*#VN_rjl~ z%-3MIH@!f~vYyiAQW`H^6-L(*E8=$C6S=-1LXxsI~rdQ8c$P_AsG`{f3jAvZ;+TsBcyZlwisGgZnhR4=#DN*Sd! zayvE39kfNhM%(31+9_YBUGhzOS1LLs-=gp3F8V|6rhnzzB2DfQnNlGnw+VNG>LkHs zmKKm5#%rzgat^9n=fp721b~s}96=720(j?%jw2>}v-NN>#^~=e1x1=!>s^D2X#}Ic zT%5kcM?HB+$!Xb;eCh=Ft)3Iaw$_7-Vqx-b~ayjyXZE5ly<6qw{ufLl>{ac%Rc@P3jV%`RR6fmpylWyIm2pD`R$b zhrsqqgP-w($!dqCN~)N9*sklc7lFd!4)J2Dpih!J0(ov~FR>m8A-j*p-~)3gbi}SN zYqyu^%<{60gwLeE-sA-yzzjuH2hr+tcoz}6n;NNrHqtEGO!Gu4Vy&dnLNSt-iXg2L z8MIzRM#7xVHKWvzcoBqrTChuo88GHEi=bXG9tvtY`V>2#!XB3h?4WZD)~d$?h!e_H z&WZfdfd`SEL>jg(IiJIo)MDV_fQL9Y-Rq?vd1qP<88;Kw zF8Unn5;MR18y`BU+Tw^A`Cd1tCu!97ot>N1vThFY(XZU1D=0ElQhwZg_Bxgbefp`S zpE0P-`DccyhvR&QL2sK@AOC;!qHkTw4RPY^S_HaSqCB&puDd!M2 z^h6I&;aL|{Uk^WKUFsI9y`04Z*VUR{E`-huQ*&*3y85n{r&w=fuqsRC(W+y`8oZ-PaX%_ry$xU;08~BO&raVZ;i~=W Uz5$-ju`ab@fU}$najjVTA9KZRm;e9( delta 35690 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 diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics.swf b/libsrc/ffdec_lib/testdata/graphics/graphics.swf index b13bec117615a26e4aba8f8c81fdc5c6eb8a2d63..6394bb7d81a58e76b3659ef0a949d5cad86a2ec3 100644 GIT binary patch delta 76326 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 delta 76242 zcmY(qWl)|?&?OuoK!D)x?(XjH?(Xic7aH8%-Q8V7aJX>|5Zv8;pLf5l-TJD|k25`0 zJ=NV~)jb26g}MMi0iv3!h#h-i-@J0Bdc66TUY-VkOOtLDOib}>dskF)X|#2qHeZ6_uXMI0YFQSlT~<=;;kIlAy&!HAziFNkc}&>-@uk(GtHLrC z95Bd*(#|jffV1;lnnozbf&dR2bJ9s7QacL?Gjb+kti`$)qnQn>CRu$Pf+bGYvG%c_ z;2mQdiQOEbtiQfLzr8+$J-;ZSJ}RrfDyzS~ygomx{$~Hwhv;2=r312b;ZC7+A&^~D ze^y*CDYv}zcDCPt5|B%P+2>=v4zRx%X34?jUa`CY+Xozc=ejm~$*4s)0b$`MVq%iR zV#5^VMfayW_rJn3Yhz?1VC0*A#>U4R;A6;OElMvb#KgeqCZlvQi1?Bx+Q8)k)Srg> zB8i=yA0S);)Z)8x50fO#;fXJ8-Z@Ho0g+K!5@rT&Vmk0jT7VvllasZ4b+}}9wc!V) zt}Gc~RBM3mU}08aX=!C-YiVz8Vq;lbZfS00Yi3$(X=YSqS>tGD6zux-R0-%b$HK`{ z+&(VpJbw+X8JXJesg$j4k<)SP2v;hb%(VV#^{ ze^@^d%K6=~lNdjAML4~Mc3}0u-4wz^B8vfK7}Ot`G$is|{T9_<#PU#I)D1xPYkBMS zm#oki$AhA+^OxcL{g+Mfi@oV*YB|7Qom($In*_tLpP8BY2aUxh0i206traWqJ2qJt z=rkijtjt#oc7c|Gf(_%G2->9(d02{uj6gchFSI90MNYZ=QTgcFf1h>-6HN(|3KJMZ zT|~FRh$@4D-A1j;Ag4;AN8x?@bAI9a{bb_=PCQ)9_76fN97}-7v9z2tU-DGaX<`=} zr`BuOJu|lZ+F6s_OZzP@`XLB6&vN>2g;mL7p;}3gn7PnFMb*Feq!$x71^Nh0Rdq#W zMb&Z${SsQ{lgVzVowym@Am~>F{B5AMoYV5`AgsIsqAX~X)swcuP|69qMB@^t)iK+Y zy|R_zX-Z1Cf>!A*N_tuFOKDAK4R-V~aGkaEp-}loi2`Pwapg+y>w5+c5mrZIRaUFp zs9nKJN?>Zj>Q<#5LTM%JanohDgu*cnTyOqLcuYIt11ru$he6_UnfIBvH4H#3?NnI@ zIj$VJo#x73|A+VRZ^iMo;UBPAC4>%pU9F9PRxqj=b|DYWYTeQ~EFC|aFYe2ixIqMh z9F(1b`dCa`0wCom;hkue@?97)yd~$a(YbB*;^``Uj0(a2+0EMJ@$nBm-HuHm{C^S3 zKXNwn%$fGDaOhs_=<`ns3y1)Mar$p1I`@9GFP!|F4?{q+GYlOW3kOmGMgPwIR#-0^ zaOutvPNq1~teHFos-UG|MA0dowA`&How7vXZqoag+VtKV(?GT6v!3R9fp=>k-7rRz zQh8Jc(@ENskLd#6+NoL)kS^(f63_lbFVtpe)h4igt*{xu%}@5}00OjQGp11Ta--2< zq;&WP+Kp2UE3S41rrhz8&h(J#4gTrMZ8}p{mv0VQ=2hUtlRCIj1?nDSSvX>~F zhh-+(z5x?Xlno{c=zKlErwBVc_lG2@D10L1J$eB9YSy%|ow>0uNM~>axxV+1gL%&? zE{(;iIM=ZW5Nj^k9s~P7_a_d7w5>1BUFA?LqEm&OG&Z8@dbQ7*cd#{Mli(J0)rqnN zre?VW4M)0yq5s+-kTfWkMtUhYjRf|{XEiNR_VAqAxcnH} zrFebI_1#{u1qsG~(ldD*l6Bwe1rpK370Y!D^xtSJu_-q){>`Rae#1`5%z~ExyX5;< z2*38eZl8X=zx-e@7hke!VrqZ4)D8T1-60!)WTam0THTCr@-IaVvl<{^$`*g)uq1X| zX>nfLN7og+7Xh$x8emI?&+I+0?S^ijgl2w@IbCxwCh5BDOtr)F5#J{2QKCq?Tf+pzXzA#5(0(EmzVsSThThr$eLX63d4X5`sV(aKRz#OK;U# zG@|}3Y&7R*6IX~9SMVF6j!>%16w&4v$^HhQWQg`op&e-pG4+=tSB1HrM+I`s&7i1- z0Zik9LLkutu1*od9aSt>ezZ#C^2W%d? zrC~J!Cr~y=HX#*2naML(y1A%bILZjy53KYVBQT7Y5wY{7CV6$zg#MSSunFQw{8*?xy=%X+0v^+of=URt~yOV(FB5bw1TgSfyg$}({ zgxUdLks2_wLR$Q46r_z$; zJnS@#OtOn3daA2$8FWFkX7Ukq8ssl$EWwoIW(nmr+fQ*%jPiQn$M<*&M&zqkGATA# zGg3TWZAJEsiTzXcWH9#)3={}=D~=mniXp-cUS~j}xSPmQaQc4bJod|=l@01*5P&BV z->m7jQ-wR7>0@&N%OC+rifH*l7R6+x+7gk7#wq8p;2$B0bTqK`m3KX9L%9n42Pro= zr6VYF40in(o?GhByvOcTwY6)uPcc7jqcl(`y*{-|W3#fi4aSYUSEgzqHXV>`en>sI z{B@Y6U#;$BbR}D5(%vX_o{<)h2Qphr!VFa41^QShP#k|plSBIB<;YGk;Barw=Cd>4 z11_DzbBJ@Az|?F4faRCs!5=bh)k5OR|+sy z3oJ^rkQ82e`-@~$z@Jl9nz9r+Wx(82`|ytc$^XHJMPFt&dGXfB69rEXOy;%|RP83@ z(?{XogGoO~#+&|KF+?Q{_wr~kmho{c1j9v>Q1zcF-PU$i2f3E(@m1h3OD_aH_66wA z`;A(hG}Ua`dP-BvJk2dmds*KKiH0k9If}X~A?e-6yRhp(?mTfBkyR_4W`Q(y?xQG>{*)D;{o?pwB~o4b_ROlIHx z;P{DhiXE~gbsbt6-{=|<>#YtLIm#rDq;JqakqQ?UrdS?g5wUc}NM9Hr`pQwlK5_lc zmuAod)Obh1x+OT?CFtu;k!88csxVKQIh*$>iM-LjS(9)q7+1UiIxMm?ymFOkT^hwR zOxcs&<%=*`;_e0Qv^8g*3%PthsAz-eCpyFQJ1suv(Wo7?T0lG$YNLgF-3vat2K5}L z4F0p;bKDIET$N-b3v+; z4?nW2new!b{*ER;cbn4l^IvLgK)1ghBXifPME(L>{Bsl%8$4FH8qAOw)RH2LK&?DuWs4({o zT?ZBShcKKNR9g9Yb$0Es+m1bC?|&MPT~O-*Nu^LFjSuE@_bhzrnU#&?j`Q~A&F9OH z0!+#o^v=D-OqwHpvW9<@i4@ITjtc4+>~1cHe#N=VVg>6J+``fDq=)KaBwX3s63Bb7tDa>0lF?GDt*lDFQ!kV7n{^ z;9KE*i_ng?TWGJfWbazd(gFuI!>=MS3vt1+_ao^&zd*WqU-e9+N*T+WoEata+Ui(k|3Wo(PP$<1$&(P-a38?1|_g^Xfuu*!%@ zQF@*Qx!-z+eFLEyq=n^|C3T2Rdhf*{68=B)sPV`}8{0j3`!e0DTz>`< zQ1;C$x)e+;%KMv0V7>jvp09dA>6(oK!>2zeSowI5t(ZTP`DTTy^u6@YT!T$~#3P2s zw0{eu38Sx-hupj}4);h)zn{vsB|-NcR{Y{iWVApkeME94lc6pHPB}36cWL17IMJ4& zyAmB^GYw(<`MN6jWmNN@V!hkR-^!dPqNSy|Pm|FK#t@bRql_Rr5b6sW2{6Hb6BeMKm96}tW-o=4J`n&fA6d(JeW=Genby@~t3)fGStM;ci+{~=h-$7W+Rr*fhuH}- zsB%-79SsBHjCq>p;l$h)*tc{W=iZL4f*daDaCMgafBRJQHy5tzI0QWPMaQLcgQq;k zr7aTuiAK1w*pw%3P&;Z;pY$iH<)2?v-`uw)Nd4C{V_0g9eQ^!EU{c-|d||o#>y&(n zW;ejgC~k}N&2EGVWDneO*0bP_$rk~t_Jo_GAbd`BJFm#vimoS42kgV2^#<2D5y^Tp zg=Eg$Xz1LGhMJm8KmRgG5~0gDNlCuA!~mXC|DxoALcQ_n5)y7*H^?FPR|yc- zXMtA24*{f=fO4SFclZo`+>VO)3`KePjtg8S7|8SX+iZHTmE|!^9a!6Zo^n-r6n}r{ z;@>}W01y7f6E?+5pQJnUMt496QHW1q#B`sMc|w?}AbBPKL0r;$b)#hb}{Be`7Pha^Buf+=*k4D4=(mWiK8BIsf53>KnZ-qOzSj@M&J z3l2T$xdH(x^?2ba=QVvjb{e?XM=xMNOvxqcz4vRVG{JMv_tnikjAL(}Z=qcuLaQ{? z%I!?c5zR$S8=jK0MOFxjn=9Dga8q;x&NTaLN7i=1oy=fyjD`2g*1a41IiA14r;IZz z;Kqi%5eX-Tz4{O0E?$+>Du8=aNsERqg$Zzf1po}&5a8dFmS3{^)U@X%Z77k$`{oh- zX9_^-rh3N_0;H-|=^?Kl1cpTQ`r5$nrvVRs__N5-$)jVCoFRr#!}j8vpg?5zLnQPcRGgeK(~CTu&^27;Pk z7ORiUwUP0&$4=1TEry%4hjUQ=x)#CE1%`eV*uLmafoton*YLN!yNj|WR6E1Y+dnIFP1w=Rl(jow= z4B$(DB;)HoFfX0}k^Jqg(|Iykr*RE&fc380rY;GA>tcJ1DpPd22=gtT%RaOtYHZ4Z z6QOHA6QM@8qU<=)6)j0sxOGRFc0oLaISJ~H!mdi28I)f4xzx9Of-CoSp0=$(Y z6X$~jakYUL*sT?bkiA^@0cXrQ;5Y}D0#K5IV{=kt#PjK{ICvr%FikxjlUc3hi_Gll{w!6o@E?}B+IJj zsc5MGwC+&(P+~u9WM?W>4tnm!S*xF&BdM67|M)9ia@Ff$Gycft-z2v9SgIJ<)E)JF z=yd9(mou_6IH60}Y*5H`EFhFmkA{a;MKtGLff;iez(YXx-bJIo_dD%Cw8|!*q4#c6 z@&fQ>^A@s1-S3Tk(!kOL?hBXC>mCRiA||lMDwxk@(wZDhib2-Jmyww;z1my2T<^bO zW6Y074qv}@PHPWwPZm$b*Jp8q6b(FH2Gb?)tBY#i*FZDTgK*RYh zmp==-s~$T&b`5D|%aJn=w%KR3;n`#)k#fc+GHa#gPV)^*)+aCrK<}zdj!G9p=cPCM z+1;-dcGbW*>`D3?$EOcBdc94Pi~K<~njY(bqxFOAo@Du|M@VdI&Er*NmHo+Akhc1Y zzS3j?%Rjguk4U^&mNW-wI^QTTV&~Z3w(GVZ609Hj^s+ALU~_%m3h&yq$Iv-_tikW?a0!!=nGQE9YH3yjSUI9z%6hLw9-?gX^#3i&YCLHSSdHsLP0s~; zCea}$I}bmBT(a$L+j<>}TW&nlEZP=;;!%_LdDZs2=fVavHvJ4Z7C-UMM_?rjg z`)8Wyl{fj^Tn_HR&Y)Kv<2k1(5U2}Md=YBlFCLd42; z6{oRXtCt40U}WBm34dMYgPpIn?GdimVuO`FG zm&3#6lx^BG_WBTAcl=gjOe=No0hxYa!XDisu)r6cDvKc}Uq9e$;E_~lgY{=KxK}MQ zwCum@jb+TW!;`v~k4TAs+b`x+^WQ;H)dPma;Rf=I+P;#De%$Mv)MajVtIP`oR)ccaef=#p z1@*nf&TT&aeP05xhTl{CA@*Ic!wbyffaDD*qWB`s>F~DNei^PXsA&!`7<~$= zp6tgpCwC;VoY!eLZ5flZEfsZOk@9kFv35p*T_i3sy7bH~LkSzUMbrGRArBWSO?D(B zD+(i&9DpCH&%;Kc<2Gjdt@AL2pJ z=m`Gs`7hyFW9ch@T|to6X+9ESuS_@T>EQf_30WqzufI(v(3G@cmM+tyP!*>72;%r^ z&^I)_jV^*-w~q+(kH$%kSK!3 z90BseJs%8Evbe%an$|4RBUHwy|Hm@U=q;l+9nxK#W2|uft8?YLNrGl7?!(0WF4#&r zEXfJ&2fc3z-XG$t_mf$IR?b!ucJ0xkyu95+&orS%r5f+Btv#W&q&}^oOkwomF?PHm zYje43j3^${YIkZhFjDTKc&S|%3dv>;{Xs)IbCwv&^(lk0(hrb#n!G$)OcuKNrI8e5KqlPN-|!3cV84?K`1 z2c&}e)(wQ0%CNBDg{X|2>_m==t#MWvuF61iU6m{o6G#)TY+&zeQGZQQIRX{k?96Mp)LCa?E)<9I~tEbi+eHqaLlpr;R$!p zdY$9h&Oyf9>@WE|M2?=CHE5F>2w>SKm1HwLbH!HZc!0E!0l|CqT-oA*UHbl)NVMtD zi|iUSi^;yqpP6!RwmBwrWuKY)YkL*D!= z77^wncrRf3$BvqOrXGg`A55tC%cmDP*-fW`bfm@H4u!B29B-i2fP^yaTQFRWEQR9@ zZ}fq;z`l~Cf#p+!v~hfU3yVSBT5HDdBTpzY-pRO%(L%miQ*$^m&xqY*+Q-A}OiP)t zN}_97ZSPYXgvf0^lUnGGGJsE^i!Q%%1#1PL{_Ty+i=uFa?4nvZ^^ko++J%IgL4WLq zc$Psg#KErcjkfDnhmX5NfHSX# zM(%RNT5}Jh^c{aa1Id%*vb$FT>(dX5r6-S<(x1oA83uKPgd)3!Xp|?AG$Za1yY(q# zMHglokrH4Kt!CVBtq?j$co+dY*O5kUH;_^mb)fug#;O%PW?hdB38n4tC1J8Tt~OFa z%hh0gh!mc>MMagSzJWP^g3dQv$hI;+E{BiScXBCVIbV`{0im>H9*||+0Kc#=<75na zh}F@f`KOv)2LgT+5>gT@^$FhJzGk|sO>Kk+C>}JhkPY+Gdu)DP@fFF{U4!v^Id^6KKz%GVPI39nc`;RJ5IA~pLOTUS9YEhrl2;rrxGoJ&DFDmaD4 z4ZpoLihbUQf%-`y-f=L98QV*G8Pp$Unn8cBr@8k{aWEFAh3=xD7fdpHp&6#qtVq{m zNme}Z z@v}}O8K&0GPw(I^jWZWTjjKyxpruF<3~3t3!FJuQ1A!pl_|Y<}sH)uJ&mX5EXFScy zN7=3?tk!Bb@gqYmmv zS80Lml-ItEemVNHbC2M2^mhIuTTH)KI;;IaR^s^fpTorHDETmq8ws|<9teE93AWk7 z9e1tGfQ20i++v-R7)6CYUZB3F-ZI<$76@t#NrF5i0W&UrJ{yIX5I&{5T_wWI6o#HWeShc4 zw!OS)J)>lw+;8m|RugtjroKxAxwy4BqffQpl8iR0=60gAGQ%MqR)*C^Y4_6wC*9Q3 zeWm)x14Mfj)$}H$J7fDO=Z=28{p@R^pPyuJs&j`kI3czC8$LUtm5P3puVyLsaNz)N z4^+TBAyFGS70c$%9o;~v4y+$)z0jSDf4dDzYZou$jSDsW1}WWSM4_k6i8MPQxS`0=*q+^CJ3FHf?q zmnr-1>kYq;`GI-AlbhOG5NcAS>h5nz2t?|Ge|BTo^-8$nNU6$k@$MSAL7T0N-hJTd zc&o8jQ8fDOSFWNJAWl7u_hyBS_{R*>_g$J-h0COuZ?gHHFt{Br)5ITbt+-)i@ZD*% zb2c~3G*g_+RLw>s3`b2RyWpZp;nQ#7wsD0) zmLYl*$XoXzImy`mO|wf|u1O5C7H!jU?SW(oX=OwBenb$bK+Er0b6*e|^T1;KNKs!3 zeqw>P3o%`gvvaWKw%Q`|z9=1MgqYk!D|G$N_z-1GiH5m`9cBQTR1Z@LT(vvJYgOvH zJ;bq|@#(i+Fvh+oJlPbu?VVX-$5Q6Ip1yMu{G{R~UP;6K(jax-xwa;73Hl)v6b8<< zM(C%}x)C&bg>~5}8ztH1`h9cqG{{;8F{52w3d~xg4~i&nPEz+}e)_hkYCF(UK1!1S zW(mpG(LzLd1|st-AC`^tUF_t`F1Jkp?4`oFzixF*=uCq zQ}#rhv^XWP7eAlx!u55fb*1Gd1?f>WeqdK@GLuKNUn5BOgp3$gTp=Br_i=fmnR{3Uj~OZeYb~ z6(0wN@|qit=+3#}d}sbYYG#a2vh)9%|GNi#L=rYNjNj52q`m5j@tE`fr^KL#Ss0SX zKR+u}10wDLX+Ug{G3dWC-2obF2CsV1D#uJo)*zQQwzJ&?l(QF4e1e~G(L&nY8bPAK zNsv}plW~~Iy(rmklSm?z$!kG#I`g#H5rgSEtn($M=5UoWqgX3Q&J6>mlQ8QbN^0yQ z0iS}WF!V2BtUmHdvOxs5lpxZJb(j|WWfa%rI2-$RY)T7c3?x8kYLp;SNPM)6p#sX7s{w`UO% zVt9L5e5VN-{Luzfz6iK4T z1f+s(OmVZi)04vU(o9*138h`AUeIbQ^@jVNe39V<&PS7qGfE@u#{vY*zr-MyD~E4! z_$)-g+LQv%k4T0_dn33BpG?P8A z`4}Y0y5MhGpps$2uXVy3+W!xL|I4TZ@@X0r;14+_lzWzydoY+8gr+hCBBW}((CYs$ zwBpD%s47_fCr0Un2xSqB$Cdf& z#B#DKM)vGeWX^TTOP@>y2nfaGvgjnq-ii0wBY=>-&J>$r7cmio*pHf#fMp{>n+8O7 zuLqnSA9#aasCt7C&HBOWm48c-&J3k#ERQEdMMS69tyY_`bd@4Kg4!XY@)0hEI>`E# z0Yh1u$neUH{6Y7w)Rc35YDUXO9K?_ExuR~l)*oMbqz4a|m5$Ql6bC={z*g{PqeLN>yg;eaG8>hY3f=33k?HbIRTWjO+HMkPty ziT1h_=S#;TEY=%(=@e7W5T0LPn=2icv>`qU^RaaX!R5ANKUbljV+(czp^r zvjl$*`hT#y0HES7p&pN*>hiN!hvfh2Iv5lFAM9wiHz2kr^!-eh!+$FYr2dUIVj5he z#^dg#^E0tS_*m_c5>o6G4fSUJD$1)Sv@%AEvnrUq73r=_E5cN@NDZn8tBh;+xdV-4 zuNj=gI9xb4OKI4Yd{{GiBEmmkt)UE~XrhDzDBAlDXB(wLUb$yD%v6dLUXFg95n1sj z4tIk-Pf12MoFL7k9wqbFRz*#i1ws`(Q6_2Fg@S;V6hX1tBobqHHH9NBTE+ZEr)kwy zyQS;=}|Vn=@q&t0tlRr-Nl#Z4gC$cn);es0U|jW6BMete`&3f!-)DUP2lv zwMteY#7EA|td2Zd*3yuppf19VDNg302Ln0}4W@f!+Mv_NG{9d5>PI;_`o#Z2inRE!@O~%F z()XobG!wXRjrKVT`a->T!f1(6r^y9q|GDZXN#ic~Ik7OhSW#8t4COK*j~qaTtv-NO zYV!|vr6BKxF4BsnID#u?CIxCH{y%Uu{T4zanSY%yMV?7~TSkwRY*EuN4B#w4ovj+rSNc$yCPk>Vkorg!NyQ|7`HT_z(`iRo|Kj@m z11s1%h{7wjdwxtxLyS@`O6XlD$3C!R67e*Nl&>U;S5LgfE6SE0DJ5njbr5U)U$9gW zRS6fqCGwbuKExukmeC_u_cb&Q|2NdlQVIRCr|9{|c^p?%lUe8rz%J4{Dnw?p^kdu{ zX;i61f{M~*Sam-VId1(&z8L9wDl+?fF+tiHsl_zbzZ(%bR=YKnGhO3#qfY!ZT2;)V zRqY71Bm!oMMmjM8TvC)zR219y#s5y{b$I3LXx=o|ijj_h7-vo<36G!1m1Lw-VHqPC z7Fyx4qZ(dm>;xOeKqo&zw5t4dUxraV(r9XBSqEaaaU}K@sjHssp_k{BGkWHpKiep} zR7`7QPFQ8M7t}pcWXF$4u)>!$l=!ub<>yNH|E7s9pNHsFhR3L>a~0&{1o&GZS6%pj zp^Wb!)NUT|wGZlwA~)e{vJSFYg__(%(zpD3qm|S3<7$xvFbh&>6%&XcjfVfi!EUpNb+>Ey``?xVFdO(Y z>nLL;UWdnm7;z`pq#RF5ie=BjSVHhPj);j#4PHP)q_E-(q&vx~ns&$Be zo3J7|@)5}-2Ni46b0uCGNf}CBsZ7l1QY5o9rt^I>L0)yd)!UyRwm76bBwzN|TgZxQ zUg)%PwsN{P*5Uc{m2IoR^p~1#9c}h=3>m~I{v!ZJKC+2jbOyU=_`~M)D!yurO*ri` zf@Tf=>2II!%A*ax*BX9%oI4$?D!(Za{Gd_2P^L3cgT||bm?{4sbk#pJh!HOQIHMb8 zllUny$4vy677n$($AN~IUF@ibmSoOp z9H@_XCYASAET`-H1s7^!#S!`HZ}MZkV`3BnhQV@Qn7R@2V=^7nNcgnX-9}uBun8lS zqpSiJ3xY$vLp=)rdDxQ7VNZeisj3?wH9~sv`>?Z%fOuBrgLDMVbcwm7G}D z{`09EAf#`9cfFsz1?Jz%l}ANP)ViM)wdZ&H1vbMa92=koPrs;XC0H&^OooAvvh+{; zmVsB$90M8aun%HCf9flSe zY*>LfCk?jE9;8NwSUn07VF3c|V)mJTiAU|&x!cQJuZS8={o~68$P2euieDRZ?L7Mb zU2{lep5C@e=9H%wSC&{UUd1GsHg`?-lIC|wGdP@KZk%DBSDG6#H0I{y>X)iXl2I}Z zkRy>{&Pax|<&d*}Of#E^gEuvk36P{crxMDo%(iswlUca^ty(gkY5+Q(TfUoMpw<`I z4&*4l|JI5=LC3)-9C!N}3m*-q8&WdkoY*Kgx_>QZ!kj<06ghR=kE4T~KG0&&8~p6f zJU3M@OOnggLUR|t%@q9E$U;rdMjV`phf9z+AV(tNd~4iQhY%ehAH!rxAtA;@YN8<) z8ZH^iTKtv3^84!+&J2iPA0kZ>(UhcYGWumFo?{z9=~*e-DE8xe!9`jO_FxRm>{mrv zMOr8Z+Dn%w!IcEiK8rJ_SkI$t_0ZC|x70GKbDGFU%n*2m`Y(#_;+Z zG9#P}?FX0!;gl)q8|yc>NThi!oiX(@P8h)hi|PS~fB=^H&J*BF7aHyBS-wF_31+%T zgfC&_8wFUmxX9hEjL{zA`Cu(<7cop4UI!6X9Kki%tPw)$Y|*Z@+7KivndTUEP`%9i zHto$IM?e6p$c#j#7SymKaU|t--4RkH(z7g0MzFXVW)zL26(pzfiBqfZ)6G9QdrYKm zchcsCv!qwJCmTS=F0n3JZg8>(U+uAztD!lW2m9GPCrv@(%F=TeώFclWqrLxG{AHG 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 - + @@ -30,7 +30,7 @@ - + @@ -94,7 +94,7 @@ - + @@ -240,10 +240,10 @@ - - + + @@ -772,10 +772,10 @@ !3980 1990|2980 1990!2980 1990|2980 990!2980 990|3980 990!3980 990|3980 1990"/> - + @@ -1374,18 +1374,18 @@ - + - - + + @@ -1991,7 +1991,7 @@ - + @@ -2003,7 +2003,7 @@ - + @@ -2012,6 +2012,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -2023,18 +2047,30 @@ + + +!5000 3000|1000 3000!1000 3000|1000 1000!1000 1000|5000 1000!5000 1000|5000 3000"/> - - - +!1000 4000|5000 4000!5000 4000|5000 6000!5000 6000|1000 6000!1000 6000|1000 4000"/> - - - + + + + + + + + + + + + + + @@ -2061,7 +2097,7 @@ - + @@ -2658,7 +2694,7 @@ - + @@ -2669,13 +2705,13 @@ - + - + - nonlinear + sRGB diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/META-INF/metadata.xml b/libsrc/ffdec_lib/testdata/graphics/graphics/META-INF/metadata.xml index ad7256a24..12601412c 100644 --- a/libsrc/ffdec_lib/testdata/graphics/graphics/META-INF/metadata.xml +++ b/libsrc/ffdec_lib/testdata/graphics/graphics/META-INF/metadata.xml @@ -5,8 +5,8 @@ xmlns:xmp="http://ns.adobe.com/xap/1.0/"> Adobe Flash Professional CS6 - build 481 2021-03-14T08:29:20+01:00 - 2021-03-20T21:28:45+01:00 - 2021-03-20T21:28:45+01:00 + 2021-03-21T17:38:19+01:00 + 2021-03-21T17:38:19+01:00 @@ -15,7 +15,7 @@ - xmp.iid:531E43DEBA89EB11A3D5CC1539172738 + xmp.iid:F561DAD7638AEB1194808358E2C66B7A xmp.did:D6D3FE199784EB1187FEAE6972EC5115 xmp.did:D6D3FE199784EB1187FEAE6972EC5115 @@ -68,6 +68,12 @@ 2021-03-14T08:29:20+01:00 Adobe Flash Professional CS6 - build 481 + + created + xmp.iid:F561DAD7638AEB1194808358E2C66B7A + 2021-03-14T08:29:20+01:00 + Adobe Flash Professional CS6 - build 481 + diff --git a/libsrc/ffdec_lib/testdata/graphics/graphics/bin/SymDepend.cache b/libsrc/ffdec_lib/testdata/graphics/graphics/bin/SymDepend.cache index 675687c2a2203a11b365c1def925a5022ed5b041..5123289e63e8234db4ed7a4538761ef3deae77d5 100644 GIT binary patch literal 385 zcmb`DPYwYw6o-Fd!7%YBVLwY-#tB&1A?gBS=7ou-!_&c~T)}PJ!|Mnc)|$NbHEqA& zmu>+(YE_y0=wg7jbUi5#>cFX`A#@$nlw(b>4Jgamo`NCp=|gBADvmTID~hcHtvNEM zL&Rk4jH4u#6~@E*LS%vwVjmNolRD;d#gQhtwV82L4;yRdbQR1eU<9#R2y#m=k+5_) zhHhfU0xrV!J4INnuSdTSp?X-oor~Nh(;3`#3Tl^K+_q3T-EZ&I3DW>pBKpTx)|FY5eSo^s6!fgy7h@e9cUTpf^8 zZb!_DO45(YscA3RPvwWg1R@r)YE4|kTky|P2egH+Dqqys&1XKQ_xy?f?J) diff --git a/libsrc/gnujpdf/src/gnu/jpdf/PDFGraphics.java b/libsrc/gnujpdf/src/gnu/jpdf/PDFGraphics.java index c5a7c4f53..717286c1c 100644 --- a/libsrc/gnujpdf/src/gnu/jpdf/PDFGraphics.java +++ b/libsrc/gnujpdf/src/gnu/jpdf/PDFGraphics.java @@ -1 +1 @@ -/* * $Id: PDFGraphics.java,v 1.6 2007/09/22 12:58:40 gil1 Exp $ * * $Date: 2007/09/22 12:58:40 $ * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package gnu.jpdf; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.LinearGradientPaint; import java.awt.MultipleGradientPaint; import java.awt.Paint; import java.awt.Polygon; import java.awt.RadialGradientPaint; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.RenderingHints.Key; import java.awt.Shape; import java.awt.Stroke; import java.awt.TexturePaint; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.awt.image.renderable.RenderableImage; import java.awt.print.PageFormat; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Serializable; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import java.util.logging.Level; import java.util.logging.Logger; /** * This class is our implementation of AWT's Graphics class. It provides a Java * standard way of rendering into a PDF Document's Page. * * @author Peter T Mount, http://www.retep.org.uk/pdf/ * @author Eric Z. Beard, ericzbeard@hotmail.com * @author Gilbert DeLeeuw, gil1@users.sourceforge.net * @version $Revision: 1.6 $, $Date: 2007/09/22 12:58:40 $ * @see gnu.jpdf.PDFGraphics */ public class PDFGraphics extends Graphics2D implements Serializable { /** * One degree in radians */ private static final double degrees_to_radians = Math.PI / 180.0; private static final int FILL = 1; private static final int STROKE = 2; private static final int CLIP = 3; private static final AffineTransform IDENTITY = new AffineTransform(); private static final Stroke DEF_STROKE = new BasicStroke(); /* * NOTE: The original class is the work of Peter T. Mount, who released it * in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as * follows: * The package name was changed to gnu.pdf. * The formatting was changed a little bit. * This used to subclass an abstract class in a different package with * the same name (confusing). Now it's one concrete class. * drawImage() was implemented * It is still licensed under the LGPL. */ // Implementation notes: // // Pages 333-335 of the PDF Reference Manual // // Unless absolutely required, use the moveto, lineto and rectangle // operators to perform those actions. // They contain some extra optimizations // which will reduce the output size by up to half in some cases. // // About fill operators: For correct operation, any fill operation should // start with closeBlock(), which will ensure any previous path is completed, // otherwise you may find the fill will include previous items private static final DecimalFormat df = new DecimalFormat("#.###", new DecimalFormatSymbols(Locale.ENGLISH)); private static final DecimalFormat matDf = new DecimalFormat("0", new DecimalFormatSymbols(Locale.ENGLISH)); static { matDf.setMaximumFractionDigits(340); } //JPEXS: cache for already used images private static Map usedImages = new WeakHashMap(); private Color background; /** * This is true for any Graphics instance that didn't create the stream. * * @see #create */ private boolean child; private Area clip; private AffineTransform clipTransform; /** * This holds the current clipRectangle */ protected Rectangle clipRectangle; private Composite composite; private Graphics2D dg2 = new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB).createGraphics(); /** * This is the current font (in Java format) */ private Font font; /** * Part of the optimizer: When true, we are drawing a path. */ private boolean inStroke; /** * Part of the optimizer: When true, we are within a Text Block. */ private boolean inText; // true if within a Text Block - see newTextBlock() /** * The stroke line cap code; */ private int lineCap = 0; /** * The stroke line join code */ private int lineJoin = 0; /** * The stroke line width */ private float lineWidth = 1.0f; /** * Part of the optimizer: The last known moveto/lineto x coordinate * * @see #moveto * @see #lineto */ private float lx; // last known moveto/lineto coordinates /** * Part of the optimizer: The last known moveto/lineto y coordinate * * @see #moveto * @see #lineto */ private float ly; // last known moveto/lineto coordinates private float miterLimit = 10.0f; /** * Part of the optimizer: When true, the font has changed. */ private boolean newFont; // true if the font changes - see newTextBlock() /** * This is a reference to the PDFPage we are rendering to. */ private PDFPage page; /** * This is the current pen/fill color */ private Paint paint; private AffineTransform paintTransform; /** * This is the current font (in PDF format) */ private PDFFont pdffont; /** * Part of the optimizer: This is written to the stream when the newPath() * is called. np then clears this value. */ private String pre_np; // PDF space transform private AffineTransform pTransform; /** * This is the PrintWriter used to write PDF drawing commands to the Stream */ private RawPrintWriter pw; /** * RenderingHints */ private RenderingHints rhints = new RenderingHints(null); private Stroke stroke; // Start of Graphics2D properties private AffineTransform transform; /** * Part of the optimizer: The last x coordinate when rendering text */ private float tx; // the last coordinate for text rendering /** * Part of the optimizer: The last y coordinate when rendering text */ private float ty; // the last coordinate for text rendering private String shading = null; private String pattern = null; private Set usedAlphas = new HashSet<>(); private Set gsBlendModes = new HashSet<>(); private int currentAlpha = 255; private String blendMode; private int shadingCount = 0; private static int[] srgbToLinear = new int[256]; static { for (int i = 0; i < 256; i++) { srgbToLinear[i] = convertSRGBtoLinearRGB(i); } } private static int convertSRGBtoLinearRGB(int color) { float input, output; input = color / 255.0f; if (input <= 0.04045f) { output = input / 12.92f; } else { output = (float) Math.pow((input + 0.055) / 1.055, 2.4); } return Math.round(output * 255.0f); } /** * @see Graphics2D#addRenderingHints(Map) */ @Override public void addRenderingHints(Map hints) { rhints.putAll(hints); } /** * This produces an arc by breaking it down into one or more Bezier curves. * It is used internally to implement the drawArc and fillArc methods. * * @param axc X coordinate of arc centre * @param ayc Y coordinate of arc centre * @param width of bounding rectangle * @param height of bounding rectangle * @param ang1 Start angle * @param ang2 End angle * @param clockwise true to draw clockwise, false anti-clockwise */ public void arc(double axc, double ayc, double width, double height, double ang1, double ang2, boolean clockwise) { double adiff; double x0, y0; double x3r, y3r; boolean first = true; // may not need this //if( ar < 0 ) { //ang1 += fixed_180; //ang2 += fixed_180; //ar = - ar; //} double ang1r = (ang1 % 360.0) * degrees_to_radians; double sin0 = Math.sin(ang1r); double cos0 = Math.cos(ang1r); x0 = axc + width * cos0; y0 = ayc + height * sin0; // NB: !clockwise here as Java Space is inverted to User Space if (!clockwise) { // Quadrant reduction while (ang1 < ang2) { ang2 -= 360.0; } while ((adiff = ang2 - ang1) < -90.0) { double w = sin0; sin0 = -cos0; cos0 = w; x3r = axc + width * cos0; y3r = ayc + height * sin0; arc_add(first, width, height, x0, y0, x3r, y3r, (x0 + width * cos0), (y0 + height * sin0) ); x0 = x3r; y0 = y3r; ang1 -= 90.0; first = false; } } else { // Quadrant reduction while (ang2 < ang1) { ang2 += 360.0; } while ((adiff = ang2 - ang1) > 90.0) { double w = cos0; cos0 = -sin0; sin0 = w; x3r = axc + width * cos0; y3r = ayc + height * sin0; arc_add(first, width, height, x0, y0, x3r, y3r, (x0 + width * cos0), (y0 + height * sin0) ); x0 = x3r; y0 = y3r; ang1 += 90.0; first = false; } } // Compute the intersection of the tangents. // We know that -fixed_90 <= adiff <= fixed_90. double trad = Math.tan(adiff * (degrees_to_radians / 2)); double ang2r = ang2 * degrees_to_radians; double xt = x0 - trad * width * sin0; double yt = y0 + trad * height * cos0; arc_add(first, width, height, x0, y0, (axc + width * Math.cos(ang2r)), (ayc + height * Math.sin(ang2r)), xt, yt); } /** * Used by the arc method to actually add an arc to the path Important: We * write directly to the stream here, because this method operates in User * space, rather than Java space. * * @param first true if the first arc * @param w width * @param h height * @param x0 coordinate * @param y0 coordinate * @param x3 coordinate * @param y3 coordinate * @param xt coordinate * @param yt coordinate */ private void arc_add(boolean first, double w, double h, double x0, double y0, double x3, double y3, double xt, double yt) { double dx = xt - x0, dy = yt - y0; double dist = dx * dx + dy * dy; double w2 = w * w, h2 = h * h; double r2 = w2 + h2; double fw = 0.0, fh = 0.0; if (dist < (r2 * 1.0e8)) { // JM fw = (w2 != 0.0) ? ((4.0 / 3.0) / (1 + Math.sqrt(1 + dist / w2))) : 0.0; fh = (h2 != 0.0) ? ((4.0 / 3.0) / (1 + Math.sqrt(1 + dist / h2))) : 0.0; } // The path must have a starting point if (first) { moveto(x0, y0); } double x = x0 + ((xt - x0) * fw); double y = y0 + ((yt - y0) * fh); x0 = x3 + ((xt - x3) * fw); y0 = y3 + ((yt - y3) * fh); // Finally the actual curve. curveto(x, y, x0, y0, x3, y3); } /** * This simply draws a White Rectangle to clear the area * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void clearRect(int x, int y, int w, int h) { closeBlock(); pw.print("q 1 1 1 RG ");// save state, set colour to White drawRect(x, y, w, h); closeBlock("B Q"); // close fill & stroke, then restore state } /** * @see Graphics2D#clip(Shape) */ @Override public void clip(Shape s) { if (s == null) { setClip(null); return; } Area newClip; if (clip == null) { newClip = new Area(s); } else { newClip = (Area) clip.clone(); newClip.intersect(new Area(s)); } setClip(newClip); } /** * This extra method allows PDF users to clip to a Polygon. * *

* In theory you could use setClip(), except that java.awt.Graphics only * supports Rectangle with that method, so we will have an extra method. * * @param p Polygon to clip to */ public void clipPolygon(Polygon p) { closeBlock(); // finish off any existing path polygon(p.xpoints, p.ypoints, p.npoints); closeBlock("W"); // clip to current path clipRectangle = p.getBounds(); } /** * Clips to a set of coordinates * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void clipRect(int x, int y, int w, int h) { setClip(x, y, w, h); } /** * All functions should call this to close any existing optimized blocks. */ void closeBlock() { closeBlock("S"); } /** *

* This is used by code that use the path in any way other than Stroke (like * Fill, close path & Stroke etc). Usually this is used internally.

* * @param code PDF operators that will close the path */ void closeBlock(String code) { if (inText) { pw.println("ET Q"); // setOrientation(); // fixes Orientation matrix } if (inStroke) { pw.println(code); } inStroke = inText = false; } /** * This is unsupported - how do you do this with Vector graphics? * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param dx coordinate * @param dy coordinate */ @Override public void copyArea(int x, int y, int w, int h, int dx, int dy) { // Hmm... Probably need to keep track of everything // that has been drawn so far to get the contents of an area } //============ Line operations ======================= /** *

* This returns a child instance of this Graphics object. As with AWT, the * affects of using the parent instance while the child exists, is not * determined.

* *

* Once complete, the child should be released with it's dispose() method * which will restore the graphics state to it's parent.

* * @return Graphics object to render onto the page */ @Override public Graphics create() { closeBlock(); PDFGraphics g = createGraphic(page, pw); // The new instance inherits a few items g.clipRectangle = new Rectangle(clipRectangle); return (Graphics) g; } // end create() /** * This method creates a new instance of the class based on the page and a * print writer. * * @param page the page to attach to * @param pw the PrintWriter to attach to. */ protected PDFGraphics createGraphic(PDFPage page, RawPrintWriter pw) { PDFGraphics g = new PDFGraphics(); g.init(page, pw); return g; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x2,y2) using the current point and (x1,y1) as the * Bezier control points. *

* The new current point is (x2,y2) * * @param x1 Second control point * @param y1 Second control point * @param x2 Destination point * @param y2 Destination point */ public void curveto(double x1, double y1, double x2, double y2) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + "v"); lx = (float) x2; ly = (float) y2; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x3,y3) using (x1,y1) and (x2,y2) as the Bezier * control points. *

* The new current point is (x3,y3) * * @param x1 First control point * @param y1 First control point * @param x2 Second control point * @param y2 Second control point * @param x3 Destination point * @param y3 Destination point */ public void curveto(double x1, double y1, double x2, double y2, double x3, double y3) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + cxy(x3, y3) + "c"); lx = (float) x3; ly = (float) y3; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x2,y2) using the current point and (x1,y1) as the * Bezier control points. *

* The new current point is (x2,y2) * * @param x1 Second control point * @param y1 Second control point * @param x2 Destination point * @param y2 Destination point */ public void curveto(int x1, int y1, int x2, int y2) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + "v"); lx = x2; ly = y2; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x3,y3) using (x1,y1) and (x2,y2) as the Bezier * control points. *

* The new current point is (x3,y3) * * @param x1 First control point * @param y1 First control point * @param x2 Second control point * @param y2 Second control point * @param x3 Destination point * @param y3 Destination point */ public void curveto(int x1, int y1, int x2, int y2, int x3, int y3) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + cxy(x3, y3) + "c"); lx = x3; ly = y3; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x2,y2) using (x1,y1) and the end point as the * Bezier control points. *

* The new current point is (x2,y2) * * @param x1 Second control point * @param y1 Second control point * @param x2 Destination point * @param y2 Destination point */ public void curveto2(double x1, double y1, double x2, double y2) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + "y"); lx = (float) x2; ly = (float) y2; } // Arcs are horrible and complex. They are at the end of the // file, because they are the largest. This is because, unlike // Postscript, PDF doesn't have any arc operators, so we must // implement them by converting into one or more Bezier curves // (which is how Postscript does them internally). /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x2,y2) using (x1,y1) and the end point as the * Bezier control points. *

* The new current point is (x2,y2) * * @param x1 Second control point * @param y1 Second control point * @param x2 Destination point * @param y2 Destination point */ public void curveto2(int x1, int y1, int x2, int y2) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + "y"); lx = x2; ly = y2; } /** * Converts the Java space dimension into pdf. * * @param w width * @param h height * @return String containing the coordinates in PDF space */ private String cwh(double w, double h) { return "" + df.format(w) + " " + df.format(h) + " "; } /** * Converts the Java space dimension into pdf. * * @param w width * @param h height * @return String containing the coordinates in PDF space */ private String cwh(int w, int h) { return cwh((double) w, (double) h); } /** * Converts the Java space coordinates into pdf. * * @param x coordinate * @param y coordinate * @return String containing the coordinates in PDF space */ private String cxy(double x, double y) { return "" + df.format(x) + " " + df.format(y) + " "; } /** * Converts the Java space coordinates into pdf. * * @param x coordinate * @param y coordinate * @return String containing the coordinates in PDF space */ private String cxy(int x, int y) { return cxy((double) x, (double) y); } /** *

* This releases any resources used by this Graphics object. You must use * this method once finished with it. Leaving it open will leave the PDF * stream in an inconsistent state, and will produce errors.

* *

* If this was created with Graphics.create() then the parent instance can * be used again. If not, then this closes the graphics operations for this * page when used with PDFJob.

* *

* When using PDFPage, you can create another fresh Graphics instance, which * will draw over this one.

* */ @Override public void dispose() { closeBlock(); if (clip != null) { restoreState(); } if (child) { pw.println("Q"); // restore graphics context } else { pw.close(); // close the stream if were the parent } } // ********************************************* // **** Implementation of java.awt.Graphics **** // ********************************************* //============ Rectangle operations ======================= /** * @see Graphics2D#draw(Shape) */ @Override public void draw(Shape s) { followPath(s, STROKE); } /** *

* Not implemented

* *

* Draws a 3-D highlighted outline of the specified rectangle. The edges of * the rectangle are highlighted so that they appear to be beveled and lit * from the upper left corner. The colors used for the highlighting effect * are determined based on the current color. The resulting rectangle covers * an area that is width + 1 pixels wide by height + 1 pixels tall. *

* * @param x an int value * @param y an int value * @param width an int value * @param height an int value * @param raised a boolean value */ @Override public void draw3DRect(int x, int y, int width, int height, boolean raised) { // Not implemented } /** * Draws an arc * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param sa Start angle * @param aa End angle */ @Override public void drawArc(int x, int y, int w, int h, int sa, int aa) { w = w >> 1; h = h >> 1; x += w; y += h; arc((double) x, (double) y, (double) w, (double) h, (double) -sa, (double) (-sa - aa), false); } /** *

* Not implemented

* * @param data a byte[] value * @param offset an int value * @param length an int value * @param x an int value * @param y an int value */ @Override public void drawBytes(byte[] data, int offset, int length, int x, int y) { } //============ Optimizers ======================= /** * @see Graphics2D#drawGlyphVector(GlyphVector, float, float) */ @Override public void drawGlyphVector(GlyphVector g, float x, float y) { Shape s = g.getOutline(x, y); fill(s); } /** * @see Graphics2D#drawImage(BufferedImage, BufferedImageOp, int, int) */ @Override public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { BufferedImage result = img; if (op != null) { result = op.createCompatibleDestImage(img, img.getColorModel()); result = op.filter(img, result); } drawImage(result, x, y, null); } /** * @see Graphics2D#drawImage(Image, AffineTransform, ImageObserver) */ @Override public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { // return drawImage(img, null, xform, null, obs); return true; } /** *

* Draw's an image onto the page, with a backing colour.

* * @param img The java.awt.Image * @param x coordinate on page * @param y coordinate on page * @param bgcolor Background colour * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver obs) { return drawImage(img, x, y, img.getWidth(obs), img.getHeight(obs), bgcolor, obs); } /** * Draw's an image onto the page * * @param img The java.awt.Image * @param x coordinate on page * @param y coordinate on page * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int x, int y, ImageObserver obs) { return drawImage(img, x, y, img.getWidth(obs), img.getHeight(obs), obs); } /** *

* Draw's an image onto the page, with a backing colour.

* * @param img The java.awt.Image * @param x coordinate on page * @param y coordinate on page * @param w Width on page * @param h height on page * @param bgcolor Background colour * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int x, int y, int w, int h, Color bgcolor, ImageObserver obs) { closeBlock(); pw.print("q "); // save state Color c = getColor(); // save current colour setColor(bgcolor); // change the colour drawRect(x, y, w, h); closeBlock("B Q"); // fill stroke, restore state paint = c; // restore original colour return drawImage(img, x, y, img.getWidth(obs), img.getHeight(obs), obs); } /** *

* Draws an image onto the page.

* *

* This method is implemented with ASCIIbase85 encoding and the zip stream * deflater. It results in a stream that is anywhere from 3 to 10 times as * big as the image. This obviously needs some improvement, but it works * well for small images

* * @param img The java.awt.Image * @param x coordinate on page * @param y coordinate on page * @param w Width on page * @param h height on page * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int x, int y, int w, int h, ImageObserver obs) { closeBlock(); PDFImage image; if (usedImages.containsKey(img)) { image = usedImages.get(img); } else { PDFMask mask = new PDFMask(img); page.getPDFDocument().add(mask); image = new PDFImage(img, x, y, w, h, obs, "" + mask.getSerialID() + " 0 R"); // The image needs to be registered in several places page.getPDFDocument().setImageName(image); page.getPDFDocument().add(image); usedImages.put(img, image); } page.addToProcset("/ImageC"); page.addImageResource(image.getName() + " " + image.getSerialID() + " 0 R"); initAlpha(255); // JM /*page.addResource("/XObject << " + image.getName() + " " + image.getSerialID() + " 0 R >>");*/ // q w 0 0 h x y cm % the coordinate matrix AffineTransform newTransform = new AffineTransform(w, 0, 0, -h, x, y + h); AffineTransform transformToSet = newTransform; pw.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); return false; } /** * Draw's an image onto the page, with scaling *

* This is not yet supported. * * @param img The java.awt.Image * @param dx1 coordinate on page * @param dy1 coordinate on page * @param dx2 coordinate on page * @param dy2 coordinate on page * @param sx1 coordinate on image * @param sy1 coordinate on image * @param sx2 coordinate on image * @param sy2 coordinate on image * @param bgcolor Background colour * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver obs) { return false; } //============ Clipping operations ======================= /** * Draw's an image onto the page, with scaling *

* This is not yet supported. * * @param img The java.awt.Image * @param dx1 coordinate on page * @param dy1 coordinate on page * @param dx2 coordinate on page * @param dy2 coordinate on page * @param sx1 coordinate on image * @param sy1 coordinate on image * @param sx2 coordinate on image * @param sy2 coordinate on image * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver obs) { // This shouldn't be too bad, just change the coordinate matrix return false; } /** * Draws a line between two coordinates. * * If the first coordinate is the same as the last one drawn (i.e. a * previous drawLine, moveto, etc) it is ignored. * * @param x1 coordinate * @param y1 coordinate * @param x2 coordinate * @param y2 coordinate */ @Override public void drawLine(int x1, int y1, int x2, int y2) { moveto(x1, y1); lineto(x2, y2); } //============ Arcs operations ============================== // These are the standard Graphics operators. They use the // arc extension operators to achieve the affect. /** *

* Draws an oval

* * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void drawOval(int x, int y, int w, int h) { drawArc(x, y, w, h, 0, 360); } /** * Draws a polygon, linking the first and last coordinates. * * @param xp Array of x coordinates * @param yp Array of y coordinates * @param np number of points in polygon */ @Override public void drawPolygon(int[] xp, int[] yp, int np) { polygon(xp, yp, np); closeBlock("s"); // close path and stroke } /** * Draws a polyline. The first and last coordinates are not linked. * * @param xp Array of x coordinates * @param yp Array of y coordinates * @param np number of points in polyline */ @Override public void drawPolyline(int[] xp, int[] yp, int np) { polygon(xp, yp, np); // no stroke, as we keep the optimizer in stroke state } /** * We override Graphics.drawRect as it doesn't join the 4 lines. Also, PDF * provides us with a Rectangle operator, so we will use that. * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void drawRect(int x, int y, int w, int h) { draw(new Rectangle(x, y, w, h)); /*newPath(); pw.print(cxy(x, y) + cwh(w, h) + "re "); // rectangle lx = x; // I don't know if this is correct, but lets see if PDF ends ly = y; // the rectangle at it's start. // stroke (optimized)*/ } /** * @see Graphics2D#drawRenderableImage(RenderableImage, AffineTransform) */ @Override public void drawRenderableImage(RenderableImage img, AffineTransform xform) { drawRenderedImage(img.createDefaultRendering(), xform); } /** * @see Graphics2D#drawRenderedImage(RenderedImage, AffineTransform) */ @Override public void drawRenderedImage(RenderedImage img, AffineTransform xform) { BufferedImage image = null; if (img instanceof BufferedImage) { image = (BufferedImage) img; } else { ColorModel cm = img.getColorModel(); int width = img.getWidth(); int height = img.getHeight(); WritableRaster raster = cm.createCompatibleWritableRaster(width, height); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); Hashtable properties = new Hashtable(); String[] keys = img.getPropertyNames(); if (keys != null) { for (int i = 0; i < keys.length; i++) { properties.put(keys[i], img.getProperty(keys[i])); } } BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties); img.copyData(raster); image = result; } drawImage(image, xform, null); } /** * This is not yet implemented * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param aw a-width * @param ah a-height */ @Override public void drawRoundRect(int x, int y, int w, int h, int aw, int ah) { } //============ Oval operations ======================= /** * Draws a string using a AttributedCharacterIterator. *

* This is not supported yet, as I have no idea what an * AttributedCharacterIterator is. *

* This method is new to the Java2 API. */ @Override public void drawString(java.text.AttributedCharacterIterator aci, float x, float y) { } /** * Draws a string using a AttributedCharacterIterator. *

* This is not supported yet, as I have no idea what an * AttributedCharacterIterator is. *

* This method is new to the Java2 API. */ @Override public void drawString(java.text.AttributedCharacterIterator aci, int x, int y) { } public void drawStringWithMode(String s, float x, float y, int mode) { newTextBlock(x, y); if (mode > -1) { pw.println("" + mode + " Tr"); } if (pdffont instanceof PDFEmbeddedFont) { pw.print("[("); pw.printRaw(PDFStringHelper.makeRawPDFString(s)); pw.println(")] TJ"); } else { pw.print(PDFStringHelper.makePDFString(s)); pw.println(" Tj"); } closeBlock(); } @Override public void drawString(String s, float x, float y) { drawStringWithMode(s, x, y, -1); } /** * This draws a string. * * @param s * @oaran s String to draw * @param x coordinate * @param y coordinate */ @Override public void drawString(String s, int x, int y) { drawString(s, (float) x, (float) y); } public void drawTransparentString(String s, float x, float y) { drawStringWithMode(s, x, y, 3); } /** * This draws a transparent string. * * @oaran s String to draw * @param x coordinate * @param y coordinate */ public void drawTransparentString(String s, int x, int y) { drawTransparentString(s, (float) x, (float) y); } /** * @see Graphics2D#fill(Shape) */ @Override public void fill(Shape s) { followPath(s, FILL); } /** *

* Not implemented

* * @param x an int value * @param y an int value * @param width an int value * @param height an int value * @param raised a boolean value */ @Override public void fill3DRect(int x, int y, int width, int height, boolean raised) { // Not implemented } /** * Fills an arc, joining the start and end coordinates * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param sa Start angle * @param aa End angle */ @Override public void fillArc(int x, int y, int w, int h, int sa, int aa) { // here we fool the optimizer. We force any open path to be closed, // then draw the arc. Finally, as the optimizer hasn't stroke'd the // path, we close and fill it, and mark the Stroke as closed. // // Note: The lineto to the centre of the object is required, because // the fill only fills the arc. Skipping this includes an extra // chord, which isn't correct. Peter May 31 2000 closeBlock(); patternFill(null/*FIXME!!!*/); drawArc(x, y, w, h, sa, aa); lineto(x + (w >> 1), y + (h >> 1)); if (shadingFill(null)) { return; } closeBlock("b"); // closepath and fill } //============ Extension operations ============================== // These are extensions, and provide access to PDF Specific // operators. /** *

* Draws a filled oval

* * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void fillOval(int x, int y, int w, int h) { fillArc(x, y, w, h, 0, 360); } //============ Polygon operations ======================= /** * Fills a polygon. * * @param xp Array of x coordinates * @param yp Array of y coordinates * @param np number of points in polygon */ @Override public void fillPolygon(int[] xp, int[] yp, int np) { closeBlock(); // finish off any previous paths patternFill(null /*FIXME!!!*/); polygon(xp, yp, np); if (shadingFill(null)) { return; } closeBlock("b"); // closepath, fill and stroke } //============ Image operations ======================= /** * Fills a rectangle with the current colour * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void fillRect(int x, int y, int w, int h) { fill(new Rectangle(x, y, w, h)); /* // end any path & stroke. This ensures the fill is on this // rectangle, and not on any previous graphics closeBlock(); patternFill(); drawRect(x, y, w, h); if (shadingFill()) { return; } closeBlock("B"); // rectangle, fill stroke*/ } private void patternFill(Shape s) { if (pattern != null) { if (paint instanceof TexturePaint) { if (pattern.equals("texture") || !paintTransform.equals(transform)) { initTexturePaint((TexturePaint) paint); paintTransform = transform; } } if (paint instanceof MultipleGradientPaint) { if (pattern.equals("gradient") || !paintTransform.equals(transform)) { initGradientPaint((MultipleGradientPaint) paint, s); paintTransform = transform; } } pw.println("/Pattern cs"); pw.println(pattern + " scn"); } } private boolean shadingFill(Shape s) { if (pattern == null && shading != null) { saveState(); pw.println("W n"); if (paint instanceof MultipleGradientPaint) { if (shading.equals("gradient") || !paintTransform.equals(transform)) { initGradientPaint((MultipleGradientPaint) paint, s); paintTransform = transform; } } pw.println(shading + " sh"); restoreState(); return true; } return false; } //============ Round Rectangle operations ======================= /** * This is not yet implemented * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param aw a-width * @param ah a-height */ @Override public void fillRoundRect(int x, int y, int w, int h, int aw, int ah) { } /////////////////////////////////////////////// // // // implementation specific methods // // private void followPath(Shape s, int drawType) { PathIterator points; if (s == null) { return; } if (drawType == FILL) { patternFill(s); } if (drawType == STROKE) { if (!(stroke instanceof BasicStroke)) { s = stroke.createStrokedShape(s); followPath(s, FILL); return; } } // if (drawType==STROKE) { // setStrokeDiff(stroke, oldStroke); // oldStroke = stroke; // setStrokePaint(); // } // else if (drawType==FILL) // setFillPaint(); points = s.getPathIterator(IDENTITY); int segments = 0; float[] coords = new float[6]; while (!points.isDone()) { segments++; int segtype = points.currentSegment(coords); switch (segtype) { case PathIterator.SEG_CLOSE: pw.print("h "); break; case PathIterator.SEG_CUBICTO: curveto(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); break; case PathIterator.SEG_LINETO: lineto(coords[0], coords[1]); break; case PathIterator.SEG_MOVETO: moveto(coords[0], coords[1]); break; case PathIterator.SEG_QUADTO: curveto(coords[0], coords[1], coords[2], coords[3]); break; } points.next(); } switch (drawType) { case FILL: if (segments > 0) { if (pattern == null && shading != null) { saveState(); if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) { closeBlock("W*"); } else { closeBlock("W"); } pw.println("n"); if (paint instanceof MultipleGradientPaint) { if (shading.equals("gradient") || !paintTransform.equals(transform)) { initGradientPaint((MultipleGradientPaint) paint, s); paintTransform = transform; } } pw.println(shading + " sh"); restoreState(); return; } if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) { closeBlock("f*"); } else { closeBlock("f"); } } break; case STROKE: if (segments > 0) { closeBlock("S"); } break; case CLIP: default: //drawType==CLIP if (segments == 0) { drawRect(0, 0, 0, 0); } if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) { closeBlock("W*"); } else { closeBlock("W"); } } } /** * @see Graphics2D#getBackground() */ @Override public Color getBackground() { return background; } /** * Returns the Shape of the clipping region As my JDK docs say, this may * break with Java 2D. * * @return Shape of the clipping region */ @Override public Shape getClip() { return null; } /** * Returns the Rectangle that fits the current clipping region * * @return the Rectangle that fits the current clipping region */ @Override public Rectangle getClipBounds() { return clipRectangle; } //============ Color operations ======================= /** * Returns the current pen Colour * * @return the current pen Colour */ @Override public Color getColor() { return (paint instanceof Color) ? (Color) paint : Color.black; } /** * @see Graphics2D#getComposite() */ @Override public Composite getComposite() { return composite; } /** * @see Graphics2D#getDeviceConfiguration() */ @Override public GraphicsConfiguration getDeviceConfiguration() { return dg2.getDeviceConfiguration(); } /** * Return's the current font. * * @return the current font. */ @Override public Font getFont() { if (font == null) { setFont(new Font("SansSerif", Font.PLAIN, 12)); } return font; } /** * Returns the FontMetrics for a font. *

* This doesn't work correctly. Perhaps having some way of mapping the base * 14 fonts to our own FontMetrics implementation? * * @param font The java.awt.Font to return the metrics for * @return FontMetrics for a font */ @Override public FontMetrics getFontMetrics(Font font) { Frame dummy = new Frame(); dummy.addNotify(); Image image = dummy.createImage(100, 100); if (image == null) { System.err.println("getFontMetrics: image is null"); } Graphics graphics = image.getGraphics(); return graphics.getFontMetrics(font); } /** * @see Graphics2D#getFontRenderContext() */ @Override public FontRenderContext getFontRenderContext() { boolean antialias = RenderingHints.VALUE_TEXT_ANTIALIAS_ON.equals(getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING)); boolean fractions = RenderingHints.VALUE_FRACTIONALMETRICS_ON.equals(getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS)); return new FontRenderContext(new AffineTransform(), antialias, fractions); } /** * Returns the associated PDFPage for this graphic * * @return the associated PDFPage for this graphic */ public PDFPage getPage() { return page; } /** * Returns the current pen Colour * * @return the current pen Colour */ @Override public Paint getPaint() { return paint; } /** * @param arg0 a key * @return the rendering hint */ @Override public Object getRenderingHint(Key arg0) { return rhints.get(arg0); } /** * @see Graphics2D#getRenderingHints() */ @Override public RenderingHints getRenderingHints() { return rhints; } /** * @see Graphics2D#getStroke() */ @Override public Stroke getStroke() { return stroke; } /** * @see Graphics2D#getTransform() */ @Override public AffineTransform getTransform() { return new AffineTransform(transform); } /** * Returns the PrintWriter handling the underlying stream * * @return the PrintWriter handling the underlying stream */ public RawPrintWriter getWriter() { return pw; } /** * @see Graphics2D#hit(Rectangle, Shape, boolean) */ @Override public boolean hit(Rectangle rect, Shape s, boolean onStroke) { if (onStroke) { s = stroke.createStrokedShape(s); } Area area = new Area(s); if (clip != null) { area.intersect(clip); } return area.intersects(rect.x, rect.y, rect.width, rect.height); } /** * This initialises the stream by saving the current graphics state, and * setting up the default line width (for us). * * It also sets up the instance ready for graphic operations and any * optimisations. * *

* For child instances, the stream is already open, so this should keep * things happy. */ private void init() { PageFormat pf = page.getPageFormat(); // save graphics state (restored by dispose) if (child) { pw.print("q "); } // now initialise the instance //setColor(Color.black); paint = Color.black; // possible: if parent.color is not black, then force black? // must check to see what AWT does? // Original User Space Transform (identity) // Transform from Java Space to PDF Space pTransform = new AffineTransform(); pTransform.translate(0, pf.getHeight()); pTransform.scale(1d, -1d); // Combined Transform User->Java->PDF setNewTranform(new AffineTransform()); // Set the line width setStroke(DEF_STROKE); } /** * This is called by PDFPage when creating a Graphcis instance. * * @param page The PDFPage to draw onto. */ protected void init(PDFPage page) { this.page = page; // We are the parent instance child = false; // Now create a stream to store the graphics in PDFStream stream = new PDFStream(); // To view detail in uncompressesd format comment out the next line //stream.setDeflate(true); page.getPDFDocument().add(stream); page.add(stream); pw = new RawPrintWriter(stream.getOutputStream()); // initially, we are limited to the page size clipRectangle = page.getImageableArea(); // finally initialise the stream init(); } /** * This method is used internally by create() and by the PDFJob class * * @param page PDFPage to draw into * @param pw PrintWriter to use */ protected void init(PDFPage page, RawPrintWriter pw) { this.page = page; this.pw = pw; // In this case, we didn't create the stream (our parent did) // so child is true (see dispose) child = true; // finally initialise the stream init(); } /** * This adds a line segment to the current path * * @param x coordinate * @param y coordinate */ public void lineto(double x, double y) { newPath(); // no optimisation here as it may introduce errors on decimal coordinates. pw.print(cxy(x, y) + "l "); lx = (float) x; ly = (float) y; } /** * This adds a line segment to the current path * * @param x coordinate * @param y coordinate */ public void lineto(int x, int y) { newPath(); if (lx != x && ly != y) { pw.print(cxy(x, y) + "l "); } lx = x; ly = y; } /** * This moves the current drawing point. * * @param x coordinate * @param y coordinate */ public void moveto(double x, double y) { newPath(); // no optimisation here as it may introduce errors on decimal coordinates. pw.print(cxy(x, y) + "m "); lx = (float) x; ly = (float) y; } /** * This moves the current drawing point. * * @param x coordinate * @param y coordinate */ public void moveto(int x, int y) { newPath(); if (lx != x || ly != y) { pw.print(cxy(x, y) + "m "); } lx = x; ly = y; } /** * Functions that draw lines should start by calling this. It starts a new * path unless inStroke is set, in that case it uses the existing path */ void newPath() { if (inText) { closeBlock(); } if (!inStroke) { if (pre_np != null) { pw.print(pre_np); // this is the prefix set by setOrientation() pre_np = null; } pw.print("n "); } inText = false; inStroke = true; // an unlikely coordinate to fool the moveto() optimizer lx = ly = -9999; } /** *

* Functions that draw text should start by calling this. It starts a text * block (accounting for media orientation) unless we are already in a Text * block.

* *

* It also handles if the font has been changed since the current text block * was started, so your function will be current.

* * @param x x coordinate in java space * @param y y coordinate in java space */ void newTextBlock(float x, float y) { // close the current path if there is one if (inStroke) { closeBlock(); } // create the text block if one is not current. If we are, the newFont // condition at the end catches font changes if (!inText) { // This ensures that there is a font available getFont(); pw.print("q BT "); tx = ty = 0; AffineTransform tm = new AffineTransform(pTransform); pw.println("" + df.format(tm.getScaleX()) + " " + "" + df.format(tm.getShearY()) + " " + "" + df.format(tm.getShearX()) + " " + "" + df.format(tm.getScaleY()) + " " + "" + df.format(tm.getTranslateX()) + " " + "" + df.format(tm.getTranslateY()) + " Tm" ); // produce the text matrix for the media // switch(mediaRot) { // case PageFormat.PORTRAIT: // Portrait // //pw.println("1 0 0 1 0 0 Tm"); // break; // // case PageFormat.LANDSCAPE: // Landscape // pw.println("0 1 -1 0 0 0 Tm"); // rotate // break; // // case 180: // Inverted Portrait // pw.println("1 0 0 -1 0 0 Tm"); // break; // // case PageFormat.REVERSE_LANDSCAPE: // Seascape // pw.println("0 -1 1 0 0 0 Tm"); // rotate // break; // } // move the text cursor by an absolute amount pw.print(txy(x, y) + "Td "); } else { // move the text cursor by a relative amount pw.print(twh(x, y, tx, ty) + "Td "); //pw.print(txy(x,y)+"Td "); } // preserve the coordinates for the next time tx = x; ty = y; if (newFont || !inText) { pw.print(pdffont.getName() + " " + font.getSize() + " Tf "); } // later add colour changes here (if required) inStroke = newFont = false; inText = true; } /** * This is used to add a polygon to the current path. Used by drawPolygon(), * drawPolyline() and fillPolygon() etal * * @param xp Array of x coordinates * @param yp Array of y coordinates * @param np number of points in polygon * @see #drawPolygon * @see #drawPolyline * @see #fillPolygon */ public void polygon(int[] xp, int[] yp, int np) { // newPath() not needed here as moveto does it ;-) moveto(xp[0], yp[0]); for (int i = 1; i < np; i++) { lineto(xp[i], yp[i]); } } /** * @see Graphics2D#rotate(double) */ @Override public void rotate(double theta) { AffineTransform newTransform = new AffineTransform(transform); newTransform.rotate(theta); setNewTranform(newTransform); } /** * @see Graphics2D#rotate(double, double, double) */ @Override public void rotate(double theta, double x, double y) { AffineTransform newTransform = new AffineTransform(transform); newTransform.rotate(theta, x, y); setNewTranform(newTransform); } /** * @see Graphics2D#scale(double, double) */ @Override public void scale(double sx, double sy) { AffineTransform newTransform = new AffineTransform(transform); newTransform.scale(sx, sy); setNewTranform(newTransform); } /** * @see Graphics2D#setBackground(Color) */ @Override public void setBackground(Color color) { background = color; } /** * Clips to a set of coordinates * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void setClip(int x, int y, int w, int h) { /*clipRectangle = new Rectangle(x, y, w, h); closeBlock(); // finish off any existing paths drawRect(x, y, w, h); closeBlock("W n"); // clip to current path*/ setClip(new Rectangle(x, y, w, h)); } /** * As my JDK docs say, this may break with Java 2D. *

* Sets the clipping region to that of a Shape. * * @param s Shape to clip to. */ @Override public void setClip(Shape s) { closeBlock(); if (clip != null) { restoreState(); transform = clipTransform; } if (s == null) { clip = null; return; } clipTransform = transform; clip = new Area(s); clipRectangle = s.getBounds(); saveState(); followPath(s, CLIP); pw.println("n"); //setClip(r.x, r.y, r.width, r.height); } /** * Sets the color for drawing * * @param c Color to use */ @Override public void setColor(Color c) { setPaint(c); } /** * @see Graphics2D#setComposite(Composite) */ @Override public void setComposite(Composite comp) { this.composite = comp; } /** * This extension sets the line width to the default of 1mm which is what * Java uses when drawing to a PrintJob. */ public void setDefaultLineWidth() { closeBlock(); // draw any path before we change the line width pw.println("1 w"); } /** * This sets the font. * * @param f java.awt.Font to set to. */ @Override public void setFont(Font f) { // optimize: Save some space if the font is already the current one. if (font != f) { font = f; pdffont = page.getFont("/Type1", f.getName(), f.getStyle()); // mark the font as changed newFont = true; } } public void setExistingTtfFont(Font f) { if (font != f) { font = f; pdffont = page.getFont("/TrueType", f.getName(), f.getStyle()); // mark the font as changed newFont = true; } } public void setTtfFont(Font f, File file) throws IOException { if (font != f) { font = f; pdffont = page.getEmbeddedFont(f.getName(), f.getStyle(), file); // mark the font as changed newFont = true; } } private void setLineCap(int cap) { int lineCap = 0; switch (cap) { case BasicStroke.JOIN_MITER: lineCap = 0; break; case BasicStroke.JOIN_ROUND: lineCap = 1; break; case BasicStroke.JOIN_BEVEL: lineCap = 2; break; } if (this.lineCap != lineCap) { closeBlock(); // draw any path before we change the line width this.lineCap = lineCap; pw.println("" + lineCap + " J"); } } private void setLineJoin(int join) { int lineJoin = 0; switch (join) { case BasicStroke.JOIN_MITER: lineJoin = 0; break; case BasicStroke.JOIN_ROUND: lineJoin = 1; break; case BasicStroke.JOIN_BEVEL: lineJoin = 2; break; } if (this.lineJoin != lineJoin) { closeBlock(); // draw any path before we change the line width this.lineJoin = lineJoin; pw.println("" + lineJoin + " j"); } } /** * This extension allows the width of the drawn line to be set * * @param width Line width in pdf graphic units (points) */ public void setLineWidth(float width) { if (width != this.lineWidth) { closeBlock(); // draw any path before we change the line width this.lineWidth = width; pw.println("" + width + " w"); } } private void setMiterLimit(float limit) { if (limit != this.miterLimit) { closeBlock(); // draw any path before we change the line width this.miterLimit = limit; pw.println("" + limit + " M"); } } private void initAlpha(int alpha) { if (currentAlpha != alpha || blendMode != null) { String gsId = "/GSAlpha" + alpha; currentAlpha = alpha; if (!usedAlphas.contains(alpha)) { page.addExtGStateResource(gsId + " <>"); usedAlphas.add(currentAlpha); } pw.println(gsId + " gs"); } } public void setBlendMode(String mode) { if (currentAlpha < 0) { currentAlpha = 255; } String gsName = "/GSBlend" + mode + "Alpha" + currentAlpha; if (!gsBlendModes.contains(gsName)) { page.addExtGStateResource(gsName + " <>"); } pw.println(gsName + " gs"); this.blendMode = mode; } /** * Sets the paint for drawing * * @param paint Paint to use */ @Override public void setPaint(Paint paint) { this.paint = paint; this.shading = null; this.pattern = null; this.paintTransform = null; if (paint instanceof Color) { Color c = (Color) paint; double r = ((double) c.getRed()) / 255.0; double g = ((double) c.getGreen()) / 255.0; double b = ((double) c.getBlue()) / 255.0; closeBlock(); // This ensures any paths are drawn in the previous initAlpha(c.getAlpha()); // colours pw.println("" + r + " " + g + " " + b + " rg " + r + " " + g + " " + b + " RG"); } if (paint instanceof MultipleGradientPaint) { closeBlock(); if ((paint instanceof RadialGradientPaint) || ((paint instanceof LinearGradientPaint) && (((LinearGradientPaint) paint).getCycleMethod() == MultipleGradientPaint.CycleMethod.NO_CYCLE))) { shading = "gradient"; } else { pattern = "gradient"; } } if (paint instanceof TexturePaint) { closeBlock(); pattern = "texture"; } } private boolean useFunctionShading(MultipleGradientPaint fgrad) { return ((fgrad instanceof RadialGradientPaint) && fgrad.getCycleMethod() != MultipleGradientPaint.CycleMethod.NO_CYCLE); } private Color[] convertColorSpace(Color[] colors, MultipleGradientPaint.ColorSpaceType colorSpaceType) { /*if (colorSpaceType == MultipleGradientPaint.ColorSpaceType.LINEAR_RGB) { Color[] ret = new Color[colors.length]; for (int i = 0; i < colors.length; i++) { int argb = colors[i].getRGB(); int a = argb >>> 24; int r = srgbToLinear[(argb >> 16) & 0xff]; int g = srgbToLinear[(argb >> 8) & 0xff]; int b = srgbToLinear[(argb) & 0xff]; ret[i] = new Color(r, g, b, a); } return ret; }*/ //return colors; return colors; } private String generateRadialFunctionBody(RadialGradientPaint radGrad, boolean alpha) { double a = ((radGrad.getCenterPoint().getX() - radGrad.getFocusPoint().getX()) * (radGrad.getCenterPoint().getX() - radGrad.getFocusPoint().getX()) + (radGrad.getCenterPoint().getY() - radGrad.getFocusPoint().getY()) * (radGrad.getCenterPoint().getY() - radGrad.getFocusPoint().getY()) - radGrad.getRadius() * radGrad.getRadius()); String functionBody = "{\n" + matDf.format(radGrad.getFocusPoint().getX()) + " 2 index sub\n" + matDf.format(radGrad.getCenterPoint().getX() - radGrad.getFocusPoint().getX()) + " mul 2 mul\n" //stack size: 3 + matDf.format(radGrad.getFocusPoint().getY()) + " 2 index sub\n" + matDf.format(radGrad.getCenterPoint().getY() - radGrad.getFocusPoint().getY()) + " mul 2 mul\n" + "add\n" //b, stack size: 3 + matDf.format(radGrad.getFocusPoint().getX()) + " 3 index sub\n" + "dup mul\n" + matDf.format(radGrad.getFocusPoint().getY()) + " 3 index sub\n" + "dup mul\n" + "add\n" //c, stack size: 4 + "1 index dup mul 4 " + matDf.format(a) + " mul 2 index mul sub\n" //D, stack size: 4 + "0 index 0 lt\n" + "{\n" + "1\n" + "}" + "{" + "0 index 0 gt\n" + "{\n" + "2 index neg 1 index sqrt add 2 " + matDf.format(a) + " mul div\n" // x1, stack size: 5 + "3 index neg 2 index sqrt sub 2 " + matDf.format(a) + " mul div\n" // x2, stack size: 6 + "0 index 2 index gt{0 index} {1 index} ifelse\n" + "exch pop exch pop\n" //x, stack size 5 + "}" + "{\n" + "2 index neg 2 " + matDf.format(a) + " mul div\n" // x, stack size 5 + "} ifelse\n" + "} ifelse\n" + "exch pop exch pop exch pop exch pop exch pop\n"; //remove index0,1,2,3,4 if (radGrad.getCycleMethod() == MultipleGradientPaint.CycleMethod.REFLECT) { functionBody += "dup\n"; } if (radGrad.getCycleMethod() == MultipleGradientPaint.CycleMethod.NO_CYCLE) { functionBody += "dup 1 gt {pop 1} if\n"; } else { functionBody += "dup 1 gt {dup floor sub} if\n"; } if (radGrad.getCycleMethod() == MultipleGradientPaint.CycleMethod.REFLECT) { functionBody += "exch floor 2 mod 1 eq {" + "neg 1 add" + "}\n" + "if\n"; } int num = radGrad.getFractions().length; Color[] rcolors = convertColorSpace(radGrad.getColors(), radGrad.getColorSpace()); for (int i = 0; i < num - 1; i++) { functionBody += "dup " + radGrad.getFractions()[i] + " lt not 1 index " + radGrad.getFractions()[i + 1] + " gt not and\n{\n" + "0 index " + radGrad.getFractions()[i] + " sub " + (radGrad.getFractions()[i + 1] - radGrad.getFractions()[i]) + " div\n"; if (alpha) { functionBody += "0 index " + ((rcolors[i + 1].getAlpha() - rcolors[i].getAlpha()) / 255.0) + " mul " + (rcolors[i].getAlpha() / 255.0) + " add\n"; functionBody += "dup dup\n"; } else { functionBody += "0 index " + ((rcolors[i + 1].getRed() - rcolors[i].getRed()) / 255.0) + " mul " + (rcolors[i].getRed() / 255.0) + " add\n" + "1 index " + ((rcolors[i + 1].getGreen() - rcolors[i].getGreen()) / 255.0) + " mul " + (rcolors[i].getGreen() / 255.0) + " add\n" + "2 index " + ((rcolors[i + 1].getBlue() - rcolors[i].getBlue()) / 255.0) + " mul " + (rcolors[i].getBlue() / 255.0) + " add\n"; } if (i < num - 2) { functionBody += "}\n{\n"; } } functionBody += "}if\n"; for (int i = 0; i < num - 2; i++) { functionBody += "}ifelse\n"; } functionBody += "}\n"; return functionBody; } private void initGradientPaint(MultipleGradientPaint grad, Shape fillShape) { if ((grad instanceof LinearGradientPaint) && (((LinearGradientPaint) grad).getCycleMethod() == MultipleGradientPaint.CycleMethod.REFLECT)) { LinearGradientPaint linGrad = (LinearGradientPaint) grad; Point2D start = linGrad.getStartPoint(); Point2D end = linGrad.getEndPoint(); double deltaX = end.getX() - start.getX(); double deltaY = end.getY() - start.getY(); Point2D newEnd = new Point2D.Double(end.getX() + deltaX, end.getY() + deltaY); int colorCount = grad.getFractions().length; float fractions2[] = new float[colorCount * 2 - 1]; Color colors2[] = new Color[colorCount * 2 - 1]; float fractionsrev[] = new float[linGrad.getFractions().length]; Color colorsrev[] = new Color[linGrad.getColors().length]; for (int i = 0; i < fractionsrev.length; i++) { colorsrev[i] = linGrad.getColors()[i]; fractionsrev[i] = linGrad.getFractions()[i]; } for (int i = 0; i < colorCount; i++) { colors2[i] = colorsrev[i]; fractions2[i] = fractionsrev[i] / 2; } for (int i = 0; i < colorCount; i++) { colors2[colors2.length - i - 1] = colorsrev[i]; fractions2[colors2.length - i - 1] = 1f - fractionsrev[i] / 2; } LinearGradientPaint linGrad2 = new LinearGradientPaint(start, newEnd, fractions2, colors2, MultipleGradientPaint.CycleMethod.REPEAT); grad = linGrad2; } List functions2Refs = new ArrayList<>(); Color[] colors = convertColorSpace(grad.getColors(), grad.getColorSpace()); for (int i = 1; i < grad.getColors().length; i++) { final Color color1 = colors[i - 1]; final Color color2 = colors[i]; PDFObject function2 = new PDFObject(null) { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write(("/FunctionType 2 /Domain [0 1] /C0 [" + (((float) color1.getRed()) / 255.0f) + " " + (((float) color1.getGreen()) / 255.0f) + " " + (((float) color1.getBlue()) / 255.0f) + "] /C1 [" + (((float) color2.getRed()) / 255.0f) + " " + (((float) color2.getGreen()) / 255.0f) + " " + (((float) color2.getBlue()) / 255.0f) + "] /N 1\n").getBytes()); writeEnd(os); } }; page.getPDFDocument().add(function2); functions2Refs.add(function2.getSerialID() + " 0 R"); } List functions2AlphaRefs = new ArrayList<>(); Color[] alphaColors = grad.getColors(); for (int i = 1; i < grad.getColors().length; i++) { final Color color1 = alphaColors[i - 1]; final Color color2 = alphaColors[i]; PDFObject function2 = new PDFObject(null) { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write(("/FunctionType 2 /Domain [0 1] /C0 [" + (((float) color1.getAlpha()) / 255.0f) + " " + (((float) color1.getAlpha()) / 255.0f) + " " + (((float) color1.getAlpha()) / 255.0f) + "] /C1 [" + (((float) color2.getAlpha()) / 255.0f) + " " + (((float) color2.getAlpha()) / 255.0f) + " " + (((float) color2.getAlpha()) / 255.0f) + "] /N 1\n").getBytes()); writeEnd(os); } }; page.getPDFDocument().add(function2); functions2AlphaRefs.add(function2.getSerialID() + " 0 R"); } final MultipleGradientPaint fgrad = grad; PDFObject function3 = new PDFGradientFunction3(fgrad, functions2Refs); page.getPDFDocument().add(function3); PDFObject function3Alpha = new PDFGradientFunction3(fgrad, functions2AlphaRefs); page.getPDFDocument().add(function3Alpha); double glen = 0; double divisor = 1; double maxlen = 256; if ((fgrad instanceof LinearGradientPaint) && (fgrad.getCycleMethod() != MultipleGradientPaint.CycleMethod.NO_CYCLE)) { LinearGradientPaint linGrad = (LinearGradientPaint) fgrad; Point2D startPoint = new Point2D.Double(); Point2D endPoint = new Point2D.Double(); startPoint = linGrad.getStartPoint(); endPoint = linGrad.getEndPoint(); double deltaX = endPoint.getX() - startPoint.getX(); double deltaY = endPoint.getY() - startPoint.getY(); glen = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (glen > maxlen) { divisor = glen / maxlen; glen = maxlen; } } final double flen = glen; PDFStream radialFunction; PDFStream radialAlphaFunction; if (useFunctionShading(fgrad)) { RadialGradientPaint radGrad = (RadialGradientPaint) fgrad; radialFunction = new PDFStream() { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/FunctionType 4\n".getBytes()); //pdf reference, page 168 os.write("/Domain [-1000000 1000000 -1000000 1000000]\n".getBytes()); os.write("/Range [0 1 0 1 0 1]\n".getBytes()); //3 - R,G,B writeStream(os); } }; radialAlphaFunction = new PDFStream() { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/FunctionType 4\n".getBytes()); //pdf reference, page 168 os.write("/Domain [-1000000 1000000 -1000000 1000000]\n".getBytes()); os.write("/Range [0 1 0 1 0 1]\n".getBytes()); //3 - R,G,B writeStream(os); } }; //PDF reference, page 176 /*double b = 2 * (focalX - x) * (centerX - focalX) + 2 * (focalY - y) * (centerY - focalY); double c = (focalX - x) * (focalX - x) + (focalY - y) * (focalY - y); double D = b * b - 4 * a * c;*/ //(-b + Math.sqrt(D)) / (2 * a) //D = b * b - 4 * a * c; String functionBody = generateRadialFunctionBody(radGrad, false); OutputStream funOs = radialFunction.getOutputStream(); try { funOs.write(functionBody.getBytes()); } catch (IOException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } String alphaFunctionBody = generateRadialFunctionBody(radGrad, true); funOs = radialAlphaFunction.getOutputStream(); try { funOs.write(alphaFunctionBody.getBytes()); } catch (IOException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } page.getPDFDocument().add(radialFunction); page.getPDFDocument().add(radialAlphaFunction); } else { radialFunction = null; radialAlphaFunction = null; } PDFObject shadingObj = new PdfGradientShading(fgrad, flen, useFunctionShading(fgrad), function3, radialFunction); page.getPDFDocument().add(shadingObj); PDFObject shadingAlphaObj = new PdfGradientShading(fgrad, flen, useFunctionShading(fgrad), function3Alpha, radialAlphaFunction); page.getPDFDocument().add(shadingAlphaObj); shadingCount++; final int fCurrentShadingCount = shadingCount; PDFStream alphaObject = new PDFStream() { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/Group << /CS /DeviceGray /S /Transparency >>\n".getBytes()); os.write("/Type /XObject\n".getBytes()); os.write("/Resources <<\n".getBytes()); os.write("/Shading <<".getBytes()); os.write(("/ShA" + fCurrentShadingCount + " " + shadingAlphaObj.getSerialID() + " 0 R").getBytes()); os.write(">>\n".getBytes()); //shading os.write(">>\n".getBytes()); //resources os.write("/Subtype /Form\n".getBytes()); os.write("/BBox [-1000000 -1000000 2000000 2000000]\n".getBytes()); //fixme writeStream(os); } }; OutputStream alphaOs = alphaObject.getOutputStream(); try { alphaOs.write(("/ShA" + fCurrentShadingCount + " sh\n").getBytes()); } catch (IOException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } page.getPDFDocument().add(alphaObject); String alphaExtGState = "/GradAlpha" + fCurrentShadingCount + " <<" + "/SMask <<" + "/Type /Mask\n" + "/S /Luminosity\n" + "/G " + alphaObject.getSerialID() + " 0 R" + ">>" + ">>"; if ((grad instanceof LinearGradientPaint) && ((LinearGradientPaint) grad).getCycleMethod() != MultipleGradientPaint.CycleMethod.NO_CYCLE) { LinearGradientPaint linGrad = (LinearGradientPaint) grad; Point2D startPoint = linGrad.getStartPoint(); Point2D endPoint = linGrad.getEndPoint(); Point2D startPointTrans = new Point2D.Double(); Point2D endPointTrans = new Point2D.Double(); transform.transform(linGrad.getStartPoint(), startPointTrans); transform.transform(linGrad.getEndPoint(), endPointTrans); double deltaX = endPoint.getX() - startPoint.getX(); double deltaY = endPoint.getY() - startPoint.getY(); double tana = deltaX / deltaY; double alfa = Math.atan(tana); AffineTransform m = new AffineTransform(); m.concatenate(pTransform); m.concatenate(transform); m.concatenate(AffineTransform.getTranslateInstance(startPoint.getX(), endPoint.getY())); m.concatenate(AffineTransform.getScaleInstance(divisor, divisor)); m.concatenate(AffineTransform.getRotateInstance(-alfa)); String matrixStr = "" + matDf.format(m.getScaleX()) + " " + matDf.format(m.getShearY()) + " " + matDf.format(m.getShearX()) + " " + matDf.format(m.getScaleY()) + " " + matDf.format(m.getTranslateX()) + " " + matDf.format(m.getTranslateY()); PDFStream innerPattern = new PDFStream("/Pattern") { @Override public void write(OutputStream os) throws IOException { writeStart(os); double w; double h; w = 1; h = flen; os.write("/PatternType 1\n".getBytes()); os.write("/PaintType 1\n".getBytes()); os.write("/TilingType 2\n".getBytes()); os.write(("/BBox [0 0 " + w + " " + h + "]\n").getBytes()); os.write(("/XStep " + w + "\n").getBytes()); os.write(("/YStep " + h + "\n").getBytes()); os.write(("/Resources << " + "/Shading << /Shin" + fCurrentShadingCount + " " + shadingObj.getSerialID() + " 0 R >>" + "/ExtGState <<" + alphaExtGState + ">>" + ">>\n").getBytes()); os.write(("/Matrix [" + matrixStr + "]\n").getBytes()); writeStream(os); } }; OutputStream patOs = innerPattern.getOutputStream(); try { patOs.write(("/GradAlpha" + fCurrentShadingCount + " gs").getBytes()); patOs.write(("/Shin" + shadingCount + " sh").getBytes()); } catch (IOException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } page.getPDFDocument().add(innerPattern); page.addPatternResource("/p" + shadingCount + " " + innerPattern.getSerialID() + " 0 R"); this.pattern = "/p" + shadingCount; return; } currentAlpha = -1; page.addExtGStateResource(alphaExtGState); pw.println("/GradAlpha" + fCurrentShadingCount + " gs"); page.addShadingResource("/Sh" + shadingCount + " " + shadingObj.getSerialID() + " 0 R "); this.shading = "/Sh" + shadingCount; } private void initTexturePaint(TexturePaint texturePaint) { BufferedImage img = texturePaint.getImage(); PDFMask mask = new PDFMask(img); page.getPDFDocument().add(mask); Rectangle2D anchorRect = texturePaint.getAnchorRect(); final double w = anchorRect.getWidth(); final double h = anchorRect.getHeight(); PDFImage image = new PDFImage(img, 0, 0, img.getWidth(), img.getHeight(), new ImageObserver() { @Override public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { return true; } }, "" + mask.getSerialID() + " 0 R"); // The image needs to be registered in several places page.getPDFDocument().setImageName(image); page.getPDFDocument().add(image); usedImages.put(img, image); AffineTransform m = new AffineTransform(); AffineTransform ptt = new AffineTransform(); ptt.concatenate(pTransform); ptt.concatenate(transform); m.concatenate(ptt); String matrixStr = "" + matDf.format(m.getScaleX()) + " " + matDf.format(m.getShearY()) + " " + matDf.format(m.getShearX()) + " " + matDf.format(m.getScaleY()) + " " + matDf.format(m.getTranslateX()) + " " + matDf.format(m.getTranslateY()); PDFStream innerPattern = new PDFStream("/Pattern") { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/PatternType 1\n".getBytes()); os.write("/PaintType 1\n".getBytes()); os.write("/TilingType 2\n".getBytes()); os.write(("/BBox [0 0 " + matDf.format(w) + " " + matDf.format(h) + "]\n").getBytes()); os.write(("/XStep " + matDf.format(w) + "\n").getBytes()); os.write(("/YStep " + matDf.format(h) + "\n").getBytes()); os.write(("/Resources << ").getBytes()); os.write("/XObject << ".getBytes()); os.write((image.getName() + " " + image.getSerialID() + " 0 R").getBytes()); os.write(" >> ".getBytes()); os.write((">>\n").getBytes()); //"1 0 0 1 0 0" os.write(("/Matrix [" + matrixStr + "]\n").getBytes()); writeStream(os); } }; OutputStream patOs = innerPattern.getOutputStream(); PrintWriter patwriter = new PrintWriter(patOs); AffineTransform transformToSet; transformToSet = new AffineTransform(w, 0, 0, -h, 0 - anchorRect.getX(), h - anchorRect.getY()); patwriter.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); transformToSet = new AffineTransform(w, 0, 0, -h, w - anchorRect.getX(), h - anchorRect.getY()); patwriter.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); transformToSet = new AffineTransform(w, 0, 0, -h, 0 - anchorRect.getX(), 2 * h - anchorRect.getY()); patwriter.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); transformToSet = new AffineTransform(w, 0, 0, -h, w - anchorRect.getX(), 2 * h - anchorRect.getY()); patwriter.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); patwriter.flush(); page.getPDFDocument().add(innerPattern); shadingCount++; page.addPatternResource("/p" + shadingCount + " " + innerPattern.getSerialID() + " 0 R"); this.pattern = "/p" + shadingCount; } /** * Not implemented, as this is not supported in the PDF specification. */ @Override public void setPaintMode() { } /** * Sets a rendering hint * * @param arg0 * @param arg1 */ @Override public void setRenderingHint(Key arg0, Object arg1) { if (arg1 != null) { rhints.put(arg0, arg1); } else { rhints.remove(arg0); } } // Add Graphics2D methods. /** * @see Graphics2D#setRenderingHints(Map) */ @Override public void setRenderingHints(Map hints) { rhints.clear(); rhints.putAll(hints); } /** * @see Graphics2D#setStroke(Stroke) */ @Override public void setStroke(Stroke s) { this.stroke = s; if (stroke instanceof BasicStroke) { BasicStroke bs = (BasicStroke) stroke; setLineCap(bs.getEndCap()); setLineJoin(bs.getLineJoin()); setLineWidth(bs.getLineWidth()); setMiterLimit(bs.getMiterLimit()); // TODO: Line dash pattern } } /** * @see Graphics2D#setTransform(AffineTransform) */ @Override public void setTransform(AffineTransform t) { setNewTranform(new AffineTransform(t)); } /** * Not implemented, as this is not supported in the PDF specification. * * @param c1 Color to xor with */ @Override public void setXORMode(Color c1) { } //============ Text operations ======================= /** * @see Graphics2D#shear(double, double) */ @Override public void shear(double shx, double shy) { AffineTransform newTransform = new AffineTransform(transform); newTransform.shear(shx, shy); setNewTranform(newTransform); } /** * @see Graphics2D#transform(AffineTransform) */ @Override public void transform(AffineTransform tx) { AffineTransform newTransform = new AffineTransform(transform); newTransform.concatenate(tx); setNewTranform(newTransform); } /** * @see Graphics2D#translate(double, double) */ @Override public void translate(double tx, double ty) { AffineTransform newTransform = new AffineTransform(transform); newTransform.translate(tx, ty); setNewTranform(newTransform); } /** * @see Graphics#translate(int, int) */ @Override public void translate(int x, int y) { translate((double) x, (double) y); } /** * Converts the Java space coordinates into pdf text space. * * @param x coordinate * @param y coordinate * @param tx coordinate * @param ty coordinate * @return String containing the coordinates in PDF text space */ private String twh(float x, float y, float tx, float ty) { float nx = x, ny = y; float ntx = tx, nty = ty; nx = (float) (x - tx); ny = (float) (y - ty); return "" + df.format(nx) + " " + df.format(ny) + " "; } /** * Converts the Java space coordinates into pdf text space. * * @param x coordinate * @param y coordinate * @return String containing the coordinates in PDF text space */ private String txy(float x, float y) { Point2D ptSrc = new Point2D.Float(x, y); Point2D ptDst = new Point2D.Float(); pTransform.transform(ptSrc, ptDst); return "" + df.format(ptDst.getX()) + " " + df.format(ptDst.getY()) + " "; } private void setNewTranform(AffineTransform t) { closeBlock(); if (true) { //return; } AffineTransform newTransform = new AffineTransform(t); AffineTransform transformToSet = new AffineTransform(newTransform); if (transform != null) { AffineTransform aInv = new AffineTransform(transform); try { aInv.invert(); } catch (NoninvertibleTransformException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } AffineTransform pInv = new AffineTransform(pTransform); try { pInv.invert(); } catch (NoninvertibleTransformException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } transformToSet = new AffineTransform(); transformToSet.concatenate(aInv); transformToSet.concatenate(pInv); transformToSet.concatenate(pTransform); transformToSet.concatenate(newTransform); } else { transformToSet.preConcatenate(pTransform); } transform = newTransform; pw.println("" + matDf.format(transformToSet.getScaleX()) + " " + "" + matDf.format(transformToSet.getShearY()) + " " + "" + matDf.format(transformToSet.getShearX()) + " " + "" + matDf.format(transformToSet.getScaleY()) + " " + "" + matDf.format(transformToSet.getTranslateX()) + " " + "" + matDf.format(transformToSet.getTranslateY()) + " cm" ); } private void saveState() { pw.println("q"); } private void restoreState() { pw.println("Q"); } } \ No newline at end of file +/* * $Id: PDFGraphics.java,v 1.6 2007/09/22 12:58:40 gil1 Exp $ * * $Date: 2007/09/22 12:58:40 $ * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package gnu.jpdf; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.LinearGradientPaint; import java.awt.MultipleGradientPaint; import java.awt.Paint; import java.awt.Polygon; import java.awt.RadialGradientPaint; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.RenderingHints.Key; import java.awt.Shape; import java.awt.Stroke; import java.awt.TexturePaint; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.awt.image.renderable.RenderableImage; import java.awt.print.PageFormat; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Serializable; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import java.util.logging.Level; import java.util.logging.Logger; /** * This class is our implementation of AWT's Graphics class. It provides a Java * standard way of rendering into a PDF Document's Page. * * @author Peter T Mount, http://www.retep.org.uk/pdf/ * @author Eric Z. Beard, ericzbeard@hotmail.com * @author Gilbert DeLeeuw, gil1@users.sourceforge.net * @version $Revision: 1.6 $, $Date: 2007/09/22 12:58:40 $ * @see gnu.jpdf.PDFGraphics */ public class PDFGraphics extends Graphics2D implements Serializable { /** * One degree in radians */ private static final double degrees_to_radians = Math.PI / 180.0; private static final int FILL = 1; private static final int STROKE = 2; private static final int CLIP = 3; private static final AffineTransform IDENTITY = new AffineTransform(); private static final Stroke DEF_STROKE = new BasicStroke(); /* * NOTE: The original class is the work of Peter T. Mount, who released it * in the uk.org.retep.pdf package. It was modified by Eric Z. Beard as * follows: * The package name was changed to gnu.pdf. * The formatting was changed a little bit. * This used to subclass an abstract class in a different package with * the same name (confusing). Now it's one concrete class. * drawImage() was implemented * It is still licensed under the LGPL. */ // Implementation notes: // // Pages 333-335 of the PDF Reference Manual // // Unless absolutely required, use the moveto, lineto and rectangle // operators to perform those actions. // They contain some extra optimizations // which will reduce the output size by up to half in some cases. // // About fill operators: For correct operation, any fill operation should // start with closeBlock(), which will ensure any previous path is completed, // otherwise you may find the fill will include previous items private static final DecimalFormat df = new DecimalFormat("#.###", new DecimalFormatSymbols(Locale.ENGLISH)); private static final DecimalFormat matDf = new DecimalFormat("0", new DecimalFormatSymbols(Locale.ENGLISH)); static { matDf.setMaximumFractionDigits(340); } //JPEXS: cache for already used images private static Map usedImages = new WeakHashMap(); private Color background; /** * This is true for any Graphics instance that didn't create the stream. * * @see #create */ private boolean child; private Area clip; private AffineTransform clipTransform; /** * This holds the current clipRectangle */ protected Rectangle clipRectangle; private Composite composite; private Graphics2D dg2 = new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB).createGraphics(); /** * This is the current font (in Java format) */ private Font font; /** * Part of the optimizer: When true, we are drawing a path. */ private boolean inStroke; /** * Part of the optimizer: When true, we are within a Text Block. */ private boolean inText; // true if within a Text Block - see newTextBlock() /** * The stroke line cap code; */ private int lineCap = 0; /** * The stroke line join code */ private int lineJoin = 0; /** * The stroke line width */ private float lineWidth = 1.0f; /** * Part of the optimizer: The last known moveto/lineto x coordinate * * @see #moveto * @see #lineto */ private float lx; // last known moveto/lineto coordinates /** * Part of the optimizer: The last known moveto/lineto y coordinate * * @see #moveto * @see #lineto */ private float ly; // last known moveto/lineto coordinates private float miterLimit = 10.0f; /** * Part of the optimizer: When true, the font has changed. */ private boolean newFont; // true if the font changes - see newTextBlock() /** * This is a reference to the PDFPage we are rendering to. */ private PDFPage page; /** * This is the current pen/fill color */ private Paint paint; private AffineTransform paintTransform; /** * This is the current font (in PDF format) */ private PDFFont pdffont; /** * Part of the optimizer: This is written to the stream when the newPath() * is called. np then clears this value. */ private String pre_np; // PDF space transform private AffineTransform pTransform; /** * This is the PrintWriter used to write PDF drawing commands to the Stream */ private RawPrintWriter pw; /** * RenderingHints */ private RenderingHints rhints = new RenderingHints(null); private Stroke stroke; // Start of Graphics2D properties private AffineTransform transform; /** * Part of the optimizer: The last x coordinate when rendering text */ private float tx; // the last coordinate for text rendering /** * Part of the optimizer: The last y coordinate when rendering text */ private float ty; // the last coordinate for text rendering private String shading = null; private String pattern = null; private Set usedAlphas = new HashSet<>(); private Set gsBlendModes = new HashSet<>(); private int currentAlpha = 255; private String blendMode; private int shadingCount = 0; private static int[] srgbToLinear = new int[256]; private static int[] linearToSrgb = new int[256]; static { for (int i = 0; i < 256; i++) { srgbToLinear[i] = convertSRGBtoLinearRGB(i); linearToSrgb[i] = convertLinearRGBtoSRGB(i); } } private static int convertSRGBtoLinearRGB(int color) { float input, output; input = color / 255.0f; if (input <= 0.04045f) { output = input / 12.92f; } else { output = (float) Math.pow((input + 0.055) / 1.055, 2.4); } return Math.round(output * 255.0f); } private static int convertLinearRGBtoSRGB(int color) { float input, output; input = color / 255.0f; if (input <= 0.0031308) { output = input * 12.92f; } else { output = (1.055f * ((float) Math.pow(input, (1.0 / 2.4)))) - 0.055f; } return Math.round(output * 255.0f); } /** * @see Graphics2D#addRenderingHints(Map) */ @Override public void addRenderingHints(Map hints) { rhints.putAll(hints); } /** * This produces an arc by breaking it down into one or more Bezier curves. * It is used internally to implement the drawArc and fillArc methods. * * @param axc X coordinate of arc centre * @param ayc Y coordinate of arc centre * @param width of bounding rectangle * @param height of bounding rectangle * @param ang1 Start angle * @param ang2 End angle * @param clockwise true to draw clockwise, false anti-clockwise */ public void arc(double axc, double ayc, double width, double height, double ang1, double ang2, boolean clockwise) { double adiff; double x0, y0; double x3r, y3r; boolean first = true; // may not need this //if( ar < 0 ) { //ang1 += fixed_180; //ang2 += fixed_180; //ar = - ar; //} double ang1r = (ang1 % 360.0) * degrees_to_radians; double sin0 = Math.sin(ang1r); double cos0 = Math.cos(ang1r); x0 = axc + width * cos0; y0 = ayc + height * sin0; // NB: !clockwise here as Java Space is inverted to User Space if (!clockwise) { // Quadrant reduction while (ang1 < ang2) { ang2 -= 360.0; } while ((adiff = ang2 - ang1) < -90.0) { double w = sin0; sin0 = -cos0; cos0 = w; x3r = axc + width * cos0; y3r = ayc + height * sin0; arc_add(first, width, height, x0, y0, x3r, y3r, (x0 + width * cos0), (y0 + height * sin0) ); x0 = x3r; y0 = y3r; ang1 -= 90.0; first = false; } } else { // Quadrant reduction while (ang2 < ang1) { ang2 += 360.0; } while ((adiff = ang2 - ang1) > 90.0) { double w = cos0; cos0 = -sin0; sin0 = w; x3r = axc + width * cos0; y3r = ayc + height * sin0; arc_add(first, width, height, x0, y0, x3r, y3r, (x0 + width * cos0), (y0 + height * sin0) ); x0 = x3r; y0 = y3r; ang1 += 90.0; first = false; } } // Compute the intersection of the tangents. // We know that -fixed_90 <= adiff <= fixed_90. double trad = Math.tan(adiff * (degrees_to_radians / 2)); double ang2r = ang2 * degrees_to_radians; double xt = x0 - trad * width * sin0; double yt = y0 + trad * height * cos0; arc_add(first, width, height, x0, y0, (axc + width * Math.cos(ang2r)), (ayc + height * Math.sin(ang2r)), xt, yt); } /** * Used by the arc method to actually add an arc to the path Important: We * write directly to the stream here, because this method operates in User * space, rather than Java space. * * @param first true if the first arc * @param w width * @param h height * @param x0 coordinate * @param y0 coordinate * @param x3 coordinate * @param y3 coordinate * @param xt coordinate * @param yt coordinate */ private void arc_add(boolean first, double w, double h, double x0, double y0, double x3, double y3, double xt, double yt) { double dx = xt - x0, dy = yt - y0; double dist = dx * dx + dy * dy; double w2 = w * w, h2 = h * h; double r2 = w2 + h2; double fw = 0.0, fh = 0.0; if (dist < (r2 * 1.0e8)) { // JM fw = (w2 != 0.0) ? ((4.0 / 3.0) / (1 + Math.sqrt(1 + dist / w2))) : 0.0; fh = (h2 != 0.0) ? ((4.0 / 3.0) / (1 + Math.sqrt(1 + dist / h2))) : 0.0; } // The path must have a starting point if (first) { moveto(x0, y0); } double x = x0 + ((xt - x0) * fw); double y = y0 + ((yt - y0) * fh); x0 = x3 + ((xt - x3) * fw); y0 = y3 + ((yt - y3) * fh); // Finally the actual curve. curveto(x, y, x0, y0, x3, y3); } /** * This simply draws a White Rectangle to clear the area * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void clearRect(int x, int y, int w, int h) { closeBlock(); pw.print("q 1 1 1 RG ");// save state, set colour to White drawRect(x, y, w, h); closeBlock("B Q"); // close fill & stroke, then restore state } /** * @see Graphics2D#clip(Shape) */ @Override public void clip(Shape s) { if (s == null) { setClip(null); return; } Area newClip; if (clip == null) { newClip = new Area(s); } else { newClip = (Area) clip.clone(); newClip.intersect(new Area(s)); } setClip(newClip); } /** * This extra method allows PDF users to clip to a Polygon. * *

* In theory you could use setClip(), except that java.awt.Graphics only * supports Rectangle with that method, so we will have an extra method. * * @param p Polygon to clip to */ public void clipPolygon(Polygon p) { closeBlock(); // finish off any existing path polygon(p.xpoints, p.ypoints, p.npoints); closeBlock("W"); // clip to current path clipRectangle = p.getBounds(); } /** * Clips to a set of coordinates * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void clipRect(int x, int y, int w, int h) { setClip(x, y, w, h); } /** * All functions should call this to close any existing optimized blocks. */ void closeBlock() { closeBlock("S"); } /** *

* This is used by code that use the path in any way other than Stroke (like * Fill, close path & Stroke etc). Usually this is used internally.

* * @param code PDF operators that will close the path */ void closeBlock(String code) { if (inText) { pw.println("ET Q"); // setOrientation(); // fixes Orientation matrix } if (inStroke) { pw.println(code); } inStroke = inText = false; } /** * This is unsupported - how do you do this with Vector graphics? * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param dx coordinate * @param dy coordinate */ @Override public void copyArea(int x, int y, int w, int h, int dx, int dy) { // Hmm... Probably need to keep track of everything // that has been drawn so far to get the contents of an area } //============ Line operations ======================= /** *

* This returns a child instance of this Graphics object. As with AWT, the * affects of using the parent instance while the child exists, is not * determined.

* *

* Once complete, the child should be released with it's dispose() method * which will restore the graphics state to it's parent.

* * @return Graphics object to render onto the page */ @Override public Graphics create() { closeBlock(); PDFGraphics g = createGraphic(page, pw); // The new instance inherits a few items g.clipRectangle = new Rectangle(clipRectangle); return (Graphics) g; } // end create() /** * This method creates a new instance of the class based on the page and a * print writer. * * @param page the page to attach to * @param pw the PrintWriter to attach to. */ protected PDFGraphics createGraphic(PDFPage page, RawPrintWriter pw) { PDFGraphics g = new PDFGraphics(); g.init(page, pw); return g; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x2,y2) using the current point and (x1,y1) as the * Bezier control points. *

* The new current point is (x2,y2) * * @param x1 Second control point * @param y1 Second control point * @param x2 Destination point * @param y2 Destination point */ public void curveto(double x1, double y1, double x2, double y2) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + "v"); lx = (float) x2; ly = (float) y2; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x3,y3) using (x1,y1) and (x2,y2) as the Bezier * control points. *

* The new current point is (x3,y3) * * @param x1 First control point * @param y1 First control point * @param x2 Second control point * @param y2 Second control point * @param x3 Destination point * @param y3 Destination point */ public void curveto(double x1, double y1, double x2, double y2, double x3, double y3) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + cxy(x3, y3) + "c"); lx = (float) x3; ly = (float) y3; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x2,y2) using the current point and (x1,y1) as the * Bezier control points. *

* The new current point is (x2,y2) * * @param x1 Second control point * @param y1 Second control point * @param x2 Destination point * @param y2 Destination point */ public void curveto(int x1, int y1, int x2, int y2) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + "v"); lx = x2; ly = y2; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x3,y3) using (x1,y1) and (x2,y2) as the Bezier * control points. *

* The new current point is (x3,y3) * * @param x1 First control point * @param y1 First control point * @param x2 Second control point * @param y2 Second control point * @param x3 Destination point * @param y3 Destination point */ public void curveto(int x1, int y1, int x2, int y2, int x3, int y3) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + cxy(x3, y3) + "c"); lx = x3; ly = y3; } /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x2,y2) using (x1,y1) and the end point as the * Bezier control points. *

* The new current point is (x2,y2) * * @param x1 Second control point * @param y1 Second control point * @param x2 Destination point * @param y2 Destination point */ public void curveto2(double x1, double y1, double x2, double y2) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + "y"); lx = (float) x2; ly = (float) y2; } // Arcs are horrible and complex. They are at the end of the // file, because they are the largest. This is because, unlike // Postscript, PDF doesn't have any arc operators, so we must // implement them by converting into one or more Bezier curves // (which is how Postscript does them internally). /** * This extension appends a Bezier curve to the path. The curve extends from * the current point to (x2,y2) using (x1,y1) and the end point as the * Bezier control points. *

* The new current point is (x2,y2) * * @param x1 Second control point * @param y1 Second control point * @param x2 Destination point * @param y2 Destination point */ public void curveto2(int x1, int y1, int x2, int y2) { newPath(); pw.println(cxy(x1, y1) + cxy(x2, y2) + "y"); lx = x2; ly = y2; } /** * Converts the Java space dimension into pdf. * * @param w width * @param h height * @return String containing the coordinates in PDF space */ private String cwh(double w, double h) { return "" + df.format(w) + " " + df.format(h) + " "; } /** * Converts the Java space dimension into pdf. * * @param w width * @param h height * @return String containing the coordinates in PDF space */ private String cwh(int w, int h) { return cwh((double) w, (double) h); } /** * Converts the Java space coordinates into pdf. * * @param x coordinate * @param y coordinate * @return String containing the coordinates in PDF space */ private String cxy(double x, double y) { return "" + df.format(x) + " " + df.format(y) + " "; } /** * Converts the Java space coordinates into pdf. * * @param x coordinate * @param y coordinate * @return String containing the coordinates in PDF space */ private String cxy(int x, int y) { return cxy((double) x, (double) y); } /** *

* This releases any resources used by this Graphics object. You must use * this method once finished with it. Leaving it open will leave the PDF * stream in an inconsistent state, and will produce errors.

* *

* If this was created with Graphics.create() then the parent instance can * be used again. If not, then this closes the graphics operations for this * page when used with PDFJob.

* *

* When using PDFPage, you can create another fresh Graphics instance, which * will draw over this one.

* */ @Override public void dispose() { closeBlock(); if (clip != null) { restoreState(); } if (child) { pw.println("Q"); // restore graphics context } else { pw.close(); // close the stream if were the parent } } // ********************************************* // **** Implementation of java.awt.Graphics **** // ********************************************* //============ Rectangle operations ======================= /** * @see Graphics2D#draw(Shape) */ @Override public void draw(Shape s) { followPath(s, STROKE); } /** *

* Not implemented

* *

* Draws a 3-D highlighted outline of the specified rectangle. The edges of * the rectangle are highlighted so that they appear to be beveled and lit * from the upper left corner. The colors used for the highlighting effect * are determined based on the current color. The resulting rectangle covers * an area that is width + 1 pixels wide by height + 1 pixels tall. *

* * @param x an int value * @param y an int value * @param width an int value * @param height an int value * @param raised a boolean value */ @Override public void draw3DRect(int x, int y, int width, int height, boolean raised) { // Not implemented } /** * Draws an arc * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param sa Start angle * @param aa End angle */ @Override public void drawArc(int x, int y, int w, int h, int sa, int aa) { w = w >> 1; h = h >> 1; x += w; y += h; arc((double) x, (double) y, (double) w, (double) h, (double) -sa, (double) (-sa - aa), false); } /** *

* Not implemented

* * @param data a byte[] value * @param offset an int value * @param length an int value * @param x an int value * @param y an int value */ @Override public void drawBytes(byte[] data, int offset, int length, int x, int y) { } //============ Optimizers ======================= /** * @see Graphics2D#drawGlyphVector(GlyphVector, float, float) */ @Override public void drawGlyphVector(GlyphVector g, float x, float y) { Shape s = g.getOutline(x, y); fill(s); } /** * @see Graphics2D#drawImage(BufferedImage, BufferedImageOp, int, int) */ @Override public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { BufferedImage result = img; if (op != null) { result = op.createCompatibleDestImage(img, img.getColorModel()); result = op.filter(img, result); } drawImage(result, x, y, null); } /** * @see Graphics2D#drawImage(Image, AffineTransform, ImageObserver) */ @Override public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { // return drawImage(img, null, xform, null, obs); return true; } /** *

* Draw's an image onto the page, with a backing colour.

* * @param img The java.awt.Image * @param x coordinate on page * @param y coordinate on page * @param bgcolor Background colour * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver obs) { return drawImage(img, x, y, img.getWidth(obs), img.getHeight(obs), bgcolor, obs); } /** * Draw's an image onto the page * * @param img The java.awt.Image * @param x coordinate on page * @param y coordinate on page * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int x, int y, ImageObserver obs) { return drawImage(img, x, y, img.getWidth(obs), img.getHeight(obs), obs); } /** *

* Draw's an image onto the page, with a backing colour.

* * @param img The java.awt.Image * @param x coordinate on page * @param y coordinate on page * @param w Width on page * @param h height on page * @param bgcolor Background colour * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int x, int y, int w, int h, Color bgcolor, ImageObserver obs) { closeBlock(); pw.print("q "); // save state Color c = getColor(); // save current colour setColor(bgcolor); // change the colour drawRect(x, y, w, h); closeBlock("B Q"); // fill stroke, restore state paint = c; // restore original colour return drawImage(img, x, y, img.getWidth(obs), img.getHeight(obs), obs); } /** *

* Draws an image onto the page.

* *

* This method is implemented with ASCIIbase85 encoding and the zip stream * deflater. It results in a stream that is anywhere from 3 to 10 times as * big as the image. This obviously needs some improvement, but it works * well for small images

* * @param img The java.awt.Image * @param x coordinate on page * @param y coordinate on page * @param w Width on page * @param h height on page * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int x, int y, int w, int h, ImageObserver obs) { closeBlock(); PDFImage image; if (usedImages.containsKey(img)) { image = usedImages.get(img); } else { PDFMask mask = new PDFMask(img); page.getPDFDocument().add(mask); image = new PDFImage(img, x, y, w, h, obs, "" + mask.getSerialID() + " 0 R"); // The image needs to be registered in several places page.getPDFDocument().setImageName(image); page.getPDFDocument().add(image); usedImages.put(img, image); } page.addToProcset("/ImageC"); page.addImageResource(image.getName() + " " + image.getSerialID() + " 0 R"); initAlpha(255); // JM /*page.addResource("/XObject << " + image.getName() + " " + image.getSerialID() + " 0 R >>");*/ // q w 0 0 h x y cm % the coordinate matrix AffineTransform newTransform = new AffineTransform(w, 0, 0, -h, x, y + h); AffineTransform transformToSet = newTransform; pw.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); return false; } /** * Draw's an image onto the page, with scaling *

* This is not yet supported. * * @param img The java.awt.Image * @param dx1 coordinate on page * @param dy1 coordinate on page * @param dx2 coordinate on page * @param dy2 coordinate on page * @param sx1 coordinate on image * @param sy1 coordinate on image * @param sx2 coordinate on image * @param sy2 coordinate on image * @param bgcolor Background colour * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver obs) { return false; } //============ Clipping operations ======================= /** * Draw's an image onto the page, with scaling *

* This is not yet supported. * * @param img The java.awt.Image * @param dx1 coordinate on page * @param dy1 coordinate on page * @param dx2 coordinate on page * @param dy2 coordinate on page * @param sx1 coordinate on image * @param sy1 coordinate on image * @param sx2 coordinate on image * @param sy2 coordinate on image * @param obs ImageObserver * @return true if drawn */ @Override public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver obs) { // This shouldn't be too bad, just change the coordinate matrix return false; } /** * Draws a line between two coordinates. * * If the first coordinate is the same as the last one drawn (i.e. a * previous drawLine, moveto, etc) it is ignored. * * @param x1 coordinate * @param y1 coordinate * @param x2 coordinate * @param y2 coordinate */ @Override public void drawLine(int x1, int y1, int x2, int y2) { moveto(x1, y1); lineto(x2, y2); } //============ Arcs operations ============================== // These are the standard Graphics operators. They use the // arc extension operators to achieve the affect. /** *

* Draws an oval

* * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void drawOval(int x, int y, int w, int h) { drawArc(x, y, w, h, 0, 360); } /** * Draws a polygon, linking the first and last coordinates. * * @param xp Array of x coordinates * @param yp Array of y coordinates * @param np number of points in polygon */ @Override public void drawPolygon(int[] xp, int[] yp, int np) { polygon(xp, yp, np); closeBlock("s"); // close path and stroke } /** * Draws a polyline. The first and last coordinates are not linked. * * @param xp Array of x coordinates * @param yp Array of y coordinates * @param np number of points in polyline */ @Override public void drawPolyline(int[] xp, int[] yp, int np) { polygon(xp, yp, np); // no stroke, as we keep the optimizer in stroke state } /** * We override Graphics.drawRect as it doesn't join the 4 lines. Also, PDF * provides us with a Rectangle operator, so we will use that. * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void drawRect(int x, int y, int w, int h) { draw(new Rectangle(x, y, w, h)); /*newPath(); pw.print(cxy(x, y) + cwh(w, h) + "re "); // rectangle lx = x; // I don't know if this is correct, but lets see if PDF ends ly = y; // the rectangle at it's start. // stroke (optimized)*/ } /** * @see Graphics2D#drawRenderableImage(RenderableImage, AffineTransform) */ @Override public void drawRenderableImage(RenderableImage img, AffineTransform xform) { drawRenderedImage(img.createDefaultRendering(), xform); } /** * @see Graphics2D#drawRenderedImage(RenderedImage, AffineTransform) */ @Override public void drawRenderedImage(RenderedImage img, AffineTransform xform) { BufferedImage image = null; if (img instanceof BufferedImage) { image = (BufferedImage) img; } else { ColorModel cm = img.getColorModel(); int width = img.getWidth(); int height = img.getHeight(); WritableRaster raster = cm.createCompatibleWritableRaster(width, height); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); Hashtable properties = new Hashtable(); String[] keys = img.getPropertyNames(); if (keys != null) { for (int i = 0; i < keys.length; i++) { properties.put(keys[i], img.getProperty(keys[i])); } } BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties); img.copyData(raster); image = result; } drawImage(image, xform, null); } /** * This is not yet implemented * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param aw a-width * @param ah a-height */ @Override public void drawRoundRect(int x, int y, int w, int h, int aw, int ah) { } //============ Oval operations ======================= /** * Draws a string using a AttributedCharacterIterator. *

* This is not supported yet, as I have no idea what an * AttributedCharacterIterator is. *

* This method is new to the Java2 API. */ @Override public void drawString(java.text.AttributedCharacterIterator aci, float x, float y) { } /** * Draws a string using a AttributedCharacterIterator. *

* This is not supported yet, as I have no idea what an * AttributedCharacterIterator is. *

* This method is new to the Java2 API. */ @Override public void drawString(java.text.AttributedCharacterIterator aci, int x, int y) { } public void drawStringWithMode(String s, float x, float y, int mode) { newTextBlock(x, y); if (mode > -1) { pw.println("" + mode + " Tr"); } if (pdffont instanceof PDFEmbeddedFont) { pw.print("[("); pw.printRaw(PDFStringHelper.makeRawPDFString(s)); pw.println(")] TJ"); } else { pw.print(PDFStringHelper.makePDFString(s)); pw.println(" Tj"); } closeBlock(); } @Override public void drawString(String s, float x, float y) { drawStringWithMode(s, x, y, -1); } /** * This draws a string. * * @param s * @oaran s String to draw * @param x coordinate * @param y coordinate */ @Override public void drawString(String s, int x, int y) { drawString(s, (float) x, (float) y); } public void drawTransparentString(String s, float x, float y) { drawStringWithMode(s, x, y, 3); } /** * This draws a transparent string. * * @oaran s String to draw * @param x coordinate * @param y coordinate */ public void drawTransparentString(String s, int x, int y) { drawTransparentString(s, (float) x, (float) y); } /** * @see Graphics2D#fill(Shape) */ @Override public void fill(Shape s) { followPath(s, FILL); } /** *

* Not implemented

* * @param x an int value * @param y an int value * @param width an int value * @param height an int value * @param raised a boolean value */ @Override public void fill3DRect(int x, int y, int width, int height, boolean raised) { // Not implemented } /** * Fills an arc, joining the start and end coordinates * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param sa Start angle * @param aa End angle */ @Override public void fillArc(int x, int y, int w, int h, int sa, int aa) { // here we fool the optimizer. We force any open path to be closed, // then draw the arc. Finally, as the optimizer hasn't stroke'd the // path, we close and fill it, and mark the Stroke as closed. // // Note: The lineto to the centre of the object is required, because // the fill only fills the arc. Skipping this includes an extra // chord, which isn't correct. Peter May 31 2000 closeBlock(); patternFill(null/*FIXME!!!*/); drawArc(x, y, w, h, sa, aa); lineto(x + (w >> 1), y + (h >> 1)); if (shadingFill(null)) { return; } closeBlock("b"); // closepath and fill } //============ Extension operations ============================== // These are extensions, and provide access to PDF Specific // operators. /** *

* Draws a filled oval

* * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void fillOval(int x, int y, int w, int h) { fillArc(x, y, w, h, 0, 360); } //============ Polygon operations ======================= /** * Fills a polygon. * * @param xp Array of x coordinates * @param yp Array of y coordinates * @param np number of points in polygon */ @Override public void fillPolygon(int[] xp, int[] yp, int np) { closeBlock(); // finish off any previous paths patternFill(null /*FIXME!!!*/); polygon(xp, yp, np); if (shadingFill(null)) { return; } closeBlock("b"); // closepath, fill and stroke } //============ Image operations ======================= /** * Fills a rectangle with the current colour * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void fillRect(int x, int y, int w, int h) { fill(new Rectangle(x, y, w, h)); /* // end any path & stroke. This ensures the fill is on this // rectangle, and not on any previous graphics closeBlock(); patternFill(); drawRect(x, y, w, h); if (shadingFill()) { return; } closeBlock("B"); // rectangle, fill stroke*/ } private void patternFill(Shape s) { if (pattern != null) { if (paint instanceof TexturePaint) { if (pattern.equals("texture") || !paintTransform.equals(transform)) { initTexturePaint((TexturePaint) paint); paintTransform = transform; } } if (paint instanceof MultipleGradientPaint) { if (pattern.equals("gradient") || !paintTransform.equals(transform)) { initGradientPaint((MultipleGradientPaint) paint, s); paintTransform = transform; } } pw.println("/Pattern cs"); pw.println(pattern + " scn"); } } private boolean shadingFill(Shape s) { if (pattern == null && shading != null) { saveState(); pw.println("W n"); if (paint instanceof MultipleGradientPaint) { if (shading.equals("gradient") || !paintTransform.equals(transform)) { initGradientPaint((MultipleGradientPaint) paint, s); paintTransform = transform; } } pw.println(shading + " sh"); restoreState(); return true; } return false; } //============ Round Rectangle operations ======================= /** * This is not yet implemented * * @param x coordinate * @param y coordinate * @param w width * @param h height * @param aw a-width * @param ah a-height */ @Override public void fillRoundRect(int x, int y, int w, int h, int aw, int ah) { } /////////////////////////////////////////////// // // // implementation specific methods // // private void followPath(Shape s, int drawType) { PathIterator points; if (s == null) { return; } if (drawType == FILL) { patternFill(s); } if (drawType == STROKE) { if (!(stroke instanceof BasicStroke)) { s = stroke.createStrokedShape(s); followPath(s, FILL); return; } } // if (drawType==STROKE) { // setStrokeDiff(stroke, oldStroke); // oldStroke = stroke; // setStrokePaint(); // } // else if (drawType==FILL) // setFillPaint(); points = s.getPathIterator(IDENTITY); int segments = 0; float[] coords = new float[6]; while (!points.isDone()) { segments++; int segtype = points.currentSegment(coords); switch (segtype) { case PathIterator.SEG_CLOSE: pw.print("h "); break; case PathIterator.SEG_CUBICTO: curveto(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); break; case PathIterator.SEG_LINETO: lineto(coords[0], coords[1]); break; case PathIterator.SEG_MOVETO: moveto(coords[0], coords[1]); break; case PathIterator.SEG_QUADTO: curveto(coords[0], coords[1], coords[2], coords[3]); break; } points.next(); } switch (drawType) { case FILL: if (segments > 0) { if (pattern == null && shading != null) { saveState(); if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) { closeBlock("W*"); } else { closeBlock("W"); } pw.println("n"); if (paint instanceof MultipleGradientPaint) { if (shading.equals("gradient") || !paintTransform.equals(transform)) { initGradientPaint((MultipleGradientPaint) paint, s); paintTransform = transform; } } pw.println(shading + " sh"); restoreState(); return; } if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) { closeBlock("f*"); } else { closeBlock("f"); } } break; case STROKE: if (segments > 0) { closeBlock("S"); } break; case CLIP: default: //drawType==CLIP if (segments == 0) { drawRect(0, 0, 0, 0); } if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) { closeBlock("W*"); } else { closeBlock("W"); } } } /** * @see Graphics2D#getBackground() */ @Override public Color getBackground() { return background; } /** * Returns the Shape of the clipping region As my JDK docs say, this may * break with Java 2D. * * @return Shape of the clipping region */ @Override public Shape getClip() { return null; } /** * Returns the Rectangle that fits the current clipping region * * @return the Rectangle that fits the current clipping region */ @Override public Rectangle getClipBounds() { return clipRectangle; } //============ Color operations ======================= /** * Returns the current pen Colour * * @return the current pen Colour */ @Override public Color getColor() { return (paint instanceof Color) ? (Color) paint : Color.black; } /** * @see Graphics2D#getComposite() */ @Override public Composite getComposite() { return composite; } /** * @see Graphics2D#getDeviceConfiguration() */ @Override public GraphicsConfiguration getDeviceConfiguration() { return dg2.getDeviceConfiguration(); } /** * Return's the current font. * * @return the current font. */ @Override public Font getFont() { if (font == null) { setFont(new Font("SansSerif", Font.PLAIN, 12)); } return font; } /** * Returns the FontMetrics for a font. *

* This doesn't work correctly. Perhaps having some way of mapping the base * 14 fonts to our own FontMetrics implementation? * * @param font The java.awt.Font to return the metrics for * @return FontMetrics for a font */ @Override public FontMetrics getFontMetrics(Font font) { Frame dummy = new Frame(); dummy.addNotify(); Image image = dummy.createImage(100, 100); if (image == null) { System.err.println("getFontMetrics: image is null"); } Graphics graphics = image.getGraphics(); return graphics.getFontMetrics(font); } /** * @see Graphics2D#getFontRenderContext() */ @Override public FontRenderContext getFontRenderContext() { boolean antialias = RenderingHints.VALUE_TEXT_ANTIALIAS_ON.equals(getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING)); boolean fractions = RenderingHints.VALUE_FRACTIONALMETRICS_ON.equals(getRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS)); return new FontRenderContext(new AffineTransform(), antialias, fractions); } /** * Returns the associated PDFPage for this graphic * * @return the associated PDFPage for this graphic */ public PDFPage getPage() { return page; } /** * Returns the current pen Colour * * @return the current pen Colour */ @Override public Paint getPaint() { return paint; } /** * @param arg0 a key * @return the rendering hint */ @Override public Object getRenderingHint(Key arg0) { return rhints.get(arg0); } /** * @see Graphics2D#getRenderingHints() */ @Override public RenderingHints getRenderingHints() { return rhints; } /** * @see Graphics2D#getStroke() */ @Override public Stroke getStroke() { return stroke; } /** * @see Graphics2D#getTransform() */ @Override public AffineTransform getTransform() { return new AffineTransform(transform); } /** * Returns the PrintWriter handling the underlying stream * * @return the PrintWriter handling the underlying stream */ public RawPrintWriter getWriter() { return pw; } /** * @see Graphics2D#hit(Rectangle, Shape, boolean) */ @Override public boolean hit(Rectangle rect, Shape s, boolean onStroke) { if (onStroke) { s = stroke.createStrokedShape(s); } Area area = new Area(s); if (clip != null) { area.intersect(clip); } return area.intersects(rect.x, rect.y, rect.width, rect.height); } /** * This initialises the stream by saving the current graphics state, and * setting up the default line width (for us). * * It also sets up the instance ready for graphic operations and any * optimisations. * *

* For child instances, the stream is already open, so this should keep * things happy. */ private void init() { PageFormat pf = page.getPageFormat(); // save graphics state (restored by dispose) if (child) { pw.print("q "); } // now initialise the instance //setColor(Color.black); paint = Color.black; // possible: if parent.color is not black, then force black? // must check to see what AWT does? // Original User Space Transform (identity) // Transform from Java Space to PDF Space pTransform = new AffineTransform(); pTransform.translate(0, pf.getHeight()); pTransform.scale(1d, -1d); // Combined Transform User->Java->PDF setNewTranform(new AffineTransform()); // Set the line width setStroke(DEF_STROKE); } /** * This is called by PDFPage when creating a Graphcis instance. * * @param page The PDFPage to draw onto. */ protected void init(PDFPage page) { this.page = page; // We are the parent instance child = false; // Now create a stream to store the graphics in PDFStream stream = new PDFStream(); // To view detail in uncompressesd format comment out the next line //stream.setDeflate(true); page.getPDFDocument().add(stream); page.add(stream); pw = new RawPrintWriter(stream.getOutputStream()); // initially, we are limited to the page size clipRectangle = page.getImageableArea(); // finally initialise the stream init(); } /** * This method is used internally by create() and by the PDFJob class * * @param page PDFPage to draw into * @param pw PrintWriter to use */ protected void init(PDFPage page, RawPrintWriter pw) { this.page = page; this.pw = pw; // In this case, we didn't create the stream (our parent did) // so child is true (see dispose) child = true; // finally initialise the stream init(); } /** * This adds a line segment to the current path * * @param x coordinate * @param y coordinate */ public void lineto(double x, double y) { newPath(); // no optimisation here as it may introduce errors on decimal coordinates. pw.print(cxy(x, y) + "l "); lx = (float) x; ly = (float) y; } /** * This adds a line segment to the current path * * @param x coordinate * @param y coordinate */ public void lineto(int x, int y) { newPath(); if (lx != x && ly != y) { pw.print(cxy(x, y) + "l "); } lx = x; ly = y; } /** * This moves the current drawing point. * * @param x coordinate * @param y coordinate */ public void moveto(double x, double y) { newPath(); // no optimisation here as it may introduce errors on decimal coordinates. pw.print(cxy(x, y) + "m "); lx = (float) x; ly = (float) y; } /** * This moves the current drawing point. * * @param x coordinate * @param y coordinate */ public void moveto(int x, int y) { newPath(); if (lx != x || ly != y) { pw.print(cxy(x, y) + "m "); } lx = x; ly = y; } /** * Functions that draw lines should start by calling this. It starts a new * path unless inStroke is set, in that case it uses the existing path */ void newPath() { if (inText) { closeBlock(); } if (!inStroke) { if (pre_np != null) { pw.print(pre_np); // this is the prefix set by setOrientation() pre_np = null; } pw.print("n "); } inText = false; inStroke = true; // an unlikely coordinate to fool the moveto() optimizer lx = ly = -9999; } /** *

* Functions that draw text should start by calling this. It starts a text * block (accounting for media orientation) unless we are already in a Text * block.

* *

* It also handles if the font has been changed since the current text block * was started, so your function will be current.

* * @param x x coordinate in java space * @param y y coordinate in java space */ void newTextBlock(float x, float y) { // close the current path if there is one if (inStroke) { closeBlock(); } // create the text block if one is not current. If we are, the newFont // condition at the end catches font changes if (!inText) { // This ensures that there is a font available getFont(); pw.print("q BT "); tx = ty = 0; AffineTransform tm = new AffineTransform(pTransform); pw.println("" + df.format(tm.getScaleX()) + " " + "" + df.format(tm.getShearY()) + " " + "" + df.format(tm.getShearX()) + " " + "" + df.format(tm.getScaleY()) + " " + "" + df.format(tm.getTranslateX()) + " " + "" + df.format(tm.getTranslateY()) + " Tm" ); // produce the text matrix for the media // switch(mediaRot) { // case PageFormat.PORTRAIT: // Portrait // //pw.println("1 0 0 1 0 0 Tm"); // break; // // case PageFormat.LANDSCAPE: // Landscape // pw.println("0 1 -1 0 0 0 Tm"); // rotate // break; // // case 180: // Inverted Portrait // pw.println("1 0 0 -1 0 0 Tm"); // break; // // case PageFormat.REVERSE_LANDSCAPE: // Seascape // pw.println("0 -1 1 0 0 0 Tm"); // rotate // break; // } // move the text cursor by an absolute amount pw.print(txy(x, y) + "Td "); } else { // move the text cursor by a relative amount pw.print(twh(x, y, tx, ty) + "Td "); //pw.print(txy(x,y)+"Td "); } // preserve the coordinates for the next time tx = x; ty = y; if (newFont || !inText) { pw.print(pdffont.getName() + " " + font.getSize() + " Tf "); } // later add colour changes here (if required) inStroke = newFont = false; inText = true; } /** * This is used to add a polygon to the current path. Used by drawPolygon(), * drawPolyline() and fillPolygon() etal * * @param xp Array of x coordinates * @param yp Array of y coordinates * @param np number of points in polygon * @see #drawPolygon * @see #drawPolyline * @see #fillPolygon */ public void polygon(int[] xp, int[] yp, int np) { // newPath() not needed here as moveto does it ;-) moveto(xp[0], yp[0]); for (int i = 1; i < np; i++) { lineto(xp[i], yp[i]); } } /** * @see Graphics2D#rotate(double) */ @Override public void rotate(double theta) { AffineTransform newTransform = new AffineTransform(transform); newTransform.rotate(theta); setNewTranform(newTransform); } /** * @see Graphics2D#rotate(double, double, double) */ @Override public void rotate(double theta, double x, double y) { AffineTransform newTransform = new AffineTransform(transform); newTransform.rotate(theta, x, y); setNewTranform(newTransform); } /** * @see Graphics2D#scale(double, double) */ @Override public void scale(double sx, double sy) { AffineTransform newTransform = new AffineTransform(transform); newTransform.scale(sx, sy); setNewTranform(newTransform); } /** * @see Graphics2D#setBackground(Color) */ @Override public void setBackground(Color color) { background = color; } /** * Clips to a set of coordinates * * @param x coordinate * @param y coordinate * @param w width * @param h height */ @Override public void setClip(int x, int y, int w, int h) { /*clipRectangle = new Rectangle(x, y, w, h); closeBlock(); // finish off any existing paths drawRect(x, y, w, h); closeBlock("W n"); // clip to current path*/ setClip(new Rectangle(x, y, w, h)); } /** * As my JDK docs say, this may break with Java 2D. *

* Sets the clipping region to that of a Shape. * * @param s Shape to clip to. */ @Override public void setClip(Shape s) { closeBlock(); if (clip != null) { restoreState(); transform = clipTransform; } if (s == null) { clip = null; return; } clipTransform = transform; clip = new Area(s); clipRectangle = s.getBounds(); saveState(); followPath(s, CLIP); pw.println("n"); //setClip(r.x, r.y, r.width, r.height); } /** * Sets the color for drawing * * @param c Color to use */ @Override public void setColor(Color c) { setPaint(c); } /** * @see Graphics2D#setComposite(Composite) */ @Override public void setComposite(Composite comp) { this.composite = comp; } /** * This extension sets the line width to the default of 1mm which is what * Java uses when drawing to a PrintJob. */ public void setDefaultLineWidth() { closeBlock(); // draw any path before we change the line width pw.println("1 w"); } /** * This sets the font. * * @param f java.awt.Font to set to. */ @Override public void setFont(Font f) { // optimize: Save some space if the font is already the current one. if (font != f) { font = f; pdffont = page.getFont("/Type1", f.getName(), f.getStyle()); // mark the font as changed newFont = true; } } public void setExistingTtfFont(Font f) { if (font != f) { font = f; pdffont = page.getFont("/TrueType", f.getName(), f.getStyle()); // mark the font as changed newFont = true; } } public void setTtfFont(Font f, File file) throws IOException { if (font != f) { font = f; pdffont = page.getEmbeddedFont(f.getName(), f.getStyle(), file); // mark the font as changed newFont = true; } } private void setLineCap(int cap) { int lineCap = 0; switch (cap) { case BasicStroke.JOIN_MITER: lineCap = 0; break; case BasicStroke.JOIN_ROUND: lineCap = 1; break; case BasicStroke.JOIN_BEVEL: lineCap = 2; break; } if (this.lineCap != lineCap) { closeBlock(); // draw any path before we change the line width this.lineCap = lineCap; pw.println("" + lineCap + " J"); } } private void setLineJoin(int join) { int lineJoin = 0; switch (join) { case BasicStroke.JOIN_MITER: lineJoin = 0; break; case BasicStroke.JOIN_ROUND: lineJoin = 1; break; case BasicStroke.JOIN_BEVEL: lineJoin = 2; break; } if (this.lineJoin != lineJoin) { closeBlock(); // draw any path before we change the line width this.lineJoin = lineJoin; pw.println("" + lineJoin + " j"); } } /** * This extension allows the width of the drawn line to be set * * @param width Line width in pdf graphic units (points) */ public void setLineWidth(float width) { if (width != this.lineWidth) { closeBlock(); // draw any path before we change the line width this.lineWidth = width; pw.println("" + width + " w"); } } private void setMiterLimit(float limit) { if (limit != this.miterLimit) { closeBlock(); // draw any path before we change the line width this.miterLimit = limit; pw.println("" + limit + " M"); } } private void initAlpha(int alpha) { if (currentAlpha != alpha || blendMode != null) { String gsId = "/GSAlpha" + alpha; currentAlpha = alpha; if (!usedAlphas.contains(alpha)) { page.addExtGStateResource(gsId + " <>"); usedAlphas.add(currentAlpha); } pw.println(gsId + " gs"); } } public void setBlendMode(String mode) { if (currentAlpha < 0) { currentAlpha = 255; } String gsName = "/GSBlend" + mode + "Alpha" + currentAlpha; if (!gsBlendModes.contains(gsName)) { page.addExtGStateResource(gsName + " <>"); } pw.println(gsName + " gs"); this.blendMode = mode; } /** * Sets the paint for drawing * * @param paint Paint to use */ @Override public void setPaint(Paint paint) { this.paint = paint; this.shading = null; this.pattern = null; this.paintTransform = null; if (paint instanceof Color) { Color c = (Color) paint; double r = ((double) c.getRed()) / 255.0; double g = ((double) c.getGreen()) / 255.0; double b = ((double) c.getBlue()) / 255.0; closeBlock(); // This ensures any paths are drawn in the previous initAlpha(c.getAlpha()); // colours pw.println("" + r + " " + g + " " + b + " rg " + r + " " + g + " " + b + " RG"); } if (paint instanceof MultipleGradientPaint) { closeBlock(); if ((paint instanceof RadialGradientPaint) || ((paint instanceof LinearGradientPaint) && (((LinearGradientPaint) paint).getCycleMethod() == MultipleGradientPaint.CycleMethod.NO_CYCLE))) { shading = "gradient"; } else { pattern = "gradient"; } } if (paint instanceof TexturePaint) { closeBlock(); pattern = "texture"; } } private boolean useFunctionShading(MultipleGradientPaint fgrad) { return ((fgrad instanceof RadialGradientPaint) && fgrad.getCycleMethod() != MultipleGradientPaint.CycleMethod.NO_CYCLE); } private Color[] convertColorSpace(Color[] colors, MultipleGradientPaint.ColorSpaceType colorSpaceType) { /*if (colorSpaceType == MultipleGradientPaint.ColorSpaceType.LINEAR_RGB) { Color[] ret = new Color[colors.length]; for (int i = 0; i < colors.length; i++) { int argb = colors[i].getRGB(); int a = argb >>> 24; int r = srgbToLinear[(argb >> 16) & 0xff]; int g = srgbToLinear[(argb >> 8) & 0xff]; int b = srgbToLinear[(argb) & 0xff]; ret[i] = new Color(r, g, b, a); } return ret; }*/ //return colors; return colors; } private String generateRadialFunctionBody(RadialGradientPaint radGrad, boolean alpha) { double a = ((radGrad.getCenterPoint().getX() - radGrad.getFocusPoint().getX()) * (radGrad.getCenterPoint().getX() - radGrad.getFocusPoint().getX()) + (radGrad.getCenterPoint().getY() - radGrad.getFocusPoint().getY()) * (radGrad.getCenterPoint().getY() - radGrad.getFocusPoint().getY()) - radGrad.getRadius() * radGrad.getRadius()); String functionBody = "{\n" + matDf.format(radGrad.getFocusPoint().getX()) + " 2 index sub\n" + matDf.format(radGrad.getCenterPoint().getX() - radGrad.getFocusPoint().getX()) + " mul 2 mul\n" //stack size: 3 + matDf.format(radGrad.getFocusPoint().getY()) + " 2 index sub\n" + matDf.format(radGrad.getCenterPoint().getY() - radGrad.getFocusPoint().getY()) + " mul 2 mul\n" + "add\n" //b, stack size: 3 + matDf.format(radGrad.getFocusPoint().getX()) + " 3 index sub\n" + "dup mul\n" + matDf.format(radGrad.getFocusPoint().getY()) + " 3 index sub\n" + "dup mul\n" + "add\n" //c, stack size: 4 + "1 index dup mul 4 " + matDf.format(a) + " mul 2 index mul sub\n" //D, stack size: 4 + "0 index 0 lt\n" + "{\n" + "1\n" + "}" + "{" + "0 index 0 gt\n" + "{\n" + "2 index neg 1 index sqrt add 2 " + matDf.format(a) + " mul div\n" // x1, stack size: 5 + "3 index neg 2 index sqrt sub 2 " + matDf.format(a) + " mul div\n" // x2, stack size: 6 + "0 index 2 index gt{0 index} {1 index} ifelse\n" + "exch pop exch pop\n" //x, stack size 5 + "}" + "{\n" + "2 index neg 2 " + matDf.format(a) + " mul div\n" // x, stack size 5 + "} ifelse\n" + "} ifelse\n" + "exch pop exch pop exch pop exch pop exch pop\n"; //remove index0,1,2,3,4 if (radGrad.getCycleMethod() == MultipleGradientPaint.CycleMethod.REFLECT) { functionBody += "dup\n"; } if (radGrad.getCycleMethod() == MultipleGradientPaint.CycleMethod.NO_CYCLE) { functionBody += "dup 1 gt {pop 1} if\n"; } else { functionBody += "dup 1 gt {dup floor sub} if\n"; } if (radGrad.getCycleMethod() == MultipleGradientPaint.CycleMethod.REFLECT) { functionBody += "exch floor 2 mod 1 eq {" + "neg 1 add" + "}\n" + "if\n"; } int num = radGrad.getFractions().length; Color[] rcolors = convertColorSpace(radGrad.getColors(), radGrad.getColorSpace()); for (int i = 0; i < num - 1; i++) { functionBody += "dup " + radGrad.getFractions()[i] + " lt not 1 index " + radGrad.getFractions()[i + 1] + " gt not and\n{\n" + "0 index " + radGrad.getFractions()[i] + " sub " + (radGrad.getFractions()[i + 1] - radGrad.getFractions()[i]) + " div\n"; if (alpha) { functionBody += "0 index " + ((rcolors[i + 1].getAlpha() - rcolors[i].getAlpha()) / 255.0) + " mul " + (rcolors[i].getAlpha() / 255.0) + " add\n"; functionBody += "dup dup\n"; } else { if (radGrad.getColorSpace() == MultipleGradientPaint.ColorSpaceType.LINEAR_RGB) { functionBody += "0 index " + ((srgbToLinear[rcolors[i + 1].getRed()] - srgbToLinear[rcolors[i].getRed()]) / 255.0) + " mul " + (srgbToLinear[rcolors[i].getRed()] / 255.0) + " add\n" + "0 index 0.0031308 gt not {12.92 mul}{1 2.4 div exp 1.055 mul 0.055 sub}ifelse\n" + "1 index " + ((srgbToLinear[rcolors[i + 1].getGreen()] - srgbToLinear[rcolors[i].getGreen()]) / 255.0) + " mul " + (srgbToLinear[rcolors[i].getGreen()] / 255.0) + " add\n" + "0 index 0.0031308 gt not {12.92 mul}{1 2.4 div exp 1.055 mul 0.055 sub}ifelse\n" + "2 index " + ((srgbToLinear[rcolors[i + 1].getBlue()] - srgbToLinear[rcolors[i].getBlue()]) / 255.0) + " mul " + (srgbToLinear[rcolors[i].getBlue()] / 255.0) + " add\n" + "0 index 0.0031308 gt not {12.92 mul}{1 2.4 div exp 1.055 mul 0.055 sub}ifelse\n"; } else { functionBody += "0 index " + ((rcolors[i + 1].getRed() - rcolors[i].getRed()) / 255.0) + " mul " + (rcolors[i].getRed() / 255.0) + " add\n" + "1 index " + ((rcolors[i + 1].getGreen() - rcolors[i].getGreen()) / 255.0) + " mul " + (rcolors[i].getGreen() / 255.0) + " add\n" + "2 index " + ((rcolors[i + 1].getBlue() - rcolors[i].getBlue()) / 255.0) + " mul " + (rcolors[i].getBlue() / 255.0) + " add\n"; } } if (i < num - 2) { functionBody += "}\n{\n"; } } functionBody += "}if\n"; for (int i = 0; i < num - 2; i++) { functionBody += "}ifelse\n"; } functionBody += "}\n"; return functionBody; } private void initGradientPaint(MultipleGradientPaint grad, Shape fillShape) { if ((grad instanceof LinearGradientPaint) && (((LinearGradientPaint) grad).getCycleMethod() == MultipleGradientPaint.CycleMethod.REFLECT)) { LinearGradientPaint linGrad = (LinearGradientPaint) grad; Point2D start = linGrad.getStartPoint(); Point2D end = linGrad.getEndPoint(); double deltaX = end.getX() - start.getX(); double deltaY = end.getY() - start.getY(); Point2D newEnd = new Point2D.Double(end.getX() + deltaX, end.getY() + deltaY); int colorCount = grad.getFractions().length; float fractions2[] = new float[colorCount * 2 - 1]; Color colors2[] = new Color[colorCount * 2 - 1]; float fractionsrev[] = new float[linGrad.getFractions().length]; Color colorsrev[] = new Color[linGrad.getColors().length]; for (int i = 0; i < fractionsrev.length; i++) { colorsrev[i] = linGrad.getColors()[i]; fractionsrev[i] = linGrad.getFractions()[i]; } for (int i = 0; i < colorCount; i++) { colors2[i] = colorsrev[i]; fractions2[i] = fractionsrev[i] / 2; } for (int i = 0; i < colorCount; i++) { colors2[colors2.length - i - 1] = colorsrev[i]; fractions2[colors2.length - i - 1] = 1f - fractionsrev[i] / 2; } LinearGradientPaint linGrad2 = new LinearGradientPaint(start, newEnd, fractions2, colors2, MultipleGradientPaint.CycleMethod.REPEAT); grad = linGrad2; } List functions2Refs = new ArrayList<>(); Color[] colors = convertColorSpace(grad.getColors(), grad.getColorSpace()); for (int i = 1; i < grad.getColors().length; i++) { final Color color1 = colors[i - 1]; final Color color2 = colors[i]; final MultipleGradientPaint.ColorSpaceType colorSpace = grad.getColorSpace(); if (colorSpace == MultipleGradientPaint.ColorSpaceType.LINEAR_RGB) { PDFStream function4 = new PDFStream(null) { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/FunctionType 4 /Domain [0 1] /Range [0 1 0 1 0 1]".getBytes()); writeStream(os); } }; OutputStream f4Os = function4.getOutputStream(); int redDelta = srgbToLinear[color2.getRed()] - srgbToLinear[color1.getRed()]; int greenDelta = srgbToLinear[color2.getGreen()] - srgbToLinear[color1.getGreen()]; int blueDelta = srgbToLinear[color2.getBlue()] - srgbToLinear[color1.getBlue()]; String functionBody = "{" + "0 index " + redDelta + " mul " + srgbToLinear[color1.getRed()] + " add 255 div\n" + "0 index 0.0031308 gt not {12.92 mul}{1 2.4 div exp 1.055 mul 0.055 sub}ifelse\n" + "1 index " + greenDelta + " mul " + srgbToLinear[color1.getGreen()] + " add 255 div\n" + "0 index 0.0031308 gt not {12.92 mul}{1 2.4 div exp 1.055 mul 0.055 sub}ifelse\n" + "2 index " + blueDelta + " mul " + srgbToLinear[color1.getBlue()] + " add 255 div\n" + "0 index 0.0031308 gt not {12.92 mul}{1 2.4 div exp 1.055 mul 0.055 sub}ifelse\n" + "}"; try { f4Os.write(functionBody.getBytes()); } catch (IOException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } page.getPDFDocument().add(function4); functions2Refs.add(function4.getSerialID() + " 0 R"); } else { // PDFObject function2 = new PDFObject(null) { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write(("/FunctionType 2 /Domain [0 1] /C0 [" + (((float) color1.getRed()) / 255.0f) + " " + (((float) color1.getGreen()) / 255.0f) + " " + (((float) color1.getBlue()) / 255.0f) + "] /C1 [" + (((float) color2.getRed()) / 255.0f) + " " + (((float) color2.getGreen()) / 255.0f) + " " + (((float) color2.getBlue()) / 255.0f) + "] /N 1\n").getBytes()); writeEnd(os); } }; page.getPDFDocument().add(function2); functions2Refs.add(function2.getSerialID() + " 0 R"); } } List functions2AlphaRefs = new ArrayList<>(); Color[] alphaColors = grad.getColors(); for (int i = 1; i < grad.getColors().length; i++) { final Color color1 = alphaColors[i - 1]; final Color color2 = alphaColors[i]; PDFObject function2 = new PDFObject(null) { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write(("/FunctionType 2 /Domain [0 1] /C0 [" + (((float) color1.getAlpha()) / 255.0f) + " " + (((float) color1.getAlpha()) / 255.0f) + " " + (((float) color1.getAlpha()) / 255.0f) + "] /C1 [" + (((float) color2.getAlpha()) / 255.0f) + " " + (((float) color2.getAlpha()) / 255.0f) + " " + (((float) color2.getAlpha()) / 255.0f) + "] /N 1\n").getBytes()); writeEnd(os); } }; page.getPDFDocument().add(function2); functions2AlphaRefs.add(function2.getSerialID() + " 0 R"); } final MultipleGradientPaint fgrad = grad; PDFObject function3 = new PDFGradientFunction3(fgrad, functions2Refs); page.getPDFDocument().add(function3); PDFObject function3Alpha = new PDFGradientFunction3(fgrad, functions2AlphaRefs); page.getPDFDocument().add(function3Alpha); double glen = 0; double divisor = 1; double maxlen = 256; if ((fgrad instanceof LinearGradientPaint) && (fgrad.getCycleMethod() != MultipleGradientPaint.CycleMethod.NO_CYCLE)) { LinearGradientPaint linGrad = (LinearGradientPaint) fgrad; Point2D startPoint = new Point2D.Double(); Point2D endPoint = new Point2D.Double(); startPoint = linGrad.getStartPoint(); endPoint = linGrad.getEndPoint(); double deltaX = endPoint.getX() - startPoint.getX(); double deltaY = endPoint.getY() - startPoint.getY(); glen = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (glen > maxlen) { divisor = glen / maxlen; glen = maxlen; } } final double flen = glen; PDFStream radialFunction; PDFStream radialAlphaFunction; if (useFunctionShading(fgrad)) { RadialGradientPaint radGrad = (RadialGradientPaint) fgrad; radialFunction = new PDFStream() { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/FunctionType 4\n".getBytes()); //pdf reference, page 168 os.write("/Domain [-1000000 1000000 -1000000 1000000]\n".getBytes()); os.write("/Range [0 1 0 1 0 1]\n".getBytes()); //3 - R,G,B writeStream(os); } }; radialAlphaFunction = new PDFStream() { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/FunctionType 4\n".getBytes()); //pdf reference, page 168 os.write("/Domain [-1000000 1000000 -1000000 1000000]\n".getBytes()); os.write("/Range [0 1 0 1 0 1]\n".getBytes()); //3 - R,G,B writeStream(os); } }; //PDF reference, page 176 /*double b = 2 * (focalX - x) * (centerX - focalX) + 2 * (focalY - y) * (centerY - focalY); double c = (focalX - x) * (focalX - x) + (focalY - y) * (focalY - y); double D = b * b - 4 * a * c;*/ //(-b + Math.sqrt(D)) / (2 * a) //D = b * b - 4 * a * c; String functionBody = generateRadialFunctionBody(radGrad, false); OutputStream funOs = radialFunction.getOutputStream(); try { funOs.write(functionBody.getBytes()); } catch (IOException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } String alphaFunctionBody = generateRadialFunctionBody(radGrad, true); funOs = radialAlphaFunction.getOutputStream(); try { funOs.write(alphaFunctionBody.getBytes()); } catch (IOException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } page.getPDFDocument().add(radialFunction); page.getPDFDocument().add(radialAlphaFunction); } else { radialFunction = null; radialAlphaFunction = null; } PDFObject shadingObj = new PdfGradientShading(fgrad, flen, useFunctionShading(fgrad), function3, radialFunction); page.getPDFDocument().add(shadingObj); PDFObject shadingAlphaObj = new PdfGradientShading(fgrad, flen, useFunctionShading(fgrad), function3Alpha, radialAlphaFunction); page.getPDFDocument().add(shadingAlphaObj); shadingCount++; final int fCurrentShadingCount = shadingCount; PDFStream alphaObject = new PDFStream() { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/Group << /CS /DeviceGray /S /Transparency >>\n".getBytes()); os.write("/Type /XObject\n".getBytes()); os.write("/Resources <<\n".getBytes()); os.write("/Shading <<".getBytes()); os.write(("/ShA" + fCurrentShadingCount + " " + shadingAlphaObj.getSerialID() + " 0 R").getBytes()); os.write(">>\n".getBytes()); //shading os.write(">>\n".getBytes()); //resources os.write("/Subtype /Form\n".getBytes()); os.write("/BBox [-1000000 -1000000 2000000 2000000]\n".getBytes()); //fixme writeStream(os); } }; OutputStream alphaOs = alphaObject.getOutputStream(); try { alphaOs.write(("/ShA" + fCurrentShadingCount + " sh\n").getBytes()); } catch (IOException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } page.getPDFDocument().add(alphaObject); String alphaExtGState = "/GradAlpha" + fCurrentShadingCount + " <<" + "/SMask <<" + "/Type /Mask\n" + "/S /Luminosity\n" + "/G " + alphaObject.getSerialID() + " 0 R" + ">>" + ">>"; if ((grad instanceof LinearGradientPaint) && ((LinearGradientPaint) grad).getCycleMethod() != MultipleGradientPaint.CycleMethod.NO_CYCLE) { LinearGradientPaint linGrad = (LinearGradientPaint) grad; Point2D startPoint = linGrad.getStartPoint(); Point2D endPoint = linGrad.getEndPoint(); Point2D startPointTrans = new Point2D.Double(); Point2D endPointTrans = new Point2D.Double(); transform.transform(linGrad.getStartPoint(), startPointTrans); transform.transform(linGrad.getEndPoint(), endPointTrans); double deltaX = endPoint.getX() - startPoint.getX(); double deltaY = endPoint.getY() - startPoint.getY(); double tana = deltaX / deltaY; double alfa = Math.atan(tana); AffineTransform m = new AffineTransform(); m.concatenate(pTransform); m.concatenate(transform); m.concatenate(AffineTransform.getTranslateInstance(startPoint.getX(), endPoint.getY())); m.concatenate(AffineTransform.getScaleInstance(divisor, divisor)); m.concatenate(AffineTransform.getRotateInstance(-alfa)); String matrixStr = "" + matDf.format(m.getScaleX()) + " " + matDf.format(m.getShearY()) + " " + matDf.format(m.getShearX()) + " " + matDf.format(m.getScaleY()) + " " + matDf.format(m.getTranslateX()) + " " + matDf.format(m.getTranslateY()); PDFStream innerPattern = new PDFStream("/Pattern") { @Override public void write(OutputStream os) throws IOException { writeStart(os); double w; double h; w = 1; h = flen; os.write("/PatternType 1\n".getBytes()); os.write("/PaintType 1\n".getBytes()); os.write("/TilingType 2\n".getBytes()); os.write(("/BBox [0 0 " + w + " " + h + "]\n").getBytes()); os.write(("/XStep " + w + "\n").getBytes()); os.write(("/YStep " + h + "\n").getBytes()); os.write(("/Resources << " + "/Shading << /Shin" + fCurrentShadingCount + " " + shadingObj.getSerialID() + " 0 R >>" + "/ExtGState <<" + alphaExtGState + ">>" + ">>\n").getBytes()); os.write(("/Matrix [" + matrixStr + "]\n").getBytes()); writeStream(os); } }; OutputStream patOs = innerPattern.getOutputStream(); try { patOs.write(("/GradAlpha" + fCurrentShadingCount + " gs").getBytes()); patOs.write(("/Shin" + shadingCount + " sh").getBytes()); } catch (IOException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } page.getPDFDocument().add(innerPattern); page.addPatternResource("/p" + shadingCount + " " + innerPattern.getSerialID() + " 0 R"); this.pattern = "/p" + shadingCount; return; } currentAlpha = -1; page.addExtGStateResource(alphaExtGState); pw.println("/GradAlpha" + fCurrentShadingCount + " gs"); page.addShadingResource("/Sh" + shadingCount + " " + shadingObj.getSerialID() + " 0 R "); this.shading = "/Sh" + shadingCount; } private void initTexturePaint(TexturePaint texturePaint) { BufferedImage img = texturePaint.getImage(); PDFMask mask = new PDFMask(img); page.getPDFDocument().add(mask); Rectangle2D anchorRect = texturePaint.getAnchorRect(); final double w = anchorRect.getWidth(); final double h = anchorRect.getHeight(); PDFImage image = new PDFImage(img, 0, 0, img.getWidth(), img.getHeight(), new ImageObserver() { @Override public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { return true; } }, "" + mask.getSerialID() + " 0 R"); // The image needs to be registered in several places page.getPDFDocument().setImageName(image); page.getPDFDocument().add(image); usedImages.put(img, image); AffineTransform m = new AffineTransform(); AffineTransform ptt = new AffineTransform(); ptt.concatenate(pTransform); ptt.concatenate(transform); m.concatenate(ptt); String matrixStr = "" + matDf.format(m.getScaleX()) + " " + matDf.format(m.getShearY()) + " " + matDf.format(m.getShearX()) + " " + matDf.format(m.getScaleY()) + " " + matDf.format(m.getTranslateX()) + " " + matDf.format(m.getTranslateY()); PDFStream innerPattern = new PDFStream("/Pattern") { @Override public void write(OutputStream os) throws IOException { writeStart(os); os.write("/PatternType 1\n".getBytes()); os.write("/PaintType 1\n".getBytes()); os.write("/TilingType 2\n".getBytes()); os.write(("/BBox [0 0 " + matDf.format(w) + " " + matDf.format(h) + "]\n").getBytes()); os.write(("/XStep " + matDf.format(w) + "\n").getBytes()); os.write(("/YStep " + matDf.format(h) + "\n").getBytes()); os.write(("/Resources << ").getBytes()); os.write("/XObject << ".getBytes()); os.write((image.getName() + " " + image.getSerialID() + " 0 R").getBytes()); os.write(" >> ".getBytes()); os.write((">>\n").getBytes()); //"1 0 0 1 0 0" os.write(("/Matrix [" + matrixStr + "]\n").getBytes()); writeStream(os); } }; OutputStream patOs = innerPattern.getOutputStream(); PrintWriter patwriter = new PrintWriter(patOs); AffineTransform transformToSet; transformToSet = new AffineTransform(w, 0, 0, -h, 0 - anchorRect.getX(), h - anchorRect.getY()); patwriter.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); transformToSet = new AffineTransform(w, 0, 0, -h, w - anchorRect.getX(), h - anchorRect.getY()); patwriter.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); transformToSet = new AffineTransform(w, 0, 0, -h, 0 - anchorRect.getX(), 2 * h - anchorRect.getY()); patwriter.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); transformToSet = new AffineTransform(w, 0, 0, -h, w - anchorRect.getX(), 2 * h - anchorRect.getY()); patwriter.print("q " + matDf.format(transformToSet.getScaleX()) + " " + matDf.format(transformToSet.getShearY()) + " " + matDf.format(transformToSet.getShearX()) + " " + matDf.format(transformToSet.getScaleY()) + " " + matDf.format(transformToSet.getTranslateX()) + " " + matDf.format(transformToSet.getTranslateY()) + " cm \n" + image.getName() + " Do\nQ\n"); patwriter.flush(); page.getPDFDocument().add(innerPattern); shadingCount++; page.addPatternResource("/p" + shadingCount + " " + innerPattern.getSerialID() + " 0 R"); this.pattern = "/p" + shadingCount; } /** * Not implemented, as this is not supported in the PDF specification. */ @Override public void setPaintMode() { } /** * Sets a rendering hint * * @param arg0 * @param arg1 */ @Override public void setRenderingHint(Key arg0, Object arg1) { if (arg1 != null) { rhints.put(arg0, arg1); } else { rhints.remove(arg0); } } // Add Graphics2D methods. /** * @see Graphics2D#setRenderingHints(Map) */ @Override public void setRenderingHints(Map hints) { rhints.clear(); rhints.putAll(hints); } /** * @see Graphics2D#setStroke(Stroke) */ @Override public void setStroke(Stroke s) { this.stroke = s; if (stroke instanceof BasicStroke) { BasicStroke bs = (BasicStroke) stroke; setLineCap(bs.getEndCap()); setLineJoin(bs.getLineJoin()); setLineWidth(bs.getLineWidth()); setMiterLimit(bs.getMiterLimit()); // TODO: Line dash pattern } } /** * @see Graphics2D#setTransform(AffineTransform) */ @Override public void setTransform(AffineTransform t) { setNewTranform(new AffineTransform(t)); } /** * Not implemented, as this is not supported in the PDF specification. * * @param c1 Color to xor with */ @Override public void setXORMode(Color c1) { } //============ Text operations ======================= /** * @see Graphics2D#shear(double, double) */ @Override public void shear(double shx, double shy) { AffineTransform newTransform = new AffineTransform(transform); newTransform.shear(shx, shy); setNewTranform(newTransform); } /** * @see Graphics2D#transform(AffineTransform) */ @Override public void transform(AffineTransform tx) { AffineTransform newTransform = new AffineTransform(transform); newTransform.concatenate(tx); setNewTranform(newTransform); } /** * @see Graphics2D#translate(double, double) */ @Override public void translate(double tx, double ty) { AffineTransform newTransform = new AffineTransform(transform); newTransform.translate(tx, ty); setNewTranform(newTransform); } /** * @see Graphics#translate(int, int) */ @Override public void translate(int x, int y) { translate((double) x, (double) y); } /** * Converts the Java space coordinates into pdf text space. * * @param x coordinate * @param y coordinate * @param tx coordinate * @param ty coordinate * @return String containing the coordinates in PDF text space */ private String twh(float x, float y, float tx, float ty) { float nx = x, ny = y; float ntx = tx, nty = ty; nx = (float) (x - tx); ny = (float) (y - ty); return "" + df.format(nx) + " " + df.format(ny) + " "; } /** * Converts the Java space coordinates into pdf text space. * * @param x coordinate * @param y coordinate * @return String containing the coordinates in PDF text space */ private String txy(float x, float y) { Point2D ptSrc = new Point2D.Float(x, y); Point2D ptDst = new Point2D.Float(); pTransform.transform(ptSrc, ptDst); return "" + df.format(ptDst.getX()) + " " + df.format(ptDst.getY()) + " "; } private void setNewTranform(AffineTransform t) { closeBlock(); if (true) { //return; } AffineTransform newTransform = new AffineTransform(t); AffineTransform transformToSet = new AffineTransform(newTransform); if (transform != null) { AffineTransform aInv = new AffineTransform(transform); try { aInv.invert(); } catch (NoninvertibleTransformException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } AffineTransform pInv = new AffineTransform(pTransform); try { pInv.invert(); } catch (NoninvertibleTransformException ex) { Logger.getLogger(PDFGraphics.class.getName()).log(Level.SEVERE, null, ex); } transformToSet = new AffineTransform(); transformToSet.concatenate(aInv); transformToSet.concatenate(pInv); transformToSet.concatenate(pTransform); transformToSet.concatenate(newTransform); } else { transformToSet.preConcatenate(pTransform); } transform = newTransform; pw.println("" + matDf.format(transformToSet.getScaleX()) + " " + "" + matDf.format(transformToSet.getShearY()) + " " + "" + matDf.format(transformToSet.getShearX()) + " " + "" + matDf.format(transformToSet.getScaleY()) + " " + "" + matDf.format(transformToSet.getTranslateX()) + " " + "" + matDf.format(transformToSet.getTranslateY()) + " cm" ); } private void saveState() { pw.println("q"); } private void restoreState() { pw.println("Q"); } } \ No newline at end of file