타이머 API 이야기

컴퓨터 프로그램이라는 건 원래 처음부터 끝까지 컴퓨터가 그야말로 눈 깜짝할 사이에 전속력으로 실행해 버리는 물건이다. 그러나 컴퓨터에는 정밀한 시간 측정 기능이 있으며, 프로그램이 원하는 경우 자신이 실행되는 주기를 그에 맞춰 인위로 조절할 수 있다.
일명 타이머 기능인데, 이것은 컴퓨터가 액세서리 차원에서 제공하는 부가 기능이 아니라 컴퓨터 자체의 내부 동작 방식의 특성상 컴퓨터가 반드시 갖추고 있는 기능이다. 단적인 예로 난수 생성을 위한 씨앗(= 매번 달라야 하는 초기값)도 내부적으로 재고 있는 시각으로부터 얻을 정도이다.

컴퓨터가 속도가 매우 느리고 자원이 부족하고, 한 프로그램이 컴퓨터의 전체 자원을 독점할 수 있던 옛날에는 매번 타이머를 측정하면서 0.n초가 경과하는 것을 프로그램이 일일이 감시하는 방식으로, 즉 polling 방식으로 동작했겠지만, 지금은 그건 어림도 없는 소리이다. 자기에게 time slice를 주는 운영체제에다가 '알람' 요청을 해서 알람이 왔을 때 동작하게 해야 한다.

Windows에서 이 기능을 사용하는 아주 대표적인 방법은 타이머 API이다. SetTimer, KillTimer와 그 이름도 유명한 WM_TIMER 메시지.
타이머는 그 성격에 따라 게임이나 멀티미디어 재생기 등에서 프레임 간격 유지를 위해 1초에 수십 번씩 돌아가는 (1) 아주 정밀한 놈부터 시작해, 수백 밀리초~수 초 정도의 간격으로 사용하는 (2) 일반적인 타이머, 그리고 드물게는 수 시간~수 일 주기를 갖는 (3) 장기 타이머도 있다. 운영체제의 보급 타이머는 일단은 가성비가 적당히 우수한 '일반적인' 용도에 가장 적합하게 설계돼 있다. 이게 무슨 뜻인지를 설명하면 이렇다.

보급 타이머도 명목상으로는 수십 밀리초 정도의 정밀도를 지원한다. 하지만, WM_TIMER는 WM_PAINT만큼이나 메시지 큐에서 처리 우선순위가 무척 낮은 메시지이기 때문에 컴퓨터가 아주 바쁘고 윈도우 메시지 트래픽이 아주 많을 때는 정밀도가 떨어질 수 있다. 더구나 Windows는 근본적으로 리얼타임 운영체제가 아닌 관계로, 커널의 시간 스케줄링을 초월해서까지 무조건적인 초정밀도는 애초에 보장되지도 않는다. 타이머의 정밀도가 올라갈수록 필요한 시스템 자원과 부하도 더 커질 테니, 초정밀 타이머가 필요하다면 QueryPerformanceCounter나 멀티미디어 타이머 같은 다른 전문 API를 쓰고 동기화도 커널 오브젝트 같은 다른 방법을 써서 해야 한다.

한편, 다른 쪽 극단에 있는 장기 타이머는 응용 프로그램 자체의 동작이라기보다는 업데이트 주기를 체크하거나 사용자에게 적당히 덜 성가신 주기로 뭔가를 알리는 용도로 사용된다. 이 정도면 타이머라기보다는 알람에 더 가깝다.
개인적으로는 지금으로부터 "5000밀리초 간격으로" 같은 것 말고, 절대적인 시각.. 예를 들어 1970년 1월 1일 0시 정각 이래로 40억 5800만 초가 딱 경과했을 때처럼 절대적인 시각을 기준으로 trigger되는 진정한 '알람' 타이머도 필요하다고 생각한다.

시계 프로그램을 만들 때는 이런 타이머 API가 더 유용하지 않겠는가? 그리고 장기 타이머를 사용할 정도의 상황이라면 지금으로부터 시간이 얼마만치 지났는지보다는 매일 몇 시가 됐는지가 더 중요한 경우가 많을 것이기 때문이다.

이렇게 극단적으로 짧은 주기의 타이머나 극단적으로 긴 타이머 말고, 보통 주기의 타이머는 여러가지 용도로 쓰인다. 가령, 키보드는 누르고 있는 동안 키 입력이 하드웨어 차원에서 자동으로 반복 전달되는 반면 마우스는 그런 게 없는데, 마우스를 누르고 있는 동안 자동 스크롤이 되는 것은 타이머로 처리가 가능하다. 그리고 간단한 비동기적인 처리를 위해서도 타이머가 약방의 감초처럼 쓰인다.

이게 도스의 제약인지 아니면 인텔 x86 CPU 차원의 제약인지 구체적인 내역은 기억이 안 나지만, 도스 시절에는 컴퓨터의 타이머 해상도가 1/18.2초여서 최소 주기가 약 55밀리초였던 것 같다. Windows 9x 시절에만 해도 운영체제의 타이머의 정밀도는 그 정도였다고 MSDN에 기록돼 있었는데 NT 계열은 하드웨어를 또 어떻게 튜닝했는지 타이머가 그것보다 훨씬 더 정밀해졌다.

자, 그럼 이 글에서는 Windows의 일반 타이머 API에 대해서 더 자세히 알아보자.
SetTimer 함수의 인자로는 타이머의 발동 주기뿐만 아니라 (1) 타이머를 메시지로 받을지 아니면 함수 호출로 받을지, (2) 그리고 메시지로 받는 경우 동일 메시지에서 이 타이머만을 식별할 번호를 지정하면 된다. SetTimer 함수는 사용하는 방법이 생각보다 좀 복잡하다.

(1) SetTimer에다가 뭔가 윈도우 핸들을 전해 주는 경우, 타이머는 메시지로 받을 수도 있고 콜백 함수로 받을 수도 있다. 두 가지 선택의 여지가 있으며, 타이머 식별 번호는 우리가 임의의 자연수로 일괄 지정해 줄 수도 있다.
(2) 그 반면 윈도우 핸들이 없이, 윈도우를 전혀 생성하지 않고도 타이머를 사용할 수 있다. 그 대신 이때는 몇 가지 제약이 따른다. 메시지가 아닌 콜백 함수로만 통지를 받을 수 있으며, 타이머 식별자는 우리가 지정할 수 없다. SetTimer 함수가 되돌린 값을 별도의 변수에다 보관하고 있어야 한다.

마치 에디팅 엔진의 기능만을 따로 떼어서 windowless 리치 에디트 컨트롤이 존재하는 것처럼 타이머도 windowless 타이머가 존재하는 셈이다. 물론 SetTimer가 무슨 스레드를 만들기라도 해서 따로 돌아가는 건 아니기 때문에, 비록 windowless 타이머를 사용한다 하더라도 메시지 loop은 돌리고 있어야 타이머가 동작할 수 있다.

개인적으로는 (1)과 (2)의 특징을 취합하는 방법이 없는 게 아쉽다. 윈도우 핸들을 지정해 줘서 WM_TIMER 메시지를 받는데 타이머 식별자는 내가 일괄 지정한 게 아니라 운영체제가 기존 타이머들과의 충돌을 피해서 동적으로 배당한 값이 오는 형태 말이다.
서브클래싱 내지 후킹을 한 윈도우에 대해서 타이머를 걸 때는 하드코딩된 타이머 ID를 써서는 안 된다. 원래의 윈도우 프로시저가 사용하는 고정 타이머 ID와 충돌을 일으킬 수 있기 때문이다. 마치 윈도우 메시지가 서로 충돌하는 것처럼 말이다.
이때는 충돌이 없음이 보장되는 windowless 타이머를 써야 한다. 하지만 windowless 타이머는 다음과 같은 이유로 인해 사용이 불편하다.

첫째, 콜백 함수에 user data를 넘겨 주는 추가 인자가 없다. 그래서 user data는 전역 변수나 TLS 값 같은 불편한 방법으로 얻어 와야 한다.
둘째, 윈도우가 붙은 타이머는 같은 ID값으로 타이머를 지정하는 경우, 기존 타이머가 새 타이머로 자동으로 대체된다. 그러나 windowless 타이머는 그런 기능이 없기 때문에 기존 ID에 대해서 KillTimer를 하고 다시 SetTimer를 해서 새 ID를 얻는 작업을 수동으로 해 줘야 한다. 다시 말해 기존 타이머의 재지정이 어렵다.

결국, 충돌을 피하기 위해서는 windowless 타이머를 써야 하는데 이 타이머도 윈도우가 붙은 타이머하고 비슷하게 동작하도록 추가 군더더기 기능을 구현한 클래스를 만든 뒤에야 그럭저럭 쓸 만하게 됐다.
윈도우가 있는 타이머와 없는 타이머에서 서로 필요한 기능을 취합하는 방법이 없어서 불편하다는 걸 다시 한 번 확인할 수 있었다.

그나저나 SetTimer 함수에서 ID를 받는 부분은 포인터나 핸들을 넘기는 용례가 없는데 자료형이 왜 UINT가 아닌 UINT_PTR로 잡혀 있는지 이것도 개인적으로는 의문이다.

Posted by 사무엘

2015/08/09 08:21 2015/08/09 08:21
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1125

1. 우리말에서 "교장 선생님 말씀이 계시겠습니다"는 높임법이 잘못 적용된 비문이다. 그러나 성경에서 "처음에 말씀이 계셨느니라"(요 1:1)는 높임법이 아주 적절하게 쓰인 문장이다.
사실, '말씀'이나 '지옥' 같은 단어는 성경 용어로서 어쩌면 영어 단어보다도 잘 번역되고 잘 만들어진 단어이다. 성경 번역 같은 데서 영어에 비해 한국어의 어휘와 문법의 한계가 많은 편이지만, 그래도 한국어가 오로지 약점밖에 없는 건 또 아니다.

2. 여느 관광 여행이나 맛집 방문 같은 것이야 당연히 백문이 불여일견이며, 직접 가서 겪어 보고 체험하는 것이 더 낫다. 그런데 글을 통한 간접 체험이 당대의 직접 체험보다 더 확실하고 더 낫다고 보증이 돼 있는 유일한 예외가 있다. 무엇일까? (힌트: 벧후 1:19, 요 20:29)

3. 세상의 다른 고전 문헌이나 골동품은 아무래도 제일 오래 된 필사본이 원문, original에 가장 근접해 있을 거라고 여겨진다. 그렇기 때문에 그런 것들은 나이가 깡패이다.
그러나 이 책만은 애초에 오래 된 필사본 같은 건 닳아 없어지고 남아 있질 않으며, 반대로 최근까지도 잡초처럼 많이 필사되어 읽히고 내용이 일치하는 것으로 교차 검증된 집단이 진본이다. 어렵게 생각할 것 없다.

4. 세상의 다른 모든 텍스트들은 원어가 당연히 원저자의 의도에 가장 근접해 있고 가치가 가장 높다. 그래서 예전에 일본어 중역이던 텍스트가 나중에 직통 번역으로 재출간되고, 그 분야 전문가는 아예 원어를 공부해서 원문을 다시 구해다 읽는다.
그러나 이 책만은 번역본이 원어 원문에 꿀릴 게 없으며, 오히려 다른 n차 파생 번역본을 모두 판단하는 절대 기준이 되는 번역본을 보유하고 있다. 이건 무엇일까?

1과 2, 그리고 3만 해도 불신자의 통념을 한참 거스르며 상식을 벗어난 논리이다. 기독교는 원래 그런 종교이다.
그러나 반대로 1~3을 일단 믿는 사람이라면 4를 믿지 못할 이유는 추호도 없다고 여겨진다. 논리적으로 그렇지 않은가? 안타깝게도 안 그러시는 분도 있지만, 그분의 양심과 믿음이 그러려니 하고 넘길 수밖에.
이것 말고 다른 분야에서도 1~9를 다 믿으면 10도 당연히 믿지 못할 이유가 없는데 도대체 왜 저러시나, 딱히 충분히 대안이 될 만한 논리 체계가 있는 것도 아닌데 싶은 게 있다.

아무리 상수도관에서 깨끗한 물이 만들어져도 가정의 수도관이 더러우면 최종 소비자는 더러운 물을 받을 수밖에 없다. 4는 앞의 다른 명제들을 성립 가능하게 하는 전제조건이라 해도 과언이 아닐 것이다.
그럼 다음으로, 이 4에 대한 보충 설명 차원에서 성경을 구성하는 언어 계층에 대해서 살펴보자.

1. 원어
성경의 '원문'이 기록된 언어이다. 구약은 히브리어(다니엘서 같은 일부는 아람 어라 함), 신약은 그리스어(헬라· 희랍은 그리스와 동의어).
그럼 원어로 원문만 읽으면 끝이고 성경의 내용 전수에 아무 문제가 없을 거라고 생각하기 쉽다. 그러나 현실에서 다음과 같은 이유로 인해 문제가 그렇게 간단하지가 않다.

