한글 조합/분리기 -Delphi source- ![]() ![]() 2005/06/17 12:44
|
Dolphin Smalltalk를 사용해서 프로그래밍을 만드는 게 있는데, 거기서
한글 자소 단위의 분리와 조합을 하는 부분이 필요했다. 그래서 예전에
Delphi에서 썼던 코드를 Dolphin으로 포팅해야 했다.
코드를 만드신 '조준래'(?)님께서 워낙 깔끔하게 만들어주셔서
리팩토링이 엄청 편했다. (아직 좀 더 손을 봐야 할 부분이 있기는 하지마는...)
프로그램의 원리는 간단하다. 일단 확장 완성형(CP949)의 한글코드를
유니코드로 바꾼 후에, 이 상태에서 한글의 초성, 중성, 종성의 위치를
계산해 내는 것이다. 그러니까 한글의 '가'부터 '힣'까지 차례대로 배치되어있는
Unicode의 특성을 십분 활용한 소스이다. (역시 이렇게 보면 유니코드가 좋다)
아래는 조준래님의 Delphi Pascal 소스이다.
--------------------------------------------------
이걸 분석이라고 해야 하나 ?
팁이라고 해야하나 ?
강좌라고 해야하나.... 암튼....
한글에 관련된 문의가 심심치않게 올라오는 것 같아서
일일이 답변을 쓰는 것보다는 여기에 적는게 좋을 것 같아서 올립니다.
코드에 앞서 잠깐 설명하자면 다음 코드에는 두가지 함수가 있습니다.
1. HanDiv
2. HanCom
HanDiv는 '강'을 'ㄱㅏㅇ'으로 변환하는 함수이며 HanCom은 그 반대입니다.
각 함수의 파라메터인 Han, Han3는 각각 한글의 한 글자,
그리고 초,중,종성으로 나누어진 글자들입니다.
Han은 최소 2바이트, Han3은 6바이트의 메모리가 할당되어 있어야 합니다.
(함수내에서는 null-terminated처리를 하지 않습니다.)
-------코드--------
// Programmed by Jounlai Cho (khouse@nuri.net)
// April 17, 1998
const
ChoSungTbl: PChar = 'ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ';
JungSungTbl: PChar = 'ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ';
JongSungTbl: PChar = ' ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ
';
// ^^요기는 꼭 2칸을 띄어야 합니다.
UniCodeHangeulBase = $AC00;
UniCodeHangeulLast = $D79F;
function HanDiv(const Han: PChar; Han3: PChar): Boolean;
var
UniCode: Integer;
ChoSung, JungSung, JongSung: Integer;
begin
Result := False;
// if StrLen(Han) < 2 then Exit;
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Han, 2, @UniCode, 1);
if (UniCode < UniCodeHangeulBase) or
(UniCode > UniCodeHangeulLast) then Exit;
UniCode := UniCode - UniCodeHangeulBase;
ChoSung := UniCode div (21 * 28);
UniCode := UniCode mod (21 * 28);
JungSung := UniCode div 28;
UniCode := UniCode mod 28;
JongSung := UniCode;
StrLCopy(Han3, ChoSungTbl + ChoSung * 2, 2);
StrLCopy(Han3 + 2, JungSungTbl + JungSung * 2, 2);
StrLCopy(Han3 + 4, JongSungTbl + JongSung * 2, 2);
Result := True;
end;
function HanCom(const Han3: PChar; Han: PChar): Boolean;
var
UniCode: Integer;
ChoSung, JungSung, JongSung: Integer;
ChoSungPos, JungSungPos, JongSungPos: Integer;
begin
Result := False;
// if StrLen(Han3) < 6 then Exit;
ChoSungPos := Pos(Copy(String(Han3), 1, 2), ChoSungTbl);
JungSungPos := Pos(Copy(String(Han3), 3, 2), JungSungTbl);
JongSungPos := Pos(Copy(String(Han3), 5, 2), JongSungTbl);
if (ChoSungPos and JungSungPos and JongSungPos) = 0 then Exit;
ChoSung := (ChoSungPos - 1) div 2;
JungSung := (JungSungPos - 1) div 2;
JongSung := (JongSungPos - 1) div 2;
UniCode := UniCodeHangeulBase +
(ChoSung * 21 + JungSung) * 28 + JongSung;
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
@UniCode, 1, Han, 2, nil, nil);
Result := True;
end;
-------코드 끝---------
참고로 이 함수를 불러 쓰는 예제를 보내드립니다.
-------코드----------
procedure TForm1.Button1Click(Sender: TObject);
var
Dest: array[0..6] of Char;
begin
if HanDiv(PChar(Edit1.Text), @Dest) then begin
Dest[6] := Char(0);
Edit2.Text := String(Dest);
end else
Edit2.Text := '?';
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Dest: array[0..2] of Char;
begin
if HanCom(PChar(Edit1.Text), @Dest) then begin
Dest[2] := Char(0);
Edit2.Text := String(Dest);
end else
Edit2.Text := '?';
end;
-------코드 끝--------
제가 사용해 본 바로는 아무런 문제없이 잘 되더군요.
델파이를 사용하시는분들에게 많은 도움이 되었으면 좋겠군요...
[출처] [한글코덱] #1 한글 조합/분리기 -Delphi source-|작성자 안드레아
'delphi' 카테고리의 다른 글
Save a web page from TWebBrowser as a JPEG file (0) | 2014.01.26 |
---|---|
how to save everything in the webbrowser as Image (0) | 2014.01.26 |
자모 분리 및 결합 (0) | 2014.01.24 |
z-order 취득 (0) | 2014.01.07 |
web (0) | 2013.12.30 |