1. Trang chủ
  2. » Công Nghệ Thông Tin

Thảo luận thêm về Bộ hỗ trợ gõ tiếng Việt bằng ngôn ngữ lập trình Pascal

14 948 6
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 14
Dung lượng 72,5 KB

Nội dung

Thảo luận thêm về Bộ hỗ trợ gõ tiếng Việt bằng ngôn ngữ lập trình Pascal

Trang 1

Thảo luận thêm về Bộ hỗ trợ gõ tiếng Việt bằng ngôn ngữ lập trình Pascal

Nguyễn Hoành (nguyen_hoanh@hotmail.c

Trong bài viết 'Hỗ trợ gõ tiếng Việt bằngngôn ngữ lập trình Pascal' của tác giả Đỗ

Hồng Ngọc trên tạp chí Tinhọc & Nhà trường số tháng 12 năm 2001 có đề cập đến vấn

đề gõ tiếng Việtdưới môi trường DOS Trong bài viết này, tác giả đã nêu lên một cách có hệthống các thành phần mà một chương trình gõ tiếng Việt cần phải có Tuy nhiêntrong bài viết có một số chỗ chưa được chi tiết như chưa đề cập đến thủ tụcNewInt09, tải phông chữ lên bộ nhớ, làm cho độc giả chưa thể tạo được mộtchương trình gõ tiếng Việt hoàn chỉnh Tôi xin đề cập lại vấn đề này, và nhìnnhận dưới góc độ chi tiết hơn

Hoàn toàn đi theo hướng mà tác giả Đỗ Hồng Ngọc đãnêu, tôi xin nêu lên thư viện KeyVnTrs có chứa các mô đun tải phông chữ Việt,thay đổi ngắt cứng 09h Thư viện KeyVnTrs có các môđun chính như sau:

procedure KhoiTaoGoTelex -Khởi tạo và cài đặt phần gõ tiếng Việt

procedure LoaiBoGoTelex -Trả lại kiểu gõ thông thường cho hệ thống

functionTaiPhongTuTep(TenTep: string): boolean - Tải phông chữ việt (phông người sửdụng định nghĩa) từ tệp

procedure LoaiBoPhong - Loạibỏ tác dụng của phông chữ người sử dụng định nghĩa

Thư viện KeyVnTrs sử dụngbảng mã TCVN3 - Với bảng mã các chữ cần quan tâm như sau:

A= 65 E= 69 I= 73 O= 79 U= 85 Y= 89 Â=162 Ă=161 Ê=163 Ô=164 Ơ=165 Ư=166 a= 97 e=101 i=105 o=111 u=117 y=121 â=169 ă=168 ê=170 ô=171 ơ=172 ư=173 á=184 é=208 í=221 ó=227 ú=243 ý=253 ấ=202 ắ=190 ế=213 ố=232 ớ=237 ứ=248 à=181 è=204 ì=215 ò=223 ù=239 ỳ=250 ầ=199 ằ=187 ề=210 ồ=229 ờ=234 ừ=245 ả=182 ẻ=206 ỉ=216 ỏ=225 ủ=241 ỷ=251 ẩ=200 ẳ=188 ể=211 ổ=230 ở=235 ử=246 ã=183 ẽ=207 ĩ=220 õ=226 ũ=242 ỹ=252 ẫ=201 ẵ=189 ễ=212 ỗ=231 ỡ=236 ữ=247 ạ=185 ẹ=209 ị=222 ọ=228 ụ=244 ỵ=254 ậ=203 ă=198 ệ=214 ộ=233 ợ=238 ự=249

Trang 2

Nội dung thư viện KeyVnTrs:

unit KeyVnTrs;

interface

procedure KhoiTaoGoTelex;

procedure LoaiBoGoTelex;

function TaiPhongTuTep(TenTep: string): boolean; procedure LoaiBoPhong;

implementation

uses crt, dos;

const

dKh = 0; {Khong co dau}

dSa = 1; {Sac (')}

dHu = 2; {Huyen (`)}

dHo = 3; {Hoi (?)}

dNg = 4; {Nga (~)}

dNa = 5; {Nang (.)}

TapKyTuNA: array[1 12 * 7] of Char =</p> ('A', 'E', 'I', 'O', 'U', 'Y', 'Â', 'Ă', 'Ê', 'Ô', 'Ơ', 'Ư', 'á, 'é, 'í, 'ó, 'ú, 'ý, 'ấ, 'ắ, 'ế, 'ố, 'ớ, 'ứ,

'á', 'é', 'í', 'ó', 'ú', 'ý', 'ấ', 'ắ', 'ế', 'ố', 'ớ', 'ứ',

'à', 'è', 'ì', 'ò', 'ù', 'ỳ', 'ầ', 'ằ', 'ề', 'ồ', 'ờ', 'ừ',

'ả', 'ẻ', 'ỉ', 'ỏ', 'ủ', 'ỷ', 'ẩ', 'ẳ', 'ể', 'ổ', 'ở', 'ử',

'ã', 'ẽ', 'ĩ', 'õ', 'ũ', 'ỹ', 'ẫ', 'ẵ', 'ễ', 'ỗ', 'ỡ', 'ữ',

Trang 3

'ạ', 'ẹ', 'ị', 'ọ', 'ụ', 'ỵ', 'ậ', 'ặ', 'ệ', 'ộ', 'ợ', 'ự');

var

TuHt: string; {Từ hiện tại đang gõ}

Int09Old: procedure; {Địa chỉ bộ nhớ của ngắt 09h cũ} FontArr: array[0 255, 0 15] of byte;

procedure ThemHDP(c:string);

{Thêm một chuỗi vào hàng đợibàn phím}

var i: Byte;

procedure DatChuVaoHDP(kt: Char);

{Đặt một chữ vào hàng đợi bàn phím}

var< > r: registers;

begin

Case kt of

#8: if TuHt <> '' then Delete(TuHt, Length(TuHt), 1); #0 #31: TuHt:= '';

#32 #255: TuHt:= TuHt + kt;

end;

if Length(TuHt) > 200 then delete(TuHt, 1, 50); r.ah:= 05;

r.cl:= ord(kt);

r.ch:= 0;

intr($16, r);

end;

Trang 4

for i:= 1 to length(c) do begin

DatChuVaoHDP(c[i]);

end;

end;

procedure ThemHDPMR(PMR:Char);

{Thêm một phím mở rộng vàohàng đợi bàn phím} var r: registers;

begin

TuHt:= '';

r.ah:= 05;

r.cl:= 0;

r.ch:= ord(PMR);

intr($16, r);

end;

function ViTriNguyenAm(c:Char): Byte;

{Tìm chỉ số của nguyên âm ctrong mảng}

var i: Byte;

begin

for i:= 1 to 12 * 7 do begin

if c = TapKyTuNA[i] then begin

ViTriNguyenAm:= i;

Exit;

Trang 5

end;

end;

VitriNguyenAm:= 0;

end;

function LaNguyenAm(c:Char): boolean;

{Có đúng ký tự c là nguyênâm không}

begin

LaNguyenAm:= (ViTriNguyenAm(c) <> 0);

end;

function BoDauChu(c: Char;DauBo: Byte): Char;

{Bỏ dấu vào chữ}

var Vt, ChuGoc, DauHt: integer;

begin

Vt:= ViTriNguyenAm(c);

ChuGoc:= (Vt mod 12); if ChuGoc = 0 then ChuGoc:= 12;

DauHt:= ((Vt - 1) div 12) - 1; if DauHt = -1 then DauHt:= 0;

if DauHt <> DauBo then BoDauChu:= TapKyTuNA[(DauBo + 1) *12 + ChuGoc] else BoDauChu:= c;

end;

function LayDau(CumTu:string): Byte;

{Xét xem dấu được bỏ ở đâutrong các nguyên âm trong cụm từ}

const

DauSau: array[1 12] of string[2] =</p>

Trang 6

('iế, 'oá, 'oấ, 'oắ, 'oé, 'uý, 'uấ, 'uế, 'uố, 'uớ,'yế', 'ướ); var i: Byte;

begin

if (CumTu[1] in ['A' 'Z']) then Inc(CumTu[1], 32);

if (CumTu[2] in ['A' 'Z']) then Inc(CumTu[2], 32); for i:= 1 to 12 do

if CumTu = DauSau[i] then begin

LayDau:= 1;

Exit;

end;

LayDau:= 0;

end;

function ViTriBoDau: Byte;

{Xác định vị trí bỏ dấu}

var l, i: Byte;

begin

l:= Length(TuHt);

for i:= L downto 1 do begin

if TuHt[i]=' ' then begin

ViTriBoDau:= 0;

Exit;

end;

if LaNguyenAm(TuHt[i]) then begin

Trang 7

if (i>1) and (LaNguyenAm(TuHt[i-1])) then begin

ViTriBoDau:= i - 1 + LayDau(Copy(TuHt, i-1, 2));

if (i>2) and (TuHt[i-2] = 'g') and (TuHt[i-1] = 'í)then ViTriBoDau:= i; end

else ViTriBoDau:= i;

Exit;

end;

end;

ViTriBoDau:= 0;

end;

function CoNguyenAm:boolean;

{Có nguyên âm trong từ cuốicùng khi gõ không}

begin

CoNguyenAm:= (ViTriBoDau <> 0)

end;

<>procedure BoDau(dau: Byte);

{Bỏ dấu vào từ cuối cùng}

var i, DoDaiXoa, Vt: Byte;

NgAm: Char;

Temp: string;

begin

Vt:= ViTriBoDau; {Tim vi tri can bo dau}

NgAm:= TuHt[Vt]; {Lay nguyen am tai vi tri do}

Trang 8

NgAm:= BoDauChu(NgAm, dau); {Them dau moi cho nguyen am}

DoDaiXoa:= Length(TuHt) - Vt + 1;

Temp:= '';

for i:= 1 to DoDaiXoa do Temp:= Temp + #8;

Temp:= Temp + NgAm;

for i:= Vt + 1 to Length(TuHt) do Temp:= Temp + TuHt[i];

ThemHDP(Temp);

end;

procedure XulyPhim(ch:Char);

{Xử lý khi có một phím gõvào}

var KQ, ChuCuoi: Char;

begin

ChuCuoi:= TuHt[Length(TuHt)];

case ch of

'D': if Upcase(ChuCuoi) = 'D' then ThemHDP(#8 + 'Đ') elseThemHDP('D'); 'A': if ChuCuoi = 'A' then ThemHDP(#8 + 'Â') else ThemHDP('A');

'E': if ChuCuoi = 'E' then ThemHDP(#8 + 'Ê') else ThemHDP('E');

'O': if ChuCuoi = 'O' then ThemHDP(#8 + 'Ô') else ThemHDP('O');

'd': if Upcase(ChuCuoi) = 'D' then ThemHDP(#8 + 'đ') elseThemHDP('d'); 'á: if ChuCuoi = 'á then ThemHDP(#8 + 'ấ) else ThemHDP('á);

'é: if ChuCuoi = 'é then ThemHDP(#8 + 'ế) else ThemHDP('é);

'ó: if ChuCuoi = 'ó then ThemHDP(#8 + 'ố) else ThemHDP('ó);

'W': case Upcase(ChuCuoi) of

Trang 9

'A': ThemHDP(#8 + 'Ă');

'O': ThemHDP(#8 + 'Ơ');

'U': ThemHDP(#8 + 'Ư');

'Ư': ThemHDP(#8 + 'W');

else ThemHDP('Ư');

end;

'w': case ChuCuoi of

'á: ThemHDP(#8 + 'ắ);

'ó: ThemHDP(#8 + 'ớ);

'ú: ThemHDP(#8 + 'ứ);

'ứ: ThemHDP(#8 + 'w');

else ThemHDP('ứ);

end;

's': if CoNguyenAm then BoDau(dSa) else ThemHDP('s'); 'f': if CoNguyenAm then BoDau(dHu) else ThemHDP('f'); 'r': if CoNguyenAm then BoDau(dHo) else ThemHDP('r'); 'x': if CoNguyenAm thenBoDau(dNg) else ThemHDP('x'); 'j': if CoNguyenAm then BoDau(dNa) else ThemHDP('j'); 'z': if CoNguyenAm then BoDau(dKh) else ThemHDP('z'); else ThemHDP(Ch);

end;

end;

procedure NewInt09;interrupt;

Trang 10

{Ngắt 09h mới - bắt buộcphải có từ khoá interrupt}

var

Temp: array[1 16] of Char;

SoPhim, i: Byte;

begin

inline($9C);{PUSHF - phải có trước khi gọi một ngắt cứng khác} Int09Old;< > {Gọi ngắt 09cũ}

SoPhim:= 0;

while keypressed do begin

Inc(SoPhim);

Temp[SoPhim]:= ReadKey;

end;

i:= 0;

while i < Sophim do begin

Inc(i);

if Temp[i]=#0 then begin

ThemHDPMR(temp[i+1]);

Inc(i);

end

else begin

Xulyphim(Temp[i]);

end;

end;

Trang 11

procedure KhoiTaoGoTelex;

begin

TuHt:='';

GetIntVec($09,@Int09Old);

SetIntVec($09,Ađr(NewInt09));

end;

procedure LoaiBoGoTelex;

begin

SetIntVec($09,@Int09Old);

end;

functionTaiPhongTuTep(TenTep: string): boolean; var f: file;< > r: registers;< > num: integer;

begin

Assign(f, TenTep);

{$i-} {Từ khoá này thêm vào để không bắt lỗi vào ra tệp} Reset(f,1);

BlockRead(f, FontArr, SizeOf(FontArr), num);

Close(f);

{$i+}

if (ioresult<>0) or (num <> SizeOf(FontArr)) thenbegin TaiPhongTuTep:= false;

Exit;

Trang 12

r.es:= Seg(FontArr); {Địa chỉ khối phông chữ cần nạp}

r.bp:= Ofs(FontArr);

r.ax:= $1110; {Tải phông chữ người sử dụng}

r.bx:= $1000; {bh = $10 = số byte / ký tự}

r.cx:= $0100; {$0100 = 256 = Số ký tự cần nạp}

r.dx:= $0000; {Bắt đầu từ ký tự #0}

intr($10, r);

TaiPhongTuTep:= True;

end;

procedure LoaiBoPhong;

var

r: registers;

begin

r.ax:= $1114; {Tải phông 8x16 của ROM}

r.bl:= 0;

intr($10, r);

end;

end

Trong môđun TaiPhongTuTep cần phải có một tệp chứaphông 8x16, tệp này có độ dài bằng 4096 Byte (8 bit * 16 dòng * 256 ký tự) Nếukhông có tệp này hoặc độ dài tệp này khác 4096 byte thì môđun sẽ bỏ qua quátrình tải phông

Và ở chương trình chính, để sử dụng thư việnKeyVnTrs:

uses KeyVnTrs, Crt;

Trang 13

var s: string;

begin

Clrscr;

KhoiTaoGoTelex;

TaiPhongTuTep('Font.dat');

WriteLn('Hãy nhập vào một chuỗi: ');

ReadLn(s);

LoaiBoGoTelex;

LoaiBoPhong;

end

Nếu muốn tạo một chương trình thường trú để gõ, bạnchỉ cần một đoạn code ngắn:

{$M 800,0,0}

uses KeyVnTrs, Dos;

begin

KhoiTaoGoTelex;

TaiPhongTuTep('Font.dat');

WriteLn;

WriteLn('Chương trình bàn phìm tiếng Việt dưới DOS - (c) NguyễnHoành 1997')

Keep(0);

end

Nhớ là bạn phải có khoá $M để giới hạn bộ nhớ, nếukhông máy sẽ bị treo Để gỡ bỏ

chương trình thường trú khỏi bộ nhớ, bạn nêntham khảo thêm cuốn 'Mẹo và thủ thuật lập trình bằng Turbo Pascal 5.5'của nhà xuất bản Khoa Học và Kỹ Thuật.

Nguyễn Hoành

Trang 14

Email:nguyen_hoanh@hotmail.com

Ngày đăng: 11/09/2012, 15:49

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w