(1) 오늘날 성경의 최초 자필 원본은 어디에도 남아 있지 않다.
또한 그 어떤 성경 필사본도 단일 필사본에 성경 66권이 온전히 집대성돼 있지 않다. 즉, 이것들은 partial이다. 내용 자체가 변개된 필사본이 있긴 하지만, 변개되지 않은 계열의 필사본이라 해도 결국은 빠짐없이 모아서 짜깁는 과정이 필요하다.

(2) 성경이 기록되던 당시에는 이들 언어가 인지도와 중요성이 있었지만, 지금은 그 원어가 사어가 돼 있다.
여느 언어들이 그렇듯이 원어의 어휘 역시, 같은 단어라도 문맥에 따라 뜻이 달라지는 것들이 굉장히 많다. 이 단어가 여기서는 무슨 뜻인지 분별해 줄 수 있는 절대무오한 권위자 역시 오늘날 존재하지 않는다. 오늘날 사도의 표적이 없는 것만큼이나 존재하지 않는다. 인간이 만든 사전· 어휘집도 100% 믿을 게 못 된다. 그러니 원어 원문만 있다고 해서 장땡이 아닌 거다. 환상을 깨시라.

2. 영어
오늘날 원어 원문이 갖고 있는 위의 문제들을 모두 해결하여 원어(영어) 원문(KJV) 차원의 지위를 가진 절대기준이다. 솔까말 기독교는 논리로만 따지면 권위에 호소하는 오류(?)가 있는 종교인데, 그 원천적인 권위가 무엇인지 정도는 인류 역사를 주관하는 하나님께서 보장을 해 주셔야 하지 않겠는가? 그래야만 그 체계 하에서 최소한의 '논리'와 일관성을 갖추지 않겠는가. 원어 원문 문제를 해결하기 위해서 배교한 불신자 신학자들의 말장난에 의존하지 않아도 되게 말이다.

원어가 불필요하다거나 무의미하다는 게 아니다. 단지 성경의 이 구절에서 이 원어를 어떻게 해석하는 게 맞는지 모르겠으면 KJV의 번역을 보면 된다. 요일 2:23 후반부가 원래 필사본에 있는지 없는지 궁금하면 KJV 구절을 보면 된다는 얘기다. 원어 원문조차도 KJV로 판단 가능하다. KJV는 단순히 가장 뛰어난 번역, 우수한 번역 차원이 아닌 것이다. 관점이 완전히 다르다. 이런 번역본 KJV에 하나님의 영감이 있는 걸까 없는 걸까? 판단은 여러분이.

KJV를 최종 권위로 믿고 안 믿고를 떠나서 신자라면 가슴에 손을 얹고 양심적으로 생각을 해 보시라. 기독교라면 저런 절대 기준이 상식적으로 있어야 하지 않겠는가? 우리가 믿는 건전한 하나님이라면 언어 접근성으로 사람 차별을 하지 않으시며, 그런 것쯤은 보장해 주셨을 것 같지 않은가?

지옥에 대해 경고를 하기 위해 굳이 죽었다가 살아난 사람을 보내서 증언시킬 필요가 없듯(눅 16:27-31),
원어가 무슨 뜻인지 파악하기 위해서 하나님께서 현대인들을 위해 굳이 그 시절의 원어 토박이를 무덤에서 끄집어내어 보내실 필요가 없다. 킹 제임스 성경이 있기 때문이다.
또한, 예수님께서 "나를 본 자는 이미 아버지를 보았거늘"(요 14:9)라고 책망했듯이, 킹 제임스 성경을 읽은 사람은 이미 원어 성경을 읽은 것이나 마찬가지이다. 그런 관계인 것이다. 이런 식으로 성경 언어의 관계는 성경의 여러 비유들을 통해 설명할 수 있다.

3. 자국어
절대 기준인 영어 KJV를 바탕으로 건전한 교리관을 갖춘 양심적인 번역자가, KJV의 표현을 그대로(가령, '유월절' 대신 '이스터', '기뻐하라' 대신 '잘 있으라', 요일 5:6-7도 온전히 갖추고 등) 자국어로 일관성 있는 스타일로 번역할 수 있다. 그 성경은 교회에서 예배를 드리고 복음 전하고 신앙 서적을 만드는 용도로 쓰일 수 있다. 이것은 "신들과 같이", "절대무오한"은 못 되더라도 노아나 욥이 "완전했던" 것과 같은 완성도를 갖췄다.

해당 자국어의 특성을 이용해서 번역을 아주 적절하게 할 수도 있지만(하나님, 말씀, 지옥 등), 어휘와 문법 체계의 특성상, 그리고 해당 언어권의 문화· 관습의 한계로 인해 KJV 특유의 도치나 중의성, 운율, 미묘한 문법 요소들을 다 담지 못할 수도 있다. 그건 해당 언어나 번역자의 자질 문제가 아니다. 성경 강사가 영어 KJV를 참고하여 보충 설명을 해 주면 된다. 마치 데나리온이라는 화폐 단위가 요즘 물가로 얼마 정도라고 얘기하듯이. 오늘날 영어의 지위를 생각하자면 히브리어, 그리스어를 꺼내는 것보다야 상황이 훨씬 더 나아진 것이다.

(그럼 원어에서 영어로 번역될 때는 원어의 모든 뉘앙스가 고스란히 옮겨지는 게 가능했느냐 하는 반문이 있을 수 있다. 이에 대해서는 언어학적인 팩트 답변도 있고, 그것만으로 좀 확신이 안 서서 믿음의 영역으로 그냥 받아들이고 넘겨야 하는 면모도 있다. 이 글에서는 이 정도까지만 얘기하도록 하겠다.)

다만, 각 언어마다 최종 권위가 제각각 또 있는 건 아니다. 그건 최종 권위라는 게 무슨 뜻인지 파악을 못 한 말도 안 되는 소리다. 단지 모든 언어적인 혼란을 일축하는 중심점에 영어 KJV가 있다는 것이 KJV 유일주의 신자의 믿음이다.

'영킹 유일주의자', '이중 영감론자' 등의 누명 내지 딱지에 전혀 움츠러들 필요가 없다. 그럼 그들이 미는 대안은 뭔데? '원어 원문 유일주의자'이건 '영어 숭배자'건 '자국어 만능주의자'이건, 어느 편에 서더라도 그에 대한 멸칭은 얼마든지 지어낼 수 있다. 무엇을 선택하든지 결국은 뭔가를 신념으로 믿는다는 점에서는 똑같다. 마치 무신론도 유신론만큼이나 동일하게 신념이고 신앙인 것처럼 말이다.

그럼 우리는 무엇을 믿어야겠는가? 원어 원문은 앞서 말했듯이 실체가 없으며, 반대로 자국어 최종 권위 운운은 당장 생각해 봐도 말도 안 되는 소리이다. 그러느니 차라리 영어 중심이 가장 현실성 있고 균형 잡혔으며, 실제로 KJV의 출간 이래로 지난 400여 년간 역사적인 증거와 열매도 넘치는 건전한 관점이다. 애초에 예수천당 불신지옥 같은 과격하고 극단적인 교리를 믿는 신자가, 한 성경 역본만이 절대적으로 옳고 이와 일치하지 않는 역본은 틀렸다고 믿지 못할 이유는 단언하건대 절대로 없다.

Posted by 사무엘

2015/08/06 08:31 2015/08/06 08:31
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1124

Windows의 역사 회상

1. 공용 대화상자

먼 옛날, Windows 3.0은 최초로 VGA를 지원하고 팔레트 API, 장치 독립 비트맵, MDI 관련 API가 추가되고, RTF 기반 winhelp 도움말이 추가되고, 버튼이 3D 회색으로 바뀌고 시스템 글꼴까지 가변폭으로 바뀌는 등 장족의 발전을 이뤘다. (386 확장 모드는 2.1때 미리 도입됐다고 하니 그건 논외로 하더라도)
그런데, 3.0에 없다가 3.1에서 새로 추가된 기능들도 만만찮았다. 트루타입 글꼴과 OLE야 워낙 잘 알려진 3.1의 신규 기능이다만.. 이것 말고도 오늘날 당연하게 여겨지고 있는 '공용 대화상자' 컬렉션들이 역시 3.1에서 처음 도입되었다.

3.1 이전에는 GetOpenFileName 함수가 Windows API에 없었다는 뜻이다. 파일 열기/저장 대화상자는 응용 프로그램들이 전부 직접 따로 구현해야 했다. MS Office 제품들이 한동안 독자적인 파일 열기/저장 대화상자를 갖추고 있었던 건 운영체제도 Windows 3.1 이전까지는 어차피 해당 기능을 제공하지 않았기 때문이지 싶다. Word, Excel은 이미 1980년대부터 개발되었던 프로그램이니까.
그리고 파일 대화상자뿐만 아니라 색깔 선택, 텍스트 검색, 인쇄 같은 잘 알려진 공용 대화상자들도 3.1에서 처음으로 도입됐다.

옛날 도스 시절에 TUI 내지 GUI를 직접 구현하면서 파일 열기/저장 대화상자도 손수 만들어 본 프로그래머라면 공용 대화상자가 얼마나 혁신적인 물건인지 이해가 될 것이다.
그리고 내 생각엔 아마 ShellAbout 함수도 3.1에 와서야 용례가 완전히 정립되지 않았나 싶다. 3.0 때는 응용 프로그램별로 About 대화상자도 서로 다르게 생긴 경우가 있었기 때문이다.

공용 대화상자에 이어 리스트/트리 컨트롤 같은 추가적인 "공용 컨트롤"은 Windows 3.1보다 한 박자 뒤인 Windows 95 내지 NT 3.51과 함께 도입됐다.
물론 일반 사용자에게 와 닿는 Windows 3.0과 3.1의 큰 차이는 저런 기술적인 요소가 아니라... 보조 프로그램으로 리버시(오델로 게임)가 짤리고 그 이름도 유명한 '지뢰찾기'가 대신 도입된 게 아닌가 싶다.

2. 9x와 NT가 따로 놀던 API

과거에 Windows 95와 NT가 공존하던 시절에는 일반적으로 95의 API는 NT의 API에 부분집합으로서 완전히 포함되는 것으로 여겨졌다. 보안이나 유니코드, 일부 고급 기능들이 빠져 있을 뿐, 공통 기능은 동일한 형태로 사용 가능하다는 것이다.
하지만 일부 기능은 95에도 전혀 없는 건 아닌데 NT와는 완전히 다른 형태로 따로 구현되어 API가 파편화되고, 이 때문에 프로그래머들 사이에서 번거로움으로 인해 악명을 떨치기도 했다. 그만큼 Windows 95팀과 NT 팀이 마치 MFC 팀과 Office 팀(리본 UI), Windows 팀과 Visual C++ 팀(CRT DLL)만큼이나 생각만치 교류가 없었다는 뜻이다. 이거 무슨 일본군 육군과 해군도 아니고.

그런 기능으로 무엇이 있느냐 하면 첫째는 사용 중인 파일을 다음 재부팅 때 지우도록 예약하는 기능이요, 둘째는 실행 중인 프로세스와 모듈들을 조회하고 heap 메모리 상태를 조회하는 기능이다.
전자는 NT에서는 MoveFileEx 함수를 쓰면 됐지만 95에서는 그 함수가 지원되지 않았다. 95에서는 wininit.ini라는 살생부 리스트를 수동으로 건드려 줘야 했는데, 이게 처리가 Windows가 아닌 도스 계층에서 행해지는지라 긴 파일 이름을 쓸 수 없어서 더욱 불편했다.

다음 후자의 경우, NT는 커널 API의 연장선 차원에서 EnumProcesses, EnumProcessModules, HeapLock, HeapWalk 같은 함수가 제공되었다. 카테고리의 명칭은 Process status API (PSAPI)라고 불렸다.
그러나 95는 Tool Helper라는 특수한 디버그용 라이브러리 개념으로 CreateToolhelp32Snapshot 이후 [Heap/Module/Process/Thread]32[First/Next] 이런 식으로 함수를 제공했다. 함수를 초기화하고 사용하는 방법이 서로 완전히 딴판이라는 얘기다.

공교롭게도 이 두 기능은 모두 설치/제거 프로그램을 만들 때 필요한 기능이다. "이 DLL은 다음 프로그램이 사용하고 있습니다. 다음 재부팅 때 제거하시겠습니까?"를 구현하려면 말이다. Windows Installer 런타임은 당연히 9x용과 NT용이 이런 점을 감안하여 제각각 구현되어 있었을 것이다.
결국 Windows 2000에 가서야 지금까지 9x에만 있던 tool help library를 NT 계열이 마저 흡수하는 걸로 문제가 종결되었다. 마치 95에서 첫 도입되었던 Plug & play를 드디어 2000이 수용했듯이 말이다. 게다가 궁극적으로는 9x 계열 자체가 없어지기도 했고.

3. 그래픽과 사운드 성능 향상

