1. 운전 중에 수시로: 눈치껏 차선 바꾸고 잘 끼어들고 들이대기 (배짱과 순발력)
2. 운전하는 전체 시간 내내: 한눈팔지 말고 앞차가 갑자기 서 버리거나 길 옆에서 뭔가가 튀어나오는 상황에 대비하기 (멘탈의 지구력이 뛰어나야 함)
3. 목적지에 도착한 후: 이 차가 차지하는 공간과 최소 회전반경을 숙지하여, 좁은 곳에서도 차 안 긁고 주차 잘 하기 (공간 감각)

(0. 운전하기 전 평소에 최소한의 자동차 점검 내지 정비 능력, 그리고 차량 고장이나 사고 발생시 멘붕· 당황하지 않고 대처하는 능력)

이들이 서로 완전히 별도의 독립적인 영역을 차지하는 게 틀림없다.
운전 학원에서 교육하고 면허 시험을 치는 내용도 이런 분야에 맞춰서 편성되어야 하지 않을까 싶다.

* 각종 운전 잡설.
승용차는 내 몸뿐만 아니라 나만의 자그마한 개인 공간을 함께 이동시켜 주는 물건이며, 대중교통과는 달리 차를 타러 가고 기다리고 갈아타는 과정에서 까먹는 시간이 거의 없다는 것만으로도 시간을 굉장히 아껴 준다.

또한 이동 과정에서 급격한 환경 변화나 온도 변화를 야기시키지 않아서 더욱 좋다. 그런 외부 요인으로 인해 몸에 피곤이나 스트레스를 주지 않기 때문에 사람의 업무 능률과 생산성을 올릴 수 있다. 가령, 밖에서는 추워서 옷을 껴입고 있다가 지하철 안에서는 더워서 옷을 벗는 식으로 온도 조절을 해야 할 필요가 없다.

밖에 비가 내리고 있으면 대중교통에 비해 자가용의 아늑함, 안락함과 편리함이 크게 증가한다. 비록 도로 사정 때문에 신속함(속도)은 별로 증가하지 않을지 모르더라도 말이다.

본인도 비 내리는 밤에 차에서 야영을 하는 걸 매우 좋아한다. 그러나 비는 차의 외형을 매우 더럽힌다는 점에서는 악재이다. 그 빗물이 흐르다가 마르면 물방울 모양으로 온갖 더러운 흙먼지 자국이 차의 표면에 남기 때문이다.

본인은 처음에는 “어제 세차했는데 오늘 비 오네”라는 푸념이, 굳이 세차를 할 필요가 없는데 해 버렸다는 말인 줄 알았다. 그러나 실상은 정반대다. 저 말은 어제 기껏 세차를 해 놓은 게 또 아무 소용 없어지게(=차가 더러워지게) 생겼다는 뜻이다.

비 오는 날 밤의 운전은 비와 야간이라는 두 변수가 합쳐져서 매우 까다롭다. 빗물 때문에 도로가 미끄럽고 더 위험하니 평상시보다 감속이 필수인데, 시야 확보도 잘 안 된다. 단순히 전방 시야뿐만 아니라 본인이 현실적으로 가장 절실하게 체험한 애로사항은.. 도로의 차선이나 횡단보도 정지선조차도 제대로 안 보인다는 것이다.

* 에어컨
요즘 날씨가 날씨인지라 요 근래부터는 드디어 전구간 에어컨을 켠 채로 운전을 하기 시작했다.
정체 없는 자동차 전용 도로를 경제 속도로 원활히 주행하고 나면, 평소에 연비는 12km/l대는 거뜬히 나오는 편이었다.
그랬는데 이번에는, 평소와 다름없이 아주 원활하게 주행했음에도 불구하고 찍힌 주행 연비는 10.xkm대.

에어컨이 연비를 10~20% 가까이 깎아먹는다는 말은 사실인 듯했다. 실험으로 입증됐다.
에어컨을 켰다고 해서 차가 딱히 더 힘들어하는 기색이 보이지는 않았으나, 연비는 슬그머니 떨어져 있었다.

힘 좋은 디젤보다는 휘발유 차량이, 그리고 대형차보다는 저배기량의 소형차· 경차일수록 에어컨 틀 때 차가 타격을 받고 휘청이는 정도가 더 커진다.
에어컨을 가동하면 엔진룸 쪽에서 무슨 기계가 추가로 돌아가는 소리가 들리기 시작한다. 옛날에 만들어진 소형차의 경우 차 엔진 회전수가 대놓고 살짝 더 올라가기까지 한다.

자전거를 몰아 보면, 헤드라이트를 켜기 위해 바퀴에다 소형 회전 발전기만 좀 연결시켜도 그 발전기의 오버헤드 때문에 자전거 페달 밟는 게 약간이나마 더 힘들어진다. 하물며 자동차의 엔진에는 발전기가 상시 연결되어 있는데, 거기에다 에어컨 실외기뻘 되는 공기 압축기까지 연결되니 부담이 더욱 가중되는 것이다.

에어컨의 전력 소비량은 자동차에서 최상급으로 전기 많이 잡아먹는 부품인 헤드라이트보다도 수 배 이상 더 많다고 한다.
그러니 헤드라이트에 에어컨을 다 켜고 와이퍼까지 켜는 비 내리는 여름 밤에는, 성능이 시원찮은 소형차의 경우 주행 중에도 배터리에 과부하가 걸리기 쉽다고 한다.

단, 이 에어컨의 전력 소비량이라는 게 안 그래도 엔진 힘까지 쭉쭉 빼 쓰고서 그것도 모자라서 또 전기까지 추가로 그렇게 별도로 쓴다는 것인지는 잘 모르겠다. 설마?
추운 겨울에 히터는 엔진열을 이용해서 송풍기만 가동하여 거의 공짜로 가동할 수 있지만, 반대로 열을 밖으로 빼내는 건 이렇게 어렵고 힘든 일인 것이다.

온도 말고 단순히 송풍기의 세기만을 바꾸는 건 어차피 연비에 그리 큰 영향을 끼치지는 않는 걸로 알려져 있다.
또한, 여러 변수가 있을 수 있겠지만 앗싸리 에어컨 트는 게 나은지, 아니면 창문만 열어서 차라리 공기 저항으로 인해 연비가 떨어지는 게 더 나은지는... 이렇다 할 답이 없는 듯하다. 둘이 어차피 비슷하게 비효율적이니, 차라리 에어컨 틀어서 정숙하게 주행하는 게 대체로 더 낫다는 게 중론인 듯. (물론 당장 차의 동력 효율뿐만이 아니라 지구와 환경까지 거시적으로 생각한다면, 에어컨이 치르는 대가가 더 크겠지만 말이다.)

또한 이건 바꿔 말하자면, 공기 저항이 에어컨에 필적할 정도로 차의 성능을 깎아먹는 주범이라는 뜻이기도 하다.

Posted by 사무엘

2014/06/07 08:24 2014/06/07 08:24
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/971

<날개셋> 한글 입력기 7.4-- 下

* 하편에서는 지난 상편보다 좀 더 실무(?)스러운 세부 기능과 안정성 위주의 얘기가 나올 것이다.

5. 글자판 전환 단축글쇠의 지능화

PC용 문자 입력 프로그램에서는 키보드 연타를 좀 더 똑똑하게 인식하는 기능이 확실히 있긴 해야 하는 것 같다.
지난 7.1 버전에서는 bksp를 연타할 경우, 최초에 선택되었던 낱자/글자 삭제 단위를 그 다음 글자의 조합 상태와 무관하게 계속 적용하는 옵션을 추가했다. 이런 기능을 구현하려면 아무래도 예전 상태를 기억하는 변수가 있어야 하고 모든 key 동작을 감시하는 오버헤드가 불가피하지만, 그 오버헤드 이상으로 그건 사실 편리하고 필요한 기능이긴 했다.

bksp에 이어 이번 새 버전에서는 입력 항목(=글자판) 전환 단축글쇠에도 연타를 인식하는 로직이 추가되었다.
입력 항목 전환 수식은 10년 전의 3.0 이래로 지금 글자판의 번호를 나타내는 변수 A 하나밖에 존재하지 않았는데, 이번에는 연타 카운트를 나타내는 B, 전체 입력 항목 개수를 나타내는 N, 그리고 우리 직전에 사용하던 입력 항목 번호를 나타내는 C라는 여러 변수들이 추가된다.

여기서 연타라 함은 계속 누르고 있거나, 아니면 modifier에서 손을 떼지 않고 main key만 눌렀다 뗐기를 반복하는 걸 말한다. Shift+Space라면 shift는 꾹 누르고 있는 채로 space만 반복해서 누르는 것이다.

그렇다. Windows 8과 맥 OS에서는 이미 익숙한 관행일 것이다. 전자의 경우 Win 키를 누른 채로 space를 눌러서 IME를 고를 수 있으며, 맥의 경우 역시 Cmd+space를 1회만 누르면 직전에 사용하던 입력기와 내 것만 toggle되고, space를 여러 번 누르면 평소에 안 쓰던 다른 입력기를 고를 수 있다. 이 동작이 이제 <날개셋> 한글 입력기로도 가능해지는 것이다. 예를 들어,

B>0||C==A ? (A+1)%N : C

이런 수식을 배당하는 경우, 이 key가 연타 상태이거나(B>0) 글자판 전환을 처음 하는 상태라면 현재 존재하는 모든 입력 항목을 돌아가며 순회한다. 현재 입력기의 바로 다음 입력기(A+1)로 넘어가되, 이 값이 N과 같아지는 경우 도로 0으로 되돌리는 것이다(%N). 그렇지 않으면 내가 바로 직전에 사용하던 입력 항목 번호를 나타내는 C로 돌아간다.

세벌식과 쿼티, 두벌식과 드보락을 한데 배당해 놓고 있었는데 세벌식/쿼티이던 것을 세벌식/드보락으로 바꾸고 싶은 경우, 세벌식 상태에서 Shift를 누른 상태에서 Space를 몇 번 눌러서 드보락으로 이동시킨다. 그 다음부터 Shift+Space를 1회만 누르면 세벌식/쿼티가 아니라 세벌식/드보락이 된다. 마찬가지로 두벌식 전환을 하고 싶은 경우, 영문 자판 상태에서 두벌식으로 돌아가면 그 뒤부터는 두벌식/드보락 toggle이 된다.

이로써 오로지 0과 1 사이만 왕복하고 더 다양한 입력 항목을 사용하려면 별도의 단축글쇠를 추가하거나 불편하게 마우스를 동원해야 했던 번거로움이 사라지게 될 것이다.

6-1. 외부 모듈: 특정 프로그램에서 첫 타가 조합이 끊어지는 문제

이건 굉장히 오래 전에 작업이 완료된 아이템인데, 블로그 옛날 글을 읽어 보니 언급을 한 번도 안 한 것 같다. 그러니 지금이라도 좀 공지를 하도록 하겠다.

<날개셋> 한글 입력기 외부 모듈은 특정 프로그램에서 한글 입력을 곧바로 시작했을 때, 첫 타의 조합이 끊어지는 문제가 있었다. 대표적인 예가 MS Office의 엑셀. 얘만 좀 아래의 한글 IME에다가 특이한 이벤트를 날리는 게 있어서 '나라'라고 입력을 시작하면 'ㄴㅏ라'가 되곤 했다.
이 문제를 당장 피해 가는 건 물론 가능했다. 그러나 그 경우, 다른 프로그램에서 조합이 종료되어야 할 때 종료가 되지 않는 오동작이 발생하니 난감한 상황이 아닐 수 없었다.

그래서 <날개셋> 한글 입력기는 고육지책으로 외부 모듈은 자신이 동작하는 프로그램 EXE의 이름을 살펴서 엑셀 같은 '요주의 프로그램'이면 문제 회피 로직을 쓰고, 다른 프로그램에서는 그 로직을 쓰지 않는... 궁극의 지저분한 꼼수를 굉장히 오랫동안 사용해 왔다.
그런데 그렇게만 하니까 첫 타가 끊어지는 문제가 Paint .NET에서도 발생하고, 다른 듣보잡 프로그램에서도 종종 보고되면서 상황이 더욱 나빠져 갔다.

일단 난 응용 프로그램이 한글 IME를 도대체 어떻게 조작해야 첫 타를 끊어지게 만들 수 있는지, 어떻게 해야 저런 프로그램을 만들 수 있는지를 이해를 못 한다. 하지만 그럼에도 불구하고 7.4에서는 논란의 여지가 있던 부분을 없애고 오랜 연구 끝에, 문제를 일단은 이름 판별이라는 꼼수 없이 완벽하게 해결했다. 이런 미세한 동작 방식 같은 건 제대로 문서화도 돼 있지 않으니 정말 프로그래머가 경험을 알아서 축적하는 수밖에 답이 없다.

참고로 첫 타의 조합이 끊어지는 문제는, 첫 타가 아예 무시되고 씹히는 문제하고는 성격이 다르다. 후자 역시 다른 상황에서 예전에 <날개셋> 한글 입력기 외부 모듈의 버그로 종종 보고되곤 했다. ㅎㅎ

6-2. 외부 모듈: Windows 7의 명령 프롬프트에서 한글이 덧나는 문제

Windows 7에는 한글 IME의 세벌식 지원과 관련하여 이전의 XP/Vista에 없었고, 후대의 8에도 없는 전무후무한 이상한 문제가 하나 있다. 명령 프롬프트에서 한글을 입력하다가 space, 마침표, 숫자 등 비한글 문자를 입력하여 조합을 중단할 경우, 조합 중이던 한글이 덧나는 현상이 발생한다.

