kolibrios-fun/programs/other/fb2reader/SRC/SelEnc.ob07
Anton Krotov c56f682434 FB2 Reader: refactoring, reduced memory usage for images, small improvements
git-svn-id: svn://kolibrios.org@9898 a494cfbc-eb01-0410-851d-a64ba20cac60
2023-02-01 13:36:55 +00:00

232 lines
5.5 KiB
Plaintext

(*
Copyright 2016, 2018, 2020-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 <http://www.gnu.org/licenses/>.
*)
MODULE SelEnc;
IMPORT
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;
tempfile* = "/tmp0/1/~temp.fb2";
VAR
Window: W.tWindow;
pos, mem, mem2, pos2: INTEGER;
PROCEDURE Buttons;
VAR
Y : INTEGER;
BEGIN
Y := BtnY;
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;
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);
Buttons;
SU.WindowRedrawStatus(2)
END DrawWindow;
PROCEDURE getch (): CHAR;
VAR
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('<?xml encoding = "');
CASE encoding OF
|CP866 : WriteStr("cp866")
|CP1251 : WriteStr("windows-1251")
|CP1252 : WriteStr("windows-1252")
|CP1250 : WriteStr("windows-1250")
|UTF8 : WriteStr("utf-8")
ELSE
SU.Halt
END;
WriteStr('"?>' + 0DX + 0AX + "<FictionBook><body>");
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("&lt;")
|">": WriteStr("&gt;")
|"&": WriteStr("&amp;")
|"'": WriteStr("&apos;")
|'"': WriteStr("&quot;")
|0DX: WriteStr("<empty-line/>")
|0AX: IF ~CR THEN WriteStr("<empty-line/>") END
| 0X: WriteChar(20X)
ELSE
WriteChar(ch)
END;
CR := ch = 0DX
END;
WriteStr("</body></FictionBook>");
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;
VAR
c, c0: BYTE;
res: BOOLEAN;
BEGIN
c := 0;
res := FALSE;
WHILE (size > 0) & ~res DO
c0 := c;
SYSTEM.GET(ptr, c);
IF (c = chr2) & (c0 = chr1) THEN
res := TRUE
END;
INC(ptr);
DEC(size)
END
RETURN res
END SearchPair;
BEGIN
IF SearchPair(ptr, size, 208, 190) THEN
enc := UTF8
ELSE
IF SearchPair(ptr, size, 239, 240) OR SearchPair(ptr, size, 241, 242) THEN
enc := CP1251
ELSE
enc := CP866
END
END
RETURN enc
END auto;
PROCEDURE ButtonClick (fname: S.STRING);
VAR
encoding: INTEGER;
program, file: S.STRING;
data, size: INTEGER;
BEGIN
data := File.Load(fname, size);
SU.ErrorIf(data = 0, 1);
encoding := SU.GetButtonCode();
IF encoding = AUTO THEN
encoding := auto(data, size)
END;
convert(data, size, tempfile, encoding);
S.PtrToString(K.GetName(), program);
file := tempfile;
file[0] := "!";
SU.Run(program, SYSTEM.ADR(file));
SU.Halt
END ButtonClick;
PROCEDURE Show* (fname: S.STRING);
VAR
X1, Y1, X2, Y2: INTEGER;
BEGIN
SU.SetEventsMask({0, 2, 31});
SU.GetScreenArea(X1, Y1, X2, Y2);
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(fname)
END
END
END Show;
END SelEnc.