1990년대 중후반에서 2000년대 초반에 이르기까지 컴퓨터의 성능이 향상됨으로써 Windows에 생긴 3대 변화를 들자면 난 다음을 꼽는다. 예전에 한 번씩은 다 언급한 적이 있었을 것이다.

(1) 화면이 막 고쳐지는 곳으로 마우스 포인터를 가져가도 깜빡임이 없게 되었다. 그래픽 카드가 마우스 포인터 주변은 건드리지 않게 하드웨어적인 처리를 진작부터 하기 시작했기 때문이다. 이것은 요즘 형광등이 깜빡임 없이 바로 켜지기 시작한 것만큼이나 신기한 일이다.

초창기에는 흑백의 기본 포인터만 처리가 되지, 컬러 내지 심지어 애니메이션이 있는 custom 포인터, 그리고 마우스 포인터 자취까지는 차마 깜빡임 방지 처리를 다 못 했다. 그러나 이것도 2000년대부터는 제약이 없어졌다.
Windows 2000은 아예 안전 모드에서 16컬러 VGA로 동작할 때에도 마우스 포인터의 깜빡임이 없는 게 무척 신기하다. NT가 원래 그랬는지 아니면 2000부터 그렇게 된 건지는 모르겠다.

(2) 멀티웨이브가 되기 시작한 것도 아주 신기한 일이다. 지금으로서는 도저히 믿을 수 없는 일이지만 Windows에 사운드/멀티미디어 지원이 처음으로 도입됐던 3.1/95 초창기에는 한 번에 한 프로그램만 사운드 카드의 사용이 가능했다. 그리고 다른 프로그램은 사운드를 이용할 수 없었다! PC에 사운드 카드가 버젓이 달려 있음에도 불구하고 사운드 초기화가 실패하는 상황에 대한 대비를 해야 했던 것이다.

9x 시절에는 일부 고급형 사운드 카드만이 멀티웨이브가 가능했다가 2000부터는 드디어 그냥 아무데서나 멀티웨이브가 가능해졌다. 이쯤에서 미디 역시 노래방 수준의 소프트웨어 신시사이저로 대체되었고 XP쯤부터는 오디오 CD까지 모든 사운드의 음원이 waveform으로 통합되었으며, Vista부터는 장치가 아닌 스피커/응용 프로그램별로 구분해서 볼륨을 지정하는 게 가능해졌다.

오늘날도 PC에 따라서는 출력 단자에 헤드폰/스피커 같은 게 전혀 연결돼 있지 않으면 사운드의 초기화가 실패하는 경우가 있다. 물론 PC 자체에 스피커가 달려 있는 노트북 PC에서는 해당사항이 없는 얘기. 옛날에도 입력 단자를 감지해서 녹음 버튼의 성공/실패를 감지하는 것 정도는 가능했던 것 같다.

(3) 그리고 제일 늦게 생겼고 Windows Vista가 이뤄낸 쾌거 중 하나는 역시 동영상 장면도 Print screen으로 간단히 캡처가 가능해졌다는 점이다. 창을 움직였는데 동영상 영역은 제대로 움직이지 않는다거나, 화면 캡처를 하면 그냥 컬러 키를 나타내는 이상한 단색만 캡처된다거나.. 이런 것도 이미 10년쯤 전부터 옛날 추억이 됐다.
기술적으로 따지고 보면 동영상만 추가적인 하드웨어 가속을 받는 게 아니라 아예 모든 그래픽이 동등하게 하드웨어 가속을 받기 시작했기 때문이다. GDI조차도 그 위에서 돌아가니까 BitBlt 같은 GDI API로 간단하게 캡처가 되기 시작한 것이다. 게다가 Vista가 처음으로 선보인 flip3d나 live preview에도 동영상이 실시간으로 표시되기 시작했다.

4. Windows 10

그리고 그 Windows 95가 출시된 지 거의 20년이 지난 지금, Windows 10이 출시되었다. 95 출시 당시에 중학생이던 본인은 뭐 이미 30대 중반의 성인이 됐고.
2015년에 마소 소프트웨어의 최대의 이슈는 단연 새 운영체제와 새 개발툴이다. Windows 10과 Visual Studio 2015.

IE가 11에서 종결되고 Edge로 넘어가는 것만큼이나 마소에서는 Windows 10이 독립된 브랜드 형태로는 Windows의 마지막 버전이 될 것이고 그 뒤로는 그때 그때 인터넷 업데이트만으로 유지보수를 할 것이라고 밝혔댄다.. 그 정책이 실제로 언제까지나 유지될지는 모르겠다.

하긴, 매번 XP, Vista 같은 브랜드명에다 숫자에다.. 이런 발상 자체가 식상해지고 아이디어가 고갈될 때도 되긴 했다.
허나 과거에 마소 내부에서는 IE 팀이 Windows 팀으로 합병될 뻔한 적도 있었고, 또 이미 윈도 7 시절부터 이건 NT 커널 기반 Windows의 마지막 버전이고 그 뒤로는 Midori던가 뭐던가 완전히 새로운 기반의 운영체제가 나온다는 식의 설레발도 나돌았다. 트렌드라는 건 언제든지 얼마든지 바뀔 수 있는 것이니 변화를 신중하게 지켜봐야겠다.

그래도 마소에서 이번 Windows 10을 뭔가 완결판이라는 컨셉을 두고 만들었다는 티가 벌써부터 팍팍 느껴진다.
외형이 8하고 별 차이가 없는 줄 알았는데, 프로그램의 제목이 가운데 정렬이던 것이 다시 왼쪽으로 복귀한 건 좀 사소한 점일 테고. ㅋㅋ
그리고 운영체제의 버전뿐만 아니라 커널의 내부 버전 번호도 Vista 이래로 지금까지 6이던 것이 7~9를 건너뛰고 10으로 맞춰졌다.
Windows 10이 저런다고 하니까 마치 Mac OS X 같은 느낌도 든다. 저 X도 10을 나타내니까.. 인터넷을 뒤져 보니 당연히 나만 그렇게 생각한 게 아니었다.

한편, Visual Studio의 경우, 2012 이래로 외형 색상의 변화는 크게 없다. 그럼 그렇지, 매 버전마다 비주얼을 다 뒤집어 엎는 것도 언제까지나 가능한 건 아니겠지 싶었다. ^^ 2013 커뮤니티 에디션이 나온 것부터가 굉장히 놀라웠는데, 갈수록 개방적으로 바뀌는 한편으로 이클립스 내지 xcode의 전통적인 영역까지 넘보고 있다.
운영체제, 브라우저, 개발툴에서 모두 마소가 종전의 소프트웨어 개발 방식 내지 패러다임을 종결하고 단절하겠다는 의지를 표현한 듯하다. 확실히 변해야만 살아남을 수 있다.

Posted by 사무엘

2015/08/03 19:38 2015/08/03 19:38
, , ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1123

다음 버전 개발 근황 약간

요즘 날씨는.. 최악의 불볕과 최악의 찜통은 별개 개념이라는 걸 온몸으로 입증해 보이는 듯하다. 미치겠다.;;
이렇게 이번 여름방학도 벌써 절반이 넘게 지났고 <날개셋> 한글 입력기 8.0이 나온 지도 역시 한 달이 좀 넘었다. 그 동안 서적 번역 등 다른 일에 관심이 쏠려 있어서 방학 전반부 동안은 사소한 이슈 말고 굵직한 기능을 설계하고 구현하는 코딩은 거의 못 하고 지냈다.

그래도 지금까지 지켜본 바로는 8.0은 별다른 새로운 버그 없이 높은 완성도로 잘 만들어졌다. 이 프로그램도 가까운 미래에는 꿈에도 그리던 전체 신규 기능 개발 완료와 고정· 정착 단계에 진입하는 게 아주 요원한 꿈은 아닐 것 같다.
국민 교육 헌장을 보면 "안으로 자주독립의 자세를 확립하고, 밖으로 인류 공영에 이바지할 때"라고 나와 있는데, 실상은 "안으로는 약 빨고 밖으로는 외계인 고문을 일삼으면서" 결과물을 내야 할 거 같다.

본인은 석사를 졸업한 지 이제 3년이 지났다.
석사 논문은 아시다시피 저 입력기의 이론적 배경과 구조, 주요 기능이 주제였다. 지금 동일 주제로 논문을 다시 쓰면 그때보다 수십까지는 아니어도 10수 페이지 정도는 더 써 넣을 분량이 있다.

가령, 다음 글자로 넘어갔을 때도 초성이 아니라 변함없이 종성 문맥으로 동작하는 '종성 지향 두벌식'은 6.7 버전에서 첫 도입되었으며 <날개셋> 한글 입력기의 역사에서 무척 중요한 위치를 차지하는 기능이지만, 논문이 다 완성되고 졸업하자마자 그 직후에야 추가된 기능이다. 그러니 논문엔 못 들어갔다.

7.9와 8.0대에서는 종성 지향 두벌식의 정반대 이념이며 두벌식 연구자의 떡밥이던 '초성 지향 두벌식'까지 추가되었다. '살 → 사라'가 아니라 반대로 '사ㄹ → 살ㅈ' 이런 식으로 되는 입력 방식 말이다.
전자는 별도의 날개셋문자 타입으로 구현된 반면, 후자는 '고급 입력기'가 제공하는 낱자 치환 옵션의 일환으로 구현되었다. 기술 계층이 서로 완전히 다른 것이다.

또한 그때 이후로 키보드 입력이라는 물리적인 프로세스 자체에 대한 기술적 이해도가 더 깊어진 덕분에, 키 입력을 흉내 내는 기능이 독립된 날개셋문자 타입으로 추가되었다. 최근에는 입력 패드 구현체가 그런 키보드 입력이 드디어 지원되기 시작한 쾌거도 이뤘다.
이런 것들이 논문에 더 들어갈 수가 있었다는 뜻이다. 박사 졸업 이수 요건에 속하는 학술지 소논문에 이런 걸 적절히 투고할 방법이 있으면 좋겠다. 엄연히 국어 정보학과 관련된 개인적인 연구 실적이니까.

  1. 한글의 고유한 특성과 활용 가능성: 한글은 IME가 필요한 복잡한 스케일의 문자이지만 중국· 일본어처럼 문장 단위가 아니라 1글자 단위로만 조합을 잡으면 된다. 이렇게 한글 같은 문자만이 처해 있는 특수한 상황에서 IME만이 제공할 수 있는 여러 편의 기능이 있을 것이다.
  2. 세벌식의 우수성: 두벌식은 자음 종류 구분과 음절 경계 구분을 위한 온갖 테크닉이 필요하다. 그러나 세벌식은 그게 기본적으로 되기 때문에 타자기나 두벌식에서는 불가능한 다른 응용 기능을 언어 의존적인 데이터 없이 바로 구현할 수 있다. PC에서 세벌식 입력 방식이 없다는 건 말이 안 된다.
  3. 이 시스템의 엔진의 독창성: 한글 입력 방식을 규정하는 모든 세부적인 동작을 customize할 수 있으며, 그 과정에서 두-세벌의 중간에 속하는 입력 방식도 구현 가능하다.
  4. 이 시스템의 구현체의 독창성: 이 엔진을 편집기, IME, 입력 패드라는 다양한 기술적인 구현체를 통해 제공한다.

지금 논문을 다시 쓴다면 내가 주장하고자 하는 바를 위와 같은 네 카테고리로 더 분명하게 구분해서 깔끔하게 결론이나 초록을 썼지 싶다. 뭐 그건 이미 다 지난 일이고...
난 다음 박사 논문을 위해서는 "한글의 고유한 특성과 활용 가능성"이라는 기본 명제는 동일하지만, 입력이 아닌 출력에 속하는 한글 글꼴과 관련된 연구를 할 생각이다. 그러니 입력기는 빨리 마무리를 좀 지어야 한다.

논문 얘기가 너무 길어졌는데, 어쨌든 <날개셋> 한글 입력기의 다음 버전에서 만날 수 있는 사소한 변화들을 늘어놓으면 다음과 같다.

1. 이제는 프로그램을 설치할 때, 원하는 구현체만 선택해서 설치할 수 있게 했다.

사용자 삽입 이미지

세 구현체들의 특징은 다음과 같이 표로 일목요연하게 정리된다.

항목 편집기 외부 모듈 입력 패드
형태 EXE (32/64비트 하나만) DLL (32/64비트 모두) EXE+DLL (각각 32/64비트 모두)
도스용 프로그램에 비유 자체한글 에디터 한글 바이오스 (입력 부분만) 램 상주 키보드 인터럽트 유틸리티
기능 지원 범위 오로지 자기 내부 자기를 사용하는 타 프로그램 내부 실행 중인 모든 프로그램들
TSF A급 O △ (동작 환경에 따라 다름) X
Alt 지원 O X O
특이사항 자체 옛한글 글꼴, 텍스트 필터, 키 입력으로 붙여넣기. 성능 오버헤드가 가장 작음 명령 프롬프트 및 Metro UI에서 유일하게 동작 가능 구현체들 중 크기가 가장 작고 가벼움. 키보드 모드는 옵션으로 제공