MS IME, 그리고 <날개셋> 한글 입력기도 동일하게, 그것도 오로지 윈도 7에서만 발생하기 때문에 이것은 IME 차원에서는 해결 불가능한 운영체제의 버그라고 간주되어 왔다.
단, MS IME로 두벌식을 쓸 때는 문제가 없는데, 두벌식의 경우 비한글 문자는 IME가 글쇠를 가로채어 직접 처리하지 않기 때문에 그렇다.

그랬는데.. 이번 7.4 버전으로 우연히 콘솔에서 한글을 입력해 봤는데.. 덧나는 현상이 없어져 있어서 깜짝 놀랐다. 윈도 7에서 세벌식으로 덧나는 현상 없이 한글을 입력하는 걸 난생 처음 본다. 저게 가능하구나!
구버전(= 현재 공식 최신 버전)인 7.11을 돌려 보니 문제가 발생하는데, 7.4를 돌리니 문제가 사라지는 게 확실하다.

도대체 무슨 변화가 생긴 건지? 저 6번하고는 영역이 다른 문제였을 텐데. 기대도 안 했던 버그가 별다른 작업 없이 저절로 해결돼 있으니 기분은 좋다만, 한편으로 좀 난감하네.

7. 타자연습

자, 입력기가 이렇게 완전히 머리부터 발끝까지 뒤집어 엎어진 동안, 타자연습도 변화가 하나도 없으면 좀 섭섭할 것이다.
입력기와 API 호환성이 다 날아갔으니 7.4 버전에 맞춰 다시 빌드되어야 한 건 두 말할 나위도 없거니와, 외형과 관련된 사소한 개선 사항이 좀 있었다.

프로그램의 16*16 소형 아이콘이 그 크기에 맞는 전용 아이콘으로 나오는 게 아니라 32*32 아이콘을 축소시킨 우중충한 형태로 지금까지 나오고 있었는데, 당장 그걸 개선했다. 개인적으로는 타자연습도 지금의 편집기나 변환기처럼 <날개셋> 한글 입력기 7.0 스타일의 동그란 네모 아이콘으로 바꾸고 싶으나, 그 작업까지 할 여유는 없다.

그리고 프로그램을 고해상도 DPI 모드에서 실행해서 UI 텍스트가 잘린다거나 하는 것을 모두 수정했다. 그 작업의 결과로 페이지의 우측 하단에 있던 “연습 시작” 버튼들이 예전보다 더욱 길쭉해지고 보기 좋아졌다. 이 역시 진작부터 개선할 생각을 왜 안 했나 모르겠다.

다음으로 장문 연습을 시작할 때 "연습을 시작합니다. 준비하세요"라고 메시지 박스가 번거롭게 뜨던 걸 없애고, 단문 연습과 마찬가지로 첫 타를 누름과 동시에 시간 측정과 경쟁 모드가 시작되게 했다. 인터페이스 개선에 기여할 것으로 보인다.

끝으로, 연습글을 상당수 교체했다. 세월을 안 타는 고전을 제외하고는 너무 구태의연하고 지금과 시기가 안 맞는 글은 삭제했다. 예를 들어 한글날이 공휴일에 국경일까지 된 마당에 한글날 국경일 지정을 촉구하는 글을 계속 남겨 둘 필요는 없으며, 월드컵 관련 글도 너무 오래 됐다고 판단하여 뺐다.
그 대신 다른 글을 넣고, 각종 인터넷 유행어 병맛 개그들을 넣었으니 타자 연습할 때 즐겁게 이용해 주시기 바란다. ^^

사실 게임도 업그레이드 시스템을 없애고 시간이 나면 시스템을 다 갈아엎고 싶었으나 도저히 손을 댈 수 없었다. 3.31에서 3.4로 번호를 작업량에 비해 좀 크게 올린 것은 거의 1년 반 만의 버전업이어서 시간 간격이 워낙 길었으며, 또 7.4와 끝자리를 맞춘다는 의미를 더 표현하고 싶었기 때문이다. 올해는 또 2014년이기도 하고.

8-1. 사소한 것: 최종 변환 규칙 UI

다른 카테고리에 분류되기가 뭣한 잡다한 얘기들은 다 여기에다가 집어넣었다.
<날개셋> 한글 입력기는 최종 변환 규칙이라는 게 추가된 무려 2.4 버전 이래로 지금까지..
입력값 from과 to를 접수하는 방식이 좀 괴이했다. 한 입력란에다가 from 문자와 to 문자를 붙여서 입력하고 '추가'를 눌러야 했으나.. 이번 7.4에서는 드디어 from과 to를 별도의 입력란에다 따로 입력하는 방식으로 UI가 직관적으로 개선되었다. 아래 그림을 참고하시라.

사용자 삽입 이미지

8-2. 떡밥 - JSON

이건 새로운 기능 얘기는 아니고 다른 잡설임.
<날개셋> 한글 입력기는 입력 설정 파일을 바이너리 고유 포맷뿐만 아니라 텍스트 에디터로 편집 가능한 XML 방식으로 저장하는 것도 꽤 오래 전부터 지원해 왔다.
그런데 텍스트 기반의 데이터 직렬화(serialize) 파일 포맷으로 XML뿐만 아니라 JSON이라는 물건도 있었구나. 얘도 보아하니 찰져 보이고 XML의 대체제가 될 수 있을 것 같다.

XML처럼 다단계 계층을 당연히 표현할 수 있으며, key-value 방식의 자료구조뿐만 아니라 배열을 통해 테이블 같은 단순 데이터 dump도 모두 손쉽게 표현할 수 있다는 게 마음에 든다. XML은 일단 후자에는 최적화돼 있지 않으니 말이다.
태그가 아니라 프로그래밍 언어의 데이터 초기화 코드에서 모티브를 땄다는 점도 참신해 보인다.

8-3. 떡밥 - 글꼴

<날개셋> 한글 입력기는 1.0 시절부터 내부 입력 프로토콜을 사용하는 자체적인 에디트 컨트롤을 갖추고 있었으며, 구현체들 중 편집기는 이 컨트롤을 기반으로 동작하는 텍스트 에디터이다. 그리고 자체 에디트 컨트롤은 16*16 비트맵 글꼴이라는 굉장히 원시적이고 똘끼 충만한 글꼴 체계를 고집하고 있다.

그것 자체는 이 프로그램의 특징이고 포기할 수 없는 특성이라고 치자. 운영체제에 의존하지 않고, TTF로는 상상도 할 수 없는 작은 크기의 조합형 글꼴로 옛한글과 미완성 한글을 출력하는 것을 애초에 목표로 삼았으니 말이다. 기계식 타자기를 컴퓨터에다 옮겨 놓은 듯한 날씬함을 개발 철학 차원에서 추구한 셈이다.

다만, 이거 하나는 대세를 무시할 수 없는 듯하다. 바로 화면 해상도. 옛날에는 16*16이라는 글자 크기가 운영체제 UI의 기본 글꼴보다 컸지만, 125% 내지 150% 배율을 쓰는 초고해상도 환경에서는 이것은 작은 크기이다.
같은 폰트라도 16픽셀을 18이나 20 정도로 확대해 주는 기능은 있어야 할 것 같다.

기능 자체는 화면에다 글자를 찍는 부분과 마우스 포인터 위치 인식 기능에다 간단한 비례식을 추가하는 정도로 구현할 수 있을 듯한데..
문제는 비트맵 그래픽을 출력하는 부분이다. 정수배 확대가 아니니 그래픽의 품질을 위해 안티앨리어싱은 필수라고 봐야 하는데, 재래식 GDI로는(StretchBlt 함수) 그걸 넣을 수 없다. 당장 <날개셋> 편집기에서 화면 인쇄 명령을 내려서 배율을 바꿔 보면, 이를 확인할 수 있음.

그러니 이것도 최소한 GDI+나 요즘 대세인 Direct2D 같은 API로 작성되어야 할 것으로 보이는데, 그것까지 신경 쓰는 건 <날개셋> 한글 입력기의 핵심 기능과 직접적인 관계가 없고, 개인적인 작업 부담이 너무 심하다. 쉽지 않은 문제다.;;

9. 마치며

(1) 후원금을 보내 주신 분들의 이름은 그 다음 버전의 프로그램 도움말의 '감사의 글' 페이지에 꼬박꼬박 등재되고 있다.
후원자가 아주 많아지면 액수 순으로, 혹은 최근 순으로 잘라서 수록하는 게 불가피하겠지만, 내 프로그램은 벌써 그런 경지에 오른 것도 전혀 아니고 아직까지는 후원해 주신 모든 분들이 명단에 올라 있다.

<날개셋> 한글 입력기는 14년째 개발자가 한글 오덕질 근성을 주체하지 못하여 자기 인생의 상당 부분을 투자하며 개발되어 왔다. 특히 이번 7.4는 개발 역사상 유례를 찾기 어려울 정도로 한글 입력 엔진에 굉장히 많은 기능 추가와 수정이 이뤄졌다. 프로그램의 개발 취지를 이해하고 후원해 주신 분들께 다시 한번 감사드린다.

(2) 단군의 후손들이 어째 라틴 알파벳도 아니고, 한자 같은 그림문자도 아니고, 한글 같은 위상의 문자를 쓰고 있는지.. IME가 필요하긴 하지만 NLP 기술 없이 글자 구조 자체와 관련된 엔지니어링이 개입할 여지가 있는 문자를 쓰는지? 생각하면 할수록 신통방통한 일이다. 거기에 세벌식 글자판까지 생각하면.. 오덕질을 안 할래야 안 할 수가 없다.

본인은 맹목적인 공 병우 빠돌이가 아니며, 맹목적인 세벌뽕도 아니다. 더 나은 한글 기계화 패러다임이 있다면 정말 열린 마음으로 수용할 의향이 있다. 어떤 한글 입력 방식이든 동등한 여건 하에서 구현되고 테스트되어야 한다. 솔직히 <날개셋> 한글 입력기야말로 바로 종류를 불문하고 한글 입력 기술의 공평한 통합을 목표로 개발되고 있기도 하고 말이다. (그러니 세벌식뿐만 아니라 두벌식 관련 고급 기능도 많이 들어있다!)

그런데 그렇게 열린 마음으로 살펴봐도 현실적으로 정말 공 병우 세벌식을 능가하는 한글 기계화 패러다임은 등장하지 않았고 앞으로도 딱히 나올 기미가 보이지 않는다. 그 정도 성능에 그 정도 범용성을 갖춘 최강 가성비를 자랑하는 입력 방식 말이다.
오히려 모바일 환경으로 가면서 굳이 그렇게 빨라야 할 필요가 없으니 의미가 퇴색했을 뿐이지, 동일 환경에서 공 병우 세벌식이 다른 패러다임에 의해 추월당한(beaten) 적은 내가 보기에 없다. 내가 식견이 부족한 것일 수도 있으니 이 명제에 대한 반박은 언제든 얼마든지 환영한다.

본인은 이런 패러다임을 바탕으로 우리나라 고유문자를 컴퓨터에서 완전 변태(?) 수준으로 쥐락펴락할 수 있는 기술을 보유한 것에 자부심을 갖고 있다. 적어도 Windows라는 한 플랫폼에서만은 마스터를 했으니 말이다. 프로그래머 만세다. 언젠가 내 프로그램의 내부 구조와 설계 이념을 강연이나 저술을 통해 지금보다 더 널리 알릴 기회가 있으면 좋겠다.

Posted by 사무엘

2014/06/04 08:27 2014/06/04 08:27
Response
No Trackback , 9 Comments
RSS :
http://moogi.new21.org/tc/rss/response/970

<날개셋> 한글 입력기 7.4-- 上

요 며칠간 개인적으로 잘 된 일도 있었고 잘 안 풀린 일도 있는 채로 다사다난한 시간을 보냈으나.. 그 어느 것도 나의 코딩을 가로막을 수는 없다. 열차는 시각표대로 무조건 달린다. 건널목에서 충돌 사고가 나도 질량과 관성 때문에 장애물을 그냥 밀고 쭉쭉 나아갈 뿐이다.

그래서 드디어 <날개셋> 한글 입력기가 7.11 이래로 무려 7개월간의 수련을 마치고 7.4 버전이 완성되었다.
원하는 기능들을 다 집어넣은 건 아니지만 한번 역에 정차하여 쉬어 가게 됐다. 이 달부터는 학기 마무리 준비를 해야 하는 관계로, 더 작업은 하고 싶어도 할 수 없기 때문이다.

5월은 안 넘긴 걸 기쁘게 생각한다. 의도했던 건 아닌데 5월 31일은 공교롭게도 <날개셋> 한글 입력기 3.0 출시의 딱 10주년 타이밍이기도 하다. 2004년 5월 31일 + 10년이다.

3.0은 최초로 유니코드 API 도입, 입력 스키마와 문자 생성기 계층 구분, 단축글쇠 테이블, 수식 기반의 오토마타, 지금과 같은 64비트 크기의 입력 단위, TSF를 인식하는 에디팅 엔진, 가변 길이 옛한글 등 오늘날 내 프로그램의 근간을 닦은 버전이었다. 2.5 이후로 거의 9개월 동안 프로그램을 밑바닥부터 다시 만들었었다.

