다윗, 미갈 이야기

1. 다윗의 조약돌

성경에 나오는 다윗과 골리앗의 싸움 장면을 모르시는 분은 없을 것이다.
그런데 하나 같이 좀 생각해 보자. 다윗은 골리앗과 싸우러 나갈 때 왜 조약돌을 5개씩이나 챙겨 갔을까? (삼상 17:40)

“발사한 돌이 빗나가는 경우 / 골리앗이 한 발 만에 안 죽을 경우에 대비해서” 같은 답변은 말이 되지 않는다는 걸 금방 알 수 있다.
필살의 일격 단 한 발로 미간을 명중시켜서 인간 흉기 골리앗을 즉사 내지 최소한 기절이라도 시키지 않으면, 다윗은 곧바로 반격을 당해서 다음 돌은 쏴 보지도 못하고 죽는다. 이 조약돌은 FPS 용어로 치면 일종의 레일건인 것이다. 골리앗은 BFG로 무장해 있었고 말이다. 그러니 한 발 이후로는 의미가 없다.
 
역사적으로 볼 때, 살아서 돌아오지 못할 비장한 각오를 단단히 한 사람들은... 거사를 치르기 전에 일부러 자기에게 주어진 리소스를 딱 자기 여건에 맞춰 제약하는 퍼포먼스를 행하곤 했다. 일종의 배수진이랄까?
 
안 이숙 여사는 왕복이 아닌 편도 배삯만 치르고 일본에 갔으며,
윤 봉길 의사는 폭탄을 던지러 가기 전에 김 구와 손목시계를 교환하여 자기가 더 저렴한 것을 챙겼다.
옛날 백제의 계백 장군은 마지막 전투를 치르기 전에 자기 처자식부터 미리 죽였다..;;
 
다윗도 만약 그런 식으로 비장하게 행동했다면 필생필사의 각오로 돌을 달랑 하나만 챙겨 가는 게 자연스러웠을 것이다.

그러나 그가 그런 스타일로 행동하지 않은 이유는 간단하다. 그는 하나님이 지켜 주시는데 자기는 죽을 일이 절대로 없으며, 골리앗을 무찌르고 멀쩡히 돌아온다고 확신했기 때문이다. 일이 틀어질 가능성 따윈 전혀 고려조차 하지 않은 것이다. 남들이 보기엔 그건 영락없이 '근자감'처럼 보였겠지만 말이다. 그래서 그는 가진 자의 여유마냥 별 생각 없이 평상시처럼 여러 스페어 조약돌을 챙겼다.

아니, 어쩌면 그는 골리앗 정도를 초월하여 아예 이렇게 생각했을 수도 있다.
당장 현실의 목표물인 골리앗을 원 샷 원 킬 하는 건 너무 당연한 소리이고, 혹시 이 돌발상황 결과에 불복하여 예정에 없던 다른 거인들이 또 튀어나와서 시비를 걸면, 그놈들까지 이 조약돌로 잡아야겠다는 준비까지 한 건지도 모른다!
실제로 성경을 보면 거인이 골리앗만 있었던 건 아니며 당장 골리앗에게도 혈육상의 친동생이 있었다고 나오니까 말이다.
 
이 PvP에서 다윗은 골리앗을 PK하고, 골리앗이 갖고 있던 커다란 검을 득템했다. 참고로 사무엘기상 17장을 읽어 보면, 성경은 골리앗을 골리앗이라고 부르는 걸 극도로 기피하면서 의도적으로 '그 블레셋 사람'이라고 에둘러 가리키는 걸 볼 수 있다.

2. 사울의 둘째 딸 미갈

성경에서 사울 왕의 딸이 본격적으로 등장하는 건 다윗이 골리앗을 죽여서 완전 나라를 구한 영웅이 된 뒤부터이다. 영웅이 된 건 좋은데 다윗이 너무 유명해지고 왕보다도 인기가 올라가자, 그는 왕의 눈 밖에 나 버렸다.

이거 뭐 누명을 씌워 죽일 수도 없고.. 왕은 꼼수 차원에서 다윗을 전쟁터에서 죽게 하려고 높은 군사 직위를 주었으며, 자기 딸을 다윗에게 주어 결혼시켰다. 사실, 왕의 사위로 만들어 주겠다는 건 삼상 17:25에서 이미 약속된 사항이기도 했고 말이다.