2. 웹 브라우저 같은 외부 프로그램의 텍스트를 <날개셋> 편집기의 빈 문서 창에다가 drag & drop을 하고 나면 가끔 편집기의 프레임이 고전 테마 형태의 이상한 모양으로 일시적으로 바뀌는 문제가 있었다. 개인적으로는 운영체제의 버그에 가깝다고 생각하는 현상이지만 Windows Vista부터 8.1까지 일관되게 발생하는 현상이고, 또 문제를 회피하는 방법도 있으므로 그걸 적용했다.

사용자 삽입 이미지

3. 도움말에서 "외부 모듈 → 알려진 버그" 부분에, 키보드 보안 프로그램으로 인한 오동작 가능성을 더 자세히 언급했다. 이런 문제가 있을 수 있는 프로그램은 크게 "IE 브라우저"뿐만 아니라 요즘은 "온라인 게임"이 더 중요하다. IME도 나름 키보드 입력을 가로채는 프로그램이다 보니, 디지털 서명이 없는 날개셋 같은 프로그램을 여타 보안 프로그램이 차단할 수도 있다.
5년 전에 스타크래프트 2가 출시 직후에 이와 관련된 대표적인 문제를 일으켰었는데, 앞으로 다른 게임에서 이런 부류의 문제가 계속 보고될 수도 있다.

4.
얼마 전, 인디자인 9에서 한글 입력과 관련된 귀찮은 문제가 출판 디자인 업계에서 거론된 적이 있었다. 한글 조합 중에 space, tab 등의 글쇠를 누르면 원래는 한글 조합도 중단되고 해당 글쇠 문자도 뒤에 입력이 돼야 한다. 그런데 인디자인은 이때 조합만 중단되고 해당 글쇠는 씹히기 시작했다. 그것도 예전엔 안 그러다가 최신 버전에서 갑자기 그러기 시작했다. space/tab이 아니라 IME가 인위적으로 처리를 하는 비한글 문자는 씹히는 문제가 없었다(세벌식 자판의 숫자처럼).

그런데 이와 비슷한 문제가 MS Word에서도 부분적으로 발생한다는 것이 최근 확인되었다. "고급 입력기"가 제공하는 사용자 정의 조합이나 한글 출력 치환 기능을 이용해서 평범한 알파벳이나 숫자를 조합하는 상태를 만들고 나면, space, tab을 눌렀을 때 조합만 종료되고 해당 글쇠는 씹힌다. 그 반면, 한글이나 전각, 특수문자, 2글자 이상의 긴 조합을 만들고 있을 때는 그런 현상이 없다! 간단히 "일본어 히라가나/가타카나" 예제 유형만 MS Word에서 사용해 봐도 확인 가능하다.

TSF를 지원하는 다른 모든 프로그램들은 안 그러는데 오로지 MS 워드만 왜 저러는지 나로서는 알 길이 없다. 아니, 애초에 왜 그 타가 씹힐 수가 있는지도 이해가 안 되지만.. 문제의 증상과 해결(회피) 방법이 인디자인과 Word가 동일하기 때문에 도움말에 동일한 항목으로 보충 설명을 넣었다.

5.
끝으로, 시대가 시대이다 보니 About 대화상자에 Windows 10을 인식하는 데이터도 추가했다.
그리고 외부 모듈에서 옛한글을 사용하는 것과 관련된 추가 설명을 UI나 도움말에 넣었다. (시스템 계층에서 한글 표현 방식도 제대로 설정했는지 확인하라, 옛한글 글쇠배열을 가져오기만 하는 것과 빠른설정으로 총체적으로 맞추는 건 다르다 등)
지금까지 두벌식으로 옛한글 글쇠배열을 설정하면 4단 아랫자리에 있는 한쪽이 길쭉한 반치음들은 종성까지 입력 가능한 형태로 배당되었는데, 이제는 그걸 없애고 초성으로만 배당되게 했다. 이들 자음은 어차피 초성 형태밖에 존재하지 않기 때문이다. 종성 표현은 <날개셋> 편집기 내부에서 사용자 정의 영역 글자를 이용해서 편의상으로나 존재한다.

현대 한글 두벌식을 사용할 때는 ㄸ, ㅃ, ㅉ이 받침이 존재하지 않기 때문에 언제나 초성으로만 입력된다.
옛한글 두벌식일 때는 이들은 종성으로도 입력 가능하고 그 대신 반치음들이 그런 형태를 이어받게 되는 것이다.

Posted by 사무엘

2015/08/01 08:38 2015/08/01 08:38
Response
No Trackback , 11 Comments
RSS :
http://moogi.new21.org/tc/rss/response/1122

근황과 잡설

* 이번엔 프로그래밍 말고 다른 분야의 컬렉션이다.

1. 이메일 주소 변경

이미 오래 된 일이지만... 본인은 대외적으로 홍보하고 사용하는 이메일 주소를 올해 상반기부터 드림위즈에서 gmail로 변경했다. <날개셋> 한글 입력기의 도움말에 안내되어 있는 메일 주소도 고쳤다. 지금까지는 영문 홈페이지에다가만 gmail을 안내했지만 이제는 한국어 사이트에다가도 주소를 바꿨다.

변경한 이유는 드림위즈가 이메일을 보내는 본연의 기능이 제대로 동작하지 않기 때문이다.
단순히 서비스가 낙후해 있고 용량이 적고 비번이 8글자까지밖에 입력 안 되는 개막장인 정도여서가 아니다.
메일을 보냈는데 실제로는 상대방에게 메일이 가 있지 않아서 중요한 일정에서 골탕을 여러 번 먹고 나니, 이제는 안심하고 드림위즈 메일을 이용할 수 없어졌다.
지도교수님에게 보낸 수강 관련 중요 메일이 안 가고, 문서 작업 때문에 보낸 초안 원고가 안 가고.. 게다가 늘 발생하는 것도 아니고 진짜 러시안 룰렛마냥 복불복인 것 같다.

예전에 알집이나 알FTP가 왜 욕을 바가지로 먹었던가? 구린 라이선스 정책은 부가적인 얘기이고, 중간에 파일을 잘라먹고 사용자의 데이터를 파괴해 버리는 크리티컬한 버그 때문에 욕 먹었던 것이다. 자기 본연의 기능을 제대로 수행을 못 하니까. 드림위즈 메일도 이와 동일한 이유 때문에 버리기로 했다.
하긴, 주변 지인에게 이걸 얘기하니 돌아오는 반응은 "드림위즈 아직도 살아 있었어?"이긴 했다. =_=;;

gmail은 다 좋지만 국내 포털들과는 달리 간편한 대용량 첨부 기능과 수신 확인 기능이 없는 게 아쉽긴 하다.
대용량 첨부 중에서는 오로지 다음만이 2GB가 넘는 ‘초대용량’까지도 첨부가 된다. 드림위즈와 네이버는 그렇지 않더라.

2. 복날 몸보신

교회엔 내가 철도를 좋아하는 것만큼이나 핫도그(ㄱㄱㄱ, ㄱㅈㄱ 또는 ㅂㅅㅌ의 애칭)에 사족을 못 쓰는 지인이 있다.
난 경험상 개고기는 수육은 좀 느끼한 것 같고 그래도 개장국은 맛있게 잘 먹는다. 양념도 마음에 들고. 개고기는 성경적으로는 하나도 걸릴 것 없으니, 하나님께서 주신 훌륭한 단백질 공급원으로서 말씀과 기도로 성결하게 한 후 먹으면 된다. 난 오히려 청국장이나 홍어 같은 건 못 먹는다.

하긴, 핫도그라 하니까 지금으로부터 100여 년 전의 아문센의 남극 탐험이 생각 난다. 그거야말로 그 당시 장비와 보급 기술만 갖고는 핫도그 없이는 성공할 수 없었다. 아, 거기서는 고기도 다 날것으로 먹었을 테니 '핫'은 아니겠다만.. -_-;;

일단은 개는 극지방에서의 생존성과 수송력 제공 가성비가 말을 훨씬 더 능가했다. 스스로 체온 조절이 가능하고 식량도 사람의 것과 동일했다. 영국의 스콧 팀은 조랑말과 스노우모빌을 운용했지만 둘 다 남극의 혹한 속에서는 죽고 고장나고 피봤다.

아문센 팀은 탐험 과정에서 효용이 떨어진 개들을 사정없이 잡아먹었다. 심지어는 먼저 잡거나 죽은 개의 고기를 다른 개에게 사료로 주기도 했다! 하지만 열량 소모가 극심한 남극에서는 최대한 여유를 갖고 준비한 기존 보급에다 바다표범 현지 조달로도 식량이 부족했고, 그렇게 해야만 살아남을 수 있었다.
스콧과 영국 언론은 영국 신사 드립을 치면서 개썰매나 타고 개고기를 쳐먹은(는) 야만인이라고 아문센을 사정없이 깠다. 그러나 신사면 뭘 하나, 결국 스콧은 아문센과는 달리 남극에서 살아서 못 돌아오고 다 죽었다.

요즘은 고어텍스, GPS, 초고밀도 생존 식품 같은 첨단 기술 덕분에 그때처럼 '서플라이 디팟'을 미리 안 만들고 동력기관이나 동물도 안 쓰고, 심지어 비행기로 실시간 보급조차 안 받고 사람만으로 남극점에 뚝딱 갔다 온다. 하지만 그래도 한여름에만 갈 수 있는 건 변함없으며 1인당 100수십 kg에 달하는 보급 자루를 썰매에다 싣고 질질 끌면서 정말 힘들게 살 잔뜩 빠지면서 갔다 온다.

옛날에 우리나라에서 올림픽을 개최하던 시절엔 "세계가 지켜보고 있습니다" 프로파간다 하에서 손님들의 동선상에 있는 보신탕집들은 강제로 셧다운 당하고, 사철탕· 영양탕 등으로 간판 바꿔 달고 음지에서 영업하던 적이 있었다.;;; 정말로 개고기만 딱히 야만적이고 잔인하다고 볼 이유가 없는데..
오히려 애완견을 집 안에서까지 데리고 와서 키우는 게 성경적으로 당장 대놓고 죄악은 아니더라도 별로 비추에 바람직하지 않은 모습이다. 인간 학살자 독재자들이 이상한 동물 보호론자였다는 점을 차치하고라도 말이다.

개고기는 아무래도 규모의 경제에서 밀리는지라 국밥류로 한 끼 식사 정도 하려면 초밥 정식 먹듯이 1만 몇천 원 이상 들 각오는 해야 한다. 그래서 그런지 여러 사람이 가면 1인 1국밥 식사 대신 야채가 많아서 가성비가 더 높은 전골류를 권하더라.
저 친구가 "맛 한번 보지도 않고 개고기를 반대한다" 이렇게 한탄을 하길래, 모 전대통령의 "나한테 당해 보지도 않고.." 드립이 문득 떠올랐다.

3. 전동차 재림 신앙

언젠가 야근을 마치고 퇴근하던 때의 일이었다. "아차!" 도시락통을 놔 둔 채 전동차에서 내렸다는 걸 알아 챈 건 왕십리 역에서 하차한 지 3분 남짓한 시간이 경과한 뒤였다.
전동차 안에서 노트북 PC로 다른 작업에 너무 집중하고 있던 게 화근이었다. 전동차로부터는 이미 100미터가 넘게 떨어진 상태.

유실물이 있다는 것을 감지한 직후에는 불안과 흥분 때문에 마치 차에 갓 시동을 건 직후처럼 심장 회전 rpm이 치솟았다. 그러나 난 최대한 침착하려 애쓰면서 rpm을 조절했다.
"역무실에다 신고를 해야 할 텐데 이 역에 코레일 역무실은 어디쯤 있더라?"(분당선이므로) 생각을 하면서 다시 코레일 관할 구간으로 갔다.

그런데 생각을 해 보니 왕십리역은 분당선의 시종점이고, 여기는 딱히 차량 기지나 주박 공간이 있지는 않다. 단지 인상선만 있을 뿐.
그러므로 다음과 같은 가설이 도출됐다. 그 열차가 떠난 지 아직 10분도 채 경과하지 않았으니, 내가 탔던 열차는 인상선을 거쳤다가 다시 반대편 승강장으로 곧 그대로 들어올 것이다. 청소부 아줌마는 바닥만 신경쓰지 그 짧은 시간 동안 선반을 일일이 다 살펴보지는 않을 것이다.

그리고 행 1:11 말씀이 내게 평안과 위로를 주었다. "너희 갈릴리 사람들아, 너희가 어찌하여 서서 하늘을 바라보느냐? 너희를 떠나 하늘로 들려 올라가신 이 동일한 예수님께서는 너희가 그분께서 하늘로 들어가심을 본 그대로 오시리라."
그렇다. "너희 전철 승객들아, 너희가 어찌하여 패닉에 빠져 있느냐? 너희를 떠나 인상선으로 들어간 이 동일한 상행 열차는 너희가 봤던 상태 그대로 진행 방향만 바꿔서 하행선 승강장으로 되돌아오리라." 아멘.