물론 지금 보면, 기술적 디테일이나 사용자 인터페이스는 그야말로 내가 겁도 없이 이런 허접한 프로그램을 대회에 출품하고 사용자에게 공개했다 싶을 정도로, 민망할 정도로 허접하기 그지없었다.
그러나.. 포니를 개발한 뒤에야 에쿠스가 나올 수 있었듯이, 그런 개허접한 3.0이 있었기 때문에 그 뒤로 꾸준히 후속 기술이 개발되고 기능이 추가되어 무려 7.4까지 나올 수 있었던 건 자명한 사실이다. 이제 7.4를 바탕으로 올가을쯤에 7.5가 나와서 잔여 과업들을 완수해 준다면, <날개셋> 한글 입력기는 거의 대망의 완전체가 도달하지 않을까 싶다.

1. 입력 엔진 부분의 대대적인 리팩터링

예전에도 한번 소개한 적이 있듯, <날개셋> 한글 입력기에는 한 번에 한 낱자가 아니라 초중종 낱자를 한꺼번에 입력하는 기능이 있다. 그리고 그냥 입력하는 정도가 아니라 두 번에 걸쳐 입력하는 기능이 있다. 예를 들어 "받침ㅆ+다"를 배당하여 '이' 다음에 '있다'를 곧바로 만든다거나, '가' 다음에 '갔다'를 바로 만드는 게 가능하다.

극단적인 예로, 한 글쇠에다 '받침ㅋ+쌰'를 배당한다. 수식으로는 'H12|SS|YA|_K'라고 표현된다. 그 뒤, 허용 한글 범위를 KSX1001 완성형으로 맞춰서 2350자만 입력 가능하게 바꾼다.
이 상태에서 '가' 입력 중에 그 글쇠를 누르면.. '가ㅋ쌰'가 찍히는 게 맞다. '갘'은 조합이 안 되니 ㅋ이 다음 글자로 떨어져 나가고, '쌰'도 완성형에 없는 한글이기 때문에 조합이 더 진행되지 못하고 끊어지는 게 맞다. 그러나 현재 7.11 버전은 'ㅋ가쌰'가 된다. 중첩 입력을 처리하는 로직이 완전하지 못하기 때문이다.

또한 이 경우 원래 조합하던 글자에 이어서 총 2개의 글자가 추가로 완성되는 것이기 때문에 삽입이 아닌 '겹침' 모드에서는 2개의 글자가 추가로 덮어써져야 한다. 그러나 7.11은 그것도 깔끔하게 처리되지 못하고 여전히 삽입만 되고 있다.

이렇듯 NLP 기술이 하나도 없는 단순 한글 입력기 같아도 <날개셋> 한글 입력기는 서로 영향을 끼치는 입력 관련 각종 옵션과 변수들을 제어하는 게 굉장히 복잡하다. 가짓수와 가짓수를 서로 고려하다 보면 가능성이 곱셈이 되어 버려서 통제를 못 하게 된다. 각 변수들을 있는 그대로 각개격파하여 덧셈으로 유지되게 해야 한다.

굳이 저런 극단적인 상황에서의 매끄러운 처리까지 생각하는 게 아니더라도, <날개셋> 한글 입력기의 핵심 엔진 부분은 지난 10여 년 동안 다양한 기능이 추가되는 과정에서 매우 심하게 지저분해졌으며 구조적으로 심각한 한계를 드러내고 있었다. 그래서 대대적인 리팩터링이 불가피했다.

한참 옛날에 만들어 놨던 코드의 모든 로직과 의미를 다시 읽으며, 머리를 쥐어뜯고 피말리는 작업이 계속되었다.
그 결과, 단독으로 1천 줄이 넘던 핵심 함수의 일부를 2개의 함수로 떼어내고, 반복적인 패턴이 발견되는 일련의 루틴들을 별도의 클래스로도 빼냈다. 복잡한 입력, 이동, 지우기 동작을 제한된 element만으로 추상화해 낸 것이다.

특히 재귀호출이 필요한 부분과 그렇지 않은 부분을 확실히 분리했으며, 중복 무한순환 재귀호출을 감지하여 막는 부분을 더욱 똑똑하고 논리 오류가 없게 개선했다.

기능 추가도 아니고 동일한 기능을 구현하는 방식만 바꾸는 데 거의 50일이 걸렸다. 이 디자인이 과연 최선의 디자인인지 스스로 확신을 얻는 데도 긴 고뇌의 시간이 필요했다.
새로운 체계 덕분에 각종 지저분한 중복 코드가 없어지고, 지저분한 임시 변수나 비트 플래그가 없어지고, 그럼에도 불구하고 입력기의 논리적인 버그가 없어질 때마다 본인은 거의 엑스터시에 가까운 환희를 경험했다.

결합 축약 테이블에 의한 입력 순서 축약은 입력 타이밍이 아니라 bksp 지우기 동작이 실제로 일어날 때 행해지게 바꿨고,
특히 겹침 모드에서 배경의 글자를 덮어쓰는 개수를 계산하는 건, 입력 동작의 결과를 보고 공통된 post-processing 과정에서 한번에 알아서 계산하게 바꿨다.

이렇게 만들어진 출력 action은 구현체에 따라 IME에서는 WM_IME_*메시지로, TSF 환경에서는 TSF interface 함수 호출로, 자체 에디터에서는 말 그대로 내부 조작으로 seamless하게 변환되어 나간다. Windows 95부터 8.1까지 버전 불문하고 32비트, 64비트 불문하고 모두 똑같이 동작하는 건 물론이고 말이다.

이번 작업 덕분에 <날개셋> 한글 입력기의 코드는 소프트웨어공학적인 품질이 크게 향상되었으며, 이를 토대로 다른 새로운 입력 기능들도 손쉽게 확장해 넣을 수 있게 되었다.

2. 고급 입력 스키마

이번 7.4 버전에서는 종전의 '동시입력 스키마'를 대체하는 '고급 입력 스키마'가 추가되었다. 아직 넣고 싶은 기능이 100% 다 구현된 건 아니지만 어쨌든 이로써 입력 스키마와 문자 생성기가 모두 (1) 빈 (2) 기본 (3) 고급이라는 3단계 계층이 갖춰지게 됐다.

빈 입력 스키마는 아무 글쇠도 스스로 처리하지 않고 응용 프로그램에 그대로 넘겨 주는 잉여이다.
기본 스키마는 우리가 지금까지 써 온 대로, 키보드에서 통상적인 문자 입력용으로 쓰이는 47개 글쇠에다 Shift 조합을 포함한 94개 자리의 keydown을 인식한다. 거기에다 사용자가 별도로 지정한 글쇠의 keydown을 추가로 인식하거나, 기존 47개 글쇠를 부분적으로 인식하지 않게 하는 기능을 액세서리 차원으로 제공한다. 추가 글쇠는 Ctrl/Alt/Shift/Win 같은 modifier 조합을 옵션으로 가질 수 있다.

이에 덧붙여 고급 입력 스키마는 지정한 글쇠에 대해서 keydown뿐만 아니라 keyup(글쇠를 뗀 것)을 모두 인식할 수 있으며, 각 상황별로 이 글쇠를 처리할지의 여부를 모두 수식으로 지정 가능하다. 또한 이 keydown 이벤트가 몇 번째 연타인지, 그리고 이 이벤트가 발생한 시각(밀리초 단위)이 언제인지 같은 정보도 변수로 제공된다(예전에 기록한 시각과의 차이를 계산하는 데 활용 가능). 기본 입력 스키마에는 존재하지 않던 정보들이다.

그래서 이를 이용하면 한 글쇠를 0.n초 이상 오래 누른 것, 혹은 0.n초 이내에 눌렀다가 뗀 것, 어떤 두 글쇠를 연달아 누른 것, 굳이 Shift+X가 아니라 Shift를 한번 눌렀다 떼고 나서 다음 X를 순차적으로 누른 것 같은 복잡한 글쇠 동작을 모두 인식할 수 있으며, 글쇠를 오래 누르고 있어도 연타는 한 번 또는 n회 이내만 인식시킬 수도 있다. 기본 입력 스키마에다가 옵션으로 넣으려고 했으나 이론적인 기반을 마련하지 못해 지금까지 전혀 구현을 못 하고 있던 변칙적인 글쇠 인식은 전부 고급 입력 스키마를 통해 general하게 구현 가능해졌다.

단, 고급 입력 스키마는 기본 입력 스키마처럼 modifier 조합 같은 게 없다. 오로지 어떤 글쇠의 눌렀다 떼는 것에만 초점이 가 있으며, 두 글쇠의 조합은 각각의 글쇠가 눌러졌을 때 사용자가 변수에다 해당 글쇠가 눌렸다는 것을 일일이 판단함으로써 모든 로직을 수동으로 구현해야 한다. 기본 입력 스키마보다 설계 철학이 더 저수준이기 때문이다.

기본 입력 스키마는 날개셋문자를 있는 그대로 차근차근 보내는 것만 가능하다. 그러나 고급 입력 스키마는 사용자가 지정한 수식값에 따라서 지금 조합 중인 문자를 덮어쓰고 조합을 무조건 새로 시작시킬 수 있으며, 지금 조합을 무조건 종료한 뒤에 조합을 새로 시작시킬 수도 있다. 전자는 'ㄱ+ㅏ'를 '가'가 아니라 'ㅏ'로 바꾸는 기능이며, 후자는 'ㄱㅏ'로 바꾸는 것이라고 생각하면 이해하기 쉽다. 자기와 연결되어 있는 문자 생성기의 상태를 무시하고 입력을 보내는 게 가능하다는 뜻이다.

이런 고급 입력 스키마가 고급 입력기라는 문자 생성기와 만나면 활용 가능성은 더욱 커지는 건 두 말할 나위가 없다. 평상시에는 일반적인 방법으로 한 타씩 한글을 입력하지만, 특수한 글쇠 두어 개를 동시에 누르거나 한 글쇠를 오래 누른다거나 하면 미리 지정해 둔 '습니다', '000' 같은 글자 묶음이 지금 조합을 무시하거나 종료시킨 상태에서 곧장 입력되게 할 수 있기 때문이다.

더 자세한 개념과 기능 설명에 대해서는 고급 입력 스키마를 꺼낸 뒤, "고급 글쇠 인식 옵션" 페이지에서 F1 도움말을 참고하면 된다. 앞으로 이걸 이용한 창의적인 문자 입력 방식이 많이 고안되어 나오면 좋겠다. 예제 템플릿 수식 같은 거라도 더 넣어서 고급 입력 스키마에 대한 사용 접근성을 더 개선하는 게 추후 과제로 남아 있다.
또한 지금 만들어 놓은 입력 설정을 그대로 유지하면서 기반 루틴만 '기본'이던 것을 '고급'으로 업그레이드하는 방법이 없는 게 문제라면 문제임을 인정한다. 기반 루틴을 바꾸고 나면 글쇠배열 같은 입력 설정은 다시 세팅을 해야 한다.

다음 버전인 7.5에서는 이번 7.4에서 실험적으로 구현한 기능을 바탕으로, 한글의 동시 입력에 특화된 보정 기능들이 추가될 예정이다.

3. 고급 입력기 -- 한글 출력 치환

입력 스키마에 이어 문자 생성기에도 '고급 입력기'에 신선한 기능이 새로 추가되었다.
잠시 개념을 좀 복습하자면, 빈 입력기는 아시다시피 오토마타, 조합, 후보 변환 같은 게 없이 문자를 있는 그대로 완성된 형태로만 보낼 수 있는 제일 원초적인 문자 생성기이다. 영문 같은 문자에나 적합하다.
기본 입력기는 그야말로 한글 한 글자를 조합하는 데 필요한 온갖 복잡 화려한 <날개셋> 한글 입력기의 핵심 기능들이 모두 구현되어 있는 문자 생성기이다.

그리고 고급 입력기는 기본 입력기의 기능들을 바탕으로, 비한글 문자의 custom 조합과, 한글 입력과 비한글 입력을 서로 연동하는 액세서리 기능이 추가적으로 들어있다. 설계 철학이 이러하다는 걸 염두에 두도록 하자.
이번 7.4에서는 '한글 출력 치환'이라는 기능이 고급 입력기에 추가되었다. 언뜻 보기에 이것은 편집기 계층에 존재하는 '최종 변환 규칙'의 입력기 계층 버전처럼 보이기 쉬우나, 성격이 그것과는 약간 다르다.

한글 출력 치환은 초중종성 낱자별로 동작하는 버전과 글자 전체 단위로 동작하는 버전이 따로 존재한다.
전자는 가상 낱자를 가리면서 동작하고--다시 말해 세벌식에서 겹모음용 ㅗ/ㅜ와 홑모음용 ㅗ/ㅜ를 구분한다는 뜻--
후자는 그걸 따지지 않고 그냥 겉으로 보이는 한글 전체의 모양만 따지며 동작한다.

낱자 버전부터 설명하도록 하겠다.
초중종이 각각 ABC로 구성된 한글이 있고, 초중종 A, B, C에 대해 각각 1, 2, 3이라는 문자열로 출력 치환하는 규칙이 존재한다면.. ABC라는 한글은 대략 1A2BC3이라고 바뀌어 출력되게 된다. 즉, 한글의 앞뒤로 비한글 일반 문자가 삽입되며 특히 중성에 치환 규칙이 존재하면 한글 자체가 초/중종 두 글자로 찢어진다.

