소리통 BETA 업데이트: 안티알리아싱 삽질 스토리

@codemaru · November 08, 2007 · 9 min read

soritong.zip

소리통 BETA가 2007.11.8.293 버전으로 업데이트 되었습니다. 위에 있는 파일을 받으시면 됩니다.
음악 방송 청취 도중 네트워크 접속이 중단되는 경우 비정상 종료되는 문제가 해결되었습니다.
사실 이 문제는 고치는 데 몇 줄 되지도 않지만 다른 일로 제법 삽질을 했습니다.
그 이야기를 조금 해볼까 합니다. ^^;;

소리통 상단을 보면 파일 명이 큰 글씨로 출력되는 부분을 볼 수 있습니다. 외곽선 글꼴이라고 그러나요? 하여튼 뭐 테두리가 있는 글씨로 출력됩니다. 이것을 만드는 방법이 크게 두 가지 정도 있습니다. 하나는 글자를 8방향으로 돌아가면서 찍은 다음에 중앙에 실제 글자색깔로 찍는 방법이고, 다른 하나는 경로를 저장해 두었다가 StrokeAndFillPath 따위를 사용해서 그 경로를 칠하면서 동시에 테두리를 그리는 방법이죠. 딱 생각해보면 후자가 좀 더 우아해 보이지 않습니다. 그런데 실제 해보면 후자의 결과물은 꽤나 우스꽝 스럽습니다. 그래서 소리통에서는 전자의 방법으로 글자를 출력하고 있습니다.

그런데 여기서 사용하는 방법도 글자에 따라서는 조금 웃기게 출력되곤 합니다. 그래서 이걸 진짜 제대로 한 번 해결해 보고자 GDI 보다는 좀 더 기능을 많이 제공해 주는 2d 렌더링 엔진을 찾아보았습니다. 딱 떠오르는 GDI+가 있지만 처음에 그 녀석은 배제했습니다. 왜냐하면 GDI+의 경우 정적으로 링크 시킬 수가 없기 때문입니다. 무조건 DLL을 같이 배포해야죠. 물론 대부분 설치되어 있기 때문에 같이 배포하지 않아도 별 문제는 없습니다.

    BETA                    md 1

그림을 한 번 살펴보도록 하겠습니다. 다소 제 이름이 많이 나오는 걸 이해해 주세요. ㅋㅋ 중간 중간에 테스트 하던 것들에 대한 캡쳐 이미지가 이것 밖에는 없어서 어쩔 수 없었습니다. 처음엔 이런 내용을 쓸 줄도 몰랐거든요. ㅎㅎ

왼쪽 아래 있는 노란색 삼각형과 신영진이란 테두리가 있는 글씨가 GDI+대신 사용한 agg란 2d 렌더링 엔진으로 출력한 샘플 입니다. 여기까진 굉장히 만족스러웠습니다. 보시면 알겠지만 삼각형의 라인이 겹치는 부분이나 대각선에 안티알리아싱이 적용된 것을 보시면 깔끔하게 처리된 것을 알 수 있습니다. 외곽선 글꼴도 그냥 저냥 쓸 수 있겠다고 생각하고는 이 녀석을 소리통에 적용하기 시작했습니다. 그런데 이 판단엔 큰 실수 였습니다. 하나는 큰 글씨로 테스트 했다는 것이고, 다른 하나는 그 글꼴도 맑은 고딕으로 테스트를 했다는 점 입니다. 다들 아시겠지만 맑은 고딕은 클리어타입과 같은 안티알리아싱 기술에 최적화된 글꼴 입니다. 클리어타입을 적용하지 않고 보면 완전 엉망이죠. 하지만 적용하면 글꼴의 차원이 달라집니다.

이제 문제를 살펴보겠습니다. 그림에서 오른쪽을 살펴보면 메모장이 있습니다. 보시면 이름이 선명하게 출력된 것을 볼 수 있습니다. 이제는 오른쪽의 소리통에 출력된 글씨를 살펴 봅시다. 흐릿하게 보일 겁니다. 확대한 그림이 각각 옆에 있습니다. 안티알리아싱 때문에 글이 뭉개진것처럼 보이는 것을 알 수 있습니다. 아마 Photoshop을 해보신 분들은 대부분 이런 것들을 겪어 보셨을 겁니다. agg 라이브러리의 경우에 기본적으로 GetGlyphOutline이라는 함수를 사용해서 글꼴의 외곽선을 추출하고 그것을 다시 자신의 오브젝트에 넣어서 렌더링을 시킵니다. 결국 크든 작든 모두 다 벡터 방식으로 그려지는 것이죠. 그렇다면 안티알리어싱만 적용하지 않으면 될까요? 알아보지도 못할 글자가 출력된답니다. 윈도우는 작은 글꼴일 경우에는 글꼴에 저장되어 있는 비트맵을 사용하기 때문에 깔끔한 글꼴이 출력된답니다. 결국 agg를 쓰게 된다면 작은 글꼴은 다시 DC 함수로 적어줘야 하는 상황이 됩니다. 그렇게 하는 것이 불가능하지는 않지만 괜히 두 번 작업하는 것이 맘에 들지 않아서 GDI+를 사용해야 겠다고 생각을 했습니다.

GDI+는 과연 배포 문제만 제외한다면 모든 조건을 만족시킬까요? 하지만 안타깝게도 아니었습니다. GDI+의 경우는 안티알리아싱 알고리즘에 문제가 있어 보였습니다. 오른쪽 아래 있는 화면이 GDI+를 사용해서 경로를 추출해서 외곽선 글꼴을 그린 샘플입니다. 다른 글꼴에서는 문제가 덜 했는데 바탕체로 출력하니 정말 흉하게 되더군요. 녹색 상자가 있는 A 부분을 보면 정말 심하다는 것을 알 수 있습니다. 검은 부분이 위로 튀어나와 있죠. High 퀄리티 이상의 출력 옵션을 적용하는 경우에는 모두 저렇게 되었습니다. 안티알리아싱을 끄면 거의 보지 못할 만큼 흉한 글이 출력됩니다. (최신 GID+는 어떨지 모르겠습니다. Windows XP에 기본적으로 설치된 것으로 테스트한 것입니다.)

결국은 다시 원점으로 돌아와서 GDI에 그냥 8방향에 출력하는 것으로 해두었습니다. 돌아서서 생각해보니 GDI와 agg를 같이 쓰는 것도 별로 나쁠것 같진 않네요. agg의 경우 DC와 같이 작업하기 편리하게 되어 있기 때문에 굳이 하나만 고집할 필요도 없어 보입니다.

생각보다 쓸만한 2d 렌더링 엔진이 별로 없다는데 놀랐습니다. 제가 사용했던 agg 라이브러리는 여러 가지 면에서 굉장히 뛰어났습니다. 사실 거기 있는 샘플들을 구동해 본다면 라이브러리가 얼마나 많은 기능을 지원하는지 알 수 있습니다. 하지만 문서가 거의 없어서 소스를 보고 분석해서 사용해야 한다는 점이 좀 단점이었습니다. 괜찮은 엔진이나 외곽선 글꼴을 만드는 방법을 알고 계시다면 코멘트 달아주세용 ^^;;

@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중