상행 열차는 맨 앞칸을 탔으므로 이번엔 난 하행 승강장의 맨 뒷칸에서 다음에 들어올 열차를 기다렸다. 잠시 후 하행 열차가 들어왔고, 그 열차의 선반에 아까 내가 놔 뒀던 도시락통이 있는 걸 창문을 통해 확인했다. 역무실에 연락을 할 필요조차도 없었다.

"그럼 그렇지!" 전동차 재림 신앙은 그 믿음대로 응답되었고 간증거리가 되었다. 지하철 영화 <튜브>에서 위기를 넘겼을 때 통제실 권 실장이 기뻐하던 그 장면이 떠올랐다.
다른 승객들은 열차에 올라타서 자리에 앉았지만, 나는 그 도시락통만 쓱 끄집어 낸 뒤 도로 내렸다. 주변의 다른 승객들은 나의 행동에 저런 배경이 있다는 것을 알 수 없었을 것이다.

Posted by 사무엘

2015/07/29 08:33 2015/07/29 08:33
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1121

* 서로 관계가 없는 여러 글들이긴 한데, 따로 따로 올리기는 좀 짧고 정보량이 적은 편이고, 귀찮은 구석이 있기도 해서 한데 묶었다.

1. 이미 실행돼 있는 프로그램을 스스로 종료한 뒤에 제거하기

본인은 설치· 배포 패키지를 만들 때 Visual Studio가 기본 제공하는 설치/배포 패키지를 사용하고 있다.
얘는 마소에서 직접 제공하는 물건이다 보니 정말 기본적인 퀄리티는 보장되고 기능이 나쁘지는 않다. 하지만 버그나 불편한 점이 아주 없는 건 아니고, 또 동작 customize의 폭이 충분하지 못해서 불편한 구석도 많다. Windows Installer라는 API가 제공하는 기능의 극히 일부만을 템플릿화해서 제공하는 형태이기 때문이다.

잘 알다시피 Windows는 실행 중인 EXE나 DLL은 이름을 바꿀 수는 있어도 지울 수가 없어서 뒤끝 없이 깔끔하게 제거하는 게 어려운 구석이 있다. 프로그램이 한번 실행했다가 간단히 종료가 가능한 EXE가 아니라 <날개셋> 한글 입력기처럼 IME가 포함돼 있다거나, 혹은 서비스/데몬류라면 참 난감하다.

EXE라면 자신을 종료하는 명령을 갖추고 있어야 한다. 즉 A라는 프로세스가 이미 돌아가고 있는데, /U나 /Q 같은 옵션으로 A가 다시 실행됐다면 그 A의 인스턴스는 이미 실행돼 있는 다른 A의 인스턴스를 찾아서 거기에다가 이벤트로든 윈도우 메시지로든 종료 명령을 내린 뒤 종료한다. 그럼 이미 실행돼 있는 A는 그 신호를 받고서 자신도 곧장 종료한다. 물론 A라는 한 프로그램의 소스에는 자기가 각각 다른 상황으로 실행되었을 때의 분기 처리가 모두 갖춰져 있어야 한다.

윈도우라면 WM_CLOSE 메시지가 있고 콘솔 프로그램에는 Ctrl+C 인터럽트가 있는데, 콘솔도 아니고 윈도우도 안 만든 채 다른 이벤트를 대기만 하고 있는 프로그램을 상대로 범용적인 종료 신호를 보내는 방법이 있는지 모르겠다. TerminateProcess라는 아주 무식하고 극단적인 방법을 쓰기보다는 그 프로그램이 직접 자신을 종료하도록 유도하는 게 바람직하기 때문이다.

인간 세계에서도 마찬가지다. 말이 안 통하는 미치광이가 만취한 상태로 자동차 운전대나 총칼 같은 위험한 물건을 잡고서 인질극 벌이고 행패를 저지르는 상황이 아닌 이상, 마취총을 쏘거나 머리를 벽돌로 내리쳐서 기절-_-시키거나 최악의 경우 저격을 하는 것보다는 곱게 말로 행동을 저지시키는 게 나은 것이다.
회사에서 필요 없는 사람을 짜를 때도 지방 한직 발령에다 빈 책상만 달랑 세팅해 놓고 아무 업무도 안 주면 그 사람이 더는 못 견디고 알아서 사표 쓰고 나가게 된다. 어지간해서는 대놓고 "너 해고. 내일부터 나오지 마" 이러는 일은 극히 드물다. 그건 고용주의 입장에서도 부담스러운 일이기 때문이다.

갑자기 쓸데없는 얘기가 좀 길어졌다만..
회사 업무 때문에 저런 성격의 EXE를 만들 일이 있었다.
DLL이라면 DllUnregisterServer이라고 원래는 COM용이지만 굳이 그 용도로만 쓰지는 않아도 되는 표준 인터페이스가 존재하지만, 얘는 EXE이다 보니 자신을 종료하여 제거 준비를 완료시키는 옵션을 구현했다. 그리고 패키지가 제공되기 전에는 당연히 그 옵션이 실행되게 이벤트도 넣어 줬다.

그러나 그럼에도 불구하고 이 프로그램을 설치하고 실행한 뒤에 제거를 하자, MSI는 "요런 프로그램이 실행 중이어서 제거를 제대로 할 수 없습니다" 대화상자를 띄우며 꼬장을 부렸다. 헐...;;
거기서 '무시'를 누르면 되긴 됐다. 그러면 종료/제거 스크립트가 실행돼서 "안 돼"가 "돼"로 바뀌었다. 실행 중인 자기 자신을 제거하는 테크닉이야 배치 파일을 이용해서 그리 어렵지 않게 구현 가능하기도 하고.

하지만 저런 대화상자가 뜨는 일은 반드시 막아야 했다. 저건 사용자가 부주의하게 띄워 놓은 게 아니라 우리 소프트웨어 제품이 정상적으로 일부러 띄워 놓은 프로그램이기 때문이다.
먼저 종료/제거 스크립트를 실행부터 좀 하고 나서 아직도 프로그램이 실행되고 있는 게 있으면 그걸 지적하면 되는데 저거 순서만 좀 바꿀 수가 없는지, Visual Studio에는 그런 기능이 없나 하는 아쉬움이 들었다. 얘로는 그럼 서비스 같은 건 제대로 배포하고 제거할 수가 없는 건지?

결국은 어떻게 했는가 하면 자기 자신을 다른 이름으로 복사해서 그놈을 대신 상주시키는 방법으로 문제를 피해 갔다. 그러면 MSI가 실행되어 있는 시점에서 자신이 제거해야 하는 프로그램은 실행돼 있지 않고, 새로 실행되는 동일체 프로그램이 자기 분신을 종료시켜 주기 때문에 모든 요구 사항을 만족할 수 있다. 하지만 굳이 안 해도 되는 삽질이 필요해졌다는 점에서는 여전히 아쉬움이 남는다.

2. 운영체제의 GUI 기본 글꼴 얻기

Windows에서 GUI의 기본 글꼴은 영문판 기준으로 System (불변폭) → System (가변폭) → MS Sans Serif → Tahoma → Segoe UI의 순으로 바뀌어 왔다. 한글 쪽은 명조 내지 바탕체가 들러리로 꼈다가 95/NT 시절부터 MS Sans Serif 대신 굴림으로 10년 가까이 장수한 뒤, 지금은 맑은 고딕이 대세가 됐다.
맑은 고딕과 Segoe UI의 경우 같은 서체이지만 윈도 비스타/7 시절과 8 이후 시절에 글자 모양이 미세하게 바뀌기도 한 것은 눈썰미 있는 분이라면 아실 것이다.

테마가 고전에서 Aero로 바뀌는 과도기를 거친 뒤, Windows 8부터는 자체 테마가 Aero시절에 비해 곡선 테두리나 그러데이션 같은 게 없어지고 굉장히 단촐해진 대신, 이 테마가 과거의 고전 테마를 완전히 대체하게 됐다. 자연히 UI 글꼴도 굴림이 밀려나고 맑은 고딕이 대세가 됐다.

그런데, 운영체제의 언어나 버전에 관계 없이 지금 시스템에 기본으로 지정돼 있는 글꼴을 얻어 오는 방법은 없을까? 이런 건 LOGFONT 값을 얻어 오거나 아예 바로 사용 가능한 stock HFONT 형태로라도 존재해야 하지 않을까? 시스템 색상에 대해서는 solid color 브러시를 얻어 오는 GetSysColorBrush 함수가 있는데 말이다.

실제로 요즘 프로그램 중에는 시스템의 기본 GUI 글꼴에 맞춰서 대화상자를 출력하는 것들도 많다. 비록 그렇게 동작하는 게 필수 관행은 아니지만 말이다. Visual Studio가 대표적인 예이고 <날개셋> 한글 입력기 프로그램들의 대화상자도 마찬가지. 기본 글꼴을 얻어 올 수 있어야 이렇게 동작을 할 수 있을 것이다.

Windows에는 이와 관련된 API가 물론 있긴 하지만 내력이 좀 꼬여 있다.
GetStockObject 함수를 보면 기본 펜이나 브러시 말고 글꼴을 되돌리는 아이템이 있다. 그러나 SYSTEM_FONT, SYSTEM_FIXED_FONT 이런 것들은 트루타입 글꼴과는 하등 관계가 없으며 말 그대로 System, FixedSys, MS Sans Serif, Terminal 같은 25년이 넘는 짬밥을 자랑하는 골동품 구닥다리 고정 봉인 비트맵 글꼴밖에 나오지 않는다.

그나마 유일하게 Windows 95/NT4에서 트루타입 글꼴을 되돌리는 stock 아이템이 딱 하나 추가되긴 했는데 그건 바로 DEFAULT_GUI_FONT이다. 얘는 한글판에서는 굴림 9포인트에, 그리고 아마 영문판에서는 Tahoma 정도에 매핑된다.
그럼 얘를 쓰면 되느냐 하면 그렇지는 않다. 얘는 좀 만들다가 만 물건-_-처럼 됐다. Windows 95 이래로 8에 이르기까지 그냥 굴림으로 고정돼 버렸다. Aero 테마라고 해서 맑은 고딕이 돌아오는 게 아니다.

실질적으로 현업에서 지금 운영체제의 기본 글꼴을 얻어 오는 방법은 SystemParametersInfo 함수를 쓰는 것이다. 아이템 인덱스로 SPI_GETICONTITLELOGFONT를 주면 기본 글꼴의 명세가 LOGFONT 형태로 돌아온다. 이를 토대로 HFONT는 우리가 수동으로 만들어서 사용하고, 다 쓴 뒤엔 해제를 해야 한다. 물론 대화상자의 글꼴을 바꾸는 건 GDI 개체를 만드는 게 아니라 대화상자 템플릿의 내용을 바꾸는 것이므로 방법이 약간 다르다.

3. 64비트 바이너리의 디렉터리 배치에 대한 생각

Windows는 잘 알다시피 Program Files 디렉터리가 32비트용과 64비트용이 나뉘어 있다. SHGetFolderPath 함수는 기본적으로 호출하는 프로그램의 비트수에 해당하는 디렉터리를 되돌리며, 이로써 32비트 프로그램 바이너리(EXE/DLL)와 64비트 프로그램 바이너리가 서로 자연스럽게 분리되어 따로 놀게 해 놓았다.

하지만 응용 프로그램의 바이너리 구분이 그렇게 마냥 깔끔하게만 되지는 않는 경우도 많다.
32비트와 64비트용 Program Files 디렉터리 구분은 편의상 존재하는 구분일 뿐이다. 32비트 디렉터리 아래에 64비트 프로그램이 있다거나 혹은 그 반대의 상황이 됐을 때 그 프로그램의 실행이 구조적으로 거부된다거나 하지는 않는다. 그러니 너무 강박관념적으로 구분하려고 애쓰지는 않아도 된다.

가령, 프로그램 자체는 전반적으로 32비트이지만 탐색기 셸 extension이나 시스템 훅 같은 일부 프로그램만 64비트인 경우..
그냥 Program Files (x86) 밑의 동일한 프로그램 디렉터리에다가 64비트 DLL도 이름을 달리해서 집어넣는다 해도 이상할 것 없다. 한두 개보다는 파일 개수가 많다면, 그 아래에다 x64 같은 별도의 디렉터리를 만들어서 말이다.

Visual Studio도 컴파일러는 32비트용 32비트 타겟뿐만 아니라 32비트용 64비트 크로스 컴파일, 그리고 64비트용 64비트 타겟 같은 컴파일러들이 모두 Program Files (x86) 아래에 있으며, Spy++ 같은 유틸도 32비트와 64비트 프로그램이 EXE와 훅 DLL 모두 한 디렉터리에 있다.
32비트 devenv.exe IDE에서 64비트 프로그램을 디버깅 하기 위해 중재 역할을 하는 64비트 원격 디버깅 서버 프로그램은 그 아래의 x64 디렉터리 안에 들어 있다. 오로지 걔들만을 위해 굳이 64비트 Program Files 디렉터리를 또 건드리지는 않았다.