이런 기능이 왜 필요하며 무슨 용도로 쓸 수 있을까?
주된 활용 방법 중 하나는, 한글 입력 과정에서 현행 한글 코드에 존재하지 않는 복잡한 겹낱자를 잠시 표현해야 할 때, 이를 여러 개의 기존 낱자로 풀어서 표현하는 것이다. 물론, 123 말고 ABC 자체의 형태를 바꾸려면 기존 가상 낱자 규칙을 쓰면 된다. 따라서 낱자 출력 치환은 가상 낱자 규칙과도 연계해서 활용하면 좋다.

이번 7.4에서는 천지인이나 나랏글 같은 휴대전화 입력 방식 예제가 다 이 기능을 사용하여 다시 만들어져 있다.
종성 부분을 보면, 내부적으로는 받침 ㅃ, ㄸ, ㅉ이지만 겉으로는 초성 ㅃ, ㄸ, ㅉ이 다음 글자에 가 있는 것처럼 화면에 나타나는데, 가상 낱자를 써서 받침 ㅃ, ㄸ, ㅉ을 0으로 치환하여 원래 있던 자리에서는 없애 버리고, 그 대신 출력 치환 규칙에다가 초성 ㅃ, ㄸ, ㅉ을 대신 출력하게 한 것이다.

ㄴ+ㅇ, ㄱ+ㅆ, ㄱ+ㅊ 같은 받침이야 더 말할 필요도 없다. 300 이상의 가상의 받침을 설정한 뒤, 가상 낱자 규칙에다가는 ㄴ, ㄱ 같은 앞부분 받침만 나타나게 하고, 뒷부분 받침은 출력 치환 규칙으로 지정했다. 한글 한 글자를 조합하는 걸로 두 글자 이상의 한글이 한꺼번에 나타나게 하는 걸 이런 이론 기반으로 구현해 냈다.
단, 외부 모듈의 경우 한글 조합이 길이가 한 글자를 넘어가면 응용 프로그램에 따라서는 조합 중인 문자가 제대로 표현되지 않을 수 있으므로 주의가 필요하다.

다음으로 글자 버전은.. 쉽다. 말 그대로 지금 조합 중인 한글을 다른 문자로 바꿔서 보여 주는 것 그 이상도 이하도 아니다. 한글 입력 방식을 한글로 다른 문자를 입력하는 데 고스란히 활용할 수 있으며, 덕분에 사용자 정의 조합 기능을 쓸 일도 크게 줄어든다.

이것 덕분에 아래아한글 97 이래로 지금까지 구현된 적이 없던.. 한글로 일본 문자 입력이 가능해졌다. 이번 버전에서는 히라가나/가타카나를 종전과 같은 로마자 기반 사용자 정의 조합뿐만 아니라, 한글 출력 치환으로 구현한 예제 파일이 새로 추가됐다.

이와 관련하여, "한글 출력 범위(=문자 집합) 제한"에도 유용한 기능이 하나 추가됐다. 지금까지는 KSX1001 2350자, 한컴 2바이트 완조형, 한양 PUA 완성형처럼 완전 legacy 잉여 문자 집합을 생색내기로 흉내 내는 기능만 있었던 반면, 바로 <날개셋> 고급 입력기의 한글 출력 치환 규칙이 존재하는 글자만 허용하는 기능이 새로 추가된 것이다.
한글로 일본어 문자를 입력하는 예제 파일을 써 보면, 일본어 치환이 존재하지 않는 한글은 아예 조합이 되지 않고 낱자가 다음 글자로 튕기는 걸 볼 수 있다.

(다만, 지금까지 사용자 정의 조합으로 구현되어 있던 구결 입력 방식은, 그냥 외장형 "사용자 후보 변환"으로 입력하는 데이터 파일로 형태를 바꿨다. 한 한글에 대응하는 구결 문자가 여럿 있기 때문에 후보 변환이 더 적절하다고 판단되어서이다.)

4. 그 밖에

이번 7.4에서 이뤄 낸 위의 1~3 아이템들은 생각만 해도 후련하다. 왜 이런 기능들이 무려 2014년에 와서야 실현된 걸까. ㅠ.ㅠ 일반 사용자의 입장에서야 <날개셋> 편집기에 다른 에디터에도 있는 기능들이 덩달아 들어가기를 더 원할지 모르고 현실적으로는 외부 모듈의 안정성 개선이 더 중요하게 느껴질지 모르나, 본인의 입장에서는 그런 건 개발 방향과 직접적인 관계가 없거나 최소한 부가적인 요소들이다.

<날개셋> 한글 입력기의 개발에서 본인이 가장 중요하게 여기는 건 한글 입력과 관련된 기술을 한데 통합할 수 있는 이론 연구와 구현이다. 그러니 편집기는 10년 전이나 지금이나 똑같은 촌스럽기 그지없는 MDI 프로그램 외형이지만, 그 속의 깊이는 갈수록 심오해지고 있다. 이번 7.4가 개발 기간이 괜히 길었던 게 아니며, 7.2나 7.3을 건너뛰고 괜히 바로 7.4로 간 게 아니다.

프로그램 버전이 7.x대까지 가고 나니 프로그램의 완성도는 충분히 정착한 듯하며, 이를 토대로 지금까지 못 하고 있던 long-term 이론 연구를 최대한 진행했다.
고급 입력 스키마와 고급 입력기는 모두 ngs3 모듈이 아니라 ngsx라는 플러그 인 모듈이 담당하고 있는데, 이런 대규모 작업 덕분에 드디어 ngsx의 프로그램 크기가 <날개셋> 편집기 ngsedit의 크기를 근소하게 추월했다.

분량이 벌써 굉장히 길어진 관계로, 이 항목에서는 고급 입력기와 관련된 변화 사항을 조금만 더 얘기하고 나머지 새 버전 자랑은 다음 하편으로 미루도록 하겠다. ㅎㅎ 그러고 보니 타자연습도 빨랑 업데이트하고 저거 얘기도 해야 되는데..

7.4에서는 한글 로마자 입력 방식의 근간인 글쇠 치환 규칙이 동작하는 방식이 살짝 바뀌었다. 새로운 기능 추가가 아니라 변경임. 글쇠 치환 규칙에 존재하던 잡다한 옵션들이 모두 없어지고 이들의 구현 방식이 다른 대체제로 바뀌었다.

caps lock 무시 옵션이 없어졌기 때문에 이제는 기반 영문 글쇠배열이 caps lock을 구분하여 동작하지 않도록 바뀌어야 한다. 이것은 글쇠배열 편집기를 우클릭한 후 "전체 간소화 → 수식 제거"를 선택하면 된다. 하지만 간단히 한글 로마자 입력 빠른설정만 다시 실행해 줘도 7.4 버전 기준에 맞는 로마자 입력 방식이 다시 세팅된다.

shift 음절 강제 구분 옵션도 없어졌으며, 조합을 하는 낱자와 조합을 안 하는 낱자는 두벌식/세벌식 한글 타입으로 오토마타 차원에서 구분을 한다. 비슷한 메커니즘이 이미 네벌식 예제 입력 방식에서도 쓰인 적이 있다.
다만 이것 때문에 현재 한글로부터 글자판 입력 문자열을 구하는 방식이 제대로 동작하지 않고 있는데, 이것은 7.5에서 해당 알고리즘을 싹 다시 구현할 때 문제를 개선할 예정이다.

끝으로, 두벌식 처리 옵션도 없어졌다. 두벌식 한글로 치환되는 글쇠는 언제나 초성과 종성이 현재의 오토마타 상태에 따라 자동으로 구분되어 두벌식으로 처리된다. 번거로운 절차를 없앴다. 이 점 착오 없으시기 바란다.

Posted by 사무엘

2014/06/01 08:27 2014/06/01 08:27
Response
No Trackback , 8 Comments
RSS :
http://moogi.new21.org/tc/rss/response/969

예전에 본인은 windowless 리치 에디트 컨트롤에 대해서 글을 쓴 적이 있었는데, 이번에는 눈에 보이는 컨트롤에 대해서 다루도록 하겠다. 난 일종의 텍스트 에디터 윈도우를 처음부터 끝까지 만들어 본 사람이다 보니, 이런 세부적인 디테일에 눈길과 관심이 간다.
여러분은 PC 사용자로서, 혹은 더 전문적인 프로그래머로서 Windows 운영체제의 에디트 컨트롤에 대해서 얼마나 알고 계신가? 그 이름도 유명한 메모장이 얘를 기반으로 동작하는 걸로 잘 알려져 있다.

얘는 서식이 없는 plain 소규모 텍스트에 대한 아주 기본적인 입력 기능만 제공하라고 만들어진 물건이다.
그래서 전문적인 에디터들이 내부적으로 줄 단위 연결 리스트 자료구조를 사용하는 것과 달리, 얘는 단일 배열 버퍼 기반이라는 게 가장 큰 특징 되겠다. 복잡한 메모리 관리 메커니즘이 전혀 없이 텍스트는 전체가 커다란 배열이며, 삽입이나 삭제는 진짜 직관적이고 단순하게 밀고 당기고 전체 메모리를 재할당하는 식으로 행해진다.

Windows 9x 시절까지만 해도 이 에디트 컨트롤은 64KB가 좀 덜 되는, 6만여 바이트 이상의 텍스트는 불러들일 수 없었다. 아무리 16비트 시절의 잔재라지만 이건 말도 안 되는 제약이었다.

오늘날의 운영체제에서야 그 정도의 막장 제약은 존재하지 않는다. 그래도 단일 버퍼 기반이며 근본적으로 대용량 텍스트를 다루는 데 최적화되지 않은 구조인 것은 변함없다. 그렇기 때문에 메모장에서 수 MB 이상의 파일을 불러들이고 편집하는 건, 불가능하지만 않을 뿐 여전히 무리다. 다른 프로그램을 써야 한다. 가령, 확장판인 리치 에디트 컨트롤은 연결 리스트 기반이며 에디트 컨트롤과 같은 제약이 없다.

간단한 물건답게 실행 취소(undo)는 직전의 동작 딱 하나만을 취소하거나 도로 철회하는 게 가능하다. 요즘 유행인 다단계는 지원하지 않는다.
텍스트 전체를 왼쪽뿐만 아니라 가운데나 오른쪽으로 정렬하여 출력하기, 숫자만 받아들이기, 알파벳은 대문자나 소문자 한 형태로만 받아들이기, 입력되는 텍스트를 '암호'로 처리하여 화면에 숨기기 같은 아기자기한 옵션이 있다. 최대 글자 수 제한을 걸 수도 있다.

얘의 동작 방식을 사소하게 바꿔서 배경이나 글자색을 바꾸고, 특정 문자는 안 받아들이게 하고, 문자열을 자동 완성한다거나 우편번호/시리얼 번호처럼 특정 형식을 만족하는 문자열만 입력되게 하는 것은... 아주 전형적인 Windows 프로그래밍 주제였다. 윈도우 프로시저를 서브클래싱하면 된다.
단일 버퍼라는 특성상 에디트 컨트롤의 메모리 핸들에 곧장 접근하여 조작하는 API도 있긴 하나, 실제로 사용되는 경우는 거의 없다. 사용이 권장되지도 않는다.

multi-line 모드의 경우 줄 바꿈 문자는 오로지 정확하게 \r\n만 지원하는 걸로 잘 알려져 있다. 그래서 유닉스 계열의 \n 텍스트를 불러와 보면 \n 문자가 실제로 보이고 줄 바꿈 처리가 되지 않아 텍스트를 제대로 볼 수 없다.
이 역시 리치 에디트 컨트롤과는 다른 점이다. 텍스트를 불러들이는 과정에서 딱히 줄 바꿈 처리를 전혀 하지 않고 normalize도 전혀 하지 않는 단순함을 추구했기 때문이랄까?

그리고 Windows GUI 프로그래밍을 좀 해 본 사람이라면 경험적으로 아는 중요한 특징이 하나 있다.
multi-line 모드에서 word-wrap(자동 줄바꿈) 옵션은 컨트롤이 생성될 때 한번 지정되고 난 뒤부터는 변경되지 않는다. 스타일을 바꿔도 바뀐 대로 동작하지 않는다.

그렇기 때문에 당장 메모장에도 있는 '자동 줄 바꿈' 옵션은 에디트 컨트롤을 파괴했다가 다시 생성하는 방식으로 구현되어 있다! 물론 창이 갖고 있던 내용을 따로 보관했다가 다시 가져와야 할 테고. 이건 Windows 95 이래로 지금까지 동작 방식이 시종일관 변함없다.

심지어는 닷넷이 제공하는 에디트 컨트롤의 관련 속성조차도 내부 구현은 창을 다시 생성하는 걸 Spy++ 같은 프로그램으로 확인할 수 있다고 한다. 핸들값이 바뀌니까 말이다.
응용 프로그램에다가 꼼수를 추가하면 추가했지, 에디트 컨트롤은 절대로 건드리지 않기로 작정하고 봉인을 시킨 모양이다. 그러니 앞으로 Windows 9, 10이 나오더라도 에디트 컨트롤이 연결 리스트 기반으로 바뀐다거나 하는 일은 없을 것으로 보인다.

