From c56f68243457584e3f07a6d20b161c8c0dcb05b1 Mon Sep 17 00:00:00 2001 From: Anton Krotov Date: Wed, 1 Feb 2023 13:36:55 +0000 Subject: [PATCH] FB2 Reader: refactoring, reduced memory usage for images, small improvements git-svn-id: svn://kolibrios.org@9898 a494cfbc-eb01-0410-851d-a64ba20cac60 --- data/common/fb2read | Bin 24753 -> 24901 bytes programs/other/fb2reader/SRC/ColorDlg.ob07 | 98 ++--- programs/other/fb2reader/SRC/Conv.ob07 | 84 ----- programs/other/fb2reader/SRC/Cursor.ob07 | 8 +- programs/other/fb2reader/SRC/DOM.ob07 | 363 +++++++++++-------- programs/other/fb2reader/SRC/Encoding.ob07 | 266 ++++++++++++++ programs/other/fb2reader/SRC/FB2READ.ob07 | 131 +++---- programs/other/fb2reader/SRC/File.ob07 | 33 +- programs/other/fb2reader/SRC/Font.ob07 | 33 +- programs/other/fb2reader/SRC/Graph.ob07 | 144 ++++---- programs/other/fb2reader/SRC/Libimg.ob07 | 30 +- programs/other/fb2reader/SRC/OpenDlg.ob07 | 4 +- programs/other/fb2reader/SRC/Read.ob07 | 42 --- programs/other/fb2reader/SRC/ReadFile.ob07 | 6 +- programs/other/fb2reader/SRC/Search.ob07 | 84 ++--- programs/other/fb2reader/SRC/SearchForm.ob07 | 28 +- programs/other/fb2reader/SRC/SelEnc.ob07 | 175 ++++++--- programs/other/fb2reader/SRC/Settings.ob07 | 64 ++-- programs/other/fb2reader/SRC/Strings.ob07 | 34 +- programs/other/fb2reader/SRC/SysUtils.ob07 | 25 +- programs/other/fb2reader/SRC/Txt2fb2.ob07 | 129 ------- programs/other/fb2reader/SRC/Vector.ob07 | 90 ++--- programs/other/fb2reader/SRC/Window.ob07 | 48 ++- programs/other/fb2reader/SRC/Write.ob07 | 42 --- programs/other/fb2reader/SRC/XML.ob07 | 48 +-- programs/other/fb2reader/SRC/box_lib.ob07 | 4 +- programs/other/fb2reader/SRC/encode.ob07 | 149 -------- programs/other/fb2reader/SRC/kfonts.ob07 | 2 +- 28 files changed, 1057 insertions(+), 1107 deletions(-) delete mode 100644 programs/other/fb2reader/SRC/Conv.ob07 create mode 100644 programs/other/fb2reader/SRC/Encoding.ob07 delete mode 100644 programs/other/fb2reader/SRC/Read.ob07 delete mode 100644 programs/other/fb2reader/SRC/Txt2fb2.ob07 delete mode 100644 programs/other/fb2reader/SRC/Write.ob07 delete mode 100644 programs/other/fb2reader/SRC/encode.ob07 diff --git a/data/common/fb2read b/data/common/fb2read index bbcdee4e75d8695b22f5703f1d5b996818cc4d66..55fab8bf468d560d1f717e3c666de87b919ab6f7 100644 GIT binary patch literal 24901 zcmV(hK={8)P(w>5Aprn^00001Mv*2LLXK;4&&M{gp_E$BL7$>)k@Ut+$-6Js-LiD5 z1(6!!GK4AO$KPU16e+5hVI#7!SDBVQ*Vspf%=KX3_s!QxG`WfnDFMCuU;R-j?c7 zF16m!IK~ra8FH;NHCrl^a_%_2HETNHjqLiDp0nu zjIQX^-g}gsFqY~_9+XALnlr#FJ>;mxsKhRA7&~K8EOzxx7rqeNHQBBt?=Ys=4to5@ z>eHPq5ayKp*1J){RpJN@E%gRy+?2^W=|z?$hps}?b@#K-(dCWWZ0QH_gQZH5?ee8L zbb2$9`<6!;Jg@1s`$13JY{rwYc%0Ii*e)Jn2FWA^V=*-u$J!ND~douO=bMz5Y(`7Y^`2lcB zn?aOm2=b#C_Wwr9{bJ{0_uH-&zweM^YbQk}`-M3M@_X@kYzoT2JmgmGdv%~=vtOl! zkMjL$XVntaLwbViRe1H@;T+4gcpsMHq9c1*UXjH3TK=)A7MC|f#9q6fDRcoFqO>nT z0*n~{ANG?H0<&vse=O|5pyd~FMh;2HYq=dE^mukf%$v%lK)Uy>7)+SdF3{F-@(@&E z_GgzlKX+hQZm>x}D*m-{p{;k3Q#8sT9@hNh0FNm2G9B{H62XFce2*p>Odkp_!2@>MT0y^xOx$Ee%*nZJk(QUeJoIFZP>pj@y^bjjI?rj z4$0~0WVZ{Vee*i^k7TH&6Rp7Z4G4)RA=62?6U+fkbQy`8@93M;m&BbGc8#CKNACs? zbhT)P0?e3ZsFzKUzT>JKveys=1-Em@{je|dMNPBZ)|9Ll<2rwR%0}*bmeFc7kNFIX zDN)?X_iKhb62Omu^@|URs6D-2Sgx-wykT-;NIdwU(8^s&jGj9|bS+12qc_KluyQD! zzHMc#a5)YVvo^P8U*M|MWmTKKn3*R8H@Gu`$;f$O6bTcUYhc)-cK+Srf*J$a3ni+- zwBPu*#MTifrd0vjy9W_$cDPYr(d0?Ot{%H@QGCo{KD93X=n~%^yH}cFAX+`oV!SU4 z{;(42D3+zbPg21*DtKt;TdD*k+J``r;(W{f&J}`015GF4o&4PIfGq7WC|~f zCijU71K!F{Z*0v=`Ct7tym@X`2bHLuygYF#X?4vtn=5aCLBwvuTE#JspUG4mfPOL1 z%$gFNe4QO_2+SNlATCF|BAD zon<`P87JNv(!&DjnbUTF=+DCi1Iw$zorI@l|JgHRv$a8C8WFA@w=M5Gul;DTIVCFX z2f3a2Y%z_ZbyTOe2<<9vn=@*ZMp(vR6NX>*z4yj1LB23=)R`SmU6a7`t#bveXpC#Q zTk5zBt4^eIz;X`^E7f5Fzq-BwZ@n$7`Du|gm=MlThV<13b(8BH6= zrx?5i=P-$nxIpnqZHwK3{l?f)JqM=P)j)l3=D4h)Kp^BgHqzt1c=Y%T;cRA`d_^?k zd(UCw0BEt(5TmBzaf8o zSs8>@+t>_J@&5(q%`_X(TDv#!U7pVwW86$qM(1<=N-R6YaOO9oV68}iHCc2;HU z>*+sJCe^v!$$UG8;8(2mIY^`E9x55|~+sTpFQ)-DR?;8Ko)PrAVFs=X?Bq zO9H?i1Ck_h1qzDZ}7Gs&VM&x4)vSmN)p=X1^ zZ|$PlpmrTQ*$WGFzMyuBWH0CdTVe%t84XQ=;bNR$hZ8!mCv(@D-R~pOaVddh!YVu< z8DppN0&ca_N(#Y28dblCiIu~b8QRq=#pqQ4Qr-ysj7y|Bd0YMHP0)vMry&^254%JI zVG4;{O*k_`kDMo+(7$&aNS~=NWr~njOZ6Eni@6(umT#WX{O#~p!wQ1)bRGR2|MRig z-lnHF3;+}WDSrTEFbRRn;uPt4gXv`JVp+okn}BJNUoEOLPcj!H`wXuYDwu!D;2N&h z;iqKxf6QKWQ`td^5JiyCWp5*K0bZeSnp)5)+B%dh!wrUn%RyB#@$_IrDgeQOVf_oKWx24@zEoc)WnY?QiH)8 zMW?)cFKK~dPvIUtfw6mgB|hfA{;quMzw1j^lLojE&lTl%om=q=ZDp~%XlY^I)qCS{ z7gfUM7}+v#7ebc4P8;JwJI;AgD2$JBD*LH~!xC?xZ8Evo`Gzp+jAs+`8lu&A*XmZe zhX!gEHwmQVP4ha0D7ZiQ5{hY-L_&oE9${PxRSHZOd=urG~39A26Ca&4>flNt=S83JEc8h{z3cgE=yJa}{S^ZSGhzL}RUd zcV`KikpD^|6)^~PiRj-eek|$HumtIGsBVaavgrRCa~pNj=}loqHJ0(a&fI;jawOd_+HA1ynR{2>XU#TtfXtVU+H`ZfESJ%GV9Vmi z1Z6U&U`)MBTRwzGnabat{xtq`?kV$e%~$^QHUf zN2Y%J>TlJyH^x!o3s$u1b5twF8k?r6meF3W6@2m%FGsp_>1GiOoVjR>7)!_`v%&mg zdOgO=&>DlC83(ec>JI^P7T|r-UtkR681jgk*hD8D{!lUKQc!dMAD|-^xXe|(Z4lcy z!9Sl4i#N((;1=?QwW9)|-Oql2cF5K=0$5J-Bmw7Yi?Jt!xMoPs69g)x6=qj7?W!IC zAV%B0!tCh1xcsyKF@F6Ww6RMxF1jb5DNGQQ_9KB?unDg(L_(ViQUBV4%BkNSv?$O1 z$eTOcr};dG_6%xC^Z*)A6CuoVA)^PLMd1Ttvm7%FvrC~b>U zOjp?FUy%K)h4nnH9~aEdy?eX-81974l_d0UZBfi~}S8VryUh$bkX|^DG^Eq0v}T``WfV zW4z725@T$;hRsD^$9Ue*~hhV^2GU_ z&JPtK=Gm8^1^3*ZS>_1c+pki{`<=?8Ul$F$QP_l#zA$N~ z2>>LerZ}S7SUWPsZJHY#6*FD+z^(~;jQNs9*&40Wzl85VAes4kwJxTHYW{70*u~xa zpkR-BRVi>(&qwcj@zS(J%nnB2;?->$W-oUGMJ_ateukC;}t^@VmC-_L|qO_Elu5r|4Udd=uHVreM`j;uV!8!1ObmE;u8OYs=xkl?7Tc8m)E!TAh98oQG>Kd{lPkphT_`>|=PpZqbT~hUNVPb3L^H z-yFU`AH5|#Q$DXrvm+%SaUy%bpyCQ<^o1#{LxJFYADdc3C z)v*1Vp?E#_Pn#}tWT+NF2=r~65Ew#}u|kptzbWXVT1tJi(dT-jgqw$h1LqM-~v4$W9t!(0V7bdVrep2qny0313(g%d?ENDL#ArE~qEd_gKl2%*dORfRsC8xRm zhH*1HfN~s)3#(R(o@2TYm559nOxT+{$GOUdoi2d={f!iDB+};py3qR=dJYp-KNt-m zjFCGpx7EejQJKXF*XBcZ<_XwcP0#r^vH<-wU0S8j5pXJCL4crzzBSQF-kywu7wBkP zqF|QV-~$w~R2DBW)>oZM9~N;E-n$b3Tih4GQ@wA(-K%2 ztQadxhrm0u=BdVu5MRggYCcTueymC;E~6vFOgI;rAYkTLM3qdX%5dnJ+Lb3OuX;+WWlYgcaNA0j zjksNy>fRAv;+t>}O$i_GZwD8!blvR^h0EuEQg({*C^#nH21e3B6SahdNS6mnNrgg7 zGG(LQBZ=Oj5_T#t7EgrH+RtIcHT=T@gfm_a$bKkoszI++2~tDY7+PPBK)SXi!;0B5 zn9`nt+;hQ_%#@f>F62j9itRYa?Y31lPOCsXRCfqF={zX0k|`2vr3n zsq)k#j7W|nL#-kE6g#qRa1okQ* ziv01#kFu6E>0pPHzqt=DB8yk{O5`$k(qQ-texYB89r};bJe~o4boiHg9CH`o{c1JB z*^hBX2jC39o@JD_B!FiJK!ljQ;*kD+ID!^tK|XCv->Yihy#A%r2@n=tH92&}nsk(E zu?n!LV`y4w!+&xZD(@4d4VQOuGf!+T7qZG|p8M$<(^q^QyI}?AVt^d_4d^OeXap}D zRj`;SWjqE))QDu!A`Rj=FDaC0sZQd+Rhn35kf^6CX}No(p^~KKgf8@dT~ICJ-*Z~0 z)io@$QTf#$ci_9dSVrsS-t38P5|KYkBn`2(sVoC!5xinhum1?&L%>&BA__&h+?@l4 zY&e^Gnmfw<~B%|8nOR*-fpR#Nx~Zd}jk@9MfkN69Xe{HPKJ z*?0PONPRel2Tf`;p?8k*uf2+D4}V;IePYK~4I`hKFE#iApSC&X2{>E7wZgkZ{t#vL zW$vHHdCoXX6x{IY`1XX8eKyS0t`zY(3v|@^aOG0-GYN{wJvZsWx4w-vI{;=$4enmF zYe^mn~`kAX{6pBbXT1I(K(-U*8BUq`GVp|*?y2l#8tngq zT~Uh6`XA-3Jf(_XMA$Kf8W#FU@*V4@BM9=eI`~h;k<~Rk>z0h|Kosip_t<)`l1K~jgcWOE4h%v3AIqySW4nBO8v*YqT z1e<5UR(p`X_sAnM`Pr@SFUD={j4!zw;g|U^||x zRQnm!a~N`&z;$?92qaIp%s^80PSP~Ozr)h!QFj#!Lu$;?OV${`hvjw9YoZhH`kOMy zf2`3eVFm0ePC)-1fu5Iz(IB!z(AuE~{eu zMS2kC`LHC0X-O+YL4TT0EN(UkOmqh%LTxZBsF%ZKKp~VGcflU8LjTadwOyxbb{+1g zc(rsT8s4%`osKn)aXB)FCX$!`+Gv$US%ceIRa9)^IN4{M-Z4p`^OW`wJwPsMs|%ng zB?}Dk>&u$&%TM5m*C{k^&prKrZ~Jx{TLy+C2$TNOBp!s~Nd+yiXPO8tSZ;_SaJ9hN^1u z!ByWjOq>(2<-@+y7v?xNH*JIP6K~jF^vFg2Q14`Q?kY-eH0nSJB^q_e;L_U7`>!0Q z2-@@p#jM355H4ZF;u`e9*@MPrN;a6|_3mcsg5tPyn=8{0;XTX>9#dT`zq77^zI5jK zfe6P)NIdRhu97)@^Ye0an=@NRG1}A{dt$E=wS^&L?`mtyH4Z!0TY)$+>K2CH|*IHuw% zd;|O+HnK+pE{^2|lR0Apf~Vj>)9V^=`c`MM>&8z?O>$?*+Q3gj&7{)557J?18rf>@q=UT@uPkaWX{jKf# z+z!TtP{nM32M#7LeslIA3A_o-m%emX{CIJW5Zg zqU4tfq{Zz*I;O5KU6k&=(pHG%XAv0E>T&C(lk8MDLeVqd1Jg6JTyd8Q6ds&g+Hp*} zW6~yA2ZZfL1I*=4ydq}bwnzJ@sfl5hWVoiNb@0I?t#FWWPGjJ+NYyR`tkI(R2wI##CFhGxD7ZZkxewKwtB@tj1av6*EMK#7fH^$w`HA)M7BI!?609m*_ zMR(!1m~8I2>r80o;cB<+{rv3jhg%Y{W`vO} z#*z%KtqM-4Ka-bw9V4)&Oz8@TVcWSBl|gkfMh>QEPWP!NIXnh-Y%+q6M+t*-pAXMbUa!UP47j8A~0%PvA$c9br9~ zbrM%`u9PD?M%6HFY+O3Qc&fbszTyz-Dk~4@Sc*@ax5qOJq+`#^oH>L%_J=qM3?b2T z327!1ZqF@RriTq_s{LmEtL|HUYc%WtxB+37VxnWSB^8=I_QZ7vPgDLw+ig=-KJP}= zc$&lc5zT!aID8hnFV`vkxxA1>%vOptKwPZSRmHHjg?|MN7)x541O%y}#B0fe%tyIi zo}w&VIUv8Eq&n2|mSLhzqHsA-`f6auQ5XgR+a8~a6sy1EZtH9MB7ohMDH3%gl`xNsI-;~#4T6ne8Qkqai zpB-C(39tIvCN379Px>!v(ep5yHc6PkxpupP~v# zh~fgm7BdpInt1LA8~e(9e6*SF$G@v>OMr3dIzlbK-CHznS{ck1I4^z4ZgBU5s0NxsS zjxc~)>*Fnsf6Ic?bP~25vDSXwE}&{X)PE0iXWyNx7f+8rE<~dXjS6wBt52W-ckbiS zF@pT)k^(^$pdynZp8=pz!lJA%dPGP~k=f4~D?e07dz#dVH%P0(IMpb<;nEWn1Q02| zZIWxM&GB363KT~Z>pvb2V=DDUb6Vy;dK3O|<@!#0ieBea`l+}xA*fMRJLiQ3ZmDvU z^{!t^6j_fnoRA^n{H`?XaiUpOYMzEV&sw{c9;NL#bNT{$oG!eP(ed_9j5A0Z*(V2PWQ z3kMDm^?Wx&c(guFP00AZ?~WAVtTJKirzJ^T4Q`-qyL%PUvvf(aoRy3|z*-Z>3F5ta zWtd9{@{OS3dj2O8xhAMvtJ(|)I}R&W)GEQ<&Z&bR67?}S&YX8RJAyMa{KSHi7r>FRW@P&FTkKaUr~~KZq;P$$N7ZnKz27{rs}hhq ztla^?I^M}%WA!9(R)e~ z1@%>DUfi}*K1Q2hc23|TiuPCU(3y$`Z#miXFZu~)aVd_D7w>WPv6{zrE&AWr$#!u< zowq6~p7mcYUz{q38pxy;dyB2eww#e(TT=~0YFuxlmsvf8=O}w!w8uJXg(8|-7$l$7 z&ocSeXtbYSoEQRr#x`z$T;2zWj-ry5ctCpU+MQJ&p%ylDJ^c9?EUYiMR2R)$m9Yzb z$P;nAU-`PZK_cM6WVb1EhpXaVL&*jmH|#ldjA5h1F97%qk1bO{xz~3@@0Z!21f^w> zCQ2iC-^wzuw&JxaPxc<&E(uTB7`mT{HsHhn^{WYA492t$|Gb~WfG3LKzOqe>NOof^ z6O9`-yhS)46nZklC(szOWPdq*w3$2=FC2;Y$CDyXd}H}W%upSR8UkU_C*=s(Tb?$X zcKKsH)?%MgFf@~KhfVWFnLm75wJm#jNn|XUFw;EUFNLlQX*|Qln2tSe>OY27#WpL2 zpd;5dt-x>vNn=yZui zJMiP~VB1-}u+&L@vS5r*d&<0(Etmjgm+Kxsh^nWOtLm6@h=r4ijlX~gGx2R#30H4N z-=31#<k2W*AZOkrzC&OStk5p zZuPUe3-}OT9ZJ^&C8G4{E`Gt3UE1uiyYHmwVI}jao0c3_e9+}|Ue35C{qIW;+6iP{ zp3pwD1$W|9p#)p4TMn0 zHTlW8EEi%>1DCQrckWC`bc|(JfD#E(U9Z{GA>tHeH8cDzE&?NWnfwov} z^Ud{MfYf)3!p#P<`zprE*!*5(A*ZXRk>P2wKH%f!S79gj_78JBf8G%#w|kzR^)-eh zhmQW3Cdh*PK7-#C@50Lk zU^Q5!`2fCg9UNNS83L$su6n(47|sIpOqbBE$7{7j00GxiY<}hf{h%PZrK)gMCWI_o z&>f(|Et3exkj4v9o^ST83&|y|;SuP#HKR|GFj#+#A{e+DN(Osy{&c~6?+meX2hy7x zU&2U$aM|i!V@~r^etpulB^UEB{!MoBjjEQl%EQ_6x3sWds=PiHzIn%?NQk~E#+)zK z=6q!kc!O@q4)l(W(r`=N3IVB+ikPQ<3+1gLszV7%qR))KUFi;Oc(PtYoO$|N!uI<> z#u*9EJ%U_VZR*k=7(TD@9{jWT+iLZN{zV~xn*>v@Hh@;VU&{!V+tsz{A9fWM&h+ac z)}+N8lm&#}M1r=ZwQ)6>qZ^* z{)6+Ci!SEyBO25d+JT>0i6;gvJj~j81KFd<@xTX@-t|XrJIt>!3kL_k}`G zy(0an45LFC4vA1=5)f|a_7~;Yt9w0hFf?4hTl9s2g06XxL5k4`d!zN5an5aL=DfaG zeqN1~xoDbGRd?3CQZ)bt|1}D^2djUtvdLrv*oM2cUs>x+Uz#-#ZG=L?;vUm!$RS{R z8sY~g05U-TcBDl53QBduF6~|7W&uVSZ?F2x<)cez&Pivd=PY)@nW)AGDCHoN87PsG zGAv)#|JZ-}Q`ZAAusk>;-@A1Wcb|c)ot`iZcd1?&ht}ODDox9jnwsew4uz<^Q z5dDlwNRH32N#Y4q8u-O3M6@)~#Yh61Ucj4L5tE;`Zwb>*Y;$DL?2t`$Zs(+@RI}fj zJKo3?8v!c`=7 zhmK_p_xU=Pfh18-PyCQKR8Gr)wXAeF{T|4ViAcIb|FS^GUCiBH0#!oB3e37U!_&Q! zUo3}P{7|+>+UDKuHggq1%5B;yOan()hj)ZL1eWxCVO|KTQ zt4%~>_9bD@G8=%<8H>E`DZZ_-y+qeglWi&8rA53g>ANYG^IQQv5 zVOy=@4AtdX86HR%{Wiz{N8cu_g&|xBqjy%GZVy3xo1udZY$tWzKpw?0M4{$8tf8-M zXSK;J=%a0m_-@yliPpg9K8V*Vtud~n^AC|(L{}WM3VuiL-@%ePvTex>2b?CmPCor_ ziHTqwTA_Ma!+N&E>eFEApRZgz1-R|;Llf+=|G>|v5uwwKwCv@#x8Y!Diz$bYngFYF z{8^viornNgZr^Ei-hucSu%#JNjgicb?Js+-S}<`^tUz7_U#u5Bp);Z(1l zl4ufvbBG_KFKL)zve!FKo#yvd4-A{Z8d{nY@Wz9%5RVA5Z@!GnRolAQ zpw?Rg-60=E$i10$);GFPho{=mrY$zDt^PQrSa1&H@_x2C3;^50xG4l0_|};J_5O;J zI-I2LLn_r{#rkrwlgF`!{jPz8bM#uAf2J(2C~r=6yN-=F_l2K>WmxR2_dgEfswbZw zlb2P{eW^tOwPDSd66&#nsR0_$=&B;)jTih zG=%D81Xwxe#GsFzG+U#H5?V;a$;s2uH^e08dwu#WZ8QuVuj1D{shRW-dlzhH?rITj zHFk*WB=>tSBpb=?S-cms4OREtx=WJWWRNF7t_Cuk$W%o=XO zGjKz2Zj5;-n|kzB=Ggc9U=G^0y!o`a8ayR)dfv+}3Q&^a`a{xTy1&BwC{BNeul_Ca1kIqrgIs?A4j;i>` zDEo#W)5hN`rb4z8?8!MVB3$#h(rMt``BJYJCJxNI;03C~%Ih0mUmFh5zGz0 zJ6e)RL}jgQ(pqo}7*c1*Qj1-FN`F?gNy$zoiKn1vJy55q83KbU2PAXs_LLM5pC(k% zmaN{GN@4_}NdbxyBMhWnE>Z0?)o?@_LM? z@^oQRdFt_t5wT)Nlc*Cc&N3sYMfPdUkOlfu&?Q6}_mZ~G*!66}KcmX< z?D_p~Bv3N{(llLdRpcE?d1SSHmLCzPoTrIhsviE$E6CaX)_zXsvWPg+F5g5bH$g@z z9RSb!>{?o$S(bIT{#BbC6RjP@TatB#POtyBO1A=~P5ns2qY;F+AGP_g`tf1lC;Id- z_%n(fdayL3x|VNX@raNE+=bP6*vVt(>v5iWOB@*vu-8hwWlbil zn*5O_z|bfQnz5JFMt`-M1W4%T<)Rpwr>OeIF>&2g^GYqt)VOvH>dNKd%$Qr3*;G?hW@AK4RayL{3Ci`3_o9}qzc>cVtU1%v zyQm~VFDqhUC%mBmF@JQTS2gf1u+lou5Lbck_>6r^m_d#@fHd&4*&p<>uB*n#2AhqG z-9`MMxa=T>QEojd<1^QS!ja~z!p-rH%??evJE;v;>YobRfddtBE!|9$f@! zn1(@<>wvk&7-9B^V8%*E>Pk7d#R??l0lR1vqC+^$p=IOf06-jc2#zYC z!XhexVmI!Z`j)nZhSjLD?6rhV!VUsg)FXaQX_h%(D-I>m&$a!eWC6{-fNYost*?tX z`ILklV`^^)?n;MkGY@yjR;0U#fY+KQl|n3apOeCqel|tkT%gG6n;UUF1-Q?p&f0B? z3te*$9&E+=f-?kWs|=w5#mA4c}xgg->oT4tEU%5B>31= z1UeKK#2aBHCz`p>fWmDAbJm-c33`d^c~aV(*Y+g5$LZPVHt1+yAxiugGZju|er2bP z7jzoLBNzCPRP+05eZj%|bgEeMZ>-U|D(TWFn5L{l+g33rLQ_Xl1@^BHI(tRG-4$%= zOJC}LtB8&v5!C+V_6?B{Crv$Ut1>*;hL#5M-m4v9Qu5(vZGQT8;I|prP%eey@mAW% zD7&gKH<#hbvL>KOUf$X7P2{Y9%%}f_8)}A*c3%}pOqMY-GRu3?N_oSxfCK?#Hgf)|Hs>(i+h|ge>DhtnZUti#oT*3?K+Sgf`skvTUgdlimR!zK;c)1%B zrQO@MRjlZ+sQM3`z-++(CFELW9-CSiNsbT5&hoXl3T=vrYj3h zKH|Rjw`yPVeT*_h!B9BnnnBl>^w=%rPD(UL9jqK{6$)lMI5q)n+`Y>llW;enalJYF z%G)BED;hCMu8OxCIf)CiqrwJA{^yS=S`JmRd3*0@5*dOgz%2!?V0Ed+b|jq^O#PkC z;&p^8^Cg6fYM05_JQoC$V)be&jX-XL%qQ14CQy2TKJv?CCLNK^vo!zC&mqSh}7@M5h1|x>V#O07G^X^q71*J^XHj96lCTT@r(3X9Udl0S&XQNKP3wE=c17| zllzxApn|{r2=ck$eu`kl9ATyy!?>aM$(L!xT9yR7f%~uwJrSyxYo$R3#c|gL8q%RT z!JCTa*MthwJk9qYPe8)gnlX{n;LWn0LMYDEPo_qus7bFD(X?oH7fvN7m!eKAq-+YO zIj9ZaUU?_+x>U6wl47dERw|Vslv&m3D){#q^JgoeLU)x}6nWHm8DnWJZC8o}gx7LO z;Hg@1YM1_OPo})A4iO&RfU8o=h)fE-)opVdVV56<6W)&3@PuxBW#zsGw~r;we;O@pS-pEdAH&1dGxb>E5(x+l^I)!wRpT$~7q=jLrE&LXuiz?)> zel_LKfR%e<-=s6y5VAdqkp>IW<1$5x-@muCji`%3hqq3C2aZg=fXsz6OH|ive)xo% zhHn2Di|s$J9K!{w4mNf+J8^O3!o0m)@@BC$ue3ksqA*N>O}(wNHugwW5>7V=9f`z* zLuQvXld?y(s>7L-^p`==C){Q@{YaOvUHi&|c+t9z%C9Upx|0Sh*{jw4*bkh_4EH`|wiM_7E5erciWuI(}m`^#L;b2J-|Q83M~V7uXa@?N&*EQ%1splA4bv(DU3h*p9k1D^fn`W`=C@?I91M91xf z^g^;%szFOUN*?z>gt{y+rkH=hD*HRAdH@nnf4U^^#V&08qx;6x?ZWA+$S6JG$=RiD z7Dt=E4y0_vfV9$c&~hMnEKL~BfkFd6Q{Z57_>*ZULAXp{qNY^w+%YE5&oRst$@V7Quhc9aKLqHZ$Z@j;#T~PV`d1 zBa10?P$L={n<){BEK^c&z`47_`Bc8pYc~-T22jTTpEZ4eXv?<+BkOU-s=C;zbhVk$ zfO)*y0z)v>n+DC7vEL;`Z>jk*$qC=@wsEEodXw)Ddy-4<8Val^W?>ODK`OY70&GDE z`t0M?Aa(*h^##4wk|xu{rCe^VaM(dTn!?5IqNYM;Wqrmx2*1lBXcJ&(R|3m*3#}ig z#}B{Fu4Kn@`axkq!AQep%PtFBHx$h(x!jUN>1ri@B~BExJmV#i80W`9w%y(HUyZBz zcexI~RlV$RzSRYpbb@`pjq#r)2=@)xp>#Rxw!W66>Y>KSyxfh&95mbaA4mN`ex_z4cU8Hqfj&i!g;U*i+{{@%9oz zL22Vhj`motr-@8~zLl?1EavsfKIOY!C0U%!t?#RV2tlRy+!)O}SF`&TvRNV3hqam) z{VL*PqEa8c_^T=6wC+{aJ|=tHzPodAmT`4b^p5^US4!1iKv^NPOfnL+cj$=jiZ?id zO}!9W+#M3ZpoU;+f{6aD9#cx`(|;EE8Uic69YaL8w5?L}Z!+3K!q;5+k@p!|)AyV2r8!lY<9X-RG@bcH{Kc(pCB`pl6(^m?8doSE zkEEVH({dpN()evHB3Y-=D`7|f!6xK5JbT!@&_QDVGV*6eqNdcd+i0Hh=H6iYz zgQXz_#av(=+?uJd0u0J47l{ErA;I2{CAcm}Id8t6=i*3Bs{Fa9IUmZnqsV2cO8={` z-}~uYhu%xQ@g*(uYwfgWnuqYfO6j)8v}}4oqR1C%+WqZ)2e!l|xp0?U=6-@H6f#8j zE+=(piQjC zTDxB>sZ>!0&N5K4fr^0u5sX~ZrzFA|^_CxKe6g`5rnCJw-SkBrw_E}PBON-9 zzef$-!;`Gw(gLtNV7F-OOKh%{tytOkzp!kHO$9eKy5zJ!vu#k$oi^KO;vP}p2^-!TO_2p5V z7Lo24qx(Y!v9mS@dA>usq!N7&vnr{RtqSXD0k4XC&dn7Y$k6$#G&%l7`QkilqfCU{ zuwTAa7j!hIVNKZE>(UV5;r26B+Vp(8q$!9y#UNxv9db$9GhJ}hAd9Qtp`(lWw5`i2 zF3a|OD=ETgCQq#U3hH*9;vncpFrm!c5hJjWq>*_m7TMHQL6PxpQG3f%Gc)rBi}v*1 zw?(_$q)Z11UpVPQa_FQ#x#8RPU9)+ZBe`Hmj0@_ODU)Zq!xn}SCG2sIwdkx(+A5x; zbt|2_haOX%V%nR~sTILAJBx@;=aXdynUjD>(USetIdE?-44eFdiQ(-XY-qwu+uNnK zZW)$2FMTzU2WB*I8U%k-mYVrIB|~v`l`KRV5l72VautLZKouo1{P&>|38CzFiZC8l z^{t|RWYPh?AY!56;HGV@T3qCkaQc;gkXnL8`|&CpHt4+dq1^dJw)T3{&X84mvb_7Y zWzfCQ?1u$tF*9I_tT-|I=@i?W<#X0nIi8a+Lp8Zr$lZlEeo>L~p~;P(#Eu2lg{TZ+ zOGlfo93*lQ+TOQPxNR7k1Mi#$wK#qR!+L+ciIP9YT$3X+ZwkaLQ#1S5v0gf%fo6Mz z#*j`)yy%wxXosZUL!*hsbGdcM$B+q5jVJyBUrDYe?DCa^e;|^b&AP;T`6>P8dE~_R zIHoT+Fp2ce%AWMq_jM%?i>+6RVl`ac!z!(puuJ&QPnq@-EU^&Cq4Xqc z$8_=lgM)ndGw-p7XE#s@JA&Q`PZ%^NpapFXP#7KHHQLeqD3rg1f5n6_zpE$uwvT{ z!EC&$6RnO$;7P!Q@NF3YfjyE6gq$dssr7yPSDw<)ukScdq%bLu+j+!fV%htY6~;1_ z+q!CBWy&KmtMZ?KdpH^R+=F;Vx<(?7aDqkV`j;{j6tbyyy%m8Y&cb8KrZ3NjrAp3%!b6UOyMPPghR5GEsolU-Y5|6!1~eXM|$a@M`y> zO+f$aGk8+M|KSuEu)$Y~bZ3=&V&orG>$YTEXE@oXDAU$~BpAmfJ|n%*&<-vaZ9+TX ziU_vv%F(G*@JVBtJSolWyH8Lo()#1)ICwt6NtxO0tEx820&6wcd(sQE1bFR&j49opSUE$Y}8P0N*y^5v9`8YRtvq^qGSf)UsCB3fTbHgR7$$3 zL36-BpUlnSkL>8eA#ktbi{2npf>) z;a&dQeVNhlq2Qvjrmwc3chV#bO-&gB7`BllK~;JD%MlVf@&`7IQoAF;S68%O#CB;N!;C4qz?4%}D zxbt(`{4H$-!Zegr8t$tlQ&Qy}+%v$1Wa`5r%O*I@rIwvw#(_+rMI8toXk0J+2WSf- zJyYXZNzrDj&AK=vNCPsD@LFo_VK=P}Yfgp7V5`*NEKc-#G5S!DWi|IYr!{U2%e+BT zoj*QTbn^|*K-W;Z(^r3z+T)pv$vyI2*o*EmBpKgx9H5Oyhl8jkBFZpHG`H}2(%|U4 zU@+7c9I0(yZ0~izumfh|z524Kbu|u40Sr#&>-PnU_1-q;M66#HNake1GJqC`92WYs zcScWsl#1rugIu(K?5Y|Wxf-=mm?R05GpC52KBJeT{#myr7r7FHuWT70&gEU$21hNA zyT?}Oh8;KF#;vEN}s-!&u}h%}t+tKe&=ujfnX(Pw3kZ;UqzNow-hHL8~Kt^bX+80yWv zaFvc0@bPoJA+w7PJ)#HE?S-sbm`8mS*;Hq@vT91;@rBqeX-h!lZV>z1IBZY=;)fpY zN-O}cY)0RI>2=F%0JnZPXJ8>j@X|Z~rV!f>7!|JUHX=)j7;4#FWO|=3|ze(QJc9u#MpAIZk&1U?yM5xpZ+ix$tWlKkgmug5QHQJ()6 zZGyv*?uMOef)^VVS8-Zf<^+6uX)a_uChaV$$0f`4##O{Z4N~iSSnrA`Fi9 zeYv~cJ{wnKLEkG|V!{ZC&rYP%5C*p|WP0?^Xr0yRd)r+(;$^2Tfmxo5@VEn08a(#I zD(BMXWsuW8-o>hQgeT@=NzRM^bfFz8O0E%JEGXM`xBV)+erp~`P2{_%)C?ZcK5;J<{KQ}44;L^1U`Z6U{_u#W&C z8MG~uajJP3iOf*X)#wt22T5M-o50suYMf}FcN)K*(DDUD7i^74QxggXGf_+f;*M4p z-_s!T#9d5w2uuDuti8YY8?TgzlgjRrKfSBfr-hC>4(``ICYUP8vZbQ6Fl#F*kk=#$ zguK@8Pb33N61%AXSW)`gz@c*D23yA6@ZR`hh=upVLI<%QRUb@}KOkkMr$!?QSTR9- zd}3S_#+DdMvdzrPBlkpG1lu{@GXGRu(>{C3z*D{lwUyDsK=(cYy6oH|a}9rAn*;ih zgd%DBD4YOAXx22BkM5Ae;&E0x(T!o26l1ZS_aj0t3!P?GHHJ5_a|@5VgML*Oa1JBH z2yHq1Xr^e;2aXu6>mK|9%$U~6EyjN-*1+V^<5|;h&Xo8Kz33t# zDRSbpQ2tBD7F9!<@8P~R-cFv|)uCGr!Gw;d13Xo(2 zCE2jMXW)glW~BB{({POmYO;eqcSzgLENfv>j##IexR+K8F?m~a77M^+Co=7P$u~W# zqQ#ym1RB%tyRbMLXem)WT%{~)jfn~7-83OE96Kw11ZbiY(?GX5E2j>MGiq2~%7<^V zXXGj$u&R-;jKD9+cJI*Wvr`VnW=f^%JVGE;?|d8=;JyX@MZkNWJ5%ayjLIjoX5;o! zu89tUw%1WSHH=zWZ!SmP@SJiIzh_D&yGV~IuQbK8j*$aedEf8#7f<@XZNi#3-W6|} zC696F)5+L5s8^wHoCs)r<+PLia74!+*yZwNtEU=+roK zoFIBvJct@MtSL;P>}yf0)}WcHAPx8)5=QX&LSqXQ0s!>pmQdoZPJ>xFZWfkXRAh^s zT_z*etvBys&=|&3TJ`rssq4c1jXhnX=pdIiP0NkZuJ!Of<}Q#HYmjGjfPa&NxNCT_ z(|RyOCqYT1rm0wSQh3pY=cssU2T<|R!l}5FfaP!z;(ZSz z*+YP(6Hj7gfAJrfx^|Xi<8_uOr^!Q5*KKz^y?ZVqb@Lrna@S^~{hQy^HW!3}Tof!X z4_DwMdp0py-(0Kr97xwa$2wVvyXx{EL~^F0JvjmFf#D(!5cd>Xd5SqNfNB}>pO&D_ zUdq0Ydf~Ojz6N`8{d1b*bVfc!-ql2>N=AFK2VOn)9cy6l{ z_$|pYOS6hPW9ssokZ%6mnPpqu-$g^F9w-PEZIK)9LtHtvG`0Fb^yTN(arHzmz8QsI zG6(}C*u{y`BryFEHaoMZM5*=IHeZ2FYqRA-YIF`l$U)y{n6mETFV30e=;Fvpj0v`* zhex*x!P4^wRc;C^tE1<3tf3{8>c@-AD)=Q(uM?{0ite`>i&^C;%FnYP}pdm>l~Mb+c{E=QEEs=Gwl>&;tX zxH89tP{1^`?w{hYwXngb*PmHrrOjBr*GKG#b|j21hM8_`j&Kp0 zU~)dg9pG|LdlgfsX1rq!o#CPO4tq!qD_NZxRoFLx&|Amw&O$HNzG>BBhdKiP^vgS} zLX~Vvq?q=-`l&hix_y<#V|~5cpuyh-CpEMWUYwuZ{kA`mqS2#?9SZ~Ir&oL6!jgUW z_t4*U_wl<73H0y~FP@rr1Wt7Jj0+rkfmpENbRp}b;k3NQc|>trAr?Y?q{`rpY3Y7j zVz?c@WT7!;>yT25N$L)jGpHPx%h8T+%x*utVUeA+Fq^A`VIbn$rgdQB)zO?e8`BBA z5B!`He{fbGXjl+EI7~Jr5_Ez8??GjY8g*JXE*xH=KTU_(&i(m;JCOd!mBqxy-E$Ff3#&?=50L7D(-W(?GJVbE4+35Y?Zyc5VpcufmVV zER2u-{J{qF);R)3v(xr|#_m>6L@m@1Y|R?xDd2}DsHt_SF>e?-)z zt3bWwp~5WGG)vZgl{nmu`bsW-09yKw`XlV8kan6%2!uyT$Ktq;uXmQ{$Wo;?EVVCw z4JLF>s~@#qJ03z`jpFq|`ucRY7VYa#KpX~BZedBQIo~NT0DYP0@3K8^dy!JX|21BS<6^J>RXDQFK)5`tF> z0%cKC_;w3Z;I}9)7a&pcM!!**{)6}wKsXMLhqh4P#uT$$I-7jr64gc7#r^Y_vPy-g zB8p2@-`7r(K1+eU<}xr%B%BD3FNbSa%>En|EABx~*w~BtN$)Y6SBu|SS2cx!%xdD_ zOzocL$oS709WYq|_cQSk*&GI$v>^Ad@Nfg;MulzotLV2O1V!5Ow4Cwn)B98S%^BmT zjh3fBb0qc-K1ffOQ%Uq;AEv2UF8#aUVwX_r{2Rr^{#YrO=Frx+=Q(2wQftr43~@JZ zX76u}9&7>!kh+O7q61pmBF=048=fBdZBiB}=eR*i?6d;2~L};^>c}u|{fl zTzq)Lle1=%0CwPH)3FKy+up_UH8A%BmewKtQA8_G8%pTs+r0+_8T($vEJOYGEZ z7Ut|qks>tcmDogW4T&p`I}NIWdu_IcR`dG8vUf#@R54*aEw@9nT23;B`?npPG?jWW<2OVCPm z-Gq~IYxHrKM3tZ{1s57EY4KM`JNt3Ss__uz`k%^xbZ}0K9*^cG#9{hlj~9wrsjUNN z3j4ojJ!~D`_e##eX3oGWUG<4_vP0Ilaky&DNgKq{XKwaJXYf}7g>=nLEp$%G+_R~( zm)J$H^U&dpz|o37maL`wuL;a#ea{ipjsJpKHrnrL9-WJ?g?1}0@M;_vb0bB|F z6l+M62#3_k$`fQW1zI{0ZP*x9d;CXYC5aQcAIsVGk5tVzBZF3WxKVp&m)G}>rVZul z(ueDH%bGrs(;bZgtTC?j=TO9i*yjwOtA~B)>(6pMNCmm_m`~ysXc6VveDx={S6uy{ z2!aYQi(_7^Qfb)9yA$M4aympA_8LC#<8s*_qA;&N0t2gBjnmiseK4In%0UYAP7e+D^1vZ<=~ zOh%|ACKr!aNBa0Mt}O}g(Z{%A4KNw_VuT9W{5IZ*<-KW?$G&pj@i%5rj&F4r9Z;L! zN3ZS^9ONgAo8b~mqvV}N8!mYHKW4GTg~XslSQJQtEFjy;t-F37aNTuVf47o&1*X?y(S9?pDSkAd_2MRMlt_paXP9osNs8DLunWB+ z>?6vLM~phB1G2B(04_-iskz^`U@YL?;4`UuYjCg^E~YB%9Y>O7Va$@rw>VWu6|5)w zg7!S=dHHW1Y*b5TnYY|pBu(VtR0&+Q-9yk2&MI!x$0&`1N)MFnH_i+sS4t>s#*GUZ z+--G2+HwU@!PEFA+EFSZn3IlTR*v%@ek*b|(rb8^h zjf-Sd2tjUh82Dl9J=D7QR%DAKeH4jl447L}aby2;dLbaL8H)jCZbkru-7KQSpt>rO z(FN1a;%0S}6mV#v3yh=b)@ILlgDN>3=emP<4Nj}HZ!3~iJJdvUkili|?646PV`^ zA4sb5GhuR0q1Id{0}P!8Oy2|GoL!bC(PE2;vX_;~5mu3)qIR_$Z#UJtXd3ph&W`Dk z;C#aw6OdVb3*cUK2_5nrV8sF{Qe_ksg9oYOo!Egg$HEXrscQD^P!ZfG=K5%k+854W>#-?UmiZB8seG0 ztUDhm5wWYX93W2l&>6vF6Dy0r8e?bV&R8vWK{FnF7VCmrs-V^zu%B$qwTJ;!X>EuzZn?CT33Y_#Q`t0(6vu;GqyeIGH6!F5f-IlQ~fT>R> z$kU8|0-%vx&ke4ZB3^a0gh!nhri)ub_2mS=+*`@OcS0uvg*Cm!R$6Qg(~g#^H7uiS zDLnZvORaZ~=mwzB`q?mAr1{|p3?*aFUgn5WKWWXCC)Pl#(H!OaCfjM4P895Sl}0?Y z93Nd~WjeB`f|7>~DW>!agb$-Ok+vsHYld~#M97Ja4|#-=d})e;%=5fFew8PRY~fC?8&fcJ}g>bxcIkr zy9?{Ty{!~MUPw@N<|iW!mSP9LA>(h);wb}eAtm6P9caq$QZlpVkyksFvB*c$z|00Q zNBr}L)s7ZIea$+Sg$}tenm}o98 zUQP}zBfCs3#{Wb?65k?7-yyu!C)6w5znjByCRbFjp4kOC%)cY4E%Fqqc49onK6E&HZcs19ZJk-Tu!F*24?NPlG?Xe@nBzjeliqOB?dOg}w z^Yuaz_q@m`?at7ATh9D0Ukg1QxHb-6jdcI?H0VWtbyoBaK1v(y3}a`JYx+BIX(i*s zmUB$bpyf|5s}s6nmoH?QX_N8rv`lN`hPgG@PP3?pIL)xb14HBI#w<DFUyZA;%f+5)sa=D!vl$qP4iwoXlR45rpO)#USWBmH9E$LaNpE-qgWY$k#^Yc( ztZxw8e_;qeW>^^Lat^zeTz#_IipMY%tnUfs0CGVYBOI`;s+O8$M|h6CCFF!?!5AjE INC*G`11zR`^8f$< literal 24753 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