그 반면, 64비트 바이너리가 전체 제품의 일부 형태로 있는 게 아니라 32비트와 완전히 대등하게 있는 경우라면 그때는 32/64비트 프로그램 디렉터리 아래에 대등한 파일과 디렉터리 구조를 갖추고 있는 게 바람직하다.
그리고 프로그램의 비트 수와 관계 없이 공유하는 데이터는 ProgramData라는 또 다른 공용 디렉터리의 아래에다 두면 된다.

<날개셋> 한글 입력기는 64비트 에디션이 처음으로 만들어지던 4.8 시절에 저런 식으로 디렉터리 구조를 싹 바꿨다. 아무래도 외부 모듈이 있다 보니 32비트와 64비트 바이너리는 애초에 대등한 구조가 되어야만 했으며, 그래서 32/64비트 프로그램 디렉터리를 모두 적절히 사용하게 만들어졌다. 프로그램마다 이런 차이가 있다는 걸 생각하면 되겠다.
하긴, 요즘은 관리자 권한을 요구하지 않고 간편하다고 해서 Program Files가 아니라 아예 사용자 계정 디렉터리에다가 프로그램을 설치하는 경우도 있으니 이건 32/64비트 구분이 더욱 모호해진 경우에 속한다.

4. 비주얼 C++ 솔루션의 중복 로딩 감지

Visual C++ IDE는 잘 알다시피 솔루션 단위로 동작한다. 한 솔루션 안에는 여러 관련 프로젝트들이 있을 수 있다. 솔루션은 프로젝트들의 묶음 컬렉션일 뿐이기 때문에 프로젝트를 바로 열면 그 프로젝트를 감싸는 껍데기 솔루션이 자동으로 만들어지기도 한다.
다만 다수의 솔루션들을 동시에 여는 것은 IDE의 능력 범위를 벗어나는 일이다. 그러니 IDE를 여러 개 실행해서 제각각 다른 솔루션을 열어야 한다.

그런데 비주얼 C++을 여러 개(=여러 인스턴스) 띄워서 여러 솔루션을 열어 놓고 작업을 하다 보면, 한 인스턴스에서 이미 열어 놓은 솔루션을 깜빡 잊고 다른 인스턴스에서 또 여는 일이 생기곤 한다. 뭐 그런다고 해서 프로그램이 뻑나거나 데이터가 날아가는 급의 큰 사고가 벌어지는 건 아니지만, 그래도 약간 불편한 일이 벌어진다.

인텔리센스 DB 파일에 공유 충돌이 발생하기 때문이다. 소스 코드의 상태와 인텔리센스 DB 상태를 언제나 동기화시키기 위해 IDE가 해당 파일을 열어 놓은 채 읽고 쓰는 동작을 완전히 독점하는 듯하다. 그래서 솔루션의 복수 중복 로딩을 시도하면, 되긴 하지만 나중에 연 쪽에서는 Class view라든가 인텔리센스가 동작하지 않는다.
이것은 과거 ncb 기반의 비주얼 C++ 200x 시절이든 지금의 201x 시절이든 동작이 동일하다. 다만 201x부터는 파일 쓰기가 가능한 임시 fallback 경로를 지정해서 문제를 좀 더 지능적으로 회피할 뿐이다.

하지만 에러 메시지를 출력하거나 대체 경로를 지정할 필요 없이,
비주얼 C++의 다른 인스턴스에서 해당 솔루션이 열려 있을 경우, 그 인스턴스로 이동만 시켜 주는 게 훨씬 더 월등히 나은 해결책이다. 그게 99.99% 사용자가 원하는 반응이 아닐까? "아, 이미 이 솔루션을 열어 놨었지!"
도대체 동일 솔루션을 중복 로딩해야 할 이유나 필요가 실무에서 무엇이 있겠으며, 이 상황에서 DB 파일을 건드리고 있을 프로그램은 비주얼 C++ IDE의 다른 인스턴스 말고는 다른 선택의 여지가 무엇이 있겠는가? 비주얼 C++의 inter-process 차원에서의 배려가 아쉬운 대목이다.

대체 경로를 지정해 주는 건 CD-ROM 같은 읽기 전용 매체에 저장된 솔루션을 열었을 때에나 유의미한 편의를 제공할 것으로 여겨진다.

5. 하이퍼-V

하이퍼-V인지, CPU 가상화인지 뭔지 잘은 모르겠지만 예전에 Windows Phone 플랫폼 개발을 위해서는 Hyper-V platform이라고 명명된 기능을 모두 켜야 했다.
그런데 VirtualBox가 멀쩡한 64비트 호스트 OS에서도 64비트 게스트 가상 머신을 만들지를 못하고 꼬장을 부리고 있어서 검색을 해 보니.. 이번엔 반대로 Hyper-V platform을 꺼야 했다.

Windows Phone 에뮬레이터도 일종의 가상 머신을 돌리는 것이고 64비트 OS에서만 돌아가는 기능이었는데 Hyper-V에 대해서 도대체 왜 이런 차이가 존재하는지를 잘 모르겠다.
그리고 VirtualBox는 64비트 호스트에서 64비트 게스트를 어떤 이유로든 만들 수 없다면, 그렇게 아무 말도 없이 슬쩍 감추기만 하지 말고 "64비트 게스트를 만들려면 Hyper-V를 꺼 주세요"라고 친절하게 메시지라도 좀 출력해 주지 하는 생각이 들었다.

Posted by 사무엘

2015/07/26 08:32 2015/07/26 08:32
, ,
Response
No Trackback , 3 Comments
RSS :
http://moogi.new21.org/tc/rss/response/1120

Windows 운영체제에서 GUI의 핵심 구성 요소인 윈도우라는 물건은 자신만의 위치, 스타일, 소속 클래스, 부모 윈도우, ID(또는 메뉴 핸들) 등 여러가지 공통 정보를 갖는다. 이들은 숫자 형태로 표현되며, 대부분 GetWindowLongPtr 함수를 이용해 값을 얻을 수 있다.

그런데 그 공통 정보 중에는 숫자뿐만 아니라 문자열인 것도 있으니, 바로 '텍스트'이다. static 컨트롤이나 버튼들이 출력하고 있는 문장이나 단어들이 바로 자신이 갖고 있는 텍스트이다. 그리고 작업 표시줄에 걸려 있는 응용 프로그램들의 제목(Caption)도 다 윈도우의 내부 텍스트이다.

윈도우에 소속된 텍스트를 읽고 쓰는 함수는 잘 알다시피 Get/SetWindowText이다. 그러나 이것의 실제 구현은 그저 C++ 클래스에서

String getText() const { return m_strText; }
void setText(String t) { m_strText=t; }

요렇게 달랑 코딩하는 것만치 단순하지 않으며, 그보다 추상화 계층이 많고 사연이 훨씬 더 복잡하다.

(1) 먼저, 윈도우는 단순히 자신의 내부 버퍼를 토대로 텍스트를 지정하거나 되돌릴지, 아니면 이런 기본 동작을 무시하고 매번 자신이 능동적으로 반응을 할지를 자기 윈도우 프로시저가 재량껏 결정할 수 있다. 이것은 마치 WM_PAINT 메시지를 이미 저장돼 있는 버퍼를 바로 뿌리는 것으로 처리하는지, 아니면 매번 그래픽 API로 그려서 처리하는지의 차이와 같다.

아까도 얘기했던 static이나 버튼 컨트롤을 포함해 대부분의 윈도우들은 기본 내부 버퍼를 기반으로 동작하는 것만으로도 충분할 것이다. 그러나 에디트 컨트롤은 get의 경우 사용자가 입력한 문자열을 되돌리며 set은 자기가 편집하고 있는 텍스트를 변경한다. 이 텍스트는 당연히 기본 내부 버퍼가 아니라 에디트 컨트롤이 자체적으로 관리하는 자료 구조로부터 얻어진 데이터이다.

그럼 그런 customize를 어떻게 하는가? Get/SetWindowText는 대상 윈도우에다가 WM_GETTEXT, WM_GETTEXTLEN, WM_SETTEXT 메시지를 보내어 그 응답을 받는 방식으로 구현된다. 윈도우가 이 메시지를 처리하지 않고 그냥 DefWindowProc으로 넘기면 내부 버퍼에 대한 문자열 get/set인 기본 기능이 구현된다. 이 메시지는 자기가 에디트 컨트롤을 직접 구현하고 있을 때 정도에나 직접 처리하면 된다.

WM_CREATE에서 넘어온 CREATESTRUCT 구조체를 들여다보면, 이 윈도우를 생성한 CreateWindowEx에서 지정해 준 window name 정보가 있는데, 이것부터 자기 자료 구조에다가 복사를 해 둬야 할 것이다.
만약 내 윈도우가 대용량 텍스트를 다루고 텍스트의 일부 구간이 빈번하게 수정된다면, 저런 원시적인 메시지에만 의존하지 말고 해당 동작만을 위한 custom 메시지를 직접 구현해서 그걸 이용하는 게 효율적이다.

(2) 서로 다른 응용 프로그램끼리는 너무 당연한 말이지만 포인터를 주고받을 수 없다. 서로 메모리 주소 체계가 완전히 다르며, 상대방 프로세스의 메모리 내부를 들여다볼 수 없기 때문이다. 그렇기 때문에 이런 프로그램들끼리 가변 길이의 임의의 데이터를 주고 받으려면 WM_COPYDATA라는 특수한 메시지를 써야 하는데, 이건 의외로 굉장히 유용하고 괜찮은 물건이긴 하다.

그런데 WM_GET/SETTEXT 메시지도 비슷한 구석이 있다. 서로 다른 응용 프로그램간에도 마치 동일 프로그램인 것처럼 텍스트를 얻어 오거나 지정할 수 있다. 이 메시지에 대해서도 운영체제가 예외적인 변환 처리를 해 주기 때문이다.
단, 여기에서는 Get/SetWindowText 함수는 동작에서 약간 차이를 보인다. 같은 프로세스끼리 get/set을 하는 것은 메시지를 날리는 것과 동일하게 동작하는 반면, 다른 프로세스에 있는 윈도우에다가 get/set을 하면.. 그 윈도우의 윈도우 프로시저를 실행하는 게 아니라 그냥 그 윈도우에 있는 내장 버퍼의 문자열만 가져오는 걸로 끝난다. 왜 그렇게 된 걸까?

이것은 보안을 위해서이다. 해당 윈도우를 관할하는 응용 프로그램이 현재 메시지에 반응하지 않고 뻗어 있는데(hang) 이때 또 텍스트를 얻거나 지정하는 메시지를 보내면.. 그 요청을 한 우리 응용 프로그램까지 응답을 기다리느라 뻗어 버릴 수 있기 때문이다. 그래서 이때는 언제나 실행이 정상적으로 즉시 끝나는 게 보장되는 윈도우 내부 버퍼만을 건드리는 걸로 끝난다.

단순 내부 텍스트가 아니라 위험을 감수하고라도 해당 프로그램의 윈도우 프로시저가 실시간으로 실행한 텍스트를 얻고 싶으면, 함수만 달랑 호출하지 말고 직접 WM_GETTEXT 메시지를 보내라는 것이 설계 의도이다. 뻗을 걱정을 최소화하면서 메시지를 보내는 함수로는 SendMessageCallback이라든가 SendMessageTimeout 같은 물건들도 있으니 말이다.

사실, 현재 시스템에 떠 있는 모든 윈도우들을 조회하는 Spy++ 같은 급의 특수한 프로그램을 만드는 게 아닌 이상, 다른 프로그램들에서 제일 겉의 프레임 윈도우도 아니고 내부의 에디트 컨트롤까지 시시콜콜하게 내용을 다 들여다봐야 할 일은 거의 없을 것이다. 그러니 16비트 API에서 최초로 32비트 멀티스레드 환경으로 넘어갈 때, 텍스트를 얻는 동작은 함수 호출에 대해서만 저런 조치를 취하는 것이 적절한 조치라고 마소의 엔지니어들이 판단했다.

(3) 프로세스 장벽에 비해서는 아주 사소한 문제에 불과하지만, 사실은 문자열 인코딩 장벽도 있다.
어떤 윈도우가 있어서 요즘 추세대로 유니코드를 사용하며 WM_GETTEXT에 대해서는 L"abc" 같은 wide 문자열만 되돌린다. 그런 윈도우를 대상으로 GetWindowTextA 함수를 호출했다 하더라도 문자열 변환은 운영체제가 몰래 알아서 해 준다. 해당 프로그램은 ansi 문자열인 "abc"를 받는다.
요청하는 측에서는 GetWindowText나 SendMessage를 A와 W 중 어느 버전으로 호출했는지로 판단을 하고, 받는 윈도우는 RegisterClass(Ex)에서 A와 W 중 어느 버전을 이용해서 등록했는지로 판단한다.

그럼, 텍스트 지정 API와 관계가 있는 다른 분야 얘기를 또 둘 늘어놓고 글을 맺도록 하겠다.