한 에디트 창을 single line으로 쓰느냐 multi line으로 쓰느냐 같은 건 프로그램 실행 중에 동적으로 바뀔 일이 거의 없다. 그러니 그런 건 고정불변으로 둘 만도 하다.
하지만 multi line에서 자동 줄 바꿈 여부는 텍스트 에디터를 만드는 사람이라면 누구나 공감하듯이 동적으로 바뀔 여지가 있다. 그런데 그걸 불변으로 굳혔다는 것은, 에디트 컨트롤을 갖고 뭔가 진지하게 대용량 텍스트 에디터를 만드는 건 설계 차원에서 정말로 고려하지 않았다는 걸 의미한다.

뭐, 단순하긴 해도 운영체제가 원초적으로 제공하는 텍스트 입출력 기술의 혜택은 그대로 받는지라, 오늘날 에디트 컨트롤은 마냥 단순하기만 한 것도 아니다. Uniscribe를 사용하여 나름 아랍어 같은 complex script의 입력과 위치 계산도 기본적인 건 그럭저럭 처리해 낸다. 우클릭했을 때 나타나는 메뉴를 보면, 텍스트의 기본 진행 방향을 L2R로 할지 R2L로 할지 지정하는 옵션이 있다.

마지막으로 입력 쪽을 살펴보면, Windows에는 TSF라는 입력 기술이 도입됐는데, 에디트 컨트롤은 기본적으로는 얘를 완벽하게 지원하지 않는다. 문자 입력기가 모든 텍스트를 자유자재로 조작할 수 있는 TSF 프로토콜은 역시나 리치 에디트 컨트롤만이 Windows XP sp1 시절부터 도입했다. 비록 이것도 모든 리치 에디트에 자동 적용되는 건 아니고, 최신 버전의 컨트롤을 사용하고 전용 메시지를 사용해야 하지만 말이다. (리치 에디트는 일반 에디트와는 달리 업그레이드가 쭉쭉 되어 온 대신, 버전 내력이 꽤 꼬여 있다..)

그렇기 때문에 이 에디트 컨트롤을 기준으로는 TSF와 관련된 두 가지 접근이 있어 왔다.
첫째는, 에디트 컨트롤을 사용하는 응용 프로그램이 윈도우 프로시저를 서브클래싱하여, 적절한 시기에 TSF API를 호출하고 TSF 인터페이스를 직접 구현하는 것이다. TSF로부터 특정 문자열을 읽거나 쓰라는 요청을 받으면, 그걸 EM_SETSEL, EM_GETSEL 메시지 같은 걸로 요청해서 결과를 되돌리면 되는 거다. 에디트 컨트롤은 단일 버퍼 기반 구조여서 텍스트 오프셋 계산은 다행히 훨씬 쉬우니까 말이다.

물론 이것은 에디트 컨트롤이 native하게 TSF를 지원하는 것보다는 효율이 훨씬 떨어지며, 오동작의 여지도 많다. 그냥 이런 발상도 가능하다는 걸 시연해 보이는 데 의미가 있을 뿐. 지금도 있는지 모르겠는데 과거에 TsfAPP라는 예제 프로그램이 바로 이걸 구현한 프로그램이었는데, 버그도 많았다.

다음 둘째로는, Windows Vista부터는 응용 프로그램이 아닌 그 밑에서 돌아가는 IME가 특수하게 요청할 경우에 한하여 에디트 컨트롤을 TSF 지원 모드로 바꿔 동작시키는 기능이 도입되었다. <날개셋> 한글 입력기는 TSF 인터페이스가 지원될 경우 기능 활용의 폭이 훨씬 더 넓어지는 관계로, 이 기능을 실제로 사용하는 옵션이 있다.
이 모드를 사용하면 한글 입력 중일 때 cursor가 깜빡이는 네모가 아니라 일반 블록 색깔로 바뀐다. 그리고 에디트 컨트롤을 특수하게 조작하는 프로그램에서 잠재적으로 오동작이 발생할 가능성도 생긴다.

이 TSF 확장 기능은 에디트 컨트롤뿐만 아니라, legacy 리치 에디트 컨트롤(=자체적으로 TSF를 지원하지는 않는 구버전)과 IE 웹브라우저 엔진이 제공하는 에디트 컨트롤에도 그대로 적용된다. 즉, 마이크로소프트가 구현한 표준 에디트 관련 컨트롤에는 거의 다 적용되므로 사용의 폭이 넓은 편이다.

이상이다.
옛날에 MSDN에서 Kyle Marsh 아저씨가 16비트 Windows 3.x 기준으로 에디트 컨트롤의 모든 기술적 디테일을 미주알고주알 늘어 놓은 글을 본 기억이 난다. 얘는 동작 방식과 규격이 20년 전이나 지금이나 완전히 굳어져 버려서 호환성 유지 차원에서 더 바꿀 수가 없고, MS가 신기술 투자는 리치 에디트에다가 집중적으로 한다고 보면 얼추 맞겠다. 그래서 리치 에디트에는 드래그 & 드롭도 있고, 하이퍼링크를 밑줄로 표시해 주는 기능도 있지만, 일반 에디트는 그런 거 없다. Ctrl+Bksp를 눌렀을 때 단어 단위로 지우는 기능 역시 리치 에디트급 이상에만 있다.

아울러, 일반 에디트는 우클릭하면 표준 메뉴가 나타나는 반면, 리치 에디트는 우클릭했을 때 제공되는 기본 메뉴가 없고 그걸 전적으로 사용자의 customization에 맡기고 있다는 차이가 있다.

Posted by 사무엘

2014/05/29 08:40 2014/05/29 08:40
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/968

요즘 운영체제들에 GUI 셸이 없는 물건은 없고, GUI에는 그림보다도 먼저 문자를 찍는 기능이 반드시 필요하다. 옛날에는 그런 출력 기능이 겨우 비트맵 글꼴밖에 지원되지 않았지만, 오늘날은 트루타입(TTF)이라고 불리는 규격의 윤곽선 글꼴이 세계를 평정한 지 오래다(오픈타입은 TTF의 superset에 해당함). 심지어 재래식 비트맵 글꼴이 필요하다 해도 일단 TTF 방식으로 저장하고서 출력한다.

게임처럼 완전 독자적인 GUI 노선을 가는 프로그램이 아닌 이상, 거의 모든 응용 프로그램들은 운영체제가 제공하고 운영체제에 기본으로 설정되어 있는 글꼴만을 사용하여 글자를 출력한다. 새로운 글꼴을 받아서 설치하는 건 사용자의 몫이다. 그러나 가끔은 응용 프로그램이 직접 글꼴을 설치해서 써야 하는 경우도 있다.

워드 프로세서 같은 오피스 프로그램이라면 운영체제 전체에 새로운 글꼴을 번들로 제공할 수 있다. 이건 global한 글꼴 추가이다. 한편, 자기 프로그램 내부에서만 특수한 custom 글꼴을 추가해서 쓰는 건 local (private)한 글꼴 추가이다.

윤곽선 글꼴 출력 엔진은 힌팅과 캐싱 기능이 곁들여진 일종의 고성능 범용 단색 벡터 그래픽 엔진이다. 그렇기 때문에 다른 프로그램들에 노출되지 않는 local 글꼴도 용도가 매우 다양하다. 수식이나 악보에서 쓰이는 비문자 기호를 찍는 건 물론이고, ‘입꼴 워드’처럼 자기만 사용하는 특수한 문자를 찍을 때도 전용 글꼴을 활용하면 된다.

당장 운영체제 자신도 이걸 잘 활용하고 있다. 테마가 도입되기 전에 Windows 창에 달린 사각형 모양의 최소화(_)/최대화/닫기(X) 그림은 글꼴 출력이고, Visual Studio 같은 데서 창을 도킹시키는 주사기/핀 모양의 그림도 글꼴이다. 아마 본인이 옛날에 블로그 글에서 언급한 적이 있을 것이다.

Windows 8은 부팅 시나 작업 중일 때 다섯 개의 구슬이 동그란 궤도를 그리면서 슝슝 돌아가는 애니메이션이 출력되는데, 이것도 애니메이션 GIF나 플래시 같은 기술이 아니라 글꼴 출력이다~! 구슬이 싹 들어갔다가 나오기도 하는 게 은근히 복잡하며, 이 애니메이션은 무려 100수십 프레임에 달한다. 유니코드 PUA 영역에다 미리 계산된 각 프레임의 모양을 그려 넣은 뒤, 그 글자를 순서대로 찍은 것이다. 놀랍지 않은가?

보급이 아닌 싸제 글꼴의 등록 및 해제를 위해 Windows는 AddFontResource와 RemoveFontResource라는 간단한 함수를 제공한다. 인자로는 등록하거나 해제하고 싶은 글꼴 파일의 경로만 달랑 주면 된다. '일단은' 말이다. 그러다 나중에는--Windows 9x 라인 말고 2000에서부터-- 두 종류의 함수가 더 추가되었다.

첫째, 바로 저 두 함수의 이름 끝에다 Ex가 붙은 버전이다. Ex 버전은 인자를 두 개 더 받는데, 하나는 아직 reserved 상태니 별 의미가 없고, 다른 하나는 사소한 비트 플래그들이다. 등록하는 이 글꼴을 시스템 전체가 아니라 우리 프로세스 내부에서만 사용하게 하는 FR_PRIVATE 옵션, 그리고 글꼴의 접근 가능 여부를 떠나서 일단 이게 EnumFontFamilies(Ex)에서 집계가 되지 않게 하는 FR_NOT_ENUM 옵션이다. 즉, 이 글꼴의 독특한 이름을 아는 프로그램만 이 글꼴을 사용할 수 있게 되는 것이다.

그리고 둘째로, 글꼴을 파일 이름이 아니라 아예 메모리 상의 데이터로 받는 AddFontMemResourceEx도 추가되었다. 이 함수로 추가되는 글꼴은 파일로 실체가 존재하지도 않고 특정 프로세스의 주소 공간에 매여 있으므로 극도로 private하며, FR_PRIVATE|FR_NOT_ENUM 속성이 언제나 선택의 여지 없이 붙는다.

요컨대 글꼴을 좀 더 가볍게 private 형태로 추가하는 기능은 Windows 2000에 와서야 새로 도입된 셈이다. 여담이지만, 이것 말고도 Windows 2000은 9x/NT4 시절에 비해 프로그램의 국제화 수준이 크게 강화된 첫 버전인지라 다국어 IME와 complex script를 포함해 글꼴을 저수준에서 조작하는 API들도 크게 추가되었다.
트루타입 글꼴의 테이블 데이터를 있는 그대로 뽑아 내는 GetFontData라든가, 글꼴이 지원하는 문자 집합을 유니코드 번호로 얻어 오는 GetFontUnicodeRanges도 이때의 산물임.

뭐 그건 그렇고 다시 글꼴 등록 얘기로 돌아오자면..
local/private 말고 전통적인 global한 글꼴 추가도 여전히 필요한 절차이다.
그런데 문제는 이게 사실 함수 호출만 한다고 완전히 끝나는 게 아니라는 것이다. 절차가 생각보다 굉장히 지저분하며 문서화가 제대로 돼 있지 않다.

1. global 글꼴은 Windows\Fonts 디렉터리에 있어야 한다. 결국 파일을 복사해 넣어야 하는데, 이 디렉터리에 read가 아닌 write를 하려면 관리자 권한이 필요하다.

2. Fonts 디렉터리에 복사된 파일을 상대로 AddFontResource(Ex) 함수를 호출한다.

3. 이 글꼴이 다음 부팅 때에도 제대로 인식되게 하려면, 글꼴 리스트를 레지스트리에다가도 등록해 줘야 한다. 위치는 다음과 같다.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
과거 9x 시절에는 Windows NT 대신 그냥 Windows이고. 저 레지스트리도 read가 아닌 write를 하려면 관리자 권한이 필요하다.


레지스트리에 등록하는 형식은 대충 보면 짐작할 수 있지만, 문제는 이 뻔한 패턴의 작업을 자동으로 대행해 주는 함수가 없다는 것이다. 등록하고자 하는 TTF 파일을 직접 파싱해서 name 테이블에 있는 이름을 얻어 와야 하나? ActiveX 컨트롤을 등록해 주는 regsvr32 유틸리티처럼 글꼴을 명령 프롬프트에서 바로 설치하거나 제거하는 유틸리티도 운영체제에 있어야 할 것 같다.

옛날에는 트루타입 글꼴을 설치하려면 CreateScalableFontResource 같은 이상한 함수도 호출해서 ttf에 대응하는 *.fot 파일이라는 걸 만들어야 했던 모양이다. 완전 불편하기 그지없는데 지금은 그럴 필요까지는 없는 듯. 20년 전 엄청 옛날의 Windows 3.1 시절에는 ttf/fot 파일 쌍이 필요했지만 95 이후로는 그런 건 없다.

반대로 이 글꼴을 제거하려면 먼저 RemoveFontResource(Ex)를 호출해 주고, 이게 성공하면 레지스트리 제거와 파일 제거를 수행하면 된다.
그런데 Windows는 파일 자체를 가상 메모리 주소 공간에다 직통으로 대응해서 쓰는(MMF) 걸 좋아하는 운영체제인지라, 시스템 공용 파일을 지우기가 더럽게 까다로운 운영체제다. 글꼴도 예외가 아니어서 파일 삭제는 access deny 에러가 뜨면서 잘 되지 않을 수도 있다. 이때는 MoveFileEx(file, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)을 줘서 다음 재부팅 때라도 파일이 삭제되게 플래그를 주면 될 것이다.

