delphi

한글 조합/분리기

knoen 2014. 1. 24. 23:10


 한글 조합/분리기 -Delphi source-  공작실/개발일지 

2005/06/17 12:44

복사http://tkandrea92.blog.me/80014083754

전용뷰어 보기

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;

 

-------코드 끝--------

 

 

제가 사용해 본 바로는 아무런 문제없이 잘 되더군요.

 

델파이를 사용하시는분들에게 많은 도움이 되었으면 좋겠군요...


'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