부록 1. 창을 없애는 것과의 관계

윈도우의 텍스트를 얻어 올 때 함수를 쓰느냐 메시지를 보내느냐 하는 건, 마치 윈도우를 닫을 때 직통으로 DestroyWindow를 호출하느냐 아니면 WM_CLOSE 메시지를 보내느냐 하는 것과 비슷한 구석이 있어 보인다.

WM_CLOSE는 마우스로 X 버튼 누르거나 키보드로 Alt+F4를 누른 것과 같다. 이 메시지를 더 처리하지 않고 DefWindowProc으로 넘기면 얘가 DestroyWindow를 호출해 준다. 응용 프로그램의 경우 "이 문서를 저장하시겠습니까?"라고 질문 메시지를 출력하는 게 이 메시지를 받았을 때이다. 물론 '취소'를 누르고 메시지를 씹으면 실제로 닫히지는 않는다.

그 반면, WM_DESTROY는 이미 자기가 닫히고 없어지는 건 막을 수 없는 지경이 됐고, 그 전에 마무리 작업이나 하라는 통지이다. 아직 자기의 자식 윈도우들도 다 남아 있다. 이 메시지는 운영체제로부터 자연스럽게 받게 해야지 사용자가 인위로 생성하지는 말아야 한다.
이게 끝나고 자식 윈도우까지 다 사라진 뒤에 정말 마지막으로 오는 메시지가 바로 WM_NCDESTROY이다. 이때 하는 일은 C++ 클래스와 연결된 윈도우 프로시저에서 delete this를 하는 것 정도가 전부이다.

Get/SetWindowText가 여타 프로세스의 윈도우에 대해서는 다소 방어적으로 동작을 하듯, DestroyWindow에도 약간의 방어적인 제약이 있다. MSDN의 설명에 따르면, 얘는 다른 프로세스 정도가 아니라 아예 다른 스레드에 의해 생성된 윈도우를 파괴하지는 못한다. 그런 창을 닫으려면 그냥 WM_CLOSE라는 간접적인 방법만을 써야 한다.

앞서 말했듯이 WM_CLOSE는 응용 프로그램이 회피· 거부가 가능하기 때문에 응용 프로그램의 입장에서는 다른 스레드/프로세스의 특정 윈도우를 무조건적으로 없애지는 못한다. 굳이 그렇게 해야 할 필요도 없을 테고.
멀티스레드 환경에서 Windows의 창 관리자가 어떤 식으로 API를 설계했는지를 살펴보면 편의와 안정성을 상호 절충하기 위해 여러가지 생각을 했다는 점을 발견할 수 있다.

부록 2. 아이콘과 글꼴은 어떻게?

앞서 살펴본 것처럼 한 윈도우의 속성 중에 텍스트(TEXT)는 운영체제가 DefWindowProc을 통해 내부 텍스트를 관리하기도 하고 한편으로 값을 읽고 쓰는 동작을 customize하는 방법도 제공한다.
그럼, 윈도우와 관련된 부가 정보 중에는 아이콘과 글꼴은 어떻게 관리되는 걸까? 얘들은 함수가 아니라 메시지로만 값을 지정하고 얻어 온다는 공통점도 있다. WM_(GET/SET)(ICON/FONT)라고 말이다.

아이콘은 기본적으로 윈도우가 클래스에 소속돼 있으며, 그 클래스를 기반으로 만들어진 윈도우들이 한 아이콘을 공유하는 형태이다. 그러나 클래스 아이콘과는 별개로 필요하다면 각각의 윈도우도 자기 아이콘을 예외적으로 변경할 수 있다. 이는 특정 윈도우 클래스가 아니라 운영체제 차원에서 기본으로 제공되는 기능이다.
코드로 표현하자면 대충 이런 구조. commonIcon뿐만 아니라 myIcon도 있다는 뜻이다.

class Window {
    static Icon commonIcon;
    Icon myIcon;
public:
    Window() { myIcon=commonIcon; }
    Icon getIcon() { return myIcon; }
    void setIcon(Icon i) { myIcon=i; }
};

그렇기 때문에 대화상자는 윈도우 클래스는 동일하지만 응용 프로그램이 WM_SETICON을 보냄으로써 자신만의 아이콘으로 customize를 할 수가 있다. 그리고 이 기능은 대화상자에만 있는 게 아니라 임의의 top-level 윈도우가 다 갖추고 있다.

이런 아이콘에 비해 글꼴은 운영체제의 윈도우 내부 자료구조에 정보가 자동으로 저장되지 않는다. 내가 custom 컨트롤을 만들고 있고 거기에 대화상자의 기본 글꼴대로 문자를 찍는 기능이 있다면 내부적으로 HFONT 핸들을 멤버로 추가하고 WM_GET/SETFONT 메시지를 직접 구현해 줘야 한다. 즉, 운영체제에는 인터페이스만 정의되어 있을 뿐이다.
요약하자면 text는 내부 자료구조와 custom 동작이 모두 존재하고, icon은 내부 기본 동작만으로 충분하고, font는 기본 동작이 없기 때문에 필요한 경우 자체 구현을 해야 한다는 뜻이다.

Posted by 사무엘

2015/07/23 08:39 2015/07/23 08:39
,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/1119

1. Windows와 Office의 IME → 독립했다가 도로 운영체제로 합병

오~ 그러고 보니 MS Office 2013부터는 Office IME가 없어졌다는 걸 이제야 확인했다.
한때 웹브라우저인 Internet Explorer가 3~5버전 시절엔 자기가 운영체제의 셸을 뜯어고치고 comctl32, shell32 같은 시스템 DLL을 마구 업데이트 했던 것처럼, 문자 입력 쪽은 아무래도 오피스 제품의 기술 수준이 더 앞서 있었다.

그래서 IME 기반이던 다국어 입력 기능을 TSF라는 인터페이스로 바꾸는 것도 2001년에 MS Office XP가 최초로 도입했다. 그때부터 Office를 설치하면 한국어/일본어판은 자국어 IME도 새 걸로 바뀌기 시작했다. CJK 쪽이 아닌 라틴 알파벳 언어에서는 필기/음성 인식 같은 기능이 이 인터페이스를 기반으로 첫 도입됐다.

TSF 자체는 Windows XP도 운영체제 차원에서 완전히 내장돼 들어갔다. 그러나 이번엔 MS Office 2003 한글판이 제공하는 IME에서 글자가 아닌 단어 단위로 한자 변환을 하는 기능이 추가됐다. 이것은 운영체제의 IME에는 없던 기능이고 비스타에 가서야 추가됐다. 즉, 운영체제가 Office보다 한 박자씩 늦었던 것이다.

그러나 문자 입력 관련 기술들이 다 상향평준화하고 발전이 정체되면서, 굳이 Office가 IME를 또 제공할 필요가 없어졌다. 실제로 윈도 비스타 내지 Office 2007부터는 Office의 한글 IME나 Windows의 한글 IME나 차이는 거의 없어졌다. 괜히 똑같은 프로그램이 중복으로 존재하는 셈이 됐고 그 관행이 2010에까지 이어졌다가 2013부터는 드디어 Office IME는 없어졌다. 2000년대를 풍미했던 관행이 끝났다.

2. Windows와 IE → 합병하려다가 철회

운영체제의 셸의 발전을 주도하던 IE는 2000년대 중반까지 버전 6으로 90%에 달하는 점유율로 리즈 시절을 찍자, 발전이 정체되면서 역설적으로 Office IME와 비슷한 운명을 맞이할 뻔했다.
물론 IE의 버전업을 완전히 중단하는 건 아니고, IE 팀을 해체하고 Windows 팀에다가 합병시켜서 유지보수 비용을 줄이는 것이다. 그래서 IE는 독자적인 프로그램이 아니라 걍 운영체제의 일부로서 Windows와 함께 같이 유지보수를 하겠다는 것이 계획이었다. 웹브라우저는 전면 무료화가 돼 버리는 바람에 오피스나 개발툴과는 달리, 어차피 독자적인 고유 수입도 없으니 말이다.

그렇게 안일하게 생각했는데 파이어폭스의 급부상으로 인해 MS도 생각을 고쳐 먹었고, 급히 IE7을 만들게 됐다. 그리고 IE는 '셸 통합'이라는 예전 트렌드와는 달리 Windows 탐색기와는 다른 길을 가기 시작했다. Windows XP + IE6 시절에만 해도, 탐색기 창이 곧바로 IE 창으로 바뀌고, IE 주소 창에서 내 컴퓨터 디렉터리를 때리면 그 창이 곧바로 탐색기로 바뀌곤 했었는데.. 이것도 참 아련한 추억이다.
물론 지금은 아예 너무 누더기가 된 IE의 개발을 끝내고 마소가 브라우저를 처음부터 다시 만드는 지경까지 갔고 말이다.

3. Windows와 Office의 파일 대화상자 → 독립했다가 도로 운영체제로 합병

지금은 벌써 세월이 많이 지났지만, 2007년경엔 요런 일도 있었다.
원래 MS Office는 운영체제가 제공하는 파일 열기 대화상자 대신 독자 개발한 대화상자를 썼는데, 이젠 Office도 운영체제의 표준 대화상자로 복귀했다. 비슷한 시기에 출시된 Visual Studio 2008도 동일한 조치를 취했다.

운영체제가 보급으로 제공하는 대화상자는 기능이 너무 빈약하다는 이유로, 혹은 별 이유 없이 잉여력이 넘쳐서 Office 팀에서는 같은 기능을 또 만들어서 썼다. 대표적으로 favorite 폴더를 바로 클릭해서 이동하는 기능은 Windows에서는 2000/ME급에서야 도입됐지만 Office에서는 97 때부터 있었다.

하지만 Windows Vista급쯤 되니까 보급 표준 대화상자도 기능이 충분히 강력해졌고, 굳이 둘을 따로 만들 이유가 전혀 없어졌으니 그 시기에 팀간의 코드 통합이 이뤄졌다.

4. Windows와 Visual C++의 CRT → 통합 불가, 영구 독립

Visual C++은 운영체제 자체만큼이나 그야말로 전세계를 석권한 컴파일러이며, 마소 내부에서도 많이 쓴다. 그러나 전부 얘만 쓰는 건 아니었다.
Windows 개발팀이 자체적으로 보유하고 있는 컴파일러와 C 라이브러리 DLL, 그리고 비주얼 C++이 제공하는 컴파일러와 라이브러리가 처음엔 호환되었지만 시간이 갈수록 서로 호환되지 않게 되면서 문제가 심각한 지경이 됐다.

20년 전이나 지금이나 printf, strcpy, qsort 같은 표준 함수의 구현체가 한번 만들어 놓은 뒤에 도대체 바뀔 게 있나 싶지만..
보안 강화 버전이 도입되고 자료형이 32에서 64비트로 확장되는 등, C 라이브러리도 영구 봉인을 하기엔 바뀌는 게 굉장히 많았다.

그래서 Visual C++ 6.0과 Windows 98 시기를 마지막으로 C 라이브러리는 msvcrt(운영체제) 계열과 msvcr???(VC++) 계열로 서로 완전히 이원화가 돼 버렸다. 그 전에는 이름조차도 crtdll(운영체제)과 msvcrt(VC)로 따로 놀았는데 그건 운영체제가 crtdll을 버리고 msvcrt로 간 것이었다. Windows, Visual Studio, Office, IE 등 마소를 구성하는 핵심 부서들간에는 코드의 공유가 생각보다 원활하게 이뤄지지는 않고 있는 듯하다.

마소에서 만든 Windows나 Office의 구버전 바이너리들은 링커 버전 같은 내부 구조를 보면 일반적인 Visual C++ 컴파일러가 생성해 주는 형태가 아니었다. 그러던 것이 Vista 타이밍이 되면서 그 직전에 나온 가장 최신 Visual C++의 버전이 찍히게 되었으며 Office의 경우 Windows가 아닌 VC++의 CRT 라이브러리를 쓰는 형태로 바뀌었다.

그러고 보니 옛날에는 플랫폼 SDK 내지 DDK에 내장돼 있는 무료 컴파일러와 Visual C++ 컴파일러도 서로 달랐다. 그러나 이 역시 지금은 통합이 이뤄졌다. Visual C++이 일부 기능이 빠진 무료 express 에디션이 2003~2005 사이부터 나오기 시작했으며, 2013부터는 아예 MFC와 리소스 컴파일러까지 다 포함된 Community 에디션이 통째로 조건부로나마 무료로 풀렸으니 말이다. 플랫폼 SDK에 내장된 무료 C/C++ 컴파일러는 비주얼 C++ 원판에 비해서는 최적화 성능이 떨어지는 물건이었으나 그것도 비주얼 C++의 오리지널 컴파일러가 대체를 하게 됐다.

마소 내부에서 컴파일러는 비주얼 C++로 이렇게 교통 정리가 돼 가고 있으나, 워낙 다양한 버전들이 난립하고 있으니 요즘은 혼란의 여지를 원천봉쇄하려고 Visual C++ 2015부터는 "CRT 정도는 어지간해서는 각자 걍 static link하세요. 디스크 용량도 많은데.. ㄲㄲㄲ" 이러는 추세이다. 어찌 보면 CRT의 DLL 링크라는 개념이 존재하지 않던 16비트 시절로 회귀하는 것이기도 하다.