local과는 달리 global 글꼴 등록과 삭제는 이렇게 번거로운데, 게다가 관리자 권한까지 필요하니 더욱 번거롭다.
관리자 권한은 한 프로세스가 필요한 때만 잠시 사용자의 동의 하에 취득했다가 반납하는 게 없다. 애초에 자기 프로그램을 더 높은 권한으로 재실행해야 한다.
잠시 다음 상황을 생각해 보자.

  •  어떤 일을 하는 동안에도 GUI는 매끄럽게 반응하고, 작업이 취소 가능하거나 진행 상황 같은 걸 별도로 표시해야 하는 경우: 작업 부분을 별도의 스레드로 떼어 내야 한다.
  • 다른 프로세스를 훅킹해서 정보를 얻어 오거나 실행을 조작해야 하는 경우: 훅 프로시저는 반드시 별도의 DLL로 만들어야 한다. DLL은 32비트와 64비트를 모두 신경 써서 만들어야 하니 더욱 번거롭다.

그리고,

  • 평소에는 일반 모드로 실행되지만, 잠시 관리자 권한을 얻어 와서 민감한 디렉터리나 레지스트리의 내용을 변경해야 하는 경우: 그 부분만 별도의 EXE(프로세스)로 만들어서 실행해야 한다. 물론 나 자신을 특수한 인자를 주고 재실행하는 것도 괜찮다.

참고로 권한이 낮은 프로그램은 권한이 높은 프로그램에다 메시지를 못 보낸다. 그러니 프로그램 간의 통신 메커니즘도 잘 생각해 봐야 한다. =_=;;

어지간하면 골치아플 일 없이 단일 모듈, 단일 스레드만으로 모든 일을 처리하고 싶은데 그럴 수가 없는 상황이 이렇게 요약되었다.
프로세스, 스레드, DLL이 시나리오별로 다 등장했다. 글꼴 설치는 '프로세스' 분리가 필요한 작업인 것이다.

Posted by 사무엘

2014/05/26 08:23 2014/05/26 08:23
, , ,
Response
No Trackback , 3 Comments
RSS :
http://moogi.new21.org/tc/rss/response/967

내 손글씨

내 손글씨는...

사용자 삽입 이미지

영문은 기본적으로 Times Roman을 표방하며 특히 숫자는 이를 더욱 엄격히 따른다. 소문자 a와 g도 언제나 Times 스타일의 정자체로 쓴다.
하지만 세부적인 획은 기분에 따라 Courier 또는 Century Gothic 스타일로 쓰기도 한다.

소문자 i, t, l 같은 글자를 보면 차이가 가장 크게 드러나는데..

  • Times 스타일은 세로획의 위쪽에 자그마한 / 모양의 삐침이 있고 글자가 대체로 홀쭉하다.
  • Courier 스타일은 세로획의 위쪽에 비교적 길게 - 모양의 삐침이 있고, 글자들의 폭이 대체로 균일하고 뚱뚱하다.
  • Century Gothic 스타일은 삐침이 전혀 없어서 t조차도 가로획과 세로획만 있다.

이 세 계열 중 어느 스타일을 따를지는 기분에 따라 달라지는 듯. 딱 하나로 떨어지지는 않는다.

한편, 한글은 바탕체를 표방하며 네모꼴 스타일과 샘물/세벌/빨랫줄 스타일 두 개가 존재한다.
내 손글씨를 정형화해서 디지털 서체로 만들고 싶은 소박한 바람이 있다.

한글은 라틴 알파벳보다 획이 (1) 더 많고 복잡하다. (따라서 한 글자를 표현하는 데 알파벳보다 일반적으로 더 많은 픽셀수가 필요하다.)
그리고 그렇게 복잡하긴 한데 (2) 개개의 획은 기하학적으로 더 단순하다. (로마자 같은 꼬부랑한 느낌이 별로 없다)

이런 이유로 인해, 글꼴에 라틴 같은 수준의 오동통한 개성이 들어갈 여지가 좀 덜하다.
한글 글꼴에 맞춰 만들어진 영문 글꼴은 순수 영문 글꼴보다 그런 기교가 neutralize된 경향이 있는 게 이 때문이 아닌가 싶다.

Posted by 사무엘

2014/05/23 08:27 2014/05/23 08:27
, ,
Response
No Trackback , a comment
RSS :
http://moogi.new21.org/tc/rss/response/966

MFC 프로그래밍 잡설

1. IE 웹브라우저 윈도우 삽입

내 프로그램에다가 로컬이든 웹이든 HTML 페이지 내용을 표시해야 할 일이 생겼다. 이 경우 가장 간단한 해결책은 Internet Explorer 웹브라우저 윈도우를 삽입하는 것이다.

그런데 얘는 ActiveX 컨트롤이다. 흔히 웹페이지 내부에 들어가는 각종 ActiveX 컨트롤들이 웹 표준을 위배하고 사용자 접근성을 저해한다는 식으로 말이 많지만, 사실은 Window의 웹브라우저 자체부터가 ActiveX 형태로 제공되는 컴포넌트인 것이다. 그리고 이미 다들 아시겠지만, 플래시도 기술적으로는 ActiveX이다. 단지 이건 너무 전세계적으로 널리 퍼진 관계로 반쯤 웹 표준인 것처럼 인정받고 있을 뿐이다. (뭐, 이것도 HTML5의 등장으로 인해 지위가 좀 위태로워지긴 했지만)

어쨌든 이런 구조적인 차이로 인해, 웹브라우저 윈도우는, 리치 에디트 같은 여느 custom control과는 달리 CreateWindowEx 함수에다가 클래스 이름만 달랑 넘겨 준다고 선뜻 만들 수 있는 물건이 아니다.
MFC에서 ActiveX 컨트롤을 생성하는 코드를 보면 CWnd::CreateControl로 내려가는데, 내부 메커니즘은 각종 COM API가 동원되며 미치도록 복잡하다. 사실, 난 MFC의 도움 없이 API만으로 ActiveX 컨트롤을 생성해 본 적이 없으며, 요즘 같은 세상에 굳이 그래야 할 필요도 없을 것이다.

예전에 비주얼 C++에는 Component Gallery라는 게 있어서 (1) 스플래시 윈도우나 '알고 계십니까' 팁 대화상자처럼 몇몇 자주 쓰이는 MFC 클래스를 프로젝트에다 자동으로 등록해 주는 템플릿, (2) 그리고 특정 ActiveX 컨트롤에 대한 wrapper 클래스를 자동 생성해 주는 기능이 있었다. 6.0의 이후 버전부터는 그런 걸 못 본 것 같다.
(1)은 그렇다 쳐도 (2)는 해당 ActiveX 컨트롤의 type library를 참고하여 이 컨트롤을 생성하는 함수, 그리고 걔가 원래 제공하는 속성과 메소드들을 그대로 C++ 클래스 형태로 옮겨 주는 기능이다. CWnd의 파생 클래스인 것은 두 말할 나위도 없고.

Component Gallery가 없으니 요즘 (2)를 수행하려면 좀 우회 경로를 가야 한다. 대화상자를 하나 만든 뒤 거기서 우클릭하여 원하는 ActiveX 컨트롤을 삽입하고, 그걸 또 우클릭하여 클래스를 추가하면 된다.

다른 것도 아니고 IE 웹브라우저 윈도우는 굉장히 유명한 ActiveX 컨트롤인 관계로, 사실은 MFC에도 이미 전용 클래스가 준비되어 있다. 바로 CHtmlView 되시겠다. 이름에서 알 수 있듯 얘는 CWnd가 아닌 CView로부터 상속을 받아서 MFC의 view-document 아키텍처에 최적화되어 있다.
즉, 대화상자의 여느 컨트롤들과는 달리 스택이 아닌 heap에 생성되고, PostNcDestroy 함수에 delete this가 구현되어 있다. 그래서 대화상자 같은 데에서 간단히 사용하기에는 어려움이 있다. (뭐, 불가능한 건 아니다. 대화상자 위에다 아예 CView를 만들지 말라는 법도 없으니)

한편, CHtmlEditCtrl이라는 클래스도 있다.
IE 윈도우는 단순히 HTML을 표시만 하는 게 아니라 위지윅 HTML 편집기 기능도 갖추고 있다. 얘는 IE 윈도우를 viewer가 아닌 editor 모드로 열어 준다.
IE가 여러 모로 리치 에디트 컨트롤과도 경쟁 구도가 된 듯하다. 물론 리치 에디트가 훨씬 더 빠르고 가볍지만, 텍스트에다 서식을 입히는 데 RTF보다야 HTML이 압도적으로 더 유명한 대세가 된 건 부인할 수 없다. 그래서 도움말조차 RTF 기반인 재래식 HLP는 진작에 밀려 사라지기도 했고 말이다.

이 CHtmlEditCtrl은 CView가 아닌 CWnd 기반이다. 그래서 CDialog 파생 클래스에다가 멤버로 선언하여 대화상자의 child control로도 비교적 쉽게 사용할 수 있다. view 버전은 CHtmlEditView와 CHtmlEditDoc이 따로 있는 듯.

하지만 에디트 기능이 없는 일반 IE 윈도우를 CWnd를 기반으로 간단히 스택에다가 생성하는 건 여전히 MFC의 기존 클래스로 가능하지 않은 것 같다. 그래서 본인은 그냥 ActiveX 컨트롤 type library로부터 CWnd 파생 클래스를 추출한 후 그걸 사용하는 재래식 방법을 동원했다.

2. MFC 액셀러레이터 버그(?)

Windows API에는 메뉴 단축키를 자동으로 처리해 주는 액셀러레이터라는 게 있다. MFC에서는 CFrameWnd::LoadFrame 함수에서 자기 프레임 윈도우 ID값에 해당하는 액셀러레이터를 불러들인다.

그런데 거기에 있는 단축키를 좀 수정하고, 메뉴에다 새로운 기능을 추가하여 단축키도 액셀러레이터 테이블에다가 배당했는데, 아무리 수정을 해 줘도 새로운 단축키가 동작하질 않고 단축키가 예전 방식으로만 동작한다.
혹시 액셀러레이터 리소스가 잘못 빌드됐나 싶어서 빌드된 EXE 파일의 내부 리소스를 살펴보기도 했지만 딱히 이상이 없다.

그렇다고 해서 해당 리소스를 아예 지워 버리면 모든 단축키가 먹통이 된다. 그러나 리소스가 있으면 단축키가 있는 그대로 인식되지 않는다. 어찌 된 영문일까?

이것은 비주얼 C++ 2008 이후부터 도입된 일명 feature pack의 추가 기능 때문에 벌어지는 현상으로, 엄밀히 말해 버그는 아니다.
알다시피 MFC feature pack에서는 CWinApp, CFrameWnd 같은 전통적인 클래스에 Ex가 붙었고, MS Office처럼 프로그램의 모든 기능의 단축키를 customize하는 기능이 추가되었다. 그래서 한번 프로그램을 사용하고 나면, 그 뒤엔 프로그램이 리소스에 있는 액셀러레이터 테이블을 참조하는 게 아니라 레지스트리에 저장된 단축키를 따라 동작하게 된다. CKeyboardManager라는 클래스를 보신 적이 있을 것이다.

그렇기 때문에 프로그램 개발 과정에서 새로운 메뉴 명령이나 단축키가 추가되어 이를 테스트하고 싶다면, 프로그램을 실행한 후에 Customize 대화상자를 꺼내서 단축키를 reset시키면 된다. 아니면 해당 레지스트리를 수동으로 날리거나 레지스트리를 날리는 코드를 추가해 주면 된다. 이에 대한 자세한 정보는 구글링하면 다 나온다.

단축키와 도구모음줄을 싹 다 customize하는 기능이 필요할 정도로 규모가 방대한 프로그램을 개발할 일은 사실 그리 많지 않다.
그러니 그냥 옛날처럼 feature pack 기능을 사용하지 않는 아주 간단한 프로그램만 만들고 싶은데 요즘 MFC 마법사는 그냥 선택의 여지가 없이 Ex 클래스만 사용하여 코드를 생성해 주는 듯하다.

요즘은 MFC DLL은 이제 ansi 버전은 기본 배포조차 안 해 준다고 하지?
그나저나 (1) DLL의 덩치가 커져도 너무 커진 것, 그리고 확장팩이 그나마 MS Office나 Visual Studio의 UI를 정확하게 고증하여 재연한 것도 아니고 (2) 동작 방식이나 글꼴, 색상이 들쭉날쭉 차이가 나면서 짝퉁 티가 팍팍 나는 것을 생각하면...
MFC의 변화 양상에 대해서 본인은 불만이 좀 있다. -_-;;

예전에도 말했지만, (1)은 걍 운영체제의 내장 mfc42.dll을 직통으로 사용하는 classic legacy 모드 같은 거 좀 넣어 주면 안 되나 싶고,
(2)는.. 운영체제의 보급 메뉴 말고 싸제 메뉴가 흔히 저지르는 실수 하나만 좀 지적하고 넘어가겠다. 업계 관계자가 내 글을 보게 될 가능성은 별로 없지만..;;

메뉴가 튀어나왔을 때는 프로그램이 자체적으로 IME를 꺼야 한다. 그래서 한글 모드일 때도 Alt를 누르지 않고 그냥 누르는 메뉴 항목에 대한 단축키(액셀러레이터 키)가 먹혀야 한다. 그 글쇠가 안 먹히고 화면 한 구석에 ㅇ, ㅂ 같은 조합 윈도우가 튀어나오는 건 프로그램의 버그이다.
이것도 MS 오피스의 싸제 메뉴는 처리를 한 반면에, 요즘 MFC가 라이선스한 싸제 메뉴는 그런 처리도 안 돼 있다. 보면 볼수록 품질이 실망스럽다. 아니, Visual Studio조차도 MS Office 라이브러리가 아니라 WPF 기반으로 새로 제작된 2010 이후의 IDE는 메뉴에 저 버그가 존재한다.

