PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i5h-3LL

HOME


5h-3LL 1.0
DIR: /srv/http/vyvoj.adent.cz/egroupware/khkstc/phpgwapi/inc/fpdf
/srv/http/vyvoj.adent.cz/egroupware/khkstc/phpgwapi/inc/fpdf/
Upload File:
Current File : /srv/http/vyvoj.adent.cz/egroupware/khkstc/phpgwapi/inc/fpdf/pdml.php
<?php


class PDML extends FPDF {

    var $parserState=0;
    var $final;             // final PDF output.
    var $inPage = false;    // are we in a page yet?
    var $anchors = array(); // map anchor names to internal ids.
    var $href = array();    // stack of current URLs to link to. (shift/unshift)
    var $href_style = array(); // should links be underlined blue? 0/1
    var $font_color = array("000000");   // current text color
    var $font_size  = array("10");   // current font size
    var $font_face  = array("Helvetica");   // current font name
    var $font_mask  = array(); // keep track of stuff so that </font> works right.
    var $B = 0;
    var $I = 0;
    var $U = 0;
    var $left_margin = array( 28.35 ); // 1cm
    var $right_margin = array( 28.35 ); // 1cm
    var $bottom_margin = array( 28.35 ); // 1cm
    var $div_x = array();
    var $div_y = array();
    var $cell_info; // stuff to keep around until a </cell> shows up
    var $cell_text; // text to put in a cell.
    var $script;    // stuff to put in our script.
    var $header='';
    var $footer='';
    var $parserBreak; // when you want to break parsing, put a stop word here.
    var $multicol = array(); // stack of columns. you never know.

    /* Rotation extension. Should go away with 1.6 */
    var $angle=0;
    function Rotate($angle,$x=-1,$y=-1)
    {
        if($x==-1)
            $x=$this->x;
        if($y==-1)
            $y=$this->y;
        if($this->angle!=0)
            $this->_out('Q');
        $this->angle=$angle;
        if($angle!=0)
        {
            $angle*=M_PI/180;
            $c=cos($angle);
            $s=sin($angle);
            $cx=$x*$this->k;
            $cy=($this->h-$y)*$this->k;
            $this->_out(sprintf('q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm',$c,   $s,-$s,$c,$cx,$cy,-$cx,-$cy));
        }
    }
    function _endpage()
    {
        if($this->angle!=0)
        {
            $this->angle=0;
            $this->_out('Q');
        }
        parent::_endpage();
    }
    /* End of Rotation Extension */

    /* Ellipse extension. Should go away with 1.6 */
    function Circle($x,$y,$r,$style='') {
        $this->Ellipse($x,$y,$r,$r,$style);
    }