Posted by 사무엘

2015/07/20 19:21 2015/07/20 19:21
,
Response
No Trackback , 5 Comments
RSS :
http://moogi.new21.org/tc/rss/response/1118

뉴 허라이즌스 호, 명왕성 접근

지난 7월 14일, 인류는 드디어 "명왕성과 카론의 모습을 실제 컬러 사진으로 볼 수 있는 시대"를 맞이하게 되었다. (☞ 관련 링크)

사용자 삽입 이미지

와 세상에~!! 우주덕 천문학 덕후라면 저 사진 보고 감격에 눈물이 줄줄 흐르지 않을까 싶다.
이미 위키백과와 각종 인터넷 사이트들은 지금까지 상상도 아니면 작은 점으로만 존재하던 명왕성 그림/사진들을 죄다 레알 표면 사진으로 업데이트한 지 오래이다.

내가 대학 졸업한 지 얼마 안 되어 병특 회사에 다니고 <날개셋> 한글 입력기 버전이 3.x 후반대이던 2006년 1월, 뉴 허라이즌스 호가 발사되던 시절의 기억이 아직도 생생하다. 그리고 그게 우주 공간에서 총알보다 훨씬 더 빠른 속도로 무려 9년 반을 날아간 뒤에야 인제 명왕성에 그럭저럭 도착했다. 욕봤다. 몇 년 전에는 "쟤는 아직도 토성과 천왕성 사이의 방대한 허허벌판을 열나게 뺑이 치며 날아가고 있겠구나!"하고 생각했더랬다.

뉴 허라이즌스 호가 있는 곳은 여기서는 빛이나 전파로도 가는 데 거의 5시간 반이나 걸린다. 그리고 지난 14일 저녁에 명왕성을 제일 가까이 통과했다.
명왕성에 무슨 착륙을 한다거나 하는 건 아니기 때문에, 인증샷 찍고 제대로 관측과 탐사를 할 수 있는 시간은 단 몇 시간에 불과함.

뉴 허라이즌스는 1970년대의 작품인 보이저 1, 2와 파이어니어 10, 11에 이어 21세기에 오랜만에 발사된 외행성 탐사선이다.
옛날에 보이저 2호는 때마침 외행성들이 쭉 늘어선 시기에 발사를 잘 한 덕분에, 명왕성은 말고 지금 우리가 보고 있는 천왕성과 해왕성의 근접 사진을 유일하게 전해 줄 수 있었다. 토성에서 천왕성, 천왕성에서 해왕성까지 가는 데 2, 3년씩 걸렸다. 그만큼 거기는 공간이 방대하다.

그 뒤, 명왕성은 나름 유일하게 미국인이 발견한 태양계 행성이라고 해서 미국에서 애착을 많이 가졌다.
하지만 해왕성 이후로 거기는 뭔가 행성다운 행성이 없고, 명왕성은 너무 작았다. 더구나 유사 궤도에 명왕성과 비슷하게 생긴 왜소행성들이 연달아 발견되면서 명왕성은 행성 지위를 잃게 됐다. 그렇게 결정된 게 하필 뉴 허라이즌스가 발사된 지 얼마 안 된 2006년 8월인 것도 참 절묘하다. 그래서...

사용자 삽입 이미지

<입시명문 사립정글고>라는 웹툰에서는 명왕성이라는 이름의 학생이 저렇게 멘붕해서 열폭· 자폭하는 장면도 나왔다. =_=;;

한편, 킹 제임스 성경 신자라면 친숙할 라킨의 <세대적 진리>라는 책에도 행성들이 늘어선 태양계 그림이 있다. 그런데 거기에는 해왕성까지만 있고 명왕성이 없다.
그 이유는 그 책 자체가 명왕성이 발견되기 전에 만들어졌기 때문이다. 명왕성은 1930년, 1차 세계 대전도 끝나고 대공황 이러던 시절에 클라이드 톰보라는 천문학자에 의해 발견됐다. 아마 은하의 생성 방식도 성운설이 대세이던 시절이었을 게다.

사용자 삽입 이미지

본인의 모교 고등학교에는 천문 동아리가 있었는데 이름이 POP (명왕성 너머의 행성)였다. 지금도 같은 이름으로 잘 돌아가고 있는지 모르겠다.

태양계에서 태양이 전체 물질들의 질량의 99%를 넘게 차지하는 중력 끝판왕인 것은 사실이지만, 한편으로 그 중력이 내는 인력은 거리의 '제곱'에 비례해서 급격하게 곤두박질치기도 한다.
해왕성보다도 더 먼 거리에 설마 단독 궤도를 가질 정도로 충분히 무거운 행성이 또 존재할 수 있을까? 행성이 딱 8개가 있다는 건 마치 정다면체가 딱 5개 있다는 것과 비슷하게 들린다.

그리고 끝으로.. 명왕성의 '명'은 한자가 '어두울 명'(冥)이다.
'사다'와 '팔다'가 형성자로 같은 '매'이고 '주다'와 '받다'가 역시 형성자로 같은 '수'인데 '밝다'와 '어둡다'까지 같은 '명'이라니 본인은 한자 내지 중국어가 참 이상한 문자와 언어라는 생각을 오랫동안 했다. 저런 반의어의 소리가 동일해도 될 정도로 중국어는 성조가 음운 변별에서 차지하는 비중이 매우 큰 것 같다. 물론 한국어에서는 '어둡다'라는 한자어는 '암'(暗)이 더 많이 쓰이긴 하지만 말이다.

Posted by 사무엘

2015/07/18 08:32 2015/07/18 08:32
, , ,
Response
No Trackback , 5 Comments
RSS :
http://moogi.new21.org/tc/rss/response/1117

이탤릭체 이야기

라틴 알파벳에는 다른 문자와는 달리 이탤릭이라고 약간 기울이고 흘려서 쓴 변형 서체 유형이 있다. 획을 진하게 하는 '볼드'와 더불어, 산술적인 변형뿐만 아니라 아예 별도의 폰트를 만들어서 제공 가능한 글자 속성 중 하나이다.

옛날에 비트맵 글꼴 시절에는 윗첨자· 아래첨자와 더불어 이탤릭은 아예 별도의 글꼴(폰트 패밀리)로 제공되는 게 보통이었다. 그러나 출력 장치의 해상도가 올라가고 결정적으로 윤곽선 글꼴 기술 덕분에 글자의 크기 제약이 없어지면서 이탤릭과 윗첨자· 아래첨자는 모두 아무 글꼴에나 추가로 적용 가능한 '변형 속성'으로 바뀐 지 오래다.

우리는 지금까지 이탤릭을 아마 수학식에서 가장 자연스럽게 보고 써 왔을 것이다. 수학에서 일종의 '예약어'라 할 수 있는 sin, lim, log 같은 단어은 반드시 regular 정자체로 쓰고, 나머지 임의의 변수명은 이탤릭으로 썼으니 말이다. 단, 소문자 이탤릭을 너무 흘려서 쓰면 그리스 문자와 구분이 어려워지기도 하므로 주의가 필요하다. 예를 들어 a와 알파, n과 η, x와 χ 같은 것.

개인적으로 20여 년 전, 아래아한글 2.1이던가 2.5에서 처음 도입된 수식체를 아주 좋아했다. regular 모양은 신명조와 별 다를 바 없지만 이탤릭이 굉장히 미려했기 때문이다. 실제로 각종 수학 교재나 상업용 출판물에서 쓰인 서체이기도 했다.
지금 아래아한글은 수식의 서체가 뭔가 LaTex스러운 서체로 바뀌었고 마소 제품의 경우 한때는 그냥 타임즈이다가 지금은 다른 걸로 바뀌었는데... 난 아래아한글의 원조 수식체가 지금도 그립다.

사용자 삽입 이미지

한편, 킹 제임스 성경 신자라면 원문에 없는 단어를 뜻하는 이탤릭체 표기가 아주 친숙할 것이다. (사실은 옛날 한글 개역 성경에도 본문보다 "약간 작게 쓴 글자"가 있어서 개념적으로 동일한 역할을 하긴 했다.)

이탤릭 서체는 세로 중심선이 사선 모양으로 기울어질 뿐만 아니라, 세리프 계열의 경우 세로획의 위· 아래 끝 부분이 살짝 둥글게 삐친 형태로 바뀐다.
이탤릭 전용 서체가 없는 글꼴은 응용 프로그램이 글자 모양을 그냥 수학적인 일차 변환으로 기울여서 찍어 준다. 이것은 엄밀히 말하면 (1) Oblique라고 불리는 다른 모양일 뿐 이탤릭이 아니다.

산세리프 계열에 속하는 서체들은 딱히 이탤릭이나 오블리크나 모양 차이가 별로 없어서 굳이 이탤릭 전용 서체가 필요한가 하는 의문이 들기도 한다. 뭐, 두 글자의 모양을 한데 포개서 차이를 비교해 봐도 되겠지만. 또한 알파벳 말고 숫자 역시 Times 같은 세리프 계열 서체를 봐도 그냥 그대로 기울인 오블리크와 별 차이가 없어 보인다. 숫자는 딱히 italic-ready 문자는 아닌 듯하다.

이탤릭은 정자체보다야 날려 쓴 듯한 느낌을 주지만, 모든 글자들이 한 획으로 완전히 이어진 (2) 필기체를 표방하는 것도 아니다. 가령, 소문자 i나 l의 이탤릭은 세로선이 기울어지고 위와 아래에 동그란 삐침까지만 있지, 필기체처럼 두 선이 한 점에서 만나는 획이 생긴다거나 하지는 않는다.
Brush Script 같은 필기체 계열의 서체들은 정자체 모양이 태생적으로 이미 좀 기울어진 형태이기 때문에 또 이탤릭을 적용하는 것은 무의미하다.

끝으로, 세로 중심선은 90도 수직선인데 이탤릭체에 적용되는 삐침만 적용한 (3) upright italic이라는 것도 타이포그래피 용어로는 있는 모양이다. 실용적인 의미나 가치가 무엇이 있는지는 잘 모르겠고 그냥 이런 게 있다는 것 정도이다.

이탤릭체는 글자의 수직 높이는 변함없는데 중심선이 약간 기울어짐으로써 실질적으로 글자의 크기가 약간 더 커지는 효과를 낸다.
그런데 여기서 궁금한 게 있다. 이탤릭체는 중심선을 정확하게 몇 도 기울이는 것이 정석일까? 여기에 통일된 규격이 있긴 할까?

MS Word의 경우, 이탤릭체가 적용된 글자로 마우스 포인터를 가져가면 신기하게도 포인터의 I자 모양도 이탤릭체 모양으로 기울어진 모양으로 바뀐다. 그리고 cursor(캐럿) 역시 단순 수직선이 아니라 기울어진 사각형 모양으로 바뀐다. 사선 모양이 굉장히 엉성하고 못생기긴 했지만 말이다.

화면 캡처를 해서 들여다보면, Arial, Verdana처럼 이탤릭 전용 서체가 있는 글꼴들은 세로선의 기울기가 5인 듯하다. 즉, 오른쪽으로 1픽셀 움직이는 동안 세로로는 대략 5픽셀이 움직인다. 이것은 각도로 환산하면 약 78.7도(수직선이 90도)이며, 따라서 11~12도 정도 기울이는 셈이 된다. 기울어진 cursor의 기울기도 이것과 얼추 일치한다.

한편, 이탤릭체 모양의 마우스 포인터는 화면을 확대해서 자세히 들여다보면 기울기가 4이다(약 76도).
흥미로운 것은 전용 서체가 없이 프로그램이 기본으로 구현하는 이탤릭이다. 얘는 기울기가 거의 3(약 71.5도)에 가까워서 누운 정도가 위의 글자들보다 더 과격하다. 따로 새로 만들어진 획이 없이 전적으로 산술적인 변형만으로 기울어짐을 구현하는 것이기 때문에 더 기울여 준 건지는 모르겠다. 아무튼 내부적으로 이런 차이가 있다는 것도 알면 흥미로울 것이다.

지금까지 설명한 모든 개념들의 예를 그림으로 정리하면 다음과 같다. Arial은 bold에 대해서도 전용 이탤릭 서체가 있는 반면, Arial Black은 전용 서체 없이 산술 연산으로 오블리크가 이탤릭의 역할까지 하고 있으며 기울기가 더 과격하다는 걸 알 수 있다.

사용자 삽입 이미지

Posted by 사무엘

2015/07/16 08:44 2015/07/16 08:44
,
Response
No Trackback , 3 Comments
RSS :
http://moogi.new21.org/tc/rss/response/1116

« Previous : 1 : ... 128 : 129 : 130 : 131 : 132 : 133 : 134 : 135 : 136 : ... 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:
4001352
Today:
1528
Yesterday:
6203