<날개셋> 한글 입력기야 MFC를 사용하지 않고, 그나마 타자연습은 나온 지 10년도 더 된 구닥다리 Visual C++ 2003을 아직도 사용하며 빌드되고 있다. MFC의 배포 방식과 덩치 때문에 업그레이드를 할 처지가 못 돼서 말이다. 아니면 차라리 WTL 같은 더 가벼운 프레임워크로 갈아타야 되나 싶다.
위의 두 아이템들은 내 개인 프로젝트가 아니라 회사 일을 하면서 발견하고 느낀 것들을 글로 옮긴 것이다. 이것 말고도 기억에 남는 게 좀 있는데.. 마저 나열하면서 글을 맺도록 하겠다.

3. ShowWindow(SW_HIDE) 하니까 창이 없어져 버렸던 것. 동일한 영역의 창에 IE ActiveX 컨트롤과 여타 윈도우를 상황에 따라 교대로 보이거나 숨기는 UI를 만들 일이 있었다. 그런데 프로그램이 자꾸 이상하게 동작하고 assertion failure가 나기에 디버깅을 해 봤더니, 이게 웬걸, IE 윈도우를 ShowWindow(SW_HIDE)를 해서 숨기는 순간 컨트롤 자체가 완전히 파괴되고 m_hWnd 값이 NULL이 되는 것이었다.

검색을 해 보니 이것은 아주 잘 알려진 문제. 처음에 Create로 생성을 할 때 WS_VISIBLE가 지정되지 않았던 IE 컨트롤은 나중에 또 ShowWindow를 통해 숨겨질 때 내부 로직에 의해 destroy되어 버리는 모양이었다.
이 문제를 피해 가려면 그 윈도우에 대해서 MFC의 CWnd::ShowWindow를 호출하지 말고 그냥 Windows API 함수를 쓰면 된다고 한다. 내부 사정은 알 수 없는 노릇. 스레드를 사용할 때 이래로 MFC 클래스 대신 Windows API의 사용이 강제되는 또 다른 상황을 만났다.

4. 내 프로그램에다 삽입시킨 IE 컨트롤로 각종 자바스크립트를 사용하는 웹페이지에 접속을 하다 보면.. 스크립트 오류가 난다. gmail만 해도 로그인을 하고 나면 동일 증상을 확인할 수 있음.
이것은 IE가 보안 때문에 취한 조치인 듯하다.
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

요 key를 만들어서 그 밑에 이름은 "자기 프로그램.exe"이고 데이터는 10진수로 IE 버전 곱하기 1000 (=0이 3개 붙은)인 REG_DWORD를 집어넣어 주면 된다.

5. MFC 라이브러리와 표준 C++ 라이브러리를 같이 사용한 상태로 프로그램을 static link 형태로 빌드하고 나면..
operator new/delete가 중복 정의되었다고 링크 에러가 나는 경우가 있다. (DLL link는 상관 없음)
이 역시 구글링을 하면 정보가 곧바로 걸려 나올 정도로 잘 알려진 문제이다. 귀찮지만 라이브러리를 링크하는 순서를 좀 바꿔 주면 해결 가능하다. 구체적인 해결책은 지금 이 개인용 컴퓨터에 들어있지 않아서 설명을 생략하겠다. -_-

Posted by 사무엘

2014/05/20 08:18 2014/05/20 08:18
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/965

2014년 5월의 철도계 새소식

내 블로그에서 언급을 하지 않을 수 없는 중요한 사건이 있기에 잠시 지면을 할애하여 소개하겠다.

1. ITX 새마을 운행 개시

등굣길에 근처 철길에서 지금까지 못 보던 열차가 지나가는 걸 봤다.
이 빨간 열차는 바로.. 지금의 새마을호(전후동력과 기관차 견인형 모두)를 대체할 차세대 열차 ITX 새마을이다. 지난 5월 12일부터 상업 운전을 시작했다~!
새마을호 전후동력형 디젤 동차가 작년 초에 퇴역하고서 1년 4개월 만의 일이다.

사용자 삽입 이미지
'새마을'.. 1974년에 등장한 이래로 40년째 열차 이름으로서 명맥을 이어 가는구나!
10여 년 전, 정식 개통 전에 클로즈 베타테스트 중이던 지금의 떼제베 개량 KTX를 보는 듯한 느낌이다.
누리로, ITX 청춘 등, 2010년대부터는 여객열차들이 이렇게 하나 둘씩 전부 전동차 기반으로 바뀌고 있다.
그리고 열차 호칭에서 등급명-차량명을 병기하는 체계도 차츰 정착해 가고 있다. KTX 산천이 원조였고 말이다.

누리로의 명칭도 이런 체계에 편입되어야 하지 않나 싶은데, 어찌 되려나 모르겠다.
무궁화호라는 이름은 그냥 예전의 기관차 견인형 여객열차 내지 개량형 디젤 동차의 총칭으로 남을 듯. 그리고 배 이름 관행의 잔재이던 '-호' 접미사도 이제는 없어져 가는 추세다.

우리 학교는 앞에 철길이 있어서 매우 아주 굉장히 좋다.
가끔 디젤 기관차가 지나가는 소리를 멀리서라도 들으면 마음의 기쁨과 안정과 평안이 찾아온다.

2. 평화열차 DMZ train 운행 개시

'경의선' 하면 내력과 관련하여 철덕이 할 말이 참 많다.
서울 시내 구간이 일반열차들의 기지 회송 구간으로 쓰인다는 특성상 오랫동안 수도권 광역전철 버프를 못 받고 있다가 2009년에야 전철이 개통했다.
그 전, 2006년 가을에는 새마을호 전후동력형 디젤 동차의 1987년 초기 도입분이 퇴역하면서 일명 '임진강 라이너' 새마을호가 3년 남짓 운행되기도 했었다.

그러나 경의선 수도권 전철이 문산까지 뚫리면서 임진강 라이너는 자연스레 폐지되었으며, 통근열차가 다니는 단선 비전철 구간은 운천, 임진강, 도라산 같은 남북 철도 연결 버프를 받은 21세기 구간으로 확 줄어 버렸다. 운행 거리가 서울 지하철 2호선의 지선 수준이 된 것이다. 전국에서 CDC 기반의 통근열차(구 통일호)가 최후까지 다니던 구간은 이 경의· 경원선밖에 없었는데, 이 둘 사이에서도 경의선은 경원선과는 처지가 많이 달라졌다. 경원선은 동두천 이북으로도 거의 50분에 가깝게 달릴 비전철 구간이 여전히 있기 때문이다.

결국, 지난 4월을 끝으로 통근열차 명목의 경의선 여객 열차의 운행은 종지부를 찍게 되었다. 그럼 오리지널 CDC를 볼 수 있는 곳은 진짜로 경원선밖에 안 남는구나.
그 대신 등장한 것은 일명 DMZ-train이라고 불리는 '평화 생명 관광 열차'이다. 어차피 경의선에서 그 짤막한 CDC 구간의 수요는 안보 관광객밖에 없었으니 적절한 조치인 것 같다. 이 열차는 운임 체계상으로 KTX, 무궁화호 같은 일반열차가 아니라 O-train, V-train 같은 관광열차의 위상이 된 것이다.

운행 횟수는 하루 두 번이고 당연히 패키지 안보 관광과 연계해서 다닌다. 차량은 새로운 건 아니고 기존 CDC를 관광용으로 개조한 물건이라 함. 물론, 운임은 과거의 통근열차보다 훨씬 더 올라갔다는 걸 감안해야 한다.
민통선 구간에 있는 도라산까지 갔다 오려면 미리 허가를 받아야 하며 돌아오는 표도 반드시 같이 구입해야 한다.

모든 변화가 달갑지는 않을지도 모르지만(특히 관광열차 명목으로 비싸진 운임) 본인은 이게 철도 경영의 관점에서는 바람직한 변화인 것 같다.
또한 한 가지 좋아진 점은, 이 열차는 문산이 아니라 서울 역에서 도라산까지 환승 없이 직통으로 간다는 것이다. 서울과 문산 사이엔 능곡 한 곳에서만 추가 정차한다.

올여름에는 경원선에도 이런 컨셉을 반영하여, 청량리에서 백마고지까지 가는 경원선 버전의 DMZ train도 운행을 시작할 거라고 한다. 그래도 경원선에는 정규 여객 통근열차도 여전히 병행이 필요할 것이다.
개인적인 생각은 정선선, 그리고 교외선에도 안보 쪽은 아니어도 비슷한 컨셉의 관광열차가 좀 다녔으면 어떨까 싶다.

Posted by 사무엘

2014/05/17 08:26 2014/05/17 08:26
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/964

패키지 관광도 하고 식사도 한 뒤, 다음 남은 시간 동안은 철원 서북부의 민통선 이남 지대를 차를 몰고 다니면서 내 마음대로 답사했다.
우리가 전선 휴게소로 갈 때는 지방도 464호선의 동남쪽을 통해 민통선으로 들어갔다. 그러나 다음으로 답사하는 곳은 그 도로의 서쪽 구간에 있다. 그래서 민통선 밖으로 나갈 때 그쪽으로 바로 나가면 목적지에 훨씬 더 빨리 갈 수 있다.

그러나 현실에서는 그럴 수 없기 때문에 들어갔던 곳으로 다시 나가야 했으며, 철원 동북-서북 외곽을 횡단하기 위해 다시 남쪽의 고석정으로 되돌아갔다가 국도 87호선을 거쳐서 다시 지방도 464로 갈아타야 했다. (전선 휴게소는 동북 외곽에 있음) 동선이 대략 좋지 않았다.

사용자 삽입 이미지

잠시 쉬어 가는 코너다. '오덕'의 압박..;;
하긴 그래도 야동리보다는 낫다. 옛날에 사람 중에도 이 오덕이라는 분이 계시기도 했고.
차 안에서 밖을 촬영한 것이어서 화면이 좀 흐리다.

사용자 삽입 이미지
그리고.. 말로만 들었던 백골 부대 백골 구조물을.. 국도 43호선상에서 실제로 봤다..;; (저건 내가 직접 찍은 사진은 아님.)

자, 내가 동선의 삽질까지 감수하면서 찾아간 곳은 바로 이곳이었다.

사용자 삽입 이미지사용자 삽입 이미지

국도 87과 지방도 464가 만나는 월하 삼거리에서 동쪽으로 얼마 안 가면 '한다리'라는 자동차 교량이 나오는데, 거기서 오른쪽(남쪽) 방면으로 한 200m쯤 떨어진 곳엔 옛날 금강산선 철도의 교량이 기둥만 남아 있다. 이걸 현장 답사했다.
그 옆을 보면 언덕이 두 동강 나기도 했을 정도로 옛날에 철길이 있었다는 걸 유추할 수 있다.

사용자 삽입 이미지사용자 삽입 이미지

그리고 한다리로부터 3km 정도 동쪽으로 더 가면.. '대위교'라는 교량이 나오며, 역시 여기서도 오른쪽을 보면 한다리보다 더 온전한 형태의 금강산선 교량이 남아 있다! “금강산 가던 철길!”이라는 글자까지 있음을 주목하시라.
이걸 직접 발견했을 때 내가 얼마나 기뻤을지 여러분은 상상할 수 있으시겠는가? 자동차는 이런 걸 답사할 때 쓰라고 만들어진 물건인 것이다.

인터넷을 뒤져 보면 나보다 어린 친구가 차도 없이 철원까지 대중교통으로 찾아간 뒤, 민통선이 코앞인 여기까지는 근성으로 걸어서 답사한 경우도 있다. 그에 비하면 나는 얼마나 빠르고 편안하게 찾아갔는가? 완전 양반이다.
한다리, 대위교 근처에 있는 교량과, 전선 휴게소 근처에 있는 교량을 지도에서 찾아서 한 선분으로 이어 보면, 옛날에 금강산선의 선형이 대략 어떠했을지를 짐작할 수 있다.

참고로 대위교 인근에는 '철길가든'이라는 식당이 있고, 또 민통선 구역으로 들어가는 초소가 있다.

사용자 삽입 이미지

대위교까지 간 뒤 본인은 차를 돌려 서쪽 백마고지 역으로 향했다. 지도를 보면 국도 87호선이 90도 꺾이는 지점이 있는데, 사실 길이 그것밖에 없는 건 아니다. 다른 방향은 민통선 안으로 들어가는 길일 뿐. 그리고 바로 그 교차점에 그 이름도 유명한 노동당사가 있었다.

철원이 북한 치하에 있었을 때 그들이 후딱 지어 사용하던 일종의 관청 건물이다. 근대 문화유산 등록 문화재 제22호. 얼마나 튼튼하게 만들었으면, 6·25 때 주변의 다른 건물들은 폭격 때 다 폭삭 무너지고 부서졌지만 쟤만 그래도 뼈대는 저렇게 온전히 남았을 정도라고 한다.