TMPk4a0$}d&wHgzJf2(FgH@<@1^v~|Wg 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 Q$jgkkAGbOHMhE}^1AKu0BLDyZ diff --git a/programs/other/fb2reader/SRC/ColorDlg.ob07 b/programs/other/fb2reader/SRC/ColorDlg.ob07 index 0091ef2572..3c7068736e 100644 --- a/programs/other/fb2reader/SRC/ColorDlg.ob07 +++ b/programs/other/fb2reader/SRC/ColorDlg.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2022 Anton Krotov + Copyright 2016, 2022, 2023 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -17,70 +17,74 @@ MODULE ColorDlg; -IMPORT sys := SYSTEM, KOSAPI; +IMPORT SYSTEM; TYPE - DRAW_WINDOW = PROCEDURE; + DRAW_WINDOW = PROCEDURE; - TDialog = RECORD - type, - procinfo, - com_area_name, - com_area, - start_path: INTEGER; - draw_window: DRAW_WINDOW; - status*, - X, Y, - color_type, - color*: INTEGER; + TDialog = RECORD + type, + procinfo, + com_area_name, + com_area, + start_path: INTEGER; + draw_window: DRAW_WINDOW; + status*, + X, Y, + color_type, + color*: INTEGER; - procinf: ARRAY 1024 OF CHAR; - s_com_area_name: ARRAY 32 OF CHAR - END; + procinf: ARRAY 1024 OF CHAR; + s_com_area_name: ARRAY 32 OF CHAR + END; - Dialog* = POINTER TO TDialog; + Dialog* = POINTER TO TDialog; PROCEDURE [stdcall, "Proc_lib.obj", ""] ColorDialog_start (cd: Dialog); END; PROCEDURE [stdcall, "Proc_lib.obj", ""] ColorDialog_init (cd: Dialog); END; -PROCEDURE Show*(cd: Dialog); + +PROCEDURE Show* (cd: Dialog); BEGIN - IF cd # NIL THEN - cd.X := 0; - cd.Y := 0; - ColorDialog_start(cd) - END + IF cd # NIL THEN + cd.X := 0; + cd.Y := 0; + ColorDialog_start(cd) + END END Show; -PROCEDURE Create*(draw_window: DRAW_WINDOW): Dialog; -VAR res: Dialog; + +PROCEDURE Create* (draw_window: DRAW_WINDOW): Dialog; +VAR + res: Dialog; BEGIN - NEW(res); - IF res # NIL THEN - res.s_com_area_name := "FFFFFFFF_color_dlg"; - res.com_area := 0; - res.type := 0; - res.color_type := 0; - res.procinfo := sys.ADR(res.procinf[0]); - res.com_area_name := sys.ADR(res.s_com_area_name[0]); - res.start_path := sys.SADR("/sys/colrdial"); - res.draw_window := draw_window; - res.status := 0; - res.X := 0; - res.Y := 0; - res.color := 0; - ColorDialog_init(res) - END - RETURN res + NEW(res); + IF res # NIL THEN + res.s_com_area_name := "FFFFFFFF_color_dlg"; + res.com_area := 0; + res.type := 0; + res.color_type := 0; + res.procinfo := SYSTEM.ADR(res.procinf[0]); + res.com_area_name := SYSTEM.ADR(res.s_com_area_name[0]); + res.start_path := SYSTEM.SADR("/sys/colrdial"); + res.draw_window := draw_window; + res.status := 0; + res.X := 0; + res.Y := 0; + res.color := 0; + ColorDialog_init(res) + END + RETURN res END Create; -PROCEDURE Destroy*(VAR cd: Dialog); + +PROCEDURE Destroy* (VAR cd: Dialog); BEGIN - IF cd # NIL THEN - DISPOSE(cd) - END + IF cd # NIL THEN + DISPOSE(cd) + END END Destroy; diff --git a/programs/other/fb2reader/SRC/Conv.ob07 b/programs/other/fb2reader/SRC/Conv.ob07 deleted file mode 100644 index 46111e1381..0000000000 --- a/programs/other/fb2reader/SRC/Conv.ob07 +++ /dev/null @@ -1,84 +0,0 @@ -(* - Copyright 2016 Anton Krotov - - This file is part of fb2read. - - fb2read is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - fb2read 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with fb2read. If not, see . -*) - -MODULE Conv; - -IMPORT sys := SYSTEM, Encode; - -VAR table: ARRAY 65536 OF CHAR; - -PROCEDURE GetUtf8 (str: INTEGER; VAR val, idx: INTEGER); -VAR ch: CHAR; -BEGIN - sys.GET(str + idx, ch); INC(idx); - IF ch < 80X THEN - val := ORD(ch) - ELSIF ch < 0E0X THEN - val := ORD(ch) - 192; - sys.GET(str + idx, ch); INC(idx); - val := val * 64 + ORD(ch) - 128 - ELSE - val := ORD(ch) - 224; - sys.GET(str + idx, ch); INC(idx); val := val * 64 + ORD(ch) - 128; - sys.GET(str + idx, ch); INC(idx); val := val * 64 + ORD(ch) - 128 - END -END GetUtf8; - -PROCEDURE convert*(adr, adr2: INTEGER; len: INTEGER); -VAR val, idx: INTEGER; -BEGIN - idx := 0; - WHILE len > 0 DO - GetUtf8(adr, val, idx); - IF (0 <= val) & (val < LEN(table)) THEN - sys.PUT(adr2, table[val]) - ELSE - sys.PUT(adr2, "?") - END; - INC(adr2); - DEC(len) - END -END convert; - -PROCEDURE utf8to1251(code: INTEGER): CHAR; -VAR res: CHAR; i: INTEGER; -BEGIN - res := "?"; - i := 0; - WHILE i <= 255 DO - IF Encode.W1251[i].code = code THEN - res := CHR(i); - i := 255 - END; - INC(i) - END - RETURN res -END utf8to1251; - -PROCEDURE main; -VAR i: INTEGER; -BEGIN - FOR i := 0 TO LEN(table) - 1 DO - table[i] := utf8to1251(i) - END -END main; - -BEGIN - main -END Conv. diff --git a/programs/other/fb2reader/SRC/Cursor.ob07 b/programs/other/fb2reader/SRC/Cursor.ob07 index 581c1fda51..ea331f521d 100644 --- a/programs/other/fb2reader/SRC/Cursor.ob07 +++ b/programs/other/fb2reader/SRC/Cursor.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2023 Anton Krotov This file is part of fb2read. @@ -20,12 +20,12 @@ MODULE Cursor; -IMPORT sys := SYSTEM; +IMPORT SYSTEM; PROCEDURE [stdcall] cur; BEGIN -sys.CODE( +SYSTEM.CODE( 000H, 000H, 002H, 000H, 001H, 000H, 020H, 020H, 000H, 000H, 005H, 000H, 000H, 000H, 0A8H, 00CH, 000H, 000H, 016H, 000H, 000H, 000H, 028H, 000H, 000H, 000H, 020H, 000H, 000H, 000H, @@ -357,7 +357,7 @@ END cur; PROCEDURE GetCursor* (): INTEGER; - RETURN sys.ADR(cur) + 3 + RETURN SYSTEM.ADR(cur) + 3 END GetCursor; diff --git a/programs/other/fb2reader/SRC/DOM.ob07 b/programs/other/fb2reader/SRC/DOM.ob07 index 45ba0bcea5..73aacebb9f 100644 --- a/programs/other/fb2reader/SRC/DOM.ob07 +++ b/programs/other/fb2reader/SRC/DOM.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016-2022 Anton Krotov + Copyright 2016-2023 Anton Krotov This file is part of fb2read. @@ -20,7 +20,7 @@ MODULE DOM; IMPORT XML, SU := SysUtils, S := Strings, Font, Window, G := Graph, LibImg, - RF := ReadFile, File, Write, Read, Ini, K := KOSAPI, sys := SYSTEM, + RF := ReadFile, File, Ini, K := KOSAPI, sys := SYSTEM, V := Vector, Cursor, box_lib, tables, Search; @@ -54,6 +54,7 @@ TYPE SUP, InterLin*, Picture*, + picture_fsize*, SpaceW: INTEGER END; @@ -73,8 +74,7 @@ VAR Settings* : TSettings; Canvas_X, Canvas_Y: INTEGER; - ColLeft : Window.TRect; - ColRight : Window.TRect; + ColLeft, ColRight: Window.tRect; Ymin, Ymax, Ycur : INTEGER; @@ -428,6 +428,44 @@ BEGIN END table; +PROCEDURE Image (VAR tag: XML.TAG; destroy: BOOLEAN); +VAR + note : BOOLEAN; + img : XML.TAG; + URL : INTEGER; + chars : S.CHARS; + sizeY : INTEGER; + FName : S.STRING; + path : S.STRING; +BEGIN + LibImg.Destroy(tag.img); + img := XML.GetRef(tag, note, URL); + IF img # NIL THEN + IF img.child.first IS XML.WORD THEN + chars := img.child.first(XML.WORD).value; + tag.img := LibImg.GetImg(chars.first, chars.last - chars.first + 1, W, sizeY) + END + ELSIF URL # 0 THEN + S.PtrToString(URL, FName); + tag.img := LibImg.LoadFromFile(FName, W, sizeY); + IF tag.img = 0 THEN + path := FilePath; + IF FName[0] # "/" THEN + S.Append(path, "/") + END; + S.Append(path, FName); + tag.img := LibImg.LoadFromFile(path, W, sizeY) + END + END; + IF (tag.img # 0) & destroy THEN + INC(Y, (sizeY DIV LineH) * LineH); + NewLine; + tag.Ymax := Y - Y MOD LineH; + LibImg.Destroy(tag.img) + END +END Image; + + PROCEDURE layout(body: XML.ELEMENT); VAR cur : XML.ELEMENT; @@ -441,51 +479,6 @@ VAR height1 : INTEGER; height2 : INTEGER; - - PROCEDURE Image (VAR tag: XML.TAG); - VAR - note : BOOLEAN; - img : XML.TAG; - URL : INTEGER; - chars : S.CHARS; - sizeY : INTEGER; - FName : S.STRING; - path : S.STRING; - BEGIN - IF tag.img # 0 THEN - LibImg.img_destroy(tag.img) - END; - img := XML.GetRef(tag, note, URL); - IF img # NIL THEN - IF img.child.first IS XML.WORD THEN - chars := img.child.first(XML.WORD).value; - tag.img := LibImg.GetImg(chars.first, chars.last - chars.first + 1, W, sizeY); - IF tag.img # 0 THEN - INC(Y, (sizeY DIV LineH) * LineH); - NewLine; - tag.Ymax := Y - Y MOD LineH - END - END - ELSIF URL # 0 THEN - S.PtrToString(URL, FName); - tag.img := LibImg.LoadFromFile(FName, W, sizeY); - IF tag.img = 0 THEN - path := FilePath; - IF FName[0] # "/" THEN - S.Append(path, "/") - END; - S.Append(path, FName); - tag.img := LibImg.LoadFromFile(path, W, sizeY); - END; - IF tag.img # 0 THEN - INC(Y, (sizeY DIV LineH) * LineH); - NewLine; - tag.Ymax := Y - Y MOD LineH - END - END - END Image; - - BEGIN cur := body; WHILE cur # NIL DO @@ -610,8 +603,7 @@ BEGIN DEC(code); Font.sysfont(code > 0) |XML.tag_image: - Image(tag) - + Image(tag, TRUE) |XML.tag_table: Y := tag.Ymin + tables.get_table_height(tag.table); tag.Ymax := Y - Y MOD LineH; @@ -680,52 +672,52 @@ VAR y, y0 : INTEGER; value : INTEGER; - PROCEDURE DrawText(Col: Window.TRect; min, max, y0, y: INTEGER; right: BOOLEAN; VAR text: XML.TEXT); + PROCEDURE DrawText(Col: Window.tRect; min, max, y0, y: INTEGER; right: BOOLEAN; VAR text: XML.TEXT); VAR word: XML.WORD; BEGIN IF (min <= y0) & (y0 <= max) THEN Font.sysfont(code > 0); IF text IS XML.WORD THEN word := text(XML.WORD); - Font.Text(Col, word.X, y - Col.Height * ORD(right), word.value.first, word.length); + Font.Text(Col, word.X, y - Col.height * ORD(right), word.value.first, word.length); END; - Font.StrikeText(Col, text.X, y - Col.Height * ORD(right), text.width) + Font.StrikeText(Col, text.X, y - Col.height * ORD(right), text.width) END END DrawText; - PROCEDURE Image(VAR tag: XML.TAG); + PROCEDURE DrawImage(VAR tag: XML.TAG); VAR sizeX, sizeY, img, y: INTEGER; BEGIN IF tag.img # 0 THEN y := Ycur; LibImg.GetInf(tag.img, sizeX, sizeY, img); - IF (y <= tag.Ymax) & (tag.Ymin <= y + ColLeft.Height) THEN - G.Image(ColLeft.Left + tag.X, tag.Ymin - y + ColLeft.Top, sizeX, sizeY, img, ColLeft.Top, ColLeft.Top + ColLeft.Height - 1) + IF (y <= tag.Ymax) & (tag.Ymin <= y + ColLeft.height) THEN + G.Image(ColLeft.left + tag.X, tag.Ymin - y + ColLeft.top, sizeX, sizeY, img, ColLeft.top, ColLeft.top + ColLeft.height - 1) END; IF Settings.TwoCol THEN - y := Ycur + ColLeft.Height; - IF (y <= tag.Ymax) & (tag.Ymin <= y + ColRight.Height) THEN - G.Image(ColRight.Left + tag.X, tag.Ymin - y + ColLeft.Top, sizeX, sizeY, img, ColRight.Top, ColRight.Top + ColRight.Height - 1) + y := Ycur + ColLeft.height; + IF (y <= tag.Ymax) & (tag.Ymin <= y + ColRight.height) THEN + G.Image(ColRight.left + tag.X, tag.Ymin - y + ColLeft.top, sizeX, sizeY, img, ColRight.top, ColRight.top + ColRight.height - 1) END END END - END Image; + END DrawImage; PROCEDURE td(VAR tag: XML.TAG); VAR x1, y1, x2, y2, cl: INTEGER; BEGIN - x1 := tag.X + ColLeft.Left; - y1 := tag.Ymin - Ycur + ColLeft.Top; + x1 := tag.X + ColLeft.left; + y1 := tag.Ymin - Ycur + ColLeft.top; x2 := x1 + tag.Width; y2 := y1 + tables.get_height(tag.table, tag.cell); cl := G.GetColor(); G.SetColor(Settings.Colors[TEXT_COLOR]); G.Rect(x1, y1, x2, y2); IF Settings.TwoCol THEN - x1 := x1 - ColLeft.Left + ColRight.Left; - x2 := x2 - ColLeft.Left + ColRight.Left; - y1 := y1 - ColLeft.Height; - y2 := y2 - ColLeft.Height; + x1 := x1 - ColLeft.left + ColRight.left; + x2 := x2 - ColLeft.left + ColRight.left; + y1 := y1 - ColLeft.height; + y2 := y2 - ColLeft.height; G.Rect(x1, y1, x2, y2) END; G.SetColor(cl) @@ -776,7 +768,9 @@ BEGIN INC(italic); Font.Italic(TRUE, refer = 0) |XML.tag_image: - Image(tag) + Image(tag, FALSE); + DrawImage(tag); + LibImg.Destroy(tag.img) |XML.tag_code: INC(code) ELSE @@ -816,9 +810,9 @@ BEGIN text := cur(XML.TEXT); y := text.Y - Ycur; y0 := y - y MOD LineH; - DrawText(ColLeft, 0, ColLeft.Height - LineH, y0, y, FALSE, text); + DrawText(ColLeft, 0, ColLeft.height - LineH, y0, y, FALSE, text); IF Settings.TwoCol THEN - DrawText(ColRight, ColLeft.Height, ColLeft.Height + ColRight.Height - LineH, y0, y, TRUE, text) + DrawText(ColRight, ColLeft.height, ColLeft.height + ColRight.height - LineH, y0, y, TRUE, text) END END; cur := cur.next @@ -826,12 +820,12 @@ BEGIN END layout2; -PROCEDURE DrawProgress(progress_color: INTEGER); +PROCEDURE DrawFrame (color: INTEGER); VAR max_X, max_Y: INTEGER; BEGIN max_X := G.Buffer.Width - 1; max_Y := G.Buffer.Height - 1; - G.SetColor(0); + G.SetColor(color); G.HLine(0, max_X, 0); G.HLine(0, max_X, max_Y); G.VLine(0, 0, max_Y); @@ -839,16 +833,18 @@ BEGIN sb.cur_area := 50; sb.position := (Ycur - Ymin) DIV LineH; box_lib.scrollbar_v_draw(sb) -END DrawProgress; +END DrawFrame; PROCEDURE Draw*; -VAR back, max_X, max_Y: INTEGER; +(*VAR max_Y: INTEGER;*) BEGIN - back := Settings.Colors[BACK_COLOR]; - max_X := G.Buffer.Width - 1; - max_Y := G.Buffer.Height - 1; - G.Copy(G.Buffer3, G.Buffer, 0, G.Buffer.Height, 0); + (*max_Y := G.Buffer.Height - 1;*) + IF Settings.b_pict & (Settings.Picture # 0) THEN + G.Copy(G.BackImg, G.Buffer, 0, G.Buffer.Height, 0) + ELSE + G.Fill(G.Buffer, Settings.Colors[BACK_COLOR]) + END; Font.SetFontColor(Settings.Colors[TEXT_COLOR]); IF ((body = description) OR (body = contents)) & Settings.TwoCol THEN Settings.TwoCol := FALSE; @@ -859,9 +855,9 @@ BEGIN layout2(body.child.first); Search.draw(body, ColLeft, ColRight, Ycur, LineH, Settings.TwoCol) END; - G.Copy(G.Buffer3, G.Buffer, 0, ColLeft.Top + 1, 0); - G.Copy(G.Buffer3, G.Buffer, max_Y - ColLeft.Top, ColLeft.Top + 1, max_Y - ColLeft.Top); - DrawProgress(0); + (*G.Copy(G.BackImg, G.Buffer, 0, ColLeft.top + 1, 0); + G.Copy(G.BackImg, G.Buffer, max_Y - ColLeft.top, ColLeft.top + 1, max_Y - ColLeft.top);*) + DrawFrame(0); G.Draw(Canvas_X, Canvas_Y); DrawToolbar; DrawStatus @@ -932,35 +928,22 @@ BEGIN END Descr; -PROCEDURE Up*; +PROCEDURE Scroll* (n: INTEGER); BEGIN - DEC(Ycur, LineH); - SU.MinMax(Ycur, Ymin, Ymax) -END Up; - - -PROCEDURE Down*; -BEGIN - INC(Ycur, LineH); - SU.MinMax(Ycur, Ymin, Ymax) -END Down; + INC(Ycur, LineH*n); + SU.MinMax(Ycur, Ymin, Ymax) +END Scroll; PROCEDURE PageUp*; -VAR i: INTEGER; BEGIN - FOR i := 1 TO Lines * (ORD(Settings.TwoCol) + 1) DO - Up - END + Scroll(-Lines * (ORD(Settings.TwoCol) + 1)) END PageUp; PROCEDURE PageDown*; -VAR i: INTEGER; BEGIN - FOR i := 1 TO Lines * (ORD(Settings.TwoCol) + 1) DO - Down - END + Scroll(Lines * (ORD(Settings.TwoCol) + 1)) END PageDown; @@ -1046,12 +1029,79 @@ BEGIN END layout3; +PROCEDURE getRefProp (VAR ref, body: XML.TAG; VAR URL: INTEGER; VAR note: BOOLEAN; VAR Y: INTEGER); +BEGIN + note := FALSE; + URL := 0; + Y := 0; + IF ref.value = XML.tag_a THEN + ref := XML.GetRef(ref, note, URL) + ELSE + ref := ref.parent(XML.TAG) + END; + IF ref # NIL THEN + Y := ref.Ymin; + END; + IF note THEN + body := ref + ELSE + body := GetBody(ref) + END +END getRefProp; + + +PROCEDURE zstreq (s1, s2: INTEGER): BOOLEAN; +VAR + c1, c2: CHAR; +BEGIN + REPEAT + sys.GET(s1, c1); INC(s1); + sys.GET(s2, c2); INC(s2); + UNTIL (c1 = 0X) OR (c2 = 0X) + + RETURN c1 = c2 +END zstreq; + + +PROCEDURE refeq (ref1, ref2: XML.TAG): BOOLEAN; +VAR + body1, body2: XML.TAG; + URL1, URL2: INTEGER; + note1, note2: BOOLEAN; + Y1, Y2: INTEGER; +BEGIN + getRefProp(ref1, body1, URL1, note1, Y1); + getRefProp(ref2, body2, URL2, note2, Y2); + RETURN (ref1 = ref2) & (body1 = body2) & (URL1 = 0) & (URL2 = 0) & (note1 = note2) & (Y1 = Y2) OR + (URL1 # 0) & (URL2 # 0) & zstreq(URL1, URL2) +END refeq; + + +PROCEDURE setVisited (ref: XML.TAG); +VAR + i: INTEGER; + cur: V.ANYPTR; +BEGIN + FOR i := 0 TO references.count - 1 DO + cur := V.get(references, i); + IF cur IS XML.TEXT THEN + cur := cur(XML.TEXT).parent; + IF refeq(cur(XML.TAG), ref) THEN + cur(XML.TAG).Visited := TRUE + END + END + END +END setVisited; + + PROCEDURE MouseDown; BEGIN IF ~mouseDown THEN mouseDown := TRUE; clickRef := ref; - ref.Clicked := TRUE; + IF ref # NIL THEN + ref.Clicked := TRUE + END; Draw END END MouseDown; @@ -1088,17 +1138,18 @@ BEGIN Ymin := body.Ymin; IF ~clickRef.Visited THEN + setVisited(clickRef); clickRef.Visited := TRUE; PushRef(clickRef) END ELSIF URL # 0 THEN SU.Run(Ini.Browser, URL); IF ~clickRef.Visited THEN + setVisited(clickRef); clickRef.Visited := TRUE; PushRef(clickRef) END - END; - + END END; IF clickRef # NIL THEN clickRef.Clicked := FALSE; @@ -1129,7 +1180,7 @@ BEGIN ref := NIL; layout3(body, X, Y); IF (ref = NIL) & Settings.TwoCol THEN - layout3(body, X - ColLeft.Width - Settings.PADDING.ColInter, Y + Lines * LineH); + layout3(body, X - ColLeft.width - Settings.PADDING.ColInter, Y + Lines * LineH); END; hoverRef := ref; IF clicked THEN @@ -1165,19 +1216,6 @@ BEGIN END Click; -PROCEDURE Scroll*(value: INTEGER); -BEGIN - value := 2 * value; - WHILE value > 0 DO - Down; - DEC(value) - ELSIF value < 0 DO - Up; - INC(value) - END -END Scroll; - - PROCEDURE main(fb: XML.ELEMENT; Contents: BOOLEAN); VAR cur: XML.ELEMENT; @@ -1283,14 +1321,13 @@ BEGIN IF y >= 0 THEN DEC(y, y MOD LineH); min := Ycur; + max := min + ColLeft.height - LineH; IF Settings.TwoCol THEN - max := min + ColLeft.Height + ColRight.Height - LineH - ELSE - max := min + ColLeft.Height - LineH + INC(max, ColRight.height) END; IF (y < min) OR (y > max) THEN - Ycur := MAX(y - ColLeft.Height DIV 2, 0) + Ycur := MAX(y - ColLeft.height DIV 2, 0) END; DEC(Ycur, Ycur MOD LineH) @@ -1330,24 +1367,24 @@ BEGIN Settings.PADDING.ColInter := G.Buffer.Width * Settings.PADDING.CInt DIV 100; LineH := Font.FontH() + Settings.SUP + Settings.SUB + Settings.InterLin; - Window.InitRect( + Window.initRect( ColLeft, Settings.PADDING.Left, Settings.PADDING.Top, G.Buffer.Width - Settings.PADDING.Left - Settings.PADDING.Right, G.Buffer.Height - Settings.PADDING.Top - Settings.PADDING.Bottom); IF Settings.TwoCol THEN - ColLeft.Width := (ColLeft.Width - Settings.PADDING.ColInter) DIV 2; + ColLeft.width := (ColLeft.width - Settings.PADDING.ColInter) DIV 2; ColRight := ColLeft; - ColRight.Left := ColLeft.Left + ColLeft.Width + Settings.PADDING.ColInter + ColRight.left := ColLeft.left + ColLeft.width + Settings.PADDING.ColInter END; - W := ColLeft.Width; - Lines := ColLeft.Height DIV LineH; - ColLeft.Height := Lines * LineH; - ColRight.Height := ColLeft.Height; + W := ColLeft.width; + Lines := ColLeft.height DIV LineH; + ColLeft.height := Lines * LineH; + ColRight.height := ColLeft.height; END FontSizeChange; PROCEDURE Resize*(Width, Height: INTEGER); -VAR d: REAL; resize: BOOLEAN; sizeX, sizeY, data: INTEGER; +VAR d: REAL; resize: BOOLEAN; sizeX, sizeY, data, back_picture: INTEGER; PROCEDURE stk1(stk: XML.LIST); VAR cur: StackItem; @@ -1374,13 +1411,18 @@ VAR d: REAL; resize: BOOLEAN; sizeX, sizeY, data: INTEGER; BEGIN resize := (Width # G.Buffer.Width) OR resized; G.Resize(Width, Height); - G.SetColor(Settings.Colors[BACK_COLOR]); IF (Settings.Picture # 0) & Settings.b_pict THEN - LibImg.GetInf(Settings.Picture, sizeX, sizeY, data); - G.BackImage(sizeX, sizeY, data); + back_picture := LibImg.GetImg(Settings.Picture, Settings.picture_fsize, 1000000, sizeY); + IF back_picture # 0 THEN + LibImg.GetInf(back_picture, sizeX, sizeY, data); + G.CreateBackImg; + G.BackImage(sizeX, sizeY, data); + LibImg.Destroy(back_picture) + END ELSE - G.Clear; - G.Copy(G.Buffer, G.Buffer3, 0, G.Buffer.Height, 0) + G.DestroyBackImg; + G.Fill(G.Buffer, Settings.Colors[BACK_COLOR]); + //G.Fill(G.BackImg, Settings.Colors[BACK_COLOR]) END; IF Font.FontH() # 0 THEN @@ -1389,16 +1431,16 @@ BEGIN FontSizeChange(Settings.FontSize); END; - ColLeft.Width := G.Buffer.Width - Settings.PADDING.Left - Settings.PADDING.Right; + ColLeft.width := G.Buffer.Width - Settings.PADDING.Left - Settings.PADDING.Right; IF Settings.TwoCol THEN - ColLeft.Width := (ColLeft.Width - Settings.PADDING.ColInter) DIV 2; - ColRight.Width := ColLeft.Width; - ColRight.Left := ColLeft.Left + ColLeft.Width + Settings.PADDING.ColInter + ColLeft.width := (ColLeft.width - Settings.PADDING.ColInter) DIV 2; + ColRight.width := ColLeft.width; + ColRight.left := ColLeft.left + ColLeft.width + Settings.PADDING.ColInter END; - ColLeft.Height := G.Buffer.Height - Settings.PADDING.Top - Settings.PADDING.Bottom; - Lines := ColLeft.Height DIV LineH; - ColLeft.Height := Lines * LineH; - ColRight.Height := ColLeft.Height; + ColLeft.height := G.Buffer.Height - Settings.PADDING.Top - Settings.PADDING.Bottom; + Lines := ColLeft.height DIV LineH; + ColLeft.height := Lines * LineH; + ColRight.height := ColLeft.height; IF done & resize THEN resized := FALSE; @@ -1408,8 +1450,8 @@ BEGIN IF contents # NIL THEN d := FLT(Ycont) / FLT(contents.Ymax) END; - W := ColLeft.Width; - W2 := ColLeft.Width + ColRight.Width + Settings.PADDING.ColInter; + W := ColLeft.width; + W2 := ColLeft.width + ColRight.width + Settings.PADDING.ColInter; W1 := W; main(XML.FB, FALSE); Search.resize; @@ -1505,7 +1547,7 @@ VAR history: File.FS; win_size_x, win_size_y, size, pos: INTEGER; PROCEDURE WriteInt(history: File.FS; x: INTEGER); BEGIN - IF Write.Int(history, x) THEN END + IF File.WriteInt(history, x) THEN END END WriteInt; PROCEDURE WriteStk(history: File.FS; VAR stk: XML.LIST; links: BOOLEAN); @@ -1533,7 +1575,7 @@ BEGIN END; size := 1 + 18*4 + 1 + 8*(XML.ListCount(b_stk) + XML.ListCount(f_stk)) + 4*XML.ListCount(vis_ref) + 12; WriteInt(history, size); - IF Write.Char(history, 0X) THEN END; + IF File.WriteChar(history, 0X) THEN END; WriteInt(history, fsize2); WriteInt(history, chksum); SU.GetWindowSize(win_size_x, win_size_y); @@ -1546,7 +1588,7 @@ BEGIN WriteInt(history, Settings.EPIGRAPH); WriteInt(history, Settings.InterLin); - IF Write.Boolean(history, Settings.TwoCol) THEN END; + IF File.WriteBool(history, Settings.TwoCol) THEN END; WriteInt(history, Settings.FontSize); WriteInt(history, body.num); @@ -1568,7 +1610,7 @@ END Save; PROCEDURE ReadInt(VAR x: INTEGER); BEGIN - IF Read.Int(history, x) THEN END + IF File.ReadInt(history, x) THEN END END ReadInt; @@ -1598,8 +1640,9 @@ VAR body_num, ycur, size, pos: INTEGER; ReadInt(num); ref := XML.GetTagByNum(num); IF ref # NIL THEN - PushRef(ref); - ref.Visited := TRUE + setVisited(ref); + ref.Visited := TRUE; + PushRef(ref) END; DEC(n) END @@ -1612,7 +1655,7 @@ BEGIN ReadInt(Settings.PARAGRAPH); ReadInt(Settings.EPIGRAPH); ReadInt(Settings.InterLin); - IF Read.Boolean(history, Settings.TwoCol) THEN END; + IF File.ReadBool(history, Settings.TwoCol) THEN END; ReadInt(Settings.FontSize); SetSettings(Settings); @@ -1630,7 +1673,7 @@ BEGIN ReadInt(size); pos := File.Seek(history, -size, 1); pos := File.Seek(history, 4, 1); - IF Write.Char(history, 1X) THEN END; + IF File.WriteChar(history, 1X) THEN END; Ycur := ycur; body := XML.GetTagByNum(body_num); @@ -1648,15 +1691,15 @@ BEGIN pos := File.Seek(history, -4, 2); last := FALSE; WHILE pos >= 0 DO - IF Read.Int(history, size) THEN + IF File.ReadInt(history, size) THEN pos := File.Seek(history, -size + 4, 1); END; - IF Read.Char(history, c) THEN END; + IF File.ReadChar(history, c) THEN END; ReadInt(fsize); ReadInt(_chksum); IF (c = 0X) & (fsize = fsize2) & (_chksum = chksum) THEN found := TRUE; - IF Read.Int(history, x) & Read.Int(history, y) THEN + IF File.ReadInt(history, x) & File.ReadInt(history, y) THEN win_size_x := x; win_size_y := y; ELSE @@ -1674,7 +1717,7 @@ BEGIN ReadInt(Settings.PARAGRAPH); ReadInt(Settings.EPIGRAPH); ReadInt(Settings.InterLin); - IF Read.Boolean(history, Settings.TwoCol) THEN END; + IF File.ReadBool(history, Settings.TwoCol) THEN END; ReadInt(Settings.FontSize); END; pos := File.Seek(history, pos - 8, 0) @@ -1699,11 +1742,11 @@ BEGIN FilePath := FName; FileName := FName; S.GetPath(FilePath); - W := ColLeft.Width; + W := ColLeft.width; W1 := W; - W2 := ColLeft.Width + ColRight.Width + Settings.PADDING.ColInter; - Lines := ColLeft.Height DIV LineH; - ColLeft.Height := Lines * LineH; + W2 := ColLeft.width + ColRight.width + Settings.PADDING.ColInter; + Lines := ColLeft.height DIV LineH; + ColLeft.height := Lines * LineH; PID := SU.NewThread(Start, Stack); WHILE ~SU.IsTerminated(PID) DO event := SU.CheckEvent(); diff --git a/programs/other/fb2reader/SRC/Encoding.ob07 b/programs/other/fb2reader/SRC/Encoding.ob07 new file mode 100644 index 0000000000..78e2275a99 --- /dev/null +++ b/programs/other/fb2reader/SRC/Encoding.ob07 @@ -0,0 +1,266 @@ +(* + Copyright 2016, 2023 Anton Krotov + + This file is part of fb2read. + + fb2read is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + fb2read 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with fb2read. If not, see . +*) + +MODULE Encoding; + +IMPORT SYSTEM; + + +CONST + TABLE_SIZE = 65536; + + +TYPE + tUtf8* = ARRAY 4 OF CHAR; + tCodePage* = ARRAY 256 OF RECORD code*, len*: INTEGER; utf8*: tUtf8 END; + + +VAR + cp1250*, cp1251*, cp1252*, cp866*: tCodePage; + + table1251: ARRAY TABLE_SIZE OF BYTE; + + +PROCEDURE getUtf8Char* (VAR ptr, size: INTEGER): INTEGER; +VAR + c: BYTE; + n, k, code: INTEGER; + end: BOOLEAN; +BEGIN + code := 0; + end := FALSE; + REPEAT + SYSTEM.GET(ptr, c); + INC(ptr); + DEC(size); + CASE c OF + | 0..127: + code := c; + end := TRUE + + |128..191: + code := code * 64 + c MOD 64; + DEC(n); + end := n <= 0 + + |192..255: + k := LSL(c, 24); + n := -2; + REPEAT + k := ROR(k, -1); + INC(n) + UNTIL k MOD 2 = 0; + k := LSL(c, n + 25); + code := LSR(k, n + 25) + + END + UNTIL (size = 0) OR end + RETURN code +END getUtf8Char; + + +PROCEDURE convert1251* (src, dst: INTEGER; len: INTEGER); +VAR + val, size: INTEGER; +BEGIN + WHILE len > 0 DO + size := 0; + val := getUtf8Char(src, size); + IF (0 <= val) & (val < TABLE_SIZE) THEN + SYSTEM.PUT8(dst, table1251[val]) + ELSE + SYSTEM.PUT8(dst, ORD("?")) + END; + INC(dst); + DEC(len) + END +END convert1251; + + +PROCEDURE utf8* (code: INTEGER; VAR utf8char: tUtf8); +BEGIN + utf8char[0] := 0X; + IF code < 80H THEN + utf8char[0] := CHR(code); + utf8char[1] := 0X + ELSIF code < 800H THEN + utf8char[1] := CHR(code MOD 64 + 80H); + utf8char[0] := CHR(code DIV 64 + 0C0H); + utf8char[2] := 0X + ELSIF code < 10000H THEN + utf8char[2] := CHR(code MOD 64 + 80H); + code := code DIV 64; + utf8char[1] := CHR(code MOD 64 + 80H); + utf8char[0] := CHR(code DIV 64 + 0E0H); + utf8char[3] := 0X + (* + ELSIF code < 200000H THEN + ELSIF code < 4000000H THEN + ELSE *) + END +END utf8; + + +PROCEDURE ucs2to1251 (code: INTEGER): BYTE; +VAR + i: INTEGER; +BEGIN + i := 255; + WHILE (i >= 0) & (cp1251[i].code # code) DO + DEC(i) + END; + IF i < 0 THEN + i := ORD("?") + END + RETURN i +END ucs2to1251; + + +PROCEDURE initCP (VAR cp: tCodePage); +VAR + i: INTEGER; +BEGIN + FOR i := 0H TO 7FH DO + cp[i].code := i + END; + FOR i := 0H TO 0FFH DO + utf8(cp[i].code, cp[i].utf8); + cp[i].len := LENGTH(cp[i].utf8) + END +END initCP; + + +PROCEDURE init8 (VAR cp: tCodePage; VAR n: INTEGER; a, b, c, d, e, f, g, h: INTEGER); +BEGIN + cp[n].code := a; INC(n); + cp[n].code := b; INC(n); + cp[n].code := c; INC(n); + cp[n].code := d; INC(n); + cp[n].code := e; INC(n); + cp[n].code := f; INC(n); + cp[n].code := g; INC(n); + cp[n].code := h; INC(n); +END init8; + + +PROCEDURE init1250 (VAR cp: tCodePage); +VAR + n: INTEGER; +BEGIN + n := 80H; + init8(cp, n, 20ACH, 20H, 201AH, 20H, 201EH, 2026H, 2020H, 2021H); + init8(cp, n, 20H, 2030H, 0160H, 2039H, 015AH, 0164H, 017DH, 0179H); + init8(cp, n, 20H, 2018H, 2019H, 201CH, 201DH, 2022H, 2013H, 2014H); + init8(cp, n, 20H, 2122H, 0161H, 203AH, 015BH, 0165H, 017EH, 017AH); + init8(cp, n, 00A0H, 02C7H, 02D8H, 0141H, 00A4H, 0104H, 00A6H, 00A7H); + init8(cp, n, 00A8H, 00A9H, 015EH, 00ABH, 00ACH, 00ADH, 00AEH, 017BH); + init8(cp, n, 00B0H, 00B1H, 02DBH, 0142H, 00B4H, 00B5H, 00B6H, 00B7H); + init8(cp, n, 00B8H, 0105H, 015FH, 00BBH, 013DH, 02DDH, 013EH, 017CH); + init8(cp, n, 0154H, 00C1H, 00C2H, 0102H, 00C4H, 0139H, 0106H, 00C7H); + init8(cp, n, 010CH, 00C9H, 0118H, 00CBH, 011AH, 00CDH, 00CEH, 010EH); + init8(cp, n, 0110H, 0143H, 0147H, 00D3H, 00D4H, 0150H, 00D6H, 00D7H); + init8(cp, n, 0158H, 016EH, 00DAH, 0170H, 00DCH, 00DDH, 0162H, 00DFH); + init8(cp, n, 0155H, 00E1H, 00E2H, 0103H, 00E4H, 013AH, 0107H, 00E7H); + init8(cp, n, 010DH, 00E9H, 0119H, 00EBH, 011BH, 00EDH, 00EEH, 010FH); + init8(cp, n, 0111H, 0144H, 0148H, 00F3H, 00F4H, 0151H, 00F6H, 00F7H); + init8(cp, n, 0159H, 016FH, 00FAH, 0171H, 00FCH, 00FDH, 0163H, 02D9H); + initCP(cp) +END init1250; + + +PROCEDURE init1251 (VAR cp: tCodePage); +VAR + n, i: INTEGER; +BEGIN + n := 80H; + init8(cp, n, 0402H, 0403H, 201AH, 0453H, 201EH, 2026H, 2020H, 2021H); + init8(cp, n, 20ACH, 2030H, 0409H, 2039H, 040AH, 040CH, 040BH, 040FH); + init8(cp, n, 0452H, 2018H, 2019H, 201CH, 201DH, 2022H, 2013H, 2014H); + init8(cp, n, 20H, 2122H, 0459H, 203AH, 045AH, 045CH, 045BH, 045FH); + init8(cp, n, 00A0H, 040EH, 045EH, 0408H, 00A4H, 0490H, 00A6H, 00A7H); + init8(cp, n, 0401H, 00A9H, 0404H, 00ABH, 00ACH, 00ADH, 00AEH, 0407H); + init8(cp, n, 00B0H, 00B1H, 0406H, 0456H, 0491H, 00B5H, 00B6H, 00B7H); + init8(cp, n, 0451H, 2116H, 0454H, 00BBH, 0458H, 0405H, 0455H, 0457H); + FOR i := 0410H TO 044FH DO + cp[i - 350H].code := i + END; + initCP(cp) +END init1251; + + +PROCEDURE init1252 (VAR cp: tCodePage); +VAR + n, i: INTEGER; +BEGIN + n := 80H; + init8(cp, n, 20ACH, 20H, 201AH, 0192H, 201EH, 2026H, 2020H, 2021H); + init8(cp, n, 02C6H, 2030H, 0160H, 2039H, 0152H, 20H, 017DH, 20H); + init8(cp, n, 20H, 2018H, 2019H, 201CH, 201DH, 2022H, 2013H, 2014H); + init8(cp, n, 02DCH, 2122H, 0161H, 203AH, 0153H, 20H, 017EH, 0178H); + FOR i := 0A0H TO 0FFH DO + cp[i].code := i + END; + initCP(cp) +END init1252; + + +PROCEDURE init866 (VAR cp: tCodePage); +VAR + n, i: INTEGER; +BEGIN + FOR i := 0410H TO 043FH DO + cp[i - 0410H + 80H].code := i + END; + FOR i := 0440H TO 044FH DO + cp[i - 0440H + 0E0H].code := i + END; + + n := 0B0H; + init8(cp, n, 2591H, 2592H, 2593H, 2502H, 2524H, 2561H, 2562H, 2556H); + init8(cp, n, 2555H, 2563H, 2551H, 2557H, 255DH, 255CH, 255BH, 2510H); + init8(cp, n, 2514H, 2534H, 252CH, 251CH, 2500H, 253CH, 255EH, 255FH); + init8(cp, n, 255AH, 2554H, 2569H, 2566H, 2560H, 2550H, 256CH, 2567H); + init8(cp, n, 2568H, 2564H, 2565H, 2559H, 2558H, 2552H, 2553H, 256BH); + init8(cp, n, 256AH, 2518H, 250CH, 2588H, 2584H, 258CH, 2590H, 2580H); + + n := 0F0H; + init8(cp, n, 0401H, 0451H, 0404H, 0454H, 0407H, 0457H, 040EH, 045EH); + init8(cp, n, 00B0H, 2219H, 00B7H, 221AH, 2116H, 00A4H, 25A0H, 00A0H); + + initCP(cp) +END init866; + + +PROCEDURE init; +VAR + i: INTEGER; +BEGIN + init1250(cp1250); + init1251(cp1251); + init1252(cp1252); + init866(cp866); + FOR i := 0 TO TABLE_SIZE - 1 DO + table1251[i] := ucs2to1251(i) + END +END init; + + +BEGIN + init +END Encoding. diff --git a/programs/other/fb2reader/SRC/FB2READ.ob07 b/programs/other/fb2reader/SRC/FB2READ.ob07 index 8e19474be1..5c89963d1d 100644 --- a/programs/other/fb2reader/SRC/FB2READ.ob07 +++ b/programs/other/fb2reader/SRC/FB2READ.ob07 @@ -35,16 +35,16 @@ CONST SETTINGS = 20; SEARCH = 21; - KEY_DOWN_CODE = 177; - KEY_UP_CODE = 178; - KEY_PG_DOWN_CODE = 183; - KEY_PG_UP_CODE = 184; - KEY_HOME_CODE = 180; - KEY_END_CODE = 181; - KEY_F2_CODE = 51; - KEY_F3_CODE = 52; - KEY_F4_CODE = 53; - KEY_F10_CODE = 49; + KEY_DOWN = 80; + KEY_UP = 72; + KEY_PG_DOWN = 81; + KEY_PG_UP = 73; + KEY_HOME = 71; + KEY_END = 79; + KEY_F2 = 60; + KEY_F3 = 61; + KEY_F4 = 62; + KEY_F10 = 68; TOOLBAR_LEFT = 5; TOOLBAR_TOP = 6; @@ -60,7 +60,7 @@ CONST VAR - Window : W.TWindow; + Window : W.tWindow; toolbar : Toolbar.tToolbar; SkinHeight : INTEGER; Open : OpenDlg.Dialog; @@ -90,15 +90,15 @@ END ToolBar; PROCEDURE Resize; VAR Width, Height: INTEGER; BEGIN - SU.GetWindowPos(Window.Left, Window.Top); + SU.GetWindowPos(Window.left, Window.top); SU.GetWindowSize(Width, Height); - IF (Window.Width # Width) OR (Window.Height # Height) OR (SkinHeight # SU.SkinHeight()) THEN + IF (Window.width # Width) OR (Window.height # Height) OR (SkinHeight # SU.SkinHeight()) THEN SU.MinMax(Width, 640, 65535); SU.MinMax(Height, 400, 65535); - Window.dWidth := Width - Window.Width; - Window.dHeight := Height - Window.Height; - Window.Width := Width; - Window.Height := Height; + Window.dWidth := Width - Window.width; + Window.dHeight := Height - Window.height; + Window.width := Width; + Window.height := Height; SU.SetWindowSize(Width, Height); DOM.Resize(G.Buffer.Width + Window.dWidth, G.Buffer.Height + Window.dHeight + (SkinHeight - SU.SkinHeight())); SkinHeight := SU.SkinHeight() @@ -108,12 +108,12 @@ END Resize; PROCEDURE DrawStatus; BEGIN - SU.DrawRect(0, Window.Height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 1, Window.Width - 2 * WINDOW_BEVEL - 1, STATUSBAR_HEIGHT, SU.winColor); + SU.DrawRect(0, Window.height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 1, Window.width - 2 * WINDOW_BEVEL - 1, STATUSBAR_HEIGHT, SU.winColor); IF DOM.urlstr # "" THEN - SU.OutText(CANVAS_LEFT, Window.Height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 2, DOM.urlstr, - MIN(LENGTH(DOM.urlstr), (Window.Width - 2 * WINDOW_BEVEL - 1 - CANVAS_LEFT * 2) DIV 8), SU.textColor) + SU.OutText(CANVAS_LEFT, Window.height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 2, DOM.urlstr, + MIN(LENGTH(DOM.urlstr), (Window.width - 2 * WINDOW_BEVEL - 1 - CANVAS_LEFT * 2) DIV 8), SU.textColor) ELSIF DOM.found() THEN - SU.OutText(CANVAS_LEFT, Window.Height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 2, + SU.OutText(CANVAS_LEFT, Window.height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 2, "F2 - first | F3 - next | F4 - prev. | F10 - exit", 48, SU.textColor) END END DrawStatus; @@ -123,17 +123,17 @@ PROCEDURE DrawWindow; BEGIN SU.GetSystemColors; SU.WindowRedrawStatus(1); - IF Window.Created THEN + IF Window.created THEN Resize ELSE - Window.Created := TRUE + Window.created := TRUE END; - SU.DefineAndDrawWindow(Window.Left, Window.Top, Window.Width, Window.Height, - SU.winColor, LSL(ORD({0, 1, 2}), 4) + 4 - ORD(DOM.loaded), Window.Caption); - SU.DrawRect(0, 0, Window.Width - 2 * WINDOW_BEVEL - 1, CANVAS_TOP, SU.winColor); - SU.DrawRect(0, Window.Height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 1, Window.Width - 2 * WINDOW_BEVEL - 1, STATUSBAR_HEIGHT, SU.winColor); - SU.DrawRect(0, 0, CANVAS_LEFT, Window.Height - SkinHeight - WINDOW_BEVEL, SU.winColor); - SU.DrawRect(Window.Width - 2 * WINDOW_BEVEL - CANVAS_LEFT - 1 - SCROLLBAR_WIDTH - 2, 0, CANVAS_LEFT + SCROLLBAR_WIDTH + 2, Window.Height - SkinHeight - WINDOW_BEVEL, SU.winColor); + SU.DefineAndDrawWindow(Window.left, Window.top, Window.width, Window.height, + SU.winColor, LSL(ORD({0, 1, 2}), 4) + 4 - ORD(DOM.loaded), Window.caption); + SU.DrawRect(0, 0, Window.width - 2 * WINDOW_BEVEL - 1, CANVAS_TOP, SU.winColor); + SU.DrawRect(0, Window.height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 1, Window.width - 2 * WINDOW_BEVEL - 1, STATUSBAR_HEIGHT, SU.winColor); + SU.DrawRect(0, 0, CANVAS_LEFT, Window.height - SkinHeight - WINDOW_BEVEL, SU.winColor); + SU.DrawRect(Window.width - 2 * WINDOW_BEVEL - CANVAS_LEFT - 1 - SCROLLBAR_WIDTH - 2, 0, CANVAS_LEFT + SCROLLBAR_WIDTH + 2, Window.height - SkinHeight - WINDOW_BEVEL, SU.winColor); IF DOM.loaded THEN ToolBar; DOM.Draw; @@ -145,8 +145,8 @@ END DrawWindow; PROCEDURE ConvMousePos(VAR X, Y: INTEGER); BEGIN - X := X - Window.Left - WINDOW_BEVEL - 1; - Y := Y - Window.Top - SkinHeight + X := X - Window.left - WINDOW_BEVEL - 1; + Y := Y - Window.top - SkinHeight END ConvMousePos; @@ -177,22 +177,28 @@ END ButtonClick; PROCEDURE KeyDown; +VAR + key: INTEGER; + shift, ctrl: BOOLEAN; BEGIN - CASE SU.GetKeyCode() OF - |KEY_DOWN_CODE : DOM.Down - |KEY_UP_CODE : DOM.Up - |KEY_PG_DOWN_CODE : DOM.PageDown - |KEY_PG_UP_CODE : DOM.PageUp - |KEY_HOME_CODE : DOM.Home - |KEY_END_CODE : DOM.End - |KEY_F2_CODE : DOM.Find(0) - |KEY_F3_CODE : DOM.Find(1) - |KEY_F4_CODE : DOM.Find(-1) - |KEY_F10_CODE : DOM.CloseSearch - ELSE - END; - DOM.Draw; - DrawStatus + SU.getKBState(shift, ctrl); + key := SU.GetKey() DIV 65536; + CASE key OF + |KEY_DOWN : DOM.Scroll(1) + |KEY_UP : DOM.Scroll(-1) + |KEY_PG_DOWN : DOM.PageDown + |KEY_PG_UP : DOM.PageUp + |KEY_HOME : DOM.Home + |KEY_END : DOM.End + |KEY_F2 : DOM.Find(0) + |KEY_F3 : DOM.Find(1) + |KEY_F4 : DOM.Find(-1) + |KEY_F10 : DOM.CloseSearch + |33 : IF ctrl THEN DOM.OpenSearch END (* ctrl-F *) + ELSE + END; + DOM.Draw; + DrawStatus END KeyDown; @@ -204,13 +210,10 @@ END CanvasIsClicked; PROCEDURE MouseEvent; - VAR - mouse_status : SET; X, Y : INTEGER; scroll : INTEGER; - BEGIN SU.MousePos(X, Y); mouse_status := SU.MouseStatus(); @@ -223,7 +226,7 @@ BEGIN DOM.Click(X, Y, TRUE) END ELSIF scroll # 0 THEN - DOM.Scroll(scroll); + DOM.Scroll(scroll*2); DOM.Draw ELSE ConvMousePos(X, Y); @@ -267,7 +270,7 @@ END IsFB2; PROCEDURE main(title: ARRAY OF CHAR); -VAR WinW, X1, Y1, X2, Y2, scr_pos: INTEGER; Win2: W.TWindow; resize: BOOLEAN; FilePath: S.STRING; defpath: BOOLEAN; +VAR WinW, X1, Y1, X2, Y2, scr_pos: INTEGER; Win2: W.tWindow; resize: BOOLEAN; FilePath: S.STRING; defpath: BOOLEAN; BEGIN SkinHeight := SU.SkinHeight(); sb := box_lib.kolibri_new_scrollbar(10 * 65536 + 200, 10 * 65536 + 30, 25, 15, 10, 0, 0, 0, 0, 0); @@ -299,31 +302,31 @@ BEGIN SU.SetEventsMask({0, 1, 2, 5, 31}); SU.GetScreenArea(X1, Y1, X2, Y2); WinW := (X2 - X1) DIV 2; - W.InitWindow(Window, WinW DIV 2, Y1, WinW, Y2 - Y1, title); + W.init(Window, WinW DIV 2, Y1, WinW, Y2 - Y1, title); Settings.Default; - DOM.GetWinSize(FileName, Window.Width, Window.Height); + DOM.GetWinSize(FileName, Window.width, Window.height); Win2 := Window; resize := FALSE; - IF Win2.Width > X2 - X1 THEN - Win2.Width := X2 - X1; + IF Win2.width > X2 - X1 THEN + Win2.width := X2 - X1; resize := TRUE END; - IF Win2.Height > Y2 - Y1 THEN - Win2.Height := Y2 - Y1; + IF Win2.height > Y2 - Y1 THEN + Win2.height := Y2 - Y1; resize := TRUE END; DOM.Init(CANVAS_LEFT, CANVAS_TOP, - Window.Width - 2 * CANVAS_LEFT - 2 * WINDOW_BEVEL - 1 - SCROLLBAR_WIDTH - 2, - Window.Height - SkinHeight - CANVAS_TOP - WINDOW_BEVEL - STATUSBAR_HEIGHT + 1); + Window.width - 2 * CANVAS_LEFT - 2 * WINDOW_BEVEL - 1 - SCROLLBAR_WIDTH - 2, + Window.height - SkinHeight - CANVAS_TOP - WINDOW_BEVEL - STATUSBAR_HEIGHT + 1); DOM.SetColors; DOM.Set_b_pict(Ini.b_pict); Window := Win2; - G.Resize2(Window.Width - 2 * CANVAS_LEFT - 2 * WINDOW_BEVEL - 1 - SCROLLBAR_WIDTH, Window.Height - SkinHeight - CANVAS_TOP - WINDOW_BEVEL + 1 - STATUSBAR_HEIGHT); - S.Append(Window.Caption, " - "); - S.Append(Window.Caption, FileName); + G.InitSize(Window.width - 2 * CANVAS_LEFT - 2 * WINDOW_BEVEL - 1 - SCROLLBAR_WIDTH, Window.height - SkinHeight - CANVAS_TOP - WINDOW_BEVEL + 1 - STATUSBAR_HEIGHT); + S.Append(Window.caption, " - "); + S.Append(Window.caption, FileName); Toolbar.create(toolbar, TOOLBAR_LEFT, TOOLBAR_TOP); Toolbar.add(toolbar, BACK, 30, ""); @@ -339,7 +342,7 @@ BEGIN DOM.Open(FileName, DrawWindow, DrawStatus, DrawToolbar); IF resize THEN - DOM.Resize(Window.Width - 2 * CANVAS_LEFT - 2 * WINDOW_BEVEL - 1 - SCROLLBAR_WIDTH, Window.Height - SkinHeight - CANVAS_TOP - WINDOW_BEVEL + 1 - STATUSBAR_HEIGHT) + DOM.Resize(Window.width - 2 * CANVAS_LEFT - 2 * WINDOW_BEVEL - 1 - SCROLLBAR_WIDTH, Window.height - SkinHeight - CANVAS_TOP - WINDOW_BEVEL + 1 - STATUSBAR_HEIGHT) END; DrawWindow; @@ -362,5 +365,5 @@ END main; BEGIN - main("FB2 Reader v0.97") + main("FB2 Reader v0.97a") END FB2READ. diff --git a/programs/other/fb2reader/SRC/File.ob07 b/programs/other/fb2reader/SRC/File.ob07 index b906546776..16a98045b4 100644 --- a/programs/other/fb2reader/SRC/File.ob07 +++ b/programs/other/fb2reader/SRC/File.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2019 Anton Krotov + Copyright 2016, 2019, 2023 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -252,4 +252,35 @@ BEGIN RETURN res = 0 END DeleteDir; + +PROCEDURE ReadChar* (F: FS; VAR x: CHAR): BOOLEAN; + RETURN Read(F, sys.ADR(x), sys.SIZE(CHAR)) = sys.SIZE(CHAR) +END ReadChar; + + +PROCEDURE ReadInt* (F: FS; VAR x: INTEGER): BOOLEAN; + RETURN Read(F, sys.ADR(x), sys.SIZE(INTEGER)) = sys.SIZE(INTEGER) +END ReadInt; + + +PROCEDURE ReadBool* (F: FS; VAR x: BOOLEAN): BOOLEAN; + RETURN Read(F, sys.ADR(x), sys.SIZE(BOOLEAN)) = sys.SIZE(BOOLEAN) +END ReadBool; + + +PROCEDURE WriteChar*(F: FS; x: CHAR): BOOLEAN; + RETURN Write(F, sys.ADR(x), sys.SIZE(CHAR)) = sys.SIZE(CHAR) +END WriteChar; + + +PROCEDURE WriteInt*(F: FS; x: INTEGER): BOOLEAN; + RETURN Write(F, sys.ADR(x), sys.SIZE(INTEGER)) = sys.SIZE(INTEGER) +END WriteInt; + + +PROCEDURE WriteBool*(F: FS; x: BOOLEAN): BOOLEAN; + RETURN Write(F, sys.ADR(x), sys.SIZE(BOOLEAN)) = sys.SIZE(BOOLEAN) +END WriteBool; + + END File. diff --git a/programs/other/fb2reader/SRC/Font.ob07 b/programs/other/fb2reader/SRC/Font.ob07 index 3513bda6b2..835ff10cc1 100644 --- a/programs/other/fb2reader/SRC/Font.ob07 +++ b/programs/other/fb2reader/SRC/Font.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2018, 2022 Anton Krotov + Copyright 2016, 2018, 2022, 2023 Anton Krotov This file is part of fb2read. @@ -19,11 +19,13 @@ MODULE Font; -IMPORT W := Window, S := Strings, G := Graph, sys := SYSTEM, K := KOSAPI, Conv, Ini, KF := kfonts; +IMPORT + W := Window, S := Strings, G := Graph, sys := SYSTEM, K := KOSAPI, + Encoding, Ini, KF := kfonts; VAR - kf_font, kf_loaded, kf_enabled: BOOLEAN; + kf_font, kf_enabled: BOOLEAN; cp1251buf: ARRAY 102400 OF CHAR; KFont*: KF.TFont; @@ -39,9 +41,9 @@ VAR ItalicColor, NormalColor: INTEGER; -PROCEDURE KFText(X, Y: INTEGER; first, quantity: INTEGER; canvas: G.PBuffer); +PROCEDURE KFText(X, Y: INTEGER; first, quantity: INTEGER; canvas: G.tBuffer); BEGIN - KF.TextOut(KFont, canvas.adr - 8, X, Y, first, quantity, Font.color, ORD(Font.bold) + ORD(Font.italic) * 2 + ORD(Font.strike) * 8) + KF.TextOut(KFont, canvas.bitmap - 8, X, Y, first, quantity, Font.color, ORD(Font.bold) + ORD(Font.italic) * 2 + ORD(Font.strike) * 8) END KFText; @@ -110,7 +112,7 @@ PROCEDURE TextWidth*(text: S.CHARS; length: INTEGER): INTEGER; VAR res: INTEGER; BEGIN IF kf_font THEN - Conv.convert(text.first, sys.ADR(cp1251buf[0]), length); + Encoding.convert1251(text.first, sys.ADR(cp1251buf[0]), length); res := KF.TextWidth(KFont, sys.ADR(cp1251buf[0]), length, ORD(Font.bold) + ORD(Font.italic) * 2) ELSE res := length * FontW() @@ -124,30 +126,30 @@ PROCEDURE MonoWidth*(): INTEGER; END MonoWidth; -PROCEDURE StrikeText*(Rect: W.TRect; X, Y: INTEGER; width: INTEGER); +PROCEDURE StrikeText*(Rect: W.tRect; X, Y: INTEGER; width: INTEGER); VAR y: INTEGER; BEGIN IF Font.strike THEN y := Y + FontH() DIV 2; // X := X + ORD(Font.italic & kf_font) * ((KF.TextHeight(KFont) DIV 2) DIV 3); G.SetColor(Font.color); - G.HLine(X + Rect.Left, X + Rect.Left + width, y + Rect.Top); + G.HLine(X + Rect.left, X + Rect.left + width, y + Rect.top); IF Font.size >= 28 THEN INC(y); - G.HLine(X + Rect.Left, X + Rect.Left + width, y + Rect.Top); + G.HLine(X + Rect.left, X + Rect.left + width, y + Rect.top); END END END StrikeText; -PROCEDURE Text*(Rect: W.TRect; X, Y: INTEGER; adr: INTEGER; length: INTEGER); +PROCEDURE Text*(Rect: W.tRect; X, Y: INTEGER; adr: INTEGER; length: INTEGER); BEGIN IF kf_font THEN - Conv.convert(adr, sys.ADR(cp1251buf[0]), length); - KFText(X + Rect.Left, Y + Rect.Top, sys.ADR(cp1251buf[0]), length, G.Buffer) + Encoding.convert1251(adr, sys.ADR(cp1251buf[0]), length); + KFText(X + Rect.left, Y + Rect.top, sys.ADR(cp1251buf[0]), length, G.Buffer) ELSE G.SetColor(Font.color); - G.TextOut(X + Rect.Left, Y + Rect.Top, adr, length, Font.size, params()) + G.TextOut(X + Rect.left, Y + Rect.top, adr, length, Font.size, params()) END END Text; @@ -170,7 +172,6 @@ END Init; BEGIN KFont := KF.LoadFont(Ini.Font); - kf_loaded := KFont # NIL; - kf_font := kf_loaded; - kf_enabled := kf_loaded + kf_font := KFont # NIL; + kf_enabled := kf_font END Font. diff --git a/programs/other/fb2reader/SRC/Graph.ob07 b/programs/other/fb2reader/SRC/Graph.ob07 index db3a7728bb..26384ee0c5 100644 --- a/programs/other/fb2reader/SRC/Graph.ob07 +++ b/programs/other/fb2reader/SRC/Graph.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016-2020, 2022 Anton Krotov + Copyright 2016-2020, 2022, 2023 Anton Krotov This file is part of fb2read. @@ -19,44 +19,44 @@ MODULE Graph; -IMPORT K := KOSAPI, sys := SYSTEM, SU := SysUtils, LibImg; +IMPORT K := KOSAPI, sys := SYSTEM, SU := SysUtils; TYPE - TBuffer = RECORD Width*, Height*, adr*, Color: INTEGER END; - PBuffer* = POINTER TO TBuffer; + tBuffer* = POINTER TO RECORD Width*, Height*, bitmap*, Color: INTEGER END; VAR - Buffer*, Buffer2, Buffer3*: PBuffer; + Buffer*, BackImg*: tBuffer; + Width0, Height0: INTEGER; PROCEDURE [stdcall-, "rasterworks.obj", ""] drawText (canvas, x, y, string, charQuantity, fontColor, params: INTEGER): INTEGER; END; -PROCEDURE Destroy*(VAR Buffer: PBuffer); +PROCEDURE Destroy*(VAR Buffer: tBuffer); BEGIN IF Buffer # NIL THEN - IF Buffer.adr # 0 THEN - DEC(Buffer.adr, 8); - Buffer.adr := K.free(Buffer.adr) + IF Buffer.bitmap # 0 THEN + DEC(Buffer.bitmap, 8); + Buffer.bitmap := K.free(Buffer.bitmap) END; DISPOSE(Buffer) END END Destroy; -PROCEDURE Create*(Width, Height: INTEGER): PBuffer; -VAR res: PBuffer; +PROCEDURE Create*(Width, Height: INTEGER): tBuffer; +VAR res: tBuffer; BEGIN NEW(res); - res.adr := K.malloc(Width * Height * 4 + 8); - sys.PUT(res.adr, Width); - sys.PUT(res.adr + 4, Height); + res.bitmap := K.malloc(Width * Height * 4 + 8); + sys.PUT(res.bitmap, Width); + sys.PUT(res.bitmap + 4, Height); res.Width := Width; res.Height := Height; - INC(res.adr, 8); + INC(res.bitmap, 8); RETURN res END Create; @@ -69,15 +69,15 @@ BEGIN END getRGB; -PROCEDURE Fill*(Buffer: PBuffer; Color: INTEGER); +PROCEDURE Fill* (Buffer: tBuffer; Color: INTEGER); VAR p, n, i: INTEGER; BEGIN - p := Buffer.adr; - n := Buffer.Width * Buffer.Height; - FOR i := 1 TO n DO - sys.PUT(p, Color); - INC(p, 4) - END + p := Buffer.bitmap; + n := Buffer.Width * Buffer.Height; + FOR i := 1 TO n DO + sys.PUT(p, Color); + INC(p, 4) + END END Fill; @@ -89,7 +89,7 @@ BEGIN IF X1 <= X2 THEN SU.MinMax(Y, 0, Buffer.Height - 1); color := Buffer.Color; - p1 := Buffer.adr + 4 * (Y * Buffer.Width + X1); + p1 := Buffer.bitmap + 4 * (Y * Buffer.Width + X1); p2 := p1 + (X2 - X1) * 4; FOR i := p1 TO p2 BY 4 DO sys.PUT(i, color) @@ -106,7 +106,7 @@ VAR BEGIN IF X1 <= X2 THEN SU.MinMax(Y, 0, Buffer.Height - 1); - p1 := Buffer.adr + 4 * (Y * Buffer.Width + X1); + p1 := Buffer.bitmap + 4 * (Y * Buffer.Width + X1); p2 := p1 + (X2 - X1) * 4; FOR i := p1 TO p2 BY 4 DO sys.GET(i, pix); @@ -125,7 +125,7 @@ BEGIN SU.MinMax(Y2, 0, Buffer.Height - 1); color := Buffer.Color; line_size := Buffer.Width * 4; - p1 := Buffer.adr + line_size * Y1 + 4 * X; + p1 := Buffer.bitmap + line_size * Y1 + 4 * X; p2 := p1 + (Y2 - Y1) * line_size; WHILE p1 <= p2 DO sys.PUT(p1, color); @@ -165,15 +165,15 @@ END GetColor; PROCEDURE TextOut*(X, Y: INTEGER; Text: INTEGER; length: INTEGER; size, params: INTEGER); BEGIN - drawText(Buffer.adr - 8, X, Y, Text, length, 0FF000000H + Buffer.Color, params) + drawText(Buffer.bitmap - 8, X, Y, Text, length, 0FF000000H + Buffer.Color, params) END TextOut; -PROCEDURE Resize2*(Width, Height: INTEGER); +PROCEDURE InitSize* (Width, Height: INTEGER); BEGIN - Buffer2.Width := Width; - Buffer2.Height := Height; -END Resize2; + Width0 := Width; + Height0 := Height; +END InitSize; PROCEDURE Image* (X, Y, sizeX, sizeY, ptr, Ymin, Ymax: INTEGER); @@ -183,14 +183,14 @@ BEGIN ASSERT(sizeX <= Buffer.Width); FOR y := 0 TO sizeY - 1 DO IF (Ymin <= Y) & (Y < Ymax) THEN - sys.MOVE(ptr + sizeX*4*y, Buffer.adr + (Buffer.Width*Y + X)*4, sizeX*4) + sys.MOVE(ptr + sizeX*4*y, Buffer.bitmap + (Buffer.Width*Y + X)*4, sizeX*4) END; INC(Y) END END Image; -PROCEDURE Image2(Buffer: PBuffer; X, Y, sizeX, sizeY, ptr: INTEGER); +PROCEDURE Image2(Buffer: tBuffer; X, Y, sizeX, sizeY, ptr: INTEGER); VAR x, y, pix, left: INTEGER; BEGIN left := X; @@ -199,7 +199,7 @@ BEGIN FOR x := 0 TO sizeX - 1 DO sys.GET32(ptr + (y*sizeX + x)*4, pix); IF (X < Buffer.Width) & (Y < Buffer.Height) THEN - sys.PUT32(Buffer.adr + (Buffer.Width*Y + X)*4, pix) + sys.PUT32(Buffer.bitmap + (Buffer.Width*Y + X)*4, pix) END; INC(X) END; @@ -213,10 +213,10 @@ VAR x, y: INTEGER; BEGIN IF ptr # 0 THEN y := 0; - WHILE y < Buffer3.Height DO + WHILE y < BackImg.Height DO x := 0; - WHILE x < Buffer3.Width DO - Image2(Buffer3, x, y, sizeX, sizeY, ptr); + WHILE x < BackImg.Width DO + Image2(BackImg, x, y, sizeX, sizeY, ptr); INC(x, sizeX) END; INC(y, sizeY) @@ -225,25 +225,15 @@ BEGIN END BackImage; -PROCEDURE Copy*(src, dst: PBuffer; y_src, lines, y_dst: INTEGER); +PROCEDURE Copy*(src, dst: tBuffer; y_src, lines, y_dst: INTEGER); BEGIN - sys.MOVE(src.adr + y_src * src.Width * 4, dst.adr + y_dst * dst.Width * 4, lines * dst.Width * 4) + sys.MOVE(src.bitmap + y_src * src.Width * 4, dst.bitmap + y_dst * dst.Width * 4, lines * dst.Width * 4) END Copy; -PROCEDURE Clear*; -VAR p, color: INTEGER; -BEGIN - color := Buffer.Color; - FOR p := Buffer.adr TO Buffer.adr + Buffer.Width * Buffer.Height * 4 - 4 BY 4 DO - sys.PUT(p, color) - END -END Clear; - - PROCEDURE Draw*(X, Y: INTEGER); BEGIN - K.sysfunc7(65, Buffer.adr, Buffer.Width * 65536 + Buffer.Height, X * 65536 + Y, 32, 0, 0) + K.sysfunc7(65, Buffer.bitmap, Buffer.Width * 65536 + Buffer.Height, X * 65536 + Y, 32, 0, 0) END Draw; @@ -259,11 +249,10 @@ END Rect; PROCEDURE Progress*(value: REAL); VAR W4, W2, H2: INTEGER; BEGIN - W4 := Buffer2.Width DIV 4; - W2 := Buffer2.Width DIV 2; - H2 := Buffer2.Height DIV 2; - SetColor(0FFFFFFH); - Clear; + W2 := Width0 DIV 2; + W4 := W2 DIV 2; + H2 := Height0 DIV 2; + Fill(Buffer, 0FFFFFFH); SetColor(0); Rect(W4, H2 - 50, 3 * W4, H2 + 30); TextOut(W2 - 10 * 8 DIV 2, H2 - 50 + 15, sys.SADR("Loading..."), 10, 1, 16 + 0 + LSL(3, 16) + LSL(128, 24)); @@ -272,39 +261,54 @@ BEGIN END Progress; -PROCEDURE Resize3(Buffer: PBuffer; Width, Height: INTEGER); +PROCEDURE _resize (Buffer: tBuffer; Width, Height: INTEGER); BEGIN - IF Buffer.adr # 0 THEN - DEC(Buffer.adr, 8) + IF Buffer.bitmap # 0 THEN + DEC(Buffer.bitmap, 8) END; - Buffer.adr := K.realloc(Buffer.adr, Width * Height * 4 + 8); - SU.MemError(Buffer.adr = 0); - sys.PUT(Buffer.adr, Width); - sys.PUT(Buffer.adr + 4, Height); - INC(Buffer.adr, 8); + Buffer.bitmap := K.realloc(Buffer.bitmap, Width * Height * 4 + 8); + SU.MemError(Buffer.bitmap = 0); + sys.PUT(Buffer.bitmap, Width); + sys.PUT(Buffer.bitmap + 4, Height); + INC(Buffer.bitmap, 8); Buffer.Width := Width; Buffer.Height := Height -END Resize3; +END _resize; PROCEDURE Resize*(Width, Height: INTEGER); BEGIN - Resize3(Buffer, Width, Height); - Resize3(Buffer3, Width, Height); + _resize(Buffer, Width, Height); + IF BackImg # NIL THEN + _resize(BackImg, Width, Height) + END END Resize; PROCEDURE Init; VAR Width, Height: INTEGER; BEGIN - NEW(Buffer); - NEW(Buffer2); - NEW(Buffer3); - SU.GetScreenSize(Width, Height); - Resize(Width, Height) + BackImg := NIL; + NEW(Buffer); + SU.GetScreenSize(Width, Height); + Resize(Width, Height) END Init; +PROCEDURE CreateBackImg*; +BEGIN + IF BackImg = NIL THEN + BackImg := Create(Buffer.Width, Buffer.Height) + END +END CreateBackImg; + + +PROCEDURE DestroyBackImg*; +BEGIN + Destroy(BackImg) +END DestroyBackImg; + + BEGIN Init END Graph. diff --git a/programs/other/fb2reader/SRC/Libimg.ob07 b/programs/other/fb2reader/SRC/Libimg.ob07 index ecc2b79c9f..b3c1fe17af 100644 --- a/programs/other/fb2reader/SRC/Libimg.ob07 +++ b/programs/other/fb2reader/SRC/Libimg.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2022 Anton Krotov + Copyright 2016, 2022, 2023 Anton Krotov This file is part of fb2read. @@ -19,21 +19,29 @@ MODULE LibImg; -IMPORT sys := SYSTEM, KOSAPI, File, S := Strings; +IMPORT SYSTEM, KOSAPI, File, S := Strings; PROCEDURE [stdcall, "Libimg.obj", ""] img_decode (data, size, options: INTEGER): INTEGER; END; -PROCEDURE [stdcall, "Libimg.obj", ""] img_to_rgb2 (data, data_rgb: INTEGER); END; PROCEDURE [stdcall, "Libimg.obj", ""] img_scale (src, crop_x, crop_y, crop_width, crop_height, dst, scale, inter, param1, param2: INTEGER): INTEGER; END; -PROCEDURE [stdcall, "Libimg.obj", ""] img_destroy* (img: INTEGER); END; +PROCEDURE [stdcall, "Libimg.obj", ""] img_destroy (img: INTEGER); END; PROCEDURE [stdcall, "Libimg.obj", ""] img_convert (src, dst, dst_type, flags, param: INTEGER): INTEGER; END; +PROCEDURE Destroy* (VAR img: INTEGER); +BEGIN + IF img # 0 THEN + img_destroy(img); + img := 0 + END +END Destroy; + + PROCEDURE GetInf* (img: INTEGER; VAR sizeX, sizeY, data: INTEGER); BEGIN - sys.GET(img + 4, sizeX); - sys.GET(img + 8, sizeY); - sys.GET(img + 24, data) + SYSTEM.GET(img + 4, sizeX); + SYSTEM.GET(img + 8, sizeY); + SYSTEM.GET(img + 24, data) END GetInf; @@ -43,9 +51,9 @@ VAR BEGIN image_data := img_decode(ptr, size, 0); IF image_data # 0 THEN - sys.GET(image_data + 4, x); - sys.GET(image_data + 8, y); - sys.GET(image_data + 20, type); + SYSTEM.GET(image_data + 4, x); + SYSTEM.GET(image_data + 8, y); + SYSTEM.GET(image_data + 20, type); IF type # 3 THEN dst := img_convert(image_data, 0, 3, 0, 0); img_destroy(image_data); @@ -57,7 +65,7 @@ BEGIN image_data := dst END; IF image_data # 0 THEN - sys.GET(image_data + 8, sizeY) + SYSTEM.GET(image_data + 8, sizeY) END END RETURN image_data diff --git a/programs/other/fb2reader/SRC/OpenDlg.ob07 b/programs/other/fb2reader/SRC/OpenDlg.ob07 index b5af638204..194b195530 100644 --- a/programs/other/fb2reader/SRC/OpenDlg.ob07 +++ b/programs/other/fb2reader/SRC/OpenDlg.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2022 Anton Krotov + Copyright 2016, 2022, 2023 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -17,7 +17,7 @@ MODULE OpenDlg; -IMPORT sys := SYSTEM, KOSAPI, S := Strings; +IMPORT sys := SYSTEM; TYPE diff --git a/programs/other/fb2reader/SRC/Read.ob07 b/programs/other/fb2reader/SRC/Read.ob07 deleted file mode 100644 index cf6c0fc922..0000000000 --- a/programs/other/fb2reader/SRC/Read.ob07 +++ /dev/null @@ -1,42 +0,0 @@ -(* - Copyright 2016 Anton Krotov - - This program 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 3 of the License, or - (at your option) any later version. - - This program 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 program. If not, see . -*) - -MODULE Read; - -IMPORT File, sys := SYSTEM; - -PROCEDURE Char*(F: File.FS; VAR x: CHAR): BOOLEAN; - RETURN File.Read(F, sys.ADR(x), sys.SIZE(CHAR)) = sys.SIZE(CHAR) -END Char; - -PROCEDURE Int*(F: File.FS; VAR x: INTEGER): BOOLEAN; - RETURN File.Read(F, sys.ADR(x), sys.SIZE(INTEGER)) = sys.SIZE(INTEGER) -END Int; - -PROCEDURE Real*(F: File.FS; VAR x: REAL): BOOLEAN; - RETURN File.Read(F, sys.ADR(x), sys.SIZE(REAL)) = sys.SIZE(REAL) -END Real; - -PROCEDURE Boolean*(F: File.FS; VAR x: BOOLEAN): BOOLEAN; - RETURN File.Read(F, sys.ADR(x), sys.SIZE(BOOLEAN)) = sys.SIZE(BOOLEAN) -END Boolean; - -PROCEDURE Set*(F: File.FS; VAR x: SET): BOOLEAN; - RETURN File.Read(F, sys.ADR(x), sys.SIZE(SET)) = sys.SIZE(SET) -END Set; - -END Read. diff --git a/programs/other/fb2reader/SRC/ReadFile.ob07 b/programs/other/fb2reader/SRC/ReadFile.ob07 index 81ccc562d4..f7cf481e4c 100644 --- a/programs/other/fb2reader/SRC/ReadFile.ob07 +++ b/programs/other/fb2reader/SRC/ReadFile.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2022 Anton Krotov + Copyright 2016, 2022, 2023 Anton Krotov This file is part of fb2read. @@ -19,7 +19,7 @@ MODULE ReadFile; -IMPORT sys := SYSTEM, K := KOSAPI, S := Strings, File, SU := SysUtils, Encode; +IMPORT sys := SYSTEM, K := KOSAPI, S := Strings, File, SU := SysUtils, Encoding; VAR @@ -87,7 +87,7 @@ BEGIN END Free; -PROCEDURE Conv*(cp: Encode.CP); +PROCEDURE Conv*(cp: Encoding.tCodePage); VAR m, nov, mem2, k: INTEGER; c: CHAR; BEGIN m := Mem; diff --git a/programs/other/fb2reader/SRC/Search.ob07 b/programs/other/fb2reader/SRC/Search.ob07 index c4f4de1c6c..3450373986 100644 --- a/programs/other/fb2reader/SRC/Search.ob07 +++ b/programs/other/fb2reader/SRC/Search.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2020, 2022 Anton Krotov + Copyright 2020, 2022, 2023 Anton Krotov This file is part of fb2read. @@ -22,7 +22,7 @@ MODULE Search; IMPORT XML, G := Graph, Window, Font, S := Strings, LISTS, SYSTEM, - SU := SysUtils, K := KOSAPI, SearchForm; + SU := SysUtils, K := KOSAPI, SearchForm, Encoding; TYPE @@ -72,7 +72,7 @@ VAR Find: PFind; -PROCEDURE SelText (Col: Window.TRect; min, max, Ycur, LineH: INTEGER; right: BOOLEAN; rect: TRect; cur: BOOLEAN); +PROCEDURE SelText (Col: Window.tRect; min, max, Ycur, LineH: INTEGER; right: BOOLEAN; rect: TRect; cur: BOOLEAN); VAR y, y0, color: INTEGER; @@ -85,12 +85,12 @@ BEGIN ELSE color := 0 END; - G.BoxNotXOR(Col.Left + rect.x1 + 1, Col.Top + y - Col.Height * ORD(right), Col.Left + rect.x2, Col.Top + y - Col.Height * ORD(right) + Font.FontH(), color) + G.BoxNotXOR(Col.left + rect.x1 + 1, Col.top + y - Col.height * ORD(right), Col.left + rect.x2, Col.top + y - Col.height * ORD(right) + Font.FontH(), color) END END SelText; -PROCEDURE draw* (body: XML.TAG; ColLeft, ColRight: Window.TRect; Ycur, LineH: INTEGER; TwoCol: BOOLEAN); +PROCEDURE draw* (body: XML.TAG; ColLeft, ColRight: Window.tRect; Ycur, LineH: INTEGER; TwoCol: BOOLEAN); VAR rect: TRect; pos, cur: TPos; @@ -107,9 +107,9 @@ BEGIN WHILE pos # NIL DO rect := pos.RectList.first(TRect); WHILE rect # NIL DO - SelText(ColLeft, 0, ColLeft.Height - LineH, Ycur, LineH, FALSE, rect, pos = cur); + SelText(ColLeft, 0, ColLeft.height - LineH, Ycur, LineH, FALSE, rect, pos = cur); IF TwoCol THEN - SelText(ColRight, ColLeft.Height, ColLeft.Height + ColRight.Height - LineH, Ycur, LineH, TRUE, rect, pos = cur) + SelText(ColRight, ColLeft.height, ColLeft.height + ColRight.height - LineH, Ycur, LineH, TRUE, rect, pos = cur) END; rect := rect.next(TRect) END; @@ -118,45 +118,6 @@ BEGIN END draw; -PROCEDURE getc_utf8 (VAR text, size, code: INTEGER); -VAR - c: BYTE; - n, k: INTEGER; - end: BOOLEAN; - -BEGIN - ASSERT(size > 0); - code := 0; - end := FALSE; - REPEAT - SYSTEM.GET(text, c); - INC(text); - DEC(size); - CASE c OF - | 0..127: - code := c; - end := TRUE - - |128..191: - code := code * 64 + c MOD 64; - DEC(n); - end := n <= 0 - - |192..255: - k := LSL(c, 24); - n := -2; - REPEAT - k := ROR(k, -1); - INC(n) - UNTIL ~ODD(k); - k := LSL(c, n + 25); - code := LSR(k, n + 25) - - END - UNTIL (size = 0) OR end -END getc_utf8; - - PROCEDURE textlen (body: XML.ELEMENT; VAR length: INTEGER); VAR cur: XML.ELEMENT; @@ -214,20 +175,18 @@ BEGIN END cap; -PROCEDURE UpCase (s1, s2, length: INTEGER); +PROCEDURE upcase (src, dst, length: INTEGER); VAR - code, n: INTEGER; - u: S.UTF8; - + n: INTEGER; + u: Encoding.tUtf8; BEGIN WHILE length > 0 DO - getc_utf8(s1, length, code); - S.utf8(cap(code), u); + Encoding.utf8(cap(Encoding.getUtf8Char(src, length)), u); n := LENGTH(u); - SYSTEM.MOVE(SYSTEM.ADR(u[0]), s2, n); - INC(s2, n) + SYSTEM.MOVE(SYSTEM.ADR(u[0]), dst, n); + INC(dst, n) END -END UpCase; +END upcase; PROCEDURE create (body: XML.ELEMENT); @@ -304,7 +263,7 @@ BEGIN buf1 := K.malloc(length); SU.MemError(buf1 = 0); - UpCase(buf, buf1, length); + upcase(buf, buf1, length); NEW(text.idx1); index(text.idx1, buf1, text.idx0.size); @@ -482,7 +441,7 @@ BEGIN text.PosList := LISTS.create(NIL); text.str0 := str; - UpCase(SYSTEM.ADR(str[0]), SYSTEM.ADR(text.str1[0]), LENGTH(str)); + upcase(SYSTEM.ADR(str[0]), SYSTEM.ADR(text.str1[0]), LENGTH(str)); IF text.case THEN idx := text.idx0; @@ -588,6 +547,7 @@ PROCEDURE close*; VAR text: Text; body: XML.TAG; + nullptr: INTEGER; BEGIN body := Body; @@ -596,7 +556,15 @@ BEGIN LISTS.destroy(text.PosList); text.PosList := LISTS.create(NIL); text.found := 0; - text.curPos := NIL + text.curPos := NIL; + nullptr := K.free(text.idx0.table); + nullptr := K.free(text.idx0.data); + nullptr := K.free(text.idx1.table); + nullptr := K.free(text.idx1.data); + DISPOSE(text.idx0); + DISPOSE(text.idx1); + DISPOSE(text); + body.text := NIL END END close; diff --git a/programs/other/fb2reader/SRC/SearchForm.ob07 b/programs/other/fb2reader/SRC/SearchForm.ob07 index ddafaa2212..536ae41607 100644 --- a/programs/other/fb2reader/SRC/SearchForm.ob07 +++ b/programs/other/fb2reader/SRC/SearchForm.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2020-2021 Anton Krotov + Copyright 2020-2021, 2023 Anton Krotov This file is part of fb2read. @@ -21,7 +21,7 @@ MODULE SearchForm; IMPORT - SYSTEM, SU := SysUtils, W := Window, box_lib, K := KOSAPI, Encode, S := Strings; + SYSTEM, SU := SysUtils, W := Window, box_lib, K := KOSAPI, Encoding; CONST @@ -49,7 +49,7 @@ VAR PID, Slot: INTEGER; Stack: ARRAY 1000000 OF CHAR; - Window: W.TWindow; + Window: W.tWindow; str: STRING; callback: PROC; @@ -80,8 +80,8 @@ PROCEDURE DrawWindow; BEGIN SU.GetSystemColors; SU.WindowRedrawStatus(1); - SU.DefineAndDrawWindow(Window.Left, Window.Top, Window.Width, Window.Height, - SU.winColor, LSL(ORD({0, 1}), 4) + 4, Window.Caption); + SU.DefineAndDrawWindow(Window.left, Window.top, Window.width, Window.height, + SU.winColor, LSL(ORD({0, 1}), 4) + 4, Window.caption); buttons; SU.WindowRedrawStatus(2) END DrawWindow; @@ -92,7 +92,7 @@ VAR pid, i, j, k, n: INTEGER; found: BOOLEAN; str0: STRING; - u: S.UTF8; + u: Encoding.tUtf8; BEGIN found := TRUE; @@ -103,8 +103,8 @@ BEGIN j := 0; i := 0; WHILE str[i] # 0X DO - u := Encode.CP866[ORD(str[i])].utf8; - n := Encode.CP866[ORD(str[i])].len; + u := Encoding.cp866[ORD(str[i])].utf8; + n := Encoding.cp866[ORD(str[i])].len; FOR k := 0 TO n - 1 DO str0[j] := u[k]; INC(j) @@ -148,19 +148,19 @@ VAR BEGIN SU.SetEventsMask({0, 1, 2, 5, 30, 31}); - W.InitWindow(Window, 0, 0, 320, 140, "Search"); + W.init(Window, 0, 0, 320, 140, "Search"); SU.GetScreenSize(scrWidth, scrHeight); - Window.Left := (scrWidth - Window.Width) DIV 2; - Window.Top := (scrHeight - Window.Height) DIV 2; + Window.left := (scrWidth - Window.width) DIV 2; + Window.top := (scrHeight - Window.height) DIV 2; DrawWindow; WHILE TRUE DO CASE SU.WaitForEvent() OF |1: DrawWindow - |2: key := K.sysfunc1(2); - IF key DIV 65536 = 28 THEN + |2: key := SU.GetKey(); + IF key DIV 65536 = 28 THEN (* enter *) close(TRUE) - ELSIF key DIV 65536 = 1 THEN + ELSIF key DIV 65536 = 1 THEN (* esc *) close(FALSE) ELSE box_lib.edit_box_key_safe(text, key) diff --git a/programs/other/fb2reader/SRC/SelEnc.ob07 b/programs/other/fb2reader/SRC/SelEnc.ob07 index 6f0d8377f6..c84f416591 100644 --- a/programs/other/fb2reader/SRC/SelEnc.ob07 +++ b/programs/other/fb2reader/SRC/SelEnc.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2018, 2020-2022 Anton Krotov + Copyright 2016, 2018, 2020-2023 Anton Krotov This file is part of fb2read. @@ -20,40 +20,42 @@ MODULE SelEnc; IMPORT - - SU := SysUtils, W := Window, OpenDlg, S := Strings, TXT := Txt2FB2, SYSTEM, K := KOSAPI, Settings, File; + SU := SysUtils, W := Window, S := Strings, SYSTEM, K := KOSAPI, File; CONST + AUTO = 15; + CP866 = 16; + CP1251 = 17; + CP1252 = 18; + CP1250 = 19; + UTF8 = 20; - BtnH = 30; - BtnW = 150; - BtnX = 5; - BtnY = 10; - BtnInter = 10; + BtnH = 30; + BtnW = 150; + BtnX = 5; + BtnY = 10; + BtnInter = 10; tempfile* = "/tmp0/1/~temp.fb2"; VAR - - Window : W.TWindow; - ENCODING* : INTEGER; - FileName : S.STRING; + Window: W.tWindow; + pos, mem, mem2, pos2: INTEGER; PROCEDURE Buttons; VAR Y : INTEGER; - BEGIN Y := BtnY; - SU.CreateButton(TXT.AUTO, BtnX, Y, BtnW, BtnH, SU.btnColor, "AUTO" ); INC(Y, BtnH + BtnInter); - SU.CreateButton(TXT.CP866, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-866" ); INC(Y, BtnH + BtnInter); - SU.CreateButton(TXT.CP1251, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-1251"); INC(Y, BtnH + BtnInter); - SU.CreateButton(TXT.CP1252, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-1252"); INC(Y, BtnH + BtnInter); - SU.CreateButton(TXT.CP1250, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-1250"); INC(Y, BtnH + BtnInter); - SU.CreateButton(TXT.UTF8, BtnX, Y, BtnW, BtnH, SU.btnColor, "UTF-8" ) + SU.CreateButton(AUTO, BtnX, Y, BtnW, BtnH, SU.btnColor, "AUTO" ); INC(Y, BtnH + BtnInter); + SU.CreateButton(CP866, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-866" ); INC(Y, BtnH + BtnInter); + SU.CreateButton(CP1251, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-1251"); INC(Y, BtnH + BtnInter); + SU.CreateButton(CP1252, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-1252"); INC(Y, BtnH + BtnInter); + SU.CreateButton(CP1250, BtnX, Y, BtnW, BtnH, SU.btnColor, "CP-1250"); INC(Y, BtnH + BtnInter); + SU.CreateButton(UTF8, BtnX, Y, BtnW, BtnH, SU.btnColor, "UTF-8" ) END Buttons; @@ -61,16 +63,94 @@ PROCEDURE DrawWindow; BEGIN SU.GetSystemColors; SU.WindowRedrawStatus(1); - SU.DefineAndDrawWindow(Window.Left, Window.Top, Window.Width, Window.Height, - SU.winColor, LSL(ORD({0, 1}), 4) + 4, Window.Caption); + SU.DefineAndDrawWindow(Window.left, Window.top, Window.width, Window.height, + SU.winColor, LSL(ORD({0, 1}), 4) + 4, Window.caption); Buttons; SU.WindowRedrawStatus(2) END DrawWindow; -PROCEDURE auto (fname: S.STRING): INTEGER; +PROCEDURE getch (): CHAR; VAR - enc, data, size, ptr: INTEGER; + ch: CHAR; +BEGIN + SYSTEM.GET(mem + pos, ch); + INC(pos) + RETURN ch +END getch; + + +PROCEDURE WriteStr (s: ARRAY OF CHAR); +BEGIN + SYSTEM.MOVE(SYSTEM.ADR(s[0]), mem2 + pos2, LENGTH(s)); + pos2 := pos2 + LENGTH(s) +END WriteStr; + + +PROCEDURE WriteChar (ch: CHAR); +BEGIN + SYSTEM.PUT(mem2 + pos2, ch); + INC(pos2) +END WriteChar; + + +PROCEDURE convert (ibuf, size: INTEGER; out: S.STRING; encoding: INTEGER); +CONST + buf_size = 1024*16; +VAR + F: File.FS; + n: INTEGER; + CR: BOOLEAN; + ch: CHAR; + buffer: ARRAY buf_size OF BYTE; +BEGIN + mem := ibuf; + pos := 0; + F := File.Create(out); + mem2 := SYSTEM.ADR(buffer[0]); + pos2 := 0; + WriteStr('' + 0DX + 0AX + ""); + + WHILE pos < size DO + IF pos2 > buf_size - 32 THEN + n := File.Write(F, mem2, pos2); + pos2 := 0 + END; + ch := getch(); + CASE ch OF + |"<": WriteStr("<") + |">": WriteStr(">") + |"&": WriteStr("&") + |"'": WriteStr("'") + |'"': WriteStr(""") + |0DX: WriteStr("") + |0AX: IF ~CR THEN WriteStr("") END + | 0X: WriteChar(20X) + ELSE + WriteChar(ch) + END; + CR := ch = 0DX + END; + + WriteStr(""); + n := File.Write(F, mem2, pos2); + File.Close(F) +END convert; + + +PROCEDURE auto (ptr, size: INTEGER): INTEGER; +VAR + enc: INTEGER; PROCEDURE SearchPair (ptr, size: INTEGER; chr1, chr2: BYTE): BOOLEAN; @@ -96,39 +176,32 @@ VAR BEGIN - data := File.Load(fname, size); - SU.ErrorIf(data = 0, 1); - ptr := data; - IF SearchPair(ptr, size, 208, 190) THEN - enc := TXT.UTF8 + enc := UTF8 ELSE IF SearchPair(ptr, size, 239, 240) OR SearchPair(ptr, size, 241, 242) THEN - enc := TXT.CP1251 + enc := CP1251 ELSE - enc := TXT.CP866 + enc := CP866 END - END; - - data := K.free(data) - + END RETURN enc END auto; -PROCEDURE ButtonClick; +PROCEDURE ButtonClick (fname: S.STRING); VAR - btn_code: INTEGER; + encoding: INTEGER; program, file: S.STRING; - + data, size: INTEGER; BEGIN - btn_code := SU.GetButtonCode(); - IF btn_code = TXT.AUTO THEN - ENCODING := auto(FileName) - ELSE - ENCODING := btn_code + data := File.Load(fname, size); + SU.ErrorIf(data = 0, 1); + encoding := SU.GetButtonCode(); + IF encoding = AUTO THEN + encoding := auto(data, size) END; - TXT.convert(FileName, tempfile, ENCODING); + convert(data, size, tempfile, encoding); S.PtrToString(K.GetName(), program); file := tempfile; file[0] := "!"; @@ -137,27 +210,23 @@ BEGIN END ButtonClick; -PROCEDURE Show*(FName: S.STRING); +PROCEDURE Show* (fname: S.STRING); VAR X1, Y1, X2, Y2: INTEGER; - BEGIN - FileName := FName; SU.SetEventsMask({0, 2, 31}); SU.GetScreenArea(X1, Y1, X2, Y2); - W.InitWindow(Window, 0, 0, BtnX * 2 + BtnW + 10, (BtnH + BtnInter) * 6 + BtnY * 2 + SU.SkinHeight() - 5, "Encoding"); - Window.Left := (X2 - X1 - Window.Width) DIV 2; - Window.Top := (Y2 - Y1 - Window.Height) DIV 2; + W.init(Window, 0, 0, BtnX * 2 + BtnW + 10, (BtnH + BtnInter) * 6 + BtnY * 2 + SU.SkinHeight() - 5, "Encoding"); + Window.left := (X2 - X1 - Window.width) DIV 2; + Window.top := (Y2 - Y1 - Window.height) DIV 2; DrawWindow; WHILE TRUE DO CASE SU.WaitForEvent() OF - |1 : DrawWindow - |3 : ButtonClick + |1: DrawWindow + |3: ButtonClick(fname) END END END Show; -BEGIN - ENCODING := 0 END SelEnc. \ No newline at end of file diff --git a/programs/other/fb2reader/SRC/Settings.ob07 b/programs/other/fb2reader/SRC/Settings.ob07 index 57a0c567e2..1a3621b1af 100644 --- a/programs/other/fb2reader/SRC/Settings.ob07 +++ b/programs/other/fb2reader/SRC/Settings.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2018, 2020-2022 Anton Krotov + Copyright 2016, 2018, 2020-2023 Anton Krotov This file is part of fb2read. @@ -19,7 +19,7 @@ MODULE Settings; -IMPORT SU := SysUtils, W := Window, C := ColorDlg, DOM, S := Strings, +IMPORT SU := SysUtils, W := Window, C := ColorDlg, DOM, S := Strings, K := KOSAPI, File, Font, KF := kfonts, OD := OpenDlg, LibImg, G := Graph, Ini, box_lib, sys := SYSTEM; @@ -56,7 +56,7 @@ CONST VAR - Window : W.TWindow; + Window : W.tWindow; PID : INTEGER; Slot : INTEGER; Color : C.Dialog; @@ -69,6 +69,7 @@ VAR check2 : box_lib.checkbox; OpenPict : OD.Dialog; picture : INTEGER; + picture_fsize : INTEGER; picture_path : S.STRING; @@ -79,8 +80,9 @@ BEGIN IF PID # 0 THEN pid := PID; PID := 0; - IF (picture # 0) & (picture # Data.Picture) THEN - LibImg.img_destroy(picture) + IF (picture # Data.Picture) & (picture # 0) THEN + picture := K.free(picture); + picture_fsize := 0 END; C.Destroy(Color); OD.Destroy(OpenPict); @@ -91,7 +93,7 @@ END Close; PROCEDURE ClearWindow; BEGIN - SU.Box(0, 0, Window.Width - 10, Window.Height - SU.SkinHeight() - 5, SU.winColor, SU.winColor) + SU.Box(0, 0, Window.width - 10, Window.height - SU.SkinHeight() - 5, SU.winColor, SU.winColor) END ClearWindow; @@ -130,18 +132,18 @@ VAR X, Y, TextY : INTEGER; WinW, WinH, SkinH : INTEGER; i : INTEGER; - Rect : W.TRect; + Rect : W.tRect; BEGIN - Rect.Left := 10; - Rect.Top := 85; - Rect.Width := 210; - Rect.Height := 255; - SU.Box(Rect.Left, Rect.Top, Rect.Width, Rect.Height, SU.winColor, SU.borderColor); - SU.Box(Rect.Left + 230, Rect.Top, Rect.Width + 170, Rect.Height, SU.winColor, SU.borderColor); + Rect.left := 10; + Rect.top := 85; + Rect.width := 210; + Rect.height := 255; + SU.Box(Rect.left, Rect.top, Rect.width, Rect.height, SU.winColor, SU.borderColor); + SU.Box(Rect.left + 230, Rect.top, Rect.width + 170, Rect.height, SU.winColor, SU.borderColor); - WinW := Window.Width; - WinH := Window.Height; + WinW := Window.width; + WinH := Window.height; SkinH := SU.SkinHeight(); X := 125; Y := 10; @@ -178,8 +180,8 @@ BEGIN Y := Y - 6; - SU.CreateButton(DAY, (Rect.Width - (BtnW + 5 + BtnW)) DIV 2 + Rect.Left, Y, 80, BtnH, SU.btnColor, "Day" ); - SU.CreateButton(NIGHT, (Rect.Width - (BtnW + 5 + BtnW)) DIV 2 + Rect.Left + 5 + BtnW, Y, 80, BtnH, SU.btnColor, "Night" ); + SU.CreateButton(DAY, (Rect.width - (BtnW + 5 + BtnW)) DIV 2 + Rect.left, Y, 80, BtnH, SU.btnColor, "Day" ); + SU.CreateButton(NIGHT, (Rect.width - (BtnW + 5 + BtnW)) DIV 2 + Rect.left + 5 + BtnW, Y, 80, BtnH, SU.btnColor, "Night" ); SU.CreateButton(APPLY, (WinW - (BtnW + 5 + BtnW) - 10) DIV 2, WinH - BtnH - SkinH - 10, 80, BtnH, SU.btnColor, "Apply" ); SU.CreateButton(CANCEL, (WinW - (BtnW + 5 + BtnW) - 10) DIV 2 + 5 + BtnW, WinH - BtnH - SkinH - 10, 80, BtnH, SU.btnColor, "Cancel"); @@ -197,8 +199,8 @@ PROCEDURE DrawWindow; BEGIN SU.GetSystemColors; SU.WindowRedrawStatus(1); - SU.DefineAndDrawWindow(Window.Left, Window.Top, Window.Width, Window.Height, - SU.winColor, LSL(ORD({0, 1}), 4) + 4, Window.Caption); + SU.DefineAndDrawWindow(Window.left, Window.top, Window.width, Window.height, + SU.winColor, LSL(ORD({0, 1}), 4) + 4, Window.caption); Buttons; SU.WindowRedrawStatus(2) END DrawWindow; @@ -258,28 +260,31 @@ BEGIN Data.PARAGRAPH := sb[4].position; Data.EPIGRAPH := sb[5].position; Data.InterLin := sb[6].position; - IF Data.Picture # picture THEN - IF Data.Picture # 0 THEN - LibImg.img_destroy(Data.Picture) + IF (picture # 0) & (picture # Data.Picture) THEN + IF Data.Picture # 0 THEN + Data.Picture := K.free(Data.Picture) END; Data.Picture := picture; + Data.picture_fsize := picture_fsize; Ini.SetPicturePath(picture_path) END; picture := 0; + picture_fsize := 0; DOM.SetSettings(Data); Close END Apply; PROCEDURE LoadPicture(file_path: S.STRING); -VAR ysize, img: INTEGER; +VAR fsize, img: INTEGER; BEGIN - img := LibImg.LoadFromFile(file_path, 10240000, ysize); + img := File.Load(file_path, fsize); IF img # 0 THEN IF (picture # 0) & (picture # Data.Picture) THEN - LibImg.img_destroy(picture) + picture := K.free(picture) END; picture := img; + picture_fsize := fsize; picture_path := file_path END END LoadPicture; @@ -335,6 +340,7 @@ BEGIN Data.EPIGRAPH := 100; Data.InterLin := 0; Data.Picture := picture; + Data.picture_fsize := picture_fsize; DOM.SetSettings(Data) END Default; @@ -343,14 +349,15 @@ PROCEDURE Show; VAR i, scrWidth, scrHeight: INTEGER; BEGIN SU.SetEventsMask({0, 2, 5, 30, 31}); - W.InitWindow(Window, 0, 0, 640, 420, "Settings"); + W.init(Window, 0, 0, 640, 420, "Settings"); SU.GetScreenSize(scrWidth, scrHeight); - Window.Left := (scrWidth - Window.Width) DIV 2; - Window.Top := (scrHeight - Window.Height) DIV 2; + Window.left := (scrWidth - Window.width) DIV 2; + Window.top := (scrHeight - Window.height) DIV 2; Color := C.Create(DrawWindow); OpenPict := OD.Create(DrawWindow, 0, "/sys", "JPG|PNG|BMP|GIF"); Data := DOM.Settings; picture := Data.Picture; + picture_fsize := Data.picture_fsize; DrawWindow; WHILE TRUE DO CASE SU.WaitForEvent() OF @@ -409,6 +416,7 @@ BEGIN check2 := box_lib.kolibri_new_check_box(TextLeft, 10 + 5, 16, 16, sys.SADR(""), LENGTH(bpicture) * 8 + 5); check1 := box_lib.kolibri_new_check_box(TextLeft, 10 + (BtnH + 10) + 5, 16, 16, sys.SADR(""), LENGTH(twocol) * 8 + 5); picture := 0; + picture_fsize := 0; IF Ini.Picture # "" THEN LoadPicture(Ini.Picture) END diff --git a/programs/other/fb2reader/SRC/Strings.ob07 b/programs/other/fb2reader/SRC/Strings.ob07 index e42437a7f6..77107d775c 100644 --- a/programs/other/fb2reader/SRC/Strings.ob07 +++ b/programs/other/fb2reader/SRC/Strings.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2019, 2022 Anton Krotov + Copyright 2016, 2019, 2022, 2023 Anton Krotov This file is part of fb2read. @@ -19,15 +19,13 @@ MODULE Strings; -IMPORT sys := SYSTEM, KOSAPI; +IMPORT sys := SYSTEM, Encoding; TYPE STRING* = ARRAY 1024 OF CHAR; - UTF8* = ARRAY 8 OF CHAR; - CHARS* = RECORD first*, last* : INTEGER END; @@ -290,30 +288,6 @@ BEGIN END Replace; -PROCEDURE utf8*(code: INTEGER; VAR uchar: UTF8); -BEGIN - uchar[0] := 0X; - IF code < 80H THEN - uchar[0] := CHR(code); - uchar[1] := 0X - ELSIF code < 800H THEN - uchar[1] := CHR(ORD(BITS(code) * {0..5}) + 80H); - uchar[0] := CHR(ASR(code, 6) + 0C0H); - uchar[2] := 0X - ELSIF code < 10000H THEN - uchar[2] := CHR(ORD(BITS(code) * {0..5}) + 80H); - code := ASR(code, 6); - uchar[1] := CHR(ORD(BITS(code) * {0..5}) + 80H); - uchar[0] := CHR(ASR(code, 6) + 0E0H); - uchar[3] := 0X -(* - ELSIF code < 200000H THEN - ELSIF code < 4000000H THEN - ELSE *) - END -END utf8; - - PROCEDURE EntOct*(VAR chars: CHARS): BOOLEAN; VAR i : INTEGER; @@ -324,7 +298,7 @@ VAR exit : BOOLEAN; str : STRING; str2 : STRING; - uchar : UTF8; + uchar : Encoding.tUtf8; res : BOOLEAN; BEGIN @@ -361,7 +335,7 @@ BEGIN IF c = ";" THEN str2[0] := c; Append(str, str2); - utf8(val, uchar); + Encoding.utf8(val, uchar); Replace(chars, str, uchar); res := TRUE; i := chars.last - chars.first diff --git a/programs/other/fb2reader/SRC/SysUtils.ob07 b/programs/other/fb2reader/SRC/SysUtils.ob07 index ba4ed391e0..f4af1b5147 100644 --- a/programs/other/fb2reader/SRC/SysUtils.ob07 +++ b/programs/other/fb2reader/SRC/SysUtils.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2019, 2021, 2022 Anton Krotov + Copyright 2016, 2019, 2021-2023 Anton Krotov This file is part of fb2read. @@ -135,7 +135,7 @@ END MouseVScroll; PROCEDURE MouseStatus*(): SET; - RETURN BITS(K.sysfunc2(37, 2)) + RETURN BITS(K.sysfunc2(37, 3)) END MouseStatus; @@ -167,9 +167,24 @@ BEGIN END SetEventsMask; -PROCEDURE GetKeyCode*(): INTEGER; - RETURN LSR(LSL(K.sysfunc1(2), 16), 24) -END GetKeyCode; +PROCEDURE GetKey* (): INTEGER; + RETURN K.sysfunc1(2) +END GetKey; + + +PROCEDURE GetControlKeys* (): SET; + RETURN BITS(K.sysfunc2(66, 3)) +END GetControlKeys; + + +PROCEDURE getKBState* (VAR shift, ctrl: BOOLEAN); +VAR + kbState: SET; +BEGIN + kbState := GetControlKeys(); + shift := {0, 1} * kbState # {}; + ctrl := {2, 3} * kbState # {}; +END getKBState; PROCEDURE GetButtonCode*(): INTEGER; diff --git a/programs/other/fb2reader/SRC/Txt2fb2.ob07 b/programs/other/fb2reader/SRC/Txt2fb2.ob07 deleted file mode 100644 index 649d9f96e6..0000000000 --- a/programs/other/fb2reader/SRC/Txt2fb2.ob07 +++ /dev/null @@ -1,129 +0,0 @@ -(* - Copyright 2016, 2020 Anton Krotov - - This file is part of fb2read. - - fb2read is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - fb2read 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with fb2read. If not, see . -*) - -MODULE Txt2FB2; - -IMPORT File, sys := SYSTEM, K := KOSAPI, S := Strings, SU := SysUtils; - - -CONST - - AUTO* = 15; - CP866* = 16; - CP1251* = 17; - CP1252* = 18; - CP1250* = 19; - UTF8* = 20; - - -VAR F: File.FS; ch: CHAR; pos, mem, mem2, pos2: INTEGER; - - -PROCEDURE getch; -BEGIN - sys.GET(mem + pos, ch); - INC(pos) -END getch; - - -PROCEDURE WriteStr(s: ARRAY OF CHAR); -BEGIN - sys.MOVE(sys.ADR(s[0]), mem2 + pos2, LENGTH(s)); - pos2 := pos2 + LENGTH(s) -END WriteStr; - - -PROCEDURE WriteChar(ch: CHAR); -BEGIN - sys.PUT(mem2 + pos2, ch); - INC(pos2) -END WriteChar; - - -PROCEDURE convert*(in, out: S.STRING; encoding: INTEGER); -CONST buf_size = 1024*16; -VAR n, size: INTEGER; CR: BOOLEAN; -BEGIN - F := File.Open(in); - size := File.Seek(F, 0, 2); - n := File.Seek(F, 0, 0); - mem := K.malloc(size + 1024); - SU.MemError(mem = 0); - n := File.Read(F, mem, size); - File.Close(F); - pos := 0; - F := File.Create(out); - mem2 := K.malloc(buf_size); - SU.MemError(mem2 = 0); - pos2 := 0; - WriteStr(""); - WriteChar(0DX); - WriteChar(0AX); - WriteStr(""); - WHILE pos < size DO - IF pos2 > buf_size - 32 THEN - n := File.Write(F, mem2, pos2); - pos2 := 0 - END; - getch; - IF ch = "<" THEN - WriteStr("<") - ELSIF ch = ">" THEN - WriteStr(">") - ELSIF ch = "&" THEN - WriteStr("&") - ELSIF ch = "'" THEN - WriteStr("'") - ELSIF ch = 22X THEN - WriteStr(""") - ELSIF ch = 0DX THEN - WriteStr("") - ELSIF ch = 0AX THEN - IF ~CR THEN - WriteStr("") - END - ELSIF ch = 0X THEN - WriteChar(20X) - ELSE - WriteChar(ch) - END; - CR := ch = 0DX - END; - - WriteStr(""); - n := File.Write(F, mem2, pos2); - File.Close(F); - mem := K.free(mem); - mem2 := K.free(mem2) -END convert; - - -END Txt2FB2. diff --git a/programs/other/fb2reader/SRC/Vector.ob07 b/programs/other/fb2reader/SRC/Vector.ob07 index a2fa7f632e..b642e6ef53 100644 --- a/programs/other/fb2reader/SRC/Vector.ob07 +++ b/programs/other/fb2reader/SRC/Vector.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016 Anton Krotov + Copyright 2016, 2023 Anton Krotov This file is part of fb2read. @@ -19,86 +19,90 @@ MODULE Vector; +IMPORT SYSTEM, K := KOSAPI; -IMPORT sys := SYSTEM, K := KOSAPI; + +CONST + ptr_size = 4; TYPE - DESC_VECTOR = RECORD + DESC_VECTOR = RECORD + data : INTEGER; + count* : INTEGER; + size : INTEGER + END; - data : INTEGER; - count* : INTEGER; - size : INTEGER + VECTOR* = POINTER TO DESC_VECTOR; - END; + ANYREC* = RECORD END; - VECTOR* = POINTER TO DESC_VECTOR; + ANYPTR* = POINTER TO ANYREC; - ANYREC* = RECORD END; - - ANYPTR* = POINTER TO ANYREC; - - DESTRUCTOR* = PROCEDURE (VAR ptr: ANYPTR); + DESTRUCTOR* = PROCEDURE (VAR ptr: ANYPTR); PROCEDURE push* (vector: VECTOR; value: ANYPTR); BEGIN - IF vector.count = vector.size THEN - vector.data := K.realloc(vector.data, (vector.size + 1024) * 4); - vector.size := vector.size + 1024 - END; - sys.PUT(vector.data + vector.count * 4, value); - INC(vector.count) + IF vector.count = vector.size THEN + vector.data := K.realloc(vector.data, (vector.size + 1024) * ptr_size); + vector.size := vector.size + 1024 + END; + SYSTEM.PUT(vector.data + vector.count * ptr_size, value); + INC(vector.count) END push; PROCEDURE get* (vector: VECTOR; idx: INTEGER): ANYPTR; -VAR res: ANYPTR; +VAR + res: ANYPTR; BEGIN - ASSERT( (0 <= idx) & (idx < vector.count) ); - sys.GET(vector.data + idx * 4, res) - RETURN res + ASSERT( (0 <= idx) & (idx < vector.count) ); + SYSTEM.GET(vector.data + idx * ptr_size, res) + RETURN res END get; PROCEDURE put* (vector: VECTOR; idx: INTEGER; value: ANYPTR); BEGIN - ASSERT( (0 <= idx) & (idx < vector.count) ); - sys.PUT(vector.data + idx * 4, value) + ASSERT( (0 <= idx) & (idx < vector.count) ); + SYSTEM.PUT(vector.data + idx * ptr_size, value) END put; PROCEDURE create* (size: INTEGER): VECTOR; -VAR vector: VECTOR; +VAR + vector: VECTOR; BEGIN - NEW(vector); - vector.data := K.malloc(4 * size); - vector.size := size; - vector.count := 0 - RETURN vector + NEW(vector); + vector.data := K.malloc(ptr_size * size); + vector.size := size; + vector.count := 0 + RETURN vector END create; PROCEDURE def_destructor (VAR any: ANYPTR); BEGIN - DISPOSE(any) + DISPOSE(any) END def_destructor; PROCEDURE destroy* (VAR vector: VECTOR; destructor: DESTRUCTOR); -VAR i: INTEGER; - any: ANYPTR; +VAR + i: INTEGER; + any: ANYPTR; BEGIN - IF destructor = NIL THEN - destructor := def_destructor - END; - FOR i := 0 TO vector.count - 1 DO - any := get(vector, i); - destructor(any) - END; - vector.data := K.free(vector.data); - DISPOSE(vector) + IF destructor = NIL THEN + destructor := def_destructor + END; + FOR i := 0 TO vector.count - 1 DO + any := get(vector, i); + destructor(any) + END; + vector.data := K.free(vector.data); + DISPOSE(vector) END destroy; diff --git a/programs/other/fb2reader/SRC/Window.ob07 b/programs/other/fb2reader/SRC/Window.ob07 index c2c71e9093..2f8b11a269 100644 --- a/programs/other/fb2reader/SRC/Window.ob07 +++ b/programs/other/fb2reader/SRC/Window.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2021 Anton Krotov + Copyright 2016, 2021, 2023 Anton Krotov This file is part of fb2read. @@ -23,36 +23,34 @@ IMPORT S := Strings; TYPE - TRect* = RECORD - Left*, Top*, Width*, Height* : INTEGER - END; + tRect* = RECORD + left*, top*, width*, height* : INTEGER + END; - TWindow* = RECORD (TRect) - Caption* : S.STRING; - Created* : BOOLEAN; - dWidth*, dHeight* : INTEGER - END; + tWindow* = RECORD (tRect) + caption* : S.STRING; + created* : BOOLEAN; + dWidth*, dHeight* : INTEGER + END; -PROCEDURE InitWindow*(VAR Window: TWindow; Left, Top, Width, Height: INTEGER; Caption: ARRAY OF CHAR); + +PROCEDURE initRect* (VAR Rect: tRect; left, top, width, height: INTEGER); BEGIN - Window.Left := Left; - Window.Top := Top; - Window.Width := Width; - Window.Height := Height; - Window.Created := FALSE; - Window.dWidth := 0; - Window.dHeight := 0; - COPY(Caption, Window.Caption) -END InitWindow; + Rect.left := left; + Rect.top := top; + Rect.width := width; + Rect.height := height +END initRect; -PROCEDURE InitRect*(VAR Rect: TRect; Left, Top, Width, Height: INTEGER); +PROCEDURE init* (VAR window: tWindow; left, top, width, height: INTEGER; caption: ARRAY OF CHAR); BEGIN - Rect.Left := Left; - Rect.Top := Top; - Rect.Width := Width; - Rect.Height := Height -END InitRect; + initRect(window, left, top, width, height); + window.created := FALSE; + window.dWidth := 0; + window.dHeight := 0; + COPY(caption, window.caption) +END init; END Window. diff --git a/programs/other/fb2reader/SRC/Write.ob07 b/programs/other/fb2reader/SRC/Write.ob07 deleted file mode 100644 index e12cb07fa4..0000000000 --- a/programs/other/fb2reader/SRC/Write.ob07 +++ /dev/null @@ -1,42 +0,0 @@ -(* - Copyright 2016 Anton Krotov - - This program 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 3 of the License, or - (at your option) any later version. - - This program 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 program. If not, see . -*) - -MODULE Write; - -IMPORT File, sys := SYSTEM; - -PROCEDURE Char*(F: File.FS; x: CHAR): BOOLEAN; - RETURN File.Write(F, sys.ADR(x), sys.SIZE(CHAR)) = sys.SIZE(CHAR) -END Char; - -PROCEDURE Int*(F: File.FS; x: INTEGER): BOOLEAN; - RETURN File.Write(F, sys.ADR(x), sys.SIZE(INTEGER)) = sys.SIZE(INTEGER) -END Int; - -PROCEDURE Real*(F: File.FS; x: REAL): BOOLEAN; - RETURN File.Write(F, sys.ADR(x), sys.SIZE(REAL)) = sys.SIZE(REAL) -END Real; - -PROCEDURE Boolean*(F: File.FS; x: BOOLEAN): BOOLEAN; - RETURN File.Write(F, sys.ADR(x), sys.SIZE(BOOLEAN)) = sys.SIZE(BOOLEAN) -END Boolean; - -PROCEDURE Set*(F: File.FS; x: SET): BOOLEAN; - RETURN File.Write(F, sys.ADR(x), sys.SIZE(SET)) = sys.SIZE(SET) -END Set; - -END Write. diff --git a/programs/other/fb2reader/SRC/XML.ob07 b/programs/other/fb2reader/SRC/XML.ob07 index c063c727dd..07641df508 100644 --- a/programs/other/fb2reader/SRC/XML.ob07 +++ b/programs/other/fb2reader/SRC/XML.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2020, 2022 Anton Krotov + Copyright 2016, 2020, 2022, 2023 Anton Krotov This file is part of fb2read. @@ -19,7 +19,7 @@ MODULE XML; -IMPORT SU := SysUtils, RF := ReadFile, S := Strings, Encode, V := Vector, tables, LISTS; +IMPORT SU := SysUtils, RF := ReadFile, S := Strings, E := Encoding, V := Vector, tables, LISTS; CONST @@ -135,7 +135,7 @@ VAR tire1, tire2, nbsp, ellipsis, apo, quot1, quot2, quot3, quot4, quot5, quot6, quot7, number, bullet, euro, - dash1, dash2: S.UTF8; + dash1, dash2: E.tUtf8; num: INTEGER; Tags: V.VECTOR; @@ -678,13 +678,13 @@ BEGIN DEC(chars.last); S.SetCS(FALSE); IF S.CharsEqStr(chars, "windows-1250") THEN - RF.Conv(Encode.W1250) + RF.Conv(E.cp1250) ELSIF S.CharsEqStr(chars, "windows-1251") THEN - RF.Conv(Encode.W1251) + RF.Conv(E.cp1251) ELSIF S.CharsEqStr(chars, "windows-1252") THEN - RF.Conv(Encode.W1252) + RF.Conv(E.cp1252) ELSIF S.CharsEqStr(chars, "cp866" ) THEN - RF.Conv(Encode.CP866) + RF.Conv(E.cp866) ELSIF S.CharsEqStr(chars, "utf-8" ) THEN RF.SeekBeg ELSE @@ -729,23 +729,23 @@ END Open; PROCEDURE Init; BEGIN - S.utf8(8212, tire1); - S.utf8(8211, tire2); - S.utf8( 160, nbsp); - S.utf8(8230, ellipsis); - S.utf8(8217, apo); - S.utf8(8220, quot1); - S.utf8(8221, quot2); - S.utf8(8222, quot3); - S.utf8(8216, quot4); - S.utf8(8218, quot5); - S.utf8(8249, quot6); - S.utf8(8250, quot7); - S.utf8(8470, number); - S.utf8(8208, dash1); - S.utf8(8209, dash2); - S.utf8(8226, bullet); - S.utf8(8364, euro); + E.utf8(8212, tire1); + E.utf8(8211, tire2); + E.utf8( 160, nbsp); + E.utf8(8230, ellipsis); + E.utf8(8217, apo); + E.utf8(8220, quot1); + E.utf8(8221, quot2); + E.utf8(8222, quot3); + E.utf8(8216, quot4); + E.utf8(8218, quot5); + E.utf8(8249, quot6); + E.utf8(8250, quot7); + E.utf8(8470, number); + E.utf8(8208, dash1); + E.utf8(8209, dash2); + E.utf8(8226, bullet); + E.utf8(8364, euro); Tags := V.create(1024) END Init; diff --git a/programs/other/fb2reader/SRC/box_lib.ob07 b/programs/other/fb2reader/SRC/box_lib.ob07 index f9683d250f..bbc5da4e24 100644 --- a/programs/other/fb2reader/SRC/box_lib.ob07 +++ b/programs/other/fb2reader/SRC/box_lib.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2016, 2017, 2020, 2022 Anton Krotov + Copyright 2016, 2017, 2020, 2022, 2023 Anton Krotov This file is part of fb2read. @@ -48,7 +48,7 @@ TYPE scrollbar* = POINTER TO RECORD - x_w: INTEGER; + x_w*: INTEGER; y_h*: INTEGER; btn_height: INTEGER; typ: INTEGER; diff --git a/programs/other/fb2reader/SRC/encode.ob07 b/programs/other/fb2reader/SRC/encode.ob07 deleted file mode 100644 index fa2621d28b..0000000000 --- a/programs/other/fb2reader/SRC/encode.ob07 +++ /dev/null @@ -1,149 +0,0 @@ -(* - Copyright 2016 Anton Krotov - - This file is part of fb2read. - - fb2read is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - fb2read 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with fb2read. If not, see . -*) - -MODULE Encode; - -IMPORT S := Strings; - -TYPE - - CP* = ARRAY 256 OF RECORD code*, len*: INTEGER; utf8*: S.UTF8 END; - - -VAR - - W1250*, W1251*, W1252*, CP866*: CP; - - -PROCEDURE InitCP(VAR cp: CP); -VAR i: INTEGER; -BEGIN - FOR i := 0H TO 7FH DO - cp[i].code := i - END; - FOR i := 0H TO 0FFH DO - S.utf8(cp[i].code, cp[i].utf8); - cp[i].len := LENGTH(cp[i].utf8) - END -END InitCP; - - -PROCEDURE Init8(VAR cp: CP; VAR n: INTEGER; a, b, c, d, e, f, g, h: INTEGER); -BEGIN - cp[n].code := a; INC(n); - cp[n].code := b; INC(n); - cp[n].code := c; INC(n); - cp[n].code := d; INC(n); - cp[n].code := e; INC(n); - cp[n].code := f; INC(n); - cp[n].code := g; INC(n); - cp[n].code := h; INC(n); -END Init8; - - -PROCEDURE InitW1250(VAR cp: CP); -VAR n: INTEGER; -BEGIN - n := 80H; - Init8(cp, n, 20ACH, 20H, 201AH, 20H, 201EH, 2026H, 2020H, 2021H); - Init8(cp, n, 20H, 2030H, 0160H, 2039H, 015AH, 0164H, 017DH, 0179H); - Init8(cp, n, 20H, 2018H, 2019H, 201CH, 201DH, 2022H, 2013H, 2014H); - Init8(cp, n, 20H, 2122H, 0161H, 203AH, 015BH, 0165H, 017EH, 017AH); - Init8(cp, n, 00A0H, 02C7H, 02D8H, 0141H, 00A4H, 0104H, 00A6H, 00A7H); - Init8(cp, n, 00A8H, 00A9H, 015EH, 00ABH, 00ACH, 00ADH, 00AEH, 017BH); - Init8(cp, n, 00B0H, 00B1H, 02DBH, 0142H, 00B4H, 00B5H, 00B6H, 00B7H); - Init8(cp, n, 00B8H, 0105H, 015FH, 00BBH, 013DH, 02DDH, 013EH, 017CH); - Init8(cp, n, 0154H, 00C1H, 00C2H, 0102H, 00C4H, 0139H, 0106H, 00C7H); - Init8(cp, n, 010CH, 00C9H, 0118H, 00CBH, 011AH, 00CDH, 00CEH, 010EH); - Init8(cp, n, 0110H, 0143H, 0147H, 00D3H, 00D4H, 0150H, 00D6H, 00D7H); - Init8(cp, n, 0158H, 016EH, 00DAH, 0170H, 00DCH, 00DDH, 0162H, 00DFH); - Init8(cp, n, 0155H, 00E1H, 00E2H, 0103H, 00E4H, 013AH, 0107H, 00E7H); - Init8(cp, n, 010DH, 00E9H, 0119H, 00EBH, 011BH, 00EDH, 00EEH, 010FH); - Init8(cp, n, 0111H, 0144H, 0148H, 00F3H, 00F4H, 0151H, 00F6H, 00F7H); - Init8(cp, n, 0159H, 016FH, 00FAH, 0171H, 00FCH, 00FDH, 0163H, 02D9H); - InitCP(cp) -END InitW1250; - - -PROCEDURE InitW1251(VAR cp: CP); -VAR n, i: INTEGER; -BEGIN - n := 80H; - Init8(cp, n, 0402H, 0403H, 201AH, 0453H, 201EH, 2026H, 2020H, 2021H); - Init8(cp, n, 20ACH, 2030H, 0409H, 2039H, 040AH, 040CH, 040BH, 040FH); - Init8(cp, n, 0452H, 2018H, 2019H, 201CH, 201DH, 2022H, 2013H, 2014H); - Init8(cp, n, 20H, 2122H, 0459H, 203AH, 045AH, 045CH, 045BH, 045FH); - Init8(cp, n, 00A0H, 040EH, 045EH, 0408H, 00A4H, 0490H, 00A6H, 00A7H); - Init8(cp, n, 0401H, 00A9H, 0404H, 00ABH, 00ACH, 00ADH, 00AEH, 0407H); - Init8(cp, n, 00B0H, 00B1H, 0406H, 0456H, 0491H, 00B5H, 00B6H, 00B7H); - Init8(cp, n, 0451H, 2116H, 0454H, 00BBH, 0458H, 0405H, 0455H, 0457H); - FOR i := 0410H TO 044FH DO - cp[i - 350H].code := i - END; - InitCP(cp) -END InitW1251; - - -PROCEDURE InitW1252(VAR cp: CP); -VAR n, i: INTEGER; -BEGIN - n := 80H; - Init8(cp, n, 20ACH, 20H, 201AH, 0192H, 201EH, 2026H, 2020H, 2021H); - Init8(cp, n, 02C6H, 2030H, 0160H, 2039H, 0152H, 20H, 017DH, 20H); - Init8(cp, n, 20H, 2018H, 2019H, 201CH, 201DH, 2022H, 2013H, 2014H); - Init8(cp, n, 02DCH, 2122H, 0161H, 203AH, 0153H, 20H, 017EH, 0178H); - FOR i := 0A0H TO 0FFH DO - cp[i].code := i - END; - InitCP(cp) -END InitW1252; - - -PROCEDURE InitCP866(VAR cp: CP); -VAR n, i: INTEGER; -BEGIN - FOR i := 0410H TO 043FH DO - cp[i - 0410H + 80H].code := i - END; - FOR i := 0440H TO 044FH DO - cp[i - 0440H + 0E0H].code := i - END; - - n := 0B0H; - Init8(cp, n, 2591H, 2592H, 2593H, 2502H, 2524H, 2561H, 2562H, 2556H); - Init8(cp, n, 2555H, 2563H, 2551H, 2557H, 255DH, 255CH, 255BH, 2510H); - Init8(cp, n, 2514H, 2534H, 252CH, 251CH, 2500H, 253CH, 255EH, 255FH); - Init8(cp, n, 255AH, 2554H, 2569H, 2566H, 2560H, 2550H, 256CH, 2567H); - Init8(cp, n, 2568H, 2564H, 2565H, 2559H, 2558H, 2552H, 2553H, 256BH); - Init8(cp, n, 256AH, 2518H, 250CH, 2588H, 2584H, 258CH, 2590H, 2580H); - - n := 0F0H; - Init8(cp, n, 0401H, 0451H, 0404H, 0454H, 0407H, 0457H, 040EH, 045EH); - Init8(cp, n, 00B0H, 2219H, 00B7H, 221AH, 2116H, 00A4H, 25A0H, 00A0H); - - InitCP(cp) -END InitCP866; - - -BEGIN - InitW1250(W1250); - InitW1251(W1251); - InitW1252(W1252); - InitCP866(CP866); -END Encode. diff --git a/programs/other/fb2reader/SRC/kfonts.ob07 b/programs/other/fb2reader/SRC/kfonts.ob07 index 01a2f0c40b..8d4825e499 100644 --- a/programs/other/fb2reader/SRC/kfonts.ob07 +++ b/programs/other/fb2reader/SRC/kfonts.ob07 @@ -1,5 +1,5 @@ (* - Copyright 2018-2020 Anton Krotov + Copyright 2018-2020, 2023 Anton Krotov This file is part of fb2read.