그런데, 다윗은 자기 같은 가난하고 천한 사람이 감히 왕의 딸과 결혼할 수는 없다고 제안을 고사했다. 이에 왕은 다윗을 또 전쟁터에서 죽게 할 명목으로, 아무 지참금 따위 안 받을 테니 다만 민족의 원수 블레셋 사람 100명을 죽여서 놈들 포피만 가져오면 둘째딸 미갈을 아내로 주겠다고 제안했다.

그러자 다윗은.. 미갈이 마음에 들었는지, 나가서 블레셋 사람 200명의 포피를 갖고 멀쩡히 돌아왔다. 그래서 결혼에 골인했다.
생각을 해 봐. 사랑하는 마누라를 얻으려고 목숨 걸고 전쟁터에서 사람 수백 명을 죽이는 게 어디 쉬운 일이겠는가.

그러나 이렇게 맺어진 결혼 생활은 그리 단란하지 못했으며 오래 못 갔다.

미갈은 거짓말까지 해 가며 다윗의 도피를 도와 줘야 했으며, 별거 모드에 빠졌던 그녀는 훗날 아버지의 명에 의해 '발디/발디엘'라는 다른 남자에게로 강제 재혼을 당했다. (삼상 25:44) 그 동안 다윗은 타지에서 또 아비가일, 아히노암이라는 아내를 두 명이나 추가했고 말이다.

허나 여기에도 반전이 있었으니...
나중에 다윗은 긴 도피 생활을 마치고 왕이 된 후, 발디에게서 미갈을 도로 뺏어 와 버렸다! (삼하 3:14-16)

아무 영문도 모른 채 하루아침에 마누라를.. 그것도 자기 나라 왕에게 빼앗긴 발디는 엉엉 울면서 미갈을 뒤따라 갔는데.. 군대 대장 아브넬의 “그만 꺼져”(성경에는 그냥 Go return이지만..ㅎㅎ) 한 마디에 “넹.. ㅠ.ㅠ” 깨갱 하고 버로우 타 버린 완전 안습한 남자로 성경에 나온다. 성경에서 처지가 제일 처량한 남자가 아닐까 싶다.

이렇게 다윗과 미갈은 재회를 하였으나, 궁극적인 결말은 또 다시 불미스러웠다.
사사 시절 이래로 방치되어 있던 언약궤가 돌아오던 날, 다윗은 왕의 체면도 다 버리고 너무 즐거워서 백성들과 덩실덩실 춤추고 즐겼는데...

미갈은 그때 무슨 생각을 했는지 남편에게 “품위라고는 안드로메다로 보내 버리면서 당신 참 가관이더군요”라는 요지로 비아냥거리면서 굉장한 악담을 퍼부었다.

다윗도 이것만은 영적인 문제인지라 그냥 넘길 수 없었고, 아내에게 굉장히 실망을 한 듯하다. “나를 왕으로 세우신 하나님 앞에서 나는 지금보다 더 어리광 부리고 기꺼이 더 망가질 수도 있소. (그리고 그러더라도 나는 당신이 언급한 그런 천한 여자들보다는 하나님 앞에서 더 대접을 받을 테니 걱정 마쇼.)”

그 뒤로 미갈은 자녀 없이 쓸쓸한 말로를 보내게 되었다고 한다. (삼하 6:23) 그 시절에 유부녀가 자기 자녀가 없는 것은 거의 죄악에 가까운 굉장한 치욕이었다는 점을 생각하자.

이것이 단순히 금슬에 금이 간 것인지, 아니면 하나님께서 생리학적 불임을 만들어 버리신 것인지는 확실치 않다.그러나 인간의 출산을 굉장히 주관적으로 좌지우지하는 성경의 전반적인 심상으로부터 유추했을 때는, 후자일 가능성이 높다.

그리고 이것이 성경에 등장하는 미갈의 마지막 장면이다. 처음엔 다윗이 미갈을 좋아한 게 아니라 미갈이 다윗을 먼저 사랑했다고 나오는데.. 본의가 아니게 시집을 다시 갔다가 돌아온 뒤, 결국 다윗의 여러 아내들 중 랭킹 끄트머리로 밀려나면서 파경으로 갔구나. 인생 한번 참 파란만장했다.

Posted by 사무엘

2014/06/09 08:37 2014/06/09 08:37
, , ,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/972

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

« Previous : 1 : ... 142 : 143 : 144 : 145 : 146 : 147 : 148 : 149 : 150 : ... 230 : Next »

블로그 이미지

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

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2026/08   »
            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 31          

Site Stats

Total hits:
4000787
Today:
963
Yesterday:
6203