우리는 조선 총독부 청사나 서대문 형무소를 기억하는 것만큼이나 이 건물을 똑똑히 기억해야 할 것이다. 여기는 북한 공산당이 양민을 수탈하고 애국 우파 인사들을 체포하고 고문하고 죽이던 악마의 소굴이었다. 공산주의는 실현 불가능한 사상이기 때문에 공산주의자들은 그걸 강제로 실현하기 위해, 사람들을 감시· 억압하고 거짓 선동하고 자유를 빼앗는 등 우리가 생각할 수 있는 가장 악랄하고 잔학한 만행을 저질러 왔다.

남산 안기부? 남영동 대공분실? 노동당사의 악랄함에 비하면 새 발의 피는 될까 싶다. 내 홈페이지를 방문하시는 분들은 절대악과 필요악을 분간 못 하는 오류를 절대로 저지르지 말아야 한다.

역사적으로 공산주의자를 상대로 빨갱이라는 극단적이고 경멸적인 호칭이 괜히 생긴 게 아니었음을 알아야 한다. 북한은 순수한 의미에서의 공산주의 국가는 아니겠지만, 공산주의를 실현하기 위해 공산주의자가 사용해 온 악한 방법론과 배경 사상은 오늘날까지 그대로 변함없이 유지하고 있는 사악한 반국가단체일 뿐이다. “우리나라에도 공산당도 허용돼야 진정한 민주주의..” 운운하는 건 정말 역사와 현실을 모르는 극도의 무개념· 무지의 소치이다..

오해가 없게 말씀드리자면, 나의 정치 성향은.. 악의 세력으로서 본질이 예나 지금이나 변함없는 북한 수뇌부와 잘 검증된 과거 역사 팩트에 굳건한 뿌리를 두고 있다.
그것보다 훨씬 덜 중요한 겨우 무슨 새누리당이니 민주당이니 일베 오유 같은 것에 뿌리가 있는 게 아니다.
달랑 진보냐 보수냐, 성장이냐 분배냐 그딴 것만을 논하는 거라면 정치색 같은 걸로 논쟁하고 싸울 필요도 없다.

사용자 삽입 이미지사용자 삽입 이미지

이제 시각은 벌써 오후 5시가 넘어 있었다. 서쪽으로 수 km를 더 달려 도착한 우리의 마지막 목적지는 지난 2012년 말에 개통한 경원선의 북쪽 종점인 백마고지 역이었다. 근처에 백마고지 유적지가 있기도 하다.

원래 옛날에는 백마고지 역 일대도 민통선 지대였는데 나중에 해제되었다. 하지만 여기서 조금 더 가면 어차피 또 민통선을 만나게 된다. 역 주변엔 걸어서 가 볼 만한 건 없다시피하다니, 연계 교통수단이 필요하다.

사용자 삽입 이미지사용자 삽입 이미지

경원선은 경의선과는 달리 남북 연결이 되지 않았기 때문에, 선로가 심지어 민통선 안 구간에도 못 들어가고 이렇게 딱 끊어져 있다. 경의선 도라산 역은 잉여롭긴 해도 출입국 사무소가 있고 승강장에서 북쪽으로 쭉 이어진 선로를 볼 수 있었던 반면, 이곳은 단촐하고 한산하기 그지없었다.

사용자 삽입 이미지사용자 삽입 이미지

원래는 신탄리 역 이북에 철도 중단점이 있었는데 그걸 그대로 옮긴 건 아니고.. 철도 중단점을 새로 만들었다. 그래, 이걸 실물을 직접 보면서 카메라에 담고 싶었다. 승차권이나 입장권 없이도 승강장과 선로 끝에 슬쩍 들어가 볼 수 있었다.

이렇게 철원에서 철도 and/or 안보와 관련된 대부분의 명소들을 답사하면서 철덕력을 키웠다. 그리고 대한민국 땅에 주어진 자유의 소중함에 대해 생각하는 즐겁고 유익한 시간을 보냈다.
돌아올 때는 국도 3호선을 이용했다. 길이 상당 부분 경원선 철길과 겹치다 보니 돌아오면서도 철도역과 철길 구경을 덤으로 할 수 있었다. 도로 정체 때문에 돌아오는 길은 2시간이 좀 넘게 걸렸으며, 아침 7시 반으로부터 정확히 12시간 뒤인 저녁 7시 반에 서울에 무사히 귀환했다.

돌아오는 길엔 친구들은 너무 피곤해서 간식을 먹을 기력조차 없이 차에서 잠들어 있었다. 하지만 본인은 운전대를 잡고 있는 동안은 절대로 피곤을 느끼지 않았다. 단지 집에 도착한 뒤에 침대에 쓰러져서 시체 모드가 됐을 뿐.

철저한 준비 덕분에 길에서 전혀 헤매지 않았으며 시간도 적절히 분배하면서 짧은 시간 동안 많은 장소를 답사할 수 있었다. 인파가 바글바글 몰리는 데가 아니어서 분위기가 좋았으며, 완벽에 가깝게 좋던 날씨 역시 성공적인 여행을 더욱 빛나게 해 주었고 말이다.
다음날 교회에서는 같이 간 친구들의 부친께서 한 분씩 날 개인적으로 불러서 좋은 구경을 시켜 주느라 수고 많았다며 칭찬을 해 주셨다. ㅎㅎ

Posted by 사무엘

2014/05/14 08:24 2014/05/14 08:24
, , , , , , , , ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/963

전망대 주변은 경치가 몹시 아름다웠다.

사용자 삽입 이미지

넓은 철원 평야에서 논농사를 지으려면 물 공급이 원활해야 하는데, 북한에서는 철원을 빼앗긴 뒤 물귀신 심보로 철원으로 가는 무슨 강의 물줄기를 끊어 버렸다고 한다. 저수지는 그 난관을 극복하게 위해 만들어진 거라 함. 물론 여기는 낚시꾼 내지 철새 사진을 찍으려는 사진 작가들도 많이 찾아온다.

워낙 날씨가 맑고 미세먼지도 없어서 북한 땅까지 어렴풋이 보였다. 다만, 이 지역엔 개성 공단이나 기정동 마을 같은 명물이 없는 관계로, 파주의 도라 전망대만치 북한 쪽에 딱히 볼거리는 별로 없다. 그냥 천혜의 자연만을 감상해야 된다.

사용자 삽입 이미지

지금까지 인터넷 사진으로만 보며 그리워하던 월정리 역 복원 건물을 드디어 직접 보게 되었다. 오오!! ㅠ.ㅠ 감사와 찬양이 절로 흘러나왔다.
난 역 건물을 팔로 꼬옥 끌어안은 채 감격에 잠겼다.

사용자 삽입 이미지

역 구내의 선로에는 두 가지 중요 유물이 있는데, 하나는 코레일 4001호 디젤 기관차이고, 다른 하나는 6·25 전쟁 중에 우리 아군의 폭격을 받고 부서진 어느 증기 기관차이다.
4001호 디젤 기관차는 굉장히 옛날 차량이긴 하지만, 월정리 역과 무슨 관계가 있으며 왜 여기에 전시되었는지 나로서는 알 길이 없다. 거기 현장에서도 딱히 설명이 돼 있지 않다.

현재 임진각에 가 보면, 알다시피 경의선 장단 역에 있던 녹슨 증기 기관차가 녹을 최대한 벗겨 내는 가공을 거친 뒤 전시되어 있다. 그건 총격 때문에 표면이 벌집이 된 것만 빼면 형태가 비교적 온전한 편이며, 그때 그 기관차를 몰던 기관사가 누군지까지도 알려져 있다. 그 기관차는 '마터'라고 불리던 산악 화물용의 굉장한 대형 기관차였다.
그러나 월정리 역 인근에 있는 '경원선' 기관차는 총알이 아니라 포탄이라도 맞았는지 형체를 알아볼 수 없을 정도로 다 으스러져 있다. 이것도 마터 형 기관차인지는 역시 모르겠다.

예전에도 얘기를 한 적이 있나 모르겠는데, 이 세상에 존재하는 모든 증기 기관차는 원래 검정색이다. 붉게 녹이 슨 모습 아니면 옛날의 흑백 사진만 봐 왔기 때문에 상상하기가 쉽지 않을 뿐이다.
뉴욕에 있는 자유의 여신상이 지금은 온통 녹이 슬어서 퍼렇지만, 원래는 그거야말로 갈색이다. 평양에 있는 갈색의 김씨 부자 동상과 비슷한 색이라고 생각하면 이해하기 쉽다.

사용자 삽입 이미지

월정리 역의 바로 옆에는 철원 비무장지대에 서식하는 온갖 동물들을 박제해서 전시해 놓은 자그마한 박물관이 있어서 거기도 잠시 둘러봤다. 동물은 원래 화약 냄새를 잘 맡는 편이지만, 지뢰를 밟아서 다리를 잃은 동물도 있다고 한다.

이렇게 매우 유익한 구경을 한 뒤, 버스는 민통선 안에 있는 옛 철원 역 부지와 몇몇 옛 건물들 흔적을 지나갔다. 딱히 정차하지는 않고 가이드가 설명만 해 줬다. 일제 강점기 내지 북한 정권이 잠시 쓰던 건물 되시겠다.

그 뒤 버스는 처음에 입장할 때 거쳤던 민통선 초소와는 다른 초소에서 민통선 구역을 빠져나갔다. 관광버스가 아니고 민통선 패스를 갖고 있지도 않은 일반인이라면 이건 가능하지 않은 일일 것이다. 일반인이라면 들어갔던 초소에다 신분증을 맡기기 때문에, 반드시 들어갔던 곳으로 다시 나가야 한다. 이 점을 내가 오해한 관계로 추후의 여행 과정에서 약간 착오가 있었다.

전체 관광은 3시간이 약간 넘게 걸렸다. 우리 일행은 고석정 관광 사업소로 돌아왔다. 시각은 1시 40분쯤. 이제 점심을 먹으러 '전선 휴게소'로 떠났다.

사용자 삽입 이미지

전선 휴게소! 휴게소라고 간판은 걸려 있지만, 이곳은 잠깐 거쳐 가는 장소가 아니라 엄연한 목적지, 아니 종점 역할을 하는 식당이나 마찬가지다. 전국에서 유일하게 민통선 안에 있으면서 민통선 밖 민간인들을 상대로도 영업을 하는 식당이다. 식사 메뉴는 메기 민물 매운탕이 유일하며 다른 선택의 여지가 없다. 인근 군부대에서는 회식을 여기서 할지도 모르겠다.

파주 임진각 쪽에서는 민통선 안에 통일촌이라고 불리는 마을이 인근에 있는지라, 안보 관광 때 거기서 식사를 하는 스케줄도 있을 정도이다. 하지만 전선 휴게소는 그런 식으로 연계가 돼 있지는 않다. 위치도 좀 외딴 곳이며 수십· 수백 명의 관광객을 한 번에 상대할 정도까지의 규모도 안 되고 말이다.

왔던 길로 돌아가서 국도 43호선을 탄 뒤, 철원 동쪽에서 북쪽으로 올라가는 지방도 464호선을 갈아탔다. 그 길로 끝까지 가면 길이 더 없이 끊어진 것처럼 나오는 지점이 있는데, 거기가 바로 민통선 초소이다. 통과 허가를 받으려면 최소한 당일 아침에 식당에 전화해서 인원 수를 말하고 식사 주문을 한 뒤, 초소에서는 “전선 휴게소 방문”이라고 얘기해야 한다.

대표자의 이름· 연락처를 적고 신분증을 맡기고, 동승자들의 이름과 생일 정도를 적어서 제출하면 초소에서는 임시 출입증과 차량 식별용 깃발을 준다. 출입증은 운전석 앞유리에다 두고 깃발은 옆유리에다 끼워서 펄럭이게 해야 한다.
참고로 식당은 민통선 초소에서도 거의 3km가 넘게 떨어져 있다. 그리고 철원 북쪽 외곽에서 들판이 아니라 수풀이 우거진 곳이 있다 치면 십중팔구 거긴 지뢰밭이다..

사용자 삽입 이미지

여기서도 텅 빈 내비 화면으로 민통선 진입을 인증하련다. ㅎㅎ

사용자 삽입 이미지

내가 어지간해서는 개인 블로그에다 맛집 광고나 음식 인증샷 같은 건 좀체 안 올리는데.. 여기 민물 매운탕은 정말 별미였다. 한탄강에서 주인장이 직접 잡아서 요리한다는 생선은 살이 입 안에서 살살 녹았으며 곁들어진 수제비와 채소는 담백했다. 국물은 딱 적당히 구수하고 얼큰했으며 너무 맵거나 짜지 않았다.
먼 길을 힘들게 찾아간 보람이 있었다. 같이 간 일행들도 이를 인정하면서 대단히 만족스러워했다.

그리고 전선 휴게소 근처에는 진귀한 구경거리가 하나 있었으니, 그건 바로 금강산선 옛 교량이다.

사용자 삽입 이미지사용자 삽입 이미지

사용자 삽입 이미지
주변 경치도 몸살 날 정도로 아름다웠다. 이런 곳에 인파가 북적거리지도 않고 우리밖에 없으니 분위기가 이보다 더 좋을 수 없었다.

사용자 삽입 이미지
(to be continued)

Posted by 사무엘

2014/05/11 19:34 2014/05/11 19:34
, , , , , , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/961

« Previous : 1 : ... 126 : 127 : 128 : 129 : 130 : 131 : 132 : 133 : 134 : ... 214 : Next »

블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2024/04   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

Site Stats

Total hits:
2667340
Today:
2578
Yesterday:
1937