    function Ellipse($x,$y,$rx,$ry,$style='D') {
        if($style=='F')
            $op='f';
        elseif($style=='FD' or $style=='DF')
            $op='B';
        else
            $op='S';
        $lx=4/3*(M_SQRT2-1)*$rx;
        $ly=4/3*(M_SQRT2-1)*$ry;
        $k=$this->k;
        $h=$this->h;
        $this->_out(sprintf('%.2f %.2f m %.2f %.2f %.2f %.2f %.2f %.2f c',
            ($x+$rx)*$k,($h-$y)*$k,
            ($x+$rx)*$k,($h-($y-$ly))*$k,
            ($x+$lx)*$k,($h-($y-$ry))*$k,
            $x*$k,($h-($y-$ry))*$k));
        $this->_out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c',
            ($x-$lx)*$k,($h-($y-$ry))*$k,
            ($x-$rx)*$k,($h-($y-$ly))*$k,
            ($x-$rx)*$k,($h-$y)*$k));
        $this->_out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c',
            ($x-$rx)*$k,($h-($y+$ly))*$k,
            ($x-$lx)*$k,($h-($y+$ry))*$k,
            $x*$k,($h-($y+$ry))*$k));
        $this->_out(sprintf('%.2f %.2f %.2f %.2f %.2f %.2f c %s',
            ($x+$lx)*$k,($h-($y+$ry))*$k,
            ($x+$rx)*$k,($h-($y+$ly))*$k,
            ($x+$rx)*$k,($h-$y)*$k,
            $op));
    }
    /* End of Ellipse Extension */

    /* Javascript extension. That may stick here a while. */
    var $javascript;
    var $n_js;
    function IncludeJS($script) {
        $this->javascript.=$script;
    }
    function _putjavascript() {
        $this->_newobj();
        $this->n_js=$this->n;
        $this->_out('<<');
        $this->_out('/Names [(EmbeddedJS) '.($this->n+1).' 0 R ]');
        $this->_out('>>');
        $this->_out('endobj');
        $this->_newobj();
        $this->_out('<<');
        $this->_out('/S /JavaScript');
        $this->_out('/JS '.$this->_textstring($this->javascript));
        $this->_out('>>');
        $this->_out('endobj');
    }
    function _putresources() {
        parent::_putresources();
        if (!empty($this->javascript)) {
            $this->_putjavascript();
        }
        $this->_putbookmarks();
    }
    function _putcatalog() {
        parent::_putcatalog();
        if (isset($this->javascript)) {
            $this->_out('/Names <</JavaScript '.($this->n_js).' 0 R>>');
        }
        if(count($this->outlines)>0)
        {
            $this->_out('/Outlines '.$this->OutlineRoot.' 0 R');
            $this->_out('/PageMode /UseOutlines');
        }
    }
    /* End of Javascript Extension */

    /* Bookmark Extension. Should go away with 1.6 */
    var $outlines=array();
    var $OutlineRoot;
    function Bookmark($txt,$level=0,$y=0)
    {
        if($y==-1)
            $y=$this->GetY();
        $this->outlines[]=array('t'=>$txt,'l'=>$level,'y'=>$y,'p'=>$this->PageNo());
    }
    function _putbookmarks()
    {
        $nb=count($this->outlines);
        if($nb==0)
            return;
        $lru=array();
        $level=0;
        foreach($this->outlines as $i=>$o)
        {
            if($o['l']>0)
            {
                $parent=$lru[$o['l']-1];
                //Set parent and last pointers
                $this->outlines[$i]['parent']=$parent;
                $this->outlines[$parent]['last']=$i;
                if($o['l']>$level)
                {
                    //Level increasing: set first pointer
                    $this->outlines[$parent]['first']=$i;
                }
            }
            else
                $this->outlines[$i]['parent']=$nb;
            if($o['l']<=$level and $i>0)
            {
                //Set prev and next pointers
                $prev=$lru[$o['l']];
                $this->outlines[$prev]['next']=$i;
                $this->outlines[$i]['prev']=$prev;
            }
            $lru[$o['l']]=$i;
            $level=$o['l'];
        }
        //Outline items
        $n=$this->n+1;
        foreach($this->outlines as $i=>$o)
        {
            $this->_newobj();
            $this->_out('<</Title '.$this->_textstring($o['t']));
            $this->_out('/Parent '.($n+$o['parent']).' 0 R');
            if(isset($o['prev']))
                $this->_out('/Prev '.($n+$o['prev']).' 0 R');
            if(isset($o['next']))
                $this->_out('/Next '.($n+$o['next']).' 0 R');
            if(isset($o['first']))
                $this->_out('/First '.($n+$o['first']).' 0 R');
            if(isset($o['last']))
                $this->_out('/Last '.($n+$o['last']).' 0 R');
            $this->_out(sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]',1+2*$o['p'],($this->h-$o['y'])*$this->k));
            $this->_out('/Count 0>>');
            $this->_out('endobj');
        }
        //Outline root
        $this->_newobj();
        $this->OutlineRoot=$this->n;
        $this->_out('<</Type /Outlines /First '.$n.' 0 R');
        $this->_out('/Last '.($n+$lru[0]).' 0 R>>');
        $this->_out('endobj');
    }
    /* End of Bookmark Extension */

    function ParsePDML($pdml) {
        // default font.
        $this->SetFont($this->font_face[0],'',$this->font_size[0]);
        // apply margins
        $this->SetRightMargin($this->right_margin[0]);
        $this->SetLeftMargin($this->left_margin[0]);
        // bottom margin
        $this->SetAutoPageBreak(true, $this->bottom_margin[0]);

        $this->AliasNbPages('&pagecount;');

        $this->_parsePDML($pdml);
        //return $this->final;
    }

    function Header() {
        $this->_parsePDML($this->header);
    }

    function Footer() {
        $this->_parsePDML($this->footer);
    }

    function AcceptPageBreak() {
        if (count($this->multicol>0)) {
            // we need: starting y0, col_width, col_spacing, columns, height, break=page/line
            list($x0, $y0, $width, $height, $spacing, $break, $cols, $current) = $this->multicol[0];
            if ($current<$cols-1) {
                // next column
                $current++;
                $this->multicol[0][7] = $current;
                $x = $x0 + $current * $width;
                $this->SetLeftMargin($x);
                $this->SetX($x);
                $this->SetY($y0);
                return false;
            } else {
                // ok. we need to break.
                $this->SetLeftMargin($x0);
                $this->SetX($x0);
                $this->multicol[0][7] = 0; // $current
                if ($break=="line") {
                    $y0 += $spacing + $height; // y0
                    $this->multicol[0][1] = $y0;
                    $this->SetAutoPageBreak(true, $this->hPt - ( $y0 + $height));
                    $this->SetY($y0);
                    //$this->Write(10,"This sux0rs.");
                    return false;
                } else {
                    // page break.
                    return true;
                }
            }
        } else {
            // no multi-column tag. do the normal thing.
            return true;
        }
    }

    function _parsePDML($pdml) {
        $a = preg_split('/<([^<]*)\/?>/U',$pdml,-1,PREG_SPLIT_DELIM_CAPTURE);
        foreach ($a as $i=>$e) {
            if ($this->parserBreak) {
                if ($i%2==0) {
                    $this->ProcessText($e);
                    continue;
                }
                if (strcasecmp($e,$this->parserBreak)) {
                    $this->ProcessText('<'.$e.'>');
                    continue;
                }
            }
            if ($i%2==0) {
                // text
                $this->ProcessText(pdml_entity_decode(preg_replace(
                    array(
                        '/\s+/',
                        '/&pagenumber;/',
                        '/&title;/',
                        '/&author;/',
                        '/&subject;/',
                        '/&creator;/'
                        ),
                    array(
                        ' ',
                        $this->PageNo(),
                        $this->title,
                        $this->author,
                        $this->subject,
                        $this->creator
                    ) ,$e)));
            } else {
                // tag
                if ($e{0}=='/') {
                    $this->CloseTag(strtoupper(substr($e,1)));
                } else {
                    $a2 = explode(' ',$e,2);
                    $tag = strtoupper(array_shift($a2));
                    $e = substr($e, strlen($tag)+1);
                    // stolen from http://www.cs.sfu.ca/~cameron/REX.html
                    // bugified into uselessness. It's the intent that counts. right?
                    $NameStrt = "[A-Za-z_:]|[^\\x00-\\x7F]";
                    $NameChar = "[A-Za-z0-9_:.-]|[^\\x00-\\x7F]";
                    $Name = "(?:$NameStrt)(?:$NameChar)*";
                    $S = "[ \\n\\t\\r]+";
                    $AttValSE = "\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]+";
                    $ElemTagCE = "($Name)(?:$S)?=(?:$S)?($AttValSE)";

                    $attr = array();
                    preg_match_all("/$ElemTagCE/", $e, $matches, PREG_SET_ORDER);
                    for ($i=0;$i<count($matches);$i++) {
                        $val = $matches[$i][2];
                        if ((($val{0}=='"') and (substr($val,-1)=='"')) or
                            (($val{0}=="'") and (substr($val,-1)=="'")) ){
                            $val = substr($val, 1, strlen($val)-2);
                        }
                        $attr[strtoupper($matches[$i][1])] = $val;
                    }
                    $this->OpenTag($tag,$attr);
                }
            }
        }
    }

    function ProcessText($text) {
        switch ($this->parserState) {
            case 0:
            case 1:
            case 2:
                // ignore text/whitespace in there.
                break;
            case 3:
                $this->SetTitle($text);
                break;
            case 4:
                $this->SetSubject($text);
                break;
            case 5:
                $this->SetAuthor($text);
                break;
            case 6:
                $this->SetKeywords($text);
                break;
            case 51:
                $this->cell_text .= $text;
                break;
            case 10:
                $this->script .= $text;
                break;
            case 63:
                $this->header .= $text;
                break;
            case 64:
                $this->footer .= $text;
                break;
            default:
                // ignore pure whitespace
                if (preg_match("/^[ \\n\\t\\r]*$/",$text)) break;
                // auto-create a page if needed.
                if (!$this->inPage) {
                    $this->inPage = true;
                    $this->AddPage();
                }
                // write stuff.
                // do we have a link to use?
                if (sizeof($this->href)>0) {
                    if ($this->href_style[0]) {
                        $this->SetTextColor(0,0,255);
                        $this->_setStyle('U',true, true);
                    }
                    $this->Write($this->font_size[0],$text,$this->href[0]);
                    if ($this->href_style[0]) {
                        $this->_setStyle('U', $this->U>0, true);
                        $this->_setFontColor($this->font_color[0]);
                    }
                } else {
                    $this->Write($this->font_size[0],$text);
                }
        }
    }

    function OpenTag($tag, $attr) {
        switch ($tag) {
            case "PDML":
                $this->_enforceState(0,1);
                break;
            case "HEAD":
                $this->_enforceState(1,2);
                break;
            case "TITLE":
                $this->_enforceState(2,3);
                break;
            case "SUBJECT":
                $this->_enforceState(2,4);
                break;
            case "AUTHOR":
                $this->_enforceState(2,5);
                break;
            case "KEYWORDS":
                $this->_enforceState(2,6);
                break;
            case "SCRIPT":
                $this->_enforceState(2,10);
                $this->script='';
                $this->parserBreak="/script";
                break;
            case "BODY":
                $this->_enforceState(1,50);
                break;
            case "PAGE":
                $this->_enforceState(50,50);
                $o = "P";
                if (isset($attr["ORIENTATION"])) {
                    if (strcasecmp($attr["ORIENTATION"],"LANDSCAPE")==0) {
                        $o = "L";
                    }
                }
                $this->inPage=true;
                $this->AddPage($o);
                break;
            case "BR":
                // no enforcement.
                if ($this->parserState==51) {
                    $this->cell_text.="\n";
                    break;
                }
                if (isset($attr["HEIGHT"])) {
                    $h=$this->_getUnit($attr["HEIGHT"], $this->font_size[0]);
                    $this->Ln($h);
                } else {
                    $this->Ln($this->font_size[0]);
                }
                break;
            case "A":
                $this->_enforceState(50,50);
                // name=
                if (isset($attr["NAME"])) {
                    // local anchor
                    $name = $attr["NAME"];
                    if (!isset($this->anchors[$name])) {
                        $this->anchors[$name] = $this->AddLink();
                    }
                    $this->SetLink($this->anchors[$name], -1);
                }
                // href=
                if (isset($attr["HREF"])) {
                    $href = $attr["HREF"];
                    if ($href[0]=='#') {
                        // local anchor
                        $href = substr($href,1);
                        if (!isset($this->anchors[$href])) {
                            $this->anchors[$href] = $this->AddLink();
                        }
                        array_unshift ($this->href, $this->anchors[$href]);
                    } else {
                        array_unshift ($this->href, $href);
                    }
                    // we should set style to underlined blue. XXX
                    array_unshift ($this->href_style, isset($attr["HIDDEN"])?0:1);
                }
                break;
            case "B":
            case "I":
            case "U":
                $this->_enforceState(50,50);
                $this->_setStyle($tag, true);
                break;
            case "FONT":
                $this->_enforceState(50,50);
                $mask = 0;
                if (isset($attr["COLOR"])) {
                    // hex-encoded color. no space for long color name list.
                    $color = $attr["COLOR"];
                    if ($color[0]=="#") { $color = substr($color,1); }
                    array_unshift($this->font_color, $color);
                    $this->_setFontColor($color);
                    $mask |= 1;
                }
                if (isset($attr["SIZE"])) {
                    $size = $this->_getUnit($attr["SIZE"], $this->font_size[0]);
                    array_unshift($this->font_size, $size);
                    $this->SetFontSize($size);
                    $mask |= 2;
                }
                if (isset($attr["FACE"])) {
                    $face = $attr["FACE"];
                    array_unshift($this->font_face, $face);
                    $this->_setFontFace($face);
                    $mask |= 4;
                }
                array_unshift($this->font_mask, $mask);
                break;
            case "IMG":
                $this->_enforceState(50,50);
                if (!isset($attr["SRC"])) break;
                $src = $attr["SRC"];
                $x = $this->GetX();
                if (isset($attr["LEFT"])) {
                    $x = $this->_getUnit($attr["LEFT"], $this->wPt);
                }
                $y = $this->GetY();
                if (isset($attr["TOP"])) {
                    $y = $this->_getUnit($attr["TOP"], $this->hPt);
                }
                $width = 0;
                if (isset($attr["WIDTH"])) {
                    $width = $this->_getUnit($attr["WIDTH"], $this->wPt);
                }
                $height = 0;
                if (isset($attr["HEIGHT"])) {
                    $height = $this->_getUnit($attr["HEIGHT"], $this->hPt);
                }
                // try to resolve src a bit if necessary.
                if (!file_exists($src)) {
                    $src1 = getenv("DOCUMENT_ROOT")."/".$src;
                    $src2 = dirname(getenv("SCRIPT_FILENAME"))."/".$src;
                    if (file_exists($src1)) {
                        $src = $src1;
                    } elseif (file_exists($src2)) {
                        $src = $src2;
                    }
                }
                if (sizeof($this->href)>0) {
                    $this->Image($src, $x, $y, $width, $height, '', $this->href[0]);
                } else {
                    $this->Image($src, $x, $y, $width, $height);
                }
                break;
            case "LINE":
                $this->_enforceState(50,50);
                $x1 = $this->GetX();
                $y1 = $this->GetY();
                if (isset($attr["FROM"])) {
                    list($x1,$y1) = explode(',',$attr["FROM"]);
                    $x1 = $this->_getUnit($x1, $this->wPt);
                    $y1 = $this->_getUnit($y1, $this->hPt);
                }
                $x2 = $this->wPt;
                $y2 = $y1;
                if (isset($attr["TO"])) {
                    list($x2,$y2) = explode(',',$attr["TO"]);
                    $x2 = $this->_getUnit($x2, $this->wPt);
                    $y2 = $this->_getUnit($y2, $this->hPt);
                }
                $color = "000000";
                if (isset($attr["COLOR"])) {
                    $color = $attr["COLOR"];
                    if ($color[0]=="#") { $color = substr($color,1); }
                }
                $lwidth = $this->_getUnit("0.2mm");
                if (isset($attr["WIDTH"])) {
                    $lwidth = $this->_getUnit($attr["WIDTH"], $lwidth);
                }
                $this->_setLineColor($color);
                $this->SetLineWidth($lwidth);
                $this->Line($x1,$y1,$x2,$y2);
                break;
            case "RECT":
                $this->_enforceState(50,50);
                $x1 = $this->GetX();
                $y1 = $this->GetY();
                if (isset($attr["FROM"])) {
                    list($x1,$y1) = explode(',',$attr["FROM"]);
                    $x1 = $this->_getUnit($x1, $this->wPt);
                    $y1 = $this->_getUnit($y1, $this->hPt);
                }
                if (isset($attr["LEFT"])) {
                    $x1 = $this->_getUnit($attr["LEFT"], $this->wPt);
                }
                if (isset($attr["TOP"])) {
                    $y1 = $this->_getUnit($attr["TOP"], $this->hPt);
                }
                $width= 144;
                $height= 36;
                if (isset($attr["TO"])) {
                    list($x2,$y2) = explode(',',$attr["TO"]);
                    $x2 = $this->_getUnit($x2, $this->wPt);
                    $y2 = $this->_getUnit($y2, $this->hPt);
                    $width  = $x2-$x1+1;
                    $height = $y2-$y1+1;
                }
                if (isset($attr["WIDTH"])) {
                    $width = $this->_getUnit($attr["WIDTH"], $this->wPt);
                }
                if (isset($attr["HEIGHT"])) {
                    $height = $this->_getUnit($attr["HEIGHT"], $this->hPt);
                }
                $style="";
                $color = "000000";
                if (isset($attr["COLOR"])) {
                    $color = $attr["COLOR"];
                    if ($color[0]=="#") { $color = substr($color,1); }
                    $style.="D";
                }
                $fill = "000000";
                if (isset($attr["FILLCOLOR"])) {
                    $fill = $attr["FILLCOLOR"];
                    if ($fill[0]=="#") { $fill = substr($fill,1); }
                    $style.="F";
                }
                $border = $this->_getUnit("0.2mm");
                if (isset($attr["BORDER"])) {
                    $border = $this->_getUnit($attr["BORDER"], $border);
                }
                $this->_setLineColor($color);
                $this->SetLineWidth($border);
                $this->_setRectColor($fill);
                $this->Rect($x1,$y1,$width,$height,$style);
                break;
            case "CIRCLE":
            case "ELLIPSE":
                $this->_enforceState(50,50);
                $x1 = $this->GetX();
                $y1 = $this->GetY();
                if (isset($attr["FROM"])) {
                    list($x1,$y1) = explode(',',$attr["FROM"]);
                    $x1 = $this->_getUnit($x1, $this->wPt);
                    $y1 = $this->_getUnit($y1, $this->hPt);
                }
                $radius = $this->_getAttrUnit($this->font_size[0], $attr, "RADIUS", $this->font_size[0]);
                $xradius = $this->_getAttrUnit($radius, $attr, "XRADIUS", $this->font_size[0]);
                $yradius = $this->_getAttrUnit($radius, $attr, "YRADIUS", $this->font_size[0]);
                $style="";
                $color = "000000";
                if (isset($attr["COLOR"])) {
                    $color = $attr["COLOR"];
                    if ($color[0]=="#") { $color = substr($color,1); }
                    $style.="D";
                }
                $fill = "000000";
                if (isset($attr["FILLCOLOR"])) {
                    $fill = $attr["FILLCOLOR"];
                    if ($fill[0]=="#") { $fill = substr($fill,1); }
                    $style.="F";
                }
                $border = $this->_getUnit("0.2mm");
                if (isset($attr["BORDER"])) {
                    $border = $this->_getUnit($attr["BORDER"], $border);
                }
                $this->_setLineColor($color);
                $this->SetLineWidth($border);
                $this->_setRectColor($fill);
                $this->Ellipse($x1, $y1, $xradius, $yradius, $style);
                break;
            case "DIV":
                $this->_enforceState(50,50);
                $save_x = $this->GetX();
                $x = $this->_getAttrUnit($save_x, $attr, "LEFT", $this->wPt);
                $save_y = $this->GetY();
                $y = $this->_getAttrUnit($save_y, $attr, "TOP", $this->hPt);
                $width = $this->_getAttrUnit($this->wPt-$x, $attr, "WIDTH", $this->wPt);
                $height = $this->_getAttrUnit($this->hPt-$y, $attr, "HEIGHT", $this->hPt);
                if ($x == $save_x) { $save_x+=$width; }
                array_unshift($this->left_margin, $x);
                array_unshift($this->right_margin, $this->wPt-$width-$x);
                array_unshift($this->div_x, $save_x);
                array_unshift($this->div_y, $save_y);
                // draw a rect, just to debug. XXX
                $style="";
                $color = "000000";
                if (isset($attr["COLOR"])) {
                    $color = $attr["COLOR"];
                    if ($color[0]=="#") { $color = substr($color,1); }
                    $style.="D";
                }
                $fill = "000000";
                if (isset($attr["FILLCOLOR"])) {
                    $fill = $attr["FILLCOLOR"];
                    if ($fill[0]=="#") { $fill = substr($fill,1); }
                    $style.="F";
                }
                $border = $this->_getUnit("0.2mm");
                if (isset($attr["BORDER"])) {
                    $border = $this->_getUnit($attr["BORDER"], $border);
                }
                $this->_setLineColor($color);
                $this->SetLineWidth($border);
                $this->_setRectColor($fill);
                if ($style) {
                    $this->Rect($x,$y,$width,$height,$style);
                }
                $this->SetLeftMargin($this->left_margin[0]);
                $this->SetRightMargin($this->right_margin[0]);
                $this->SetXY($x,$y);
                break;
            case "MULTICELL":
            case "CELL":
                $this->_enforceState(50,51);
                $save_x = $this->GetX();
                $x = $this->_getAttrUnit($save_x, $attr, "LEFT", $this->wPt);
                $save_y = $this->GetY();
                $y = $this->_getAttrUnit($save_y, $attr, "TOP", $this->hPt);
                $width = $this->_getAttrUnit($this->wPt-$x, $attr, "WIDTH", $this->wPt);
                // used by multicell only
                $inter = $this->_getAttrUnit($this->font_size[0], $attr, "INTER", $this->font_size[0]);
                // used by cell only.
                $height = $this->_getAttrUnit($this->font_size[0], $attr, "HEIGHT", $this->font_size[0]);
                $next = 0;
                if (isset($attr["NEXT"])) {
                    $n = strtolower($attr["NEXT"]);
                    switch ($n) {
                        case "right": $next =0; break;
                        case "bottom": case "down": $next=2; break;
                        case "break": $next = 1; break;
                    }
                }
                $style="";
                $color = "000000";
                if (isset($attr["COLOR"])) {
                    $color = $attr["COLOR"];
                    if ($color[0]=="#") { $color = substr($color,1); }
                    $style.="D";
                }
                $fillflag = 0;
                $fill = "000000";
                if (isset($attr["FILLCOLOR"])) {
                    $fill = $attr["FILLCOLOR"];
                    if ($fill[0]=="#") { $fill = substr($fill,1); }
                    $fillflag=1;
                }
                $borderflag=0;
                $border = $this->_getUnit("0.2mm");
                if (isset($attr["BORDER"])) {
                    $border = $this->_getUnit($attr["BORDER"], $border);
                    $borderflag=1;
                }
                $align = ($tag=="CELL")?"L":"J";
                if (isset($attr["ALIGN"])) {
                    $al = strtolower($attr["ALIGN"]);
                    switch ($al){
                        case "left": $align="L"; break;
                        case "center": $align="C"; break;
                        case "right": $align="R"; break;
                        case "justify": $align="J"; break;
                    }
                }
                $this->_setLineColor($color);
                $this->SetLineWidth($border);
                $this->_setRectColor($fill);
                $this->SetXY($x,$y);
                $this->cell_info = array($width, $inter, $height, $borderflag, $align, $fillflag, $next);
                $this->cell_text = '';
                break;
            case "ROTATE":
                $angle=45;
                if (isset($attr["ANGLE"])) {
                    $angle = $attr["ANGLE"];
                }
                $x=-1;
                $y=-1;
                if (isset($attr["CENTER"])) {
                    list($x,$y) = explode(',',$attr["CENTER"]);
                    $x = $this->_getUnit($x, $this->wPt);
                    $y = $this->_getUnit($y, $this->hPt);
                }
                $this->rotate($angle, $x, $y);
                break;
            case "BOOKMARK":
                if (!isset($attr["TITLE"])) break;
                $title = $attr["TITLE"];
                $level = 0;
                if (isset($attr["LEVEL"])) {
                    $level = $attr["LEVEL"];
                }
                $top = -1;
                if (isset($attr["TOP"])) {
                    $top = $this->_getUnit($attr["TOP"], $this->hPt);
                }
                $this->Bookmark($title, $level, $top);
                break;
            case "HEADER":
                $this->_enforceState(50,63);
                $this->header='';
                $this->parserBreak='/header';
                break;
            case "FOOTER":
                $this->_enforceState(50,64);
                $this->footer='';
                $this->parserBreak='/footer';
                break;
            case "COLUMN":
                $this->_enforceState(50,50);
                $save_x = $this->GetX();
                $x = $this->_getAttrUnit($save_x, $attr, "LEFT", $this->wPt);
                $save_y = $this->GetY();
                $y = $this->_getAttrUnit($save_y, $attr, "TOP", $this->hPt);
                $count = 2;
                if (isset($attr["COUNT"])) {
                    $count = (int)$attr["COUNT"];
                }
                $width = $this->_getAttrUnit(($this->wPt-$x)/$count, $attr, "WIDTH", $this->wPt);
                $height = $this->_getAttrUnit($this->hPt-$y, $attr, "HEIGHT", $this->hPt);
                $spacing = $this->_getAttrUnit($this->font_size[0], $attr, "SPACING", $this->font_size[0]);
                $break = "page";
                if (isset($attr["BREAK"]) and (strtolower($attr["BREAK"])=="line")) {
                    $break = "line";
                }
                // store stuff for acceptPageBreak to make sense of, and stuff we're saving
                array_unshift($this->multicol, array($x,$y,$width,$height,$spacing, $break, $count, 0, ));
                array_unshift($this->left_margin, $x);
                array_unshift($this->bottom_margin, $this->hPt-($y+$height));
                // set margins to make things work.
                $this->SetLeftMargin($this->left_margin[0]);
                $this->SetAutoPageBreak(true, $this->bottom_margin[0]);
                break;
        }
    }

    function CloseTag($tag) {
        switch ($tag) {
            case "PDML":
                $this->_enforceState(1,0);
                //$this->final = $this->Output("","S");
                break;
            case "HEAD":
                $this->_enforceState(2,1);
                break;
            case "TITLE":
                $this->_enforceState(3,2);
                break;
            case "SUBJECT":
                $this->_enforceState(4,2);
                break;
            case "AUTHOR":
                $this->_enforceState(5,2);
                break;
            case "KEYWORDS":
                $this->_enforceState(6,2);
                break;
            case "SCRIPT":
                $this->_enforceState(10,2);
                $this->IncludeJS($this->script);
                $this->parserBreak='';
                break;
            case "BODY":
                $this->Close();
                $this->_enforceState(50,1);
                break;
            case "A":
                array_shift ($this->href);
                array_shift ($this->href_style);
                // we should remove underline + blue.
                break;
            case "B":
            case "I":
            case "U":
                $this->_setStyle($tag, false);
                break;
            case "FONT":
                if (sizeof($this->font_mask)>0) {
                    $mask = array_shift($this->font_mask);
                }
                if (($mask&1)==1) {
                    array_shift($this->font_color);
                    $this->_setFontColor($this->font_color[0]);
                }
                if (($mask&2)==2) {
                    array_shift($this->font_size);
                    $this->SetFontSize($this->font_size[0]);
                }
                if (($mask&4)==4) {
                    array_shift($this->font_face);
                    $this->_setFontFace($this->font_face[0]);
                }
                break;
            case "DIV":
                if (sizeof($this->div_x)<1) break;
                array_shift($this->left_margin);
                array_shift($this->right_margin);
                $this->SetLeftMargin($this->left_margin[0]);
                $this->SetRightMargin($this->right_margin[0]);
                $this->SetXY($this->div_x[0],$this->div_y[0]);
                array_shift($this->div_x);
                array_shift($this->div_y);
                break;
            case "MULTICELL":
                $this->_enforceState(51,50);
                // auto-create a page if needed.
                if (!$this->inPage) {
                    $this->inPage = true;
                    $this->AddPage();
                }
                $this->MultiCell(
                    $this->cell_info[0],
                    $this->cell_info[1],
                    $this->cell_text,
                    $this->cell_info[3],
                    $this->cell_info[4],
                    $this->cell_info[5]);
                break;
            case "CELL":
                $this->_enforceState(51,50);
                // auto-create a page if needed.
                if (!$this->inPage) {
                    $this->inPage = true;
                    $this->AddPage();
                }
                // redo the link logic here. blah.
                if (sizeof($this->href)>0) {
                    if ($this->href_style[0]) {
                        $this->SetTextColor(0,0,255);
                        $this->_setStyle('U',true, true);
                    }
                    $this->Cell(
                        $this->cell_info[0],
                        $this->cell_info[2],
                        $this->cell_text,
                        $this->cell_info[3],
                        $this->cell_info[6],
                        $this->cell_info[4],
                        $this->cell_info[5],
                        $this->href[0]);
                    if ($this->href_style[0]) {
                        $this->_setStyle('U', $this->U>0, true);
                        $this->_setFontColor($this->font_color[0]);
                    }
                } else {
                    $this->Cell(
                        $this->cell_info[0],
                        $this->cell_info[2],
                        $this->cell_text,
                        $this->cell_info[3],
                        $this->cell_info[6],
                        $this->cell_info[4],
                        $this->cell_info[5]);
                }
                break;
            case "ROTATE":
                $this->rotate(0);
                break;
            case "HEADER":
                $this->_enforceState(63,50);
                $this->parserBreak='';
                break;
            case "FOOTER":
                $this->_enforceState(64,50);
                $this->parserBreak='';
                break;
            case "COLUMN":
                $this->_enforceState(50,50);
                array_shift($this->multicol);
                array_shift($this->left_margin);
                array_shift($this->bottom_margin);
                $this->SetLeftMargin($this->left_margin[0]);
                $this->SetAutoPageBreak(true, $this->bottom_margin[0]);
                break;
        }
    }

    function _enforceState($from, $to) {
        if ($this->parserState!=$from) {
            error_log("unexpected tag (from $from to $to, but state=".$this->parserState.")");
        //$this->Write("[unexpected tag (from $from to $to)]");
        }
        $this->parserState=$to;
    }

    // default is pt. works good for fonts, so yeah.
    function _getUnit($str, $max=100) {
        $str=rtrim($str);
        $v=(float)$str;
        if (substr($str,-1)=='%') {
            return $max * $v / 100;
        }
        $u=substr($str,-2);
        switch ($u) {
            default:
            case "pt": $m=1; break;
            case "mm": $m=72/25.4; break;
            case "cm": $m=72/2.54; break;
            case "in": $m=72; break;
        }
        return $v * $m;
    }

    function _getAttrUnit($default, $attr, $name, $ref) {
        if (isset($attr[$name])) {
            return $this->_getUnit($attr[$name], $ref);
        } else {
            return $default;
        }
    }

    function _setStyle($tag, $enable, $forget=0) {
        $this->$tag+=($enable ? 1: -1);
        $style='';
        foreach(array('B','I','U') as $s) {
            if ($this->$s>0) {
                $style.=$s;
            }
        }
        $this->SetFont('',$style);
        if ($forget) {
            $this->$tag-=($enable ? 1: -1);
        }
    }

    function _setFontFace($face) {
        $style='';
        foreach(array('B','I','U') as $s) {
            if ($this->$s>0) {
                $style.=$s;
            }
        }
        $this->SetFont($face,$style);
    }

    function _setFontColor($hex) {
        $this->SetTextColor(
            hexdec(substr($hex,0,2)),
            hexdec(substr($hex,2,2)),
            hexdec(substr($hex,4,2)));
    }

    function _setLineColor($hex) {
        $this->SetDrawColor(
            hexdec(substr($hex,0,2)),
            hexdec(substr($hex,2,2)),
            hexdec(substr($hex,4,2)));
    }

    function _setRectColor($hex) {
        $this->SetFillColor(
            hexdec(substr($hex,0,2)),
            hexdec(substr($hex,2,2)),
            hexdec(substr($hex,4,2)));
    }


}


function ob_pdml($buffer) {
  $pdml = new PDML('P','pt','A4'); // P and A4 should be customizable. XXX
  $pdml->compress=0;
  $pdml->ParsePDML($buffer);
  $s = $pdml->Output("","S");
  Header('Content-Type: application/pdf');
  Header('Content-Length: '.strlen($s));
  Header('Content-disposition: inline; filename=doc.pdf');
  return $s;
}

function pdml_entity_decode( $given_html, $quote_style = ENT_QUOTES ) {
   $trans_table = array_flip(array_merge(
     get_html_translation_table( HTML_SPECIALCHARS, $quote_style ),
     get_html_translation_table( HTML_ENTITIES, $quote_style) ));
   $trans_table['&#39;'] = "'";
   return ( strtr( $given_html, $trans_table ) );
}


//ob_start("ob_pdml");

?>