앙골모아에 보면 좀 희한하게 생긴 글꼴이 하나 있다. 원래는 (완벽하게 내가 다 그린 건 아니지만 실질적으로 내가 조정을 가해서 내가 그린 거나 마찬가지인) 비트맵 글꼴인 것에다가 반자동 보간을 넣어서 확대해도 말끔하게 보이게 한 것인데, 음… 어쩌다가 보니까 여기까지 왔는지. 그래서 소개합니다. “나름” 유니코드 글꼴을 지향하는 Unison 글꼴입니다.

…시작할 때는 이 정도로 커질 거라고 생각을 안 했는데 정신을 차려 보니 꽤 많이 그려 놓았다. 참고로 글자를 어떻게 그리냐 하면 이렇게 그린다. 이런 걸 1천개 정도 그렸다. (물론 유니코드 BMP만이라도 커버하려면 5만개 정도 더 그려야 한다.)
glyph sz-lower
........
........
........
./@@@@\.
.@@..@@.
.@@..@@.
.@@.d@/.
.@@.9@\.
.@@..9@\
.@@...@@
.@@...@@
.@@...@@
.@/@@@@/
........
........
........
glyph ß = sz-lower
물론 한글 같은 것도 있고 문자 조합 시스템도 만들어져 있다. 이렇게 써 놓으면 꽤 거창해 보이지만 그냥 문자열 장난이다. 대부분은 노가다…
글꼴 라이선스는 아직 정하지 않았다. 뭐 쓰는 데 제약을 둘 생각은 전혀 없지만 GPL+FE로 할 것인가 SIL OFL로 할 것인가 같은 류의 선택을 경험이 없어서 아직 할 단계가 아닌지라, 정말로 쓸 생각이라면 이 점은 주의하시길. 이 글의 나머지 부분은 글꼴을 만들면서 생긴 이런 저런 일들을 주저리 주저리 써 보도록 한다.
1 글꼴을 무에서부터 만들어 보자
사실 글꼴을 한 번 만들어 보고 싶다는 생각은 옛날부터 있었다. 그러나 폰트포지 같은 것을 쓰기에는 처음부터 알아야 할 것이 꽤 많아 보이기도 했고, 글꼴을 만든다고 해도 도대체 어떤 모양으로 만들어야 하지?(…) 같은 생각 때문에 그냥 생각으로 그쳤다. 그러다가 모 IRC 채널에서 비트맵으로 유니코드 글꼴을 만드는 괴인 무모한 사람을 봐서, 좀 황당하다 싶었지만 비트맵 글꼴이면 그래도 할만하지 않을까? 하고 옛날에 만들었던 글꼴이 생각나서 가져다가 이것 저것 살을 붙이기 시작하니 이 지경이 되었다. 정말로 우연한 계기였다.
그래서 사용할 수 있는 글꼴을 처음부터 만들었냐 하면, 그건 아니다. 첫 2주 동안은 SVG 출력만 있었다. (실시간 미리보기와 별개로 글리프 샘플 페이지가 따로 있는 게 이 시절의 잔재이다.) 좀 더 정확하게 말하면, 앙골모아 1.0에서 쓰던 글꼴은 서브픽셀 보간을 거의 자동(!)으로 하고 있었는데, 휴리스틱에 문제가 있어서 일부 글자(#
같은 것)에서 보간을 안 하게 설정해 놓았다가 2.0 만들면서 “이럴 바에는 그냥 보간 정보를 글꼴에 넣자”라고 생각해서 보간 정보를 데이터로 독립시킨 것을 SVG로 옮긴 게 시초이다. 물론 이 시점에서 윤곽선을 딸 생각은 안 했고 각 픽셀을 그냥 무식하게 도형으로 그린 게 전부였지만.
초기에는 라틴 문자를 많이 그렸기 때문에 발음 구분 기호(diacritics)가 많이 필요해서 조합 시스템은 처음부터 만들었다. 합자(ligature)나 조합 가능한(combining) 문자는 별 생각을 안 했기 때문에 (왜냐하면 이들을 구현하려면 오픈타입에 대한 지식이 필수라는 걸 알고 있었기 때문에) 일단 그 쪽은 생각을 제쳐 두고, 유니코드에 이미 조합된(pre-combined) 문자들부터 먼저 채워 나갈 생각으로 만든 조합 시스템이라 기능은 단순했다. “그냥 특정 위치에 다른 이름의 글리프를 출력하라” 하나 뿐. 나중에 이름을 짜맞춰서 자동으로 글자를 만들거나(특히 한글), 기본 조합 위치를 지정하거나 하는 등의 개선 사항이 있었지만 근간은 그대로 유지하고 있다. 나중에 뒤로 미뤄 두었던 오픈타입에서의 문자 조합을 잘 살펴 보니, 물론 내가 생각했던 글리프 조합도 가능했지만 GPOS 테이블을 사용한 반자동 조합도 가능하다는 걸 알고 뭔가 많이 삽질을 한 것 같아서 기분이 묘해졌다. (실제로는 이 또한 “반자동”이므로 내가 했던 작업의 연장선에 가깝긴 하다. 위치 지정하는 작업이 똑같다.)
글리프를 텍스트로 그리는 것은… 시작하긴 편했지만 작업하면 할 수록 멘탈이 붕괴되더라. 일단 하나의 데이터로 비트맵 글꼴과 보간된 윤곽선 글꼴을 함께 표현할 수 있게 하려고, 서브픽셀을 나타내는 문자가 비트맵에서 해당 픽셀이 그려지느냐의 여부와 확대시 어떻게 보간될 것이냐의 정보를 함께 나타낼 수 있게 하였다. 위의 데이터에서 /
같은 것과 d
같은 것의 차이가 바로 그것. 그런데 시간이 지나다 보니 1:1 경사로는 도저히 그릴 수 없는 것들이 나타남에 따라 1:2 및 2:1 경사를 그리기 위해서 /d
와 같은 표기를 쓰기 시작했는데, 그렇게 하고 보니 모호한 경우도 생겨나고 (일단 코드에서는 최대한 잡으려고 하고 있지만) 원하는 글자를 도저히 그릴 수 없는 경우도 생겨나서 이거 확 갈아 엎어 버릴까 생각하고 있다. 아직 글리프를 텍스트로 그리는 걸 포기하진 않았다.
어느 정도 글자를 그리고 나니 진짜로 글꼴을 만들고 싶다는 생각이 들었는데, 물론 비트를 하나 하나 쪼개서 만드는 미친 생각은 하지 않았고 fontTools를 사용했다. TTX라고 해서 글꼴 포맷과 거의 1:1 대응되는 XML 포맷이 있는데 이걸 생성하는 것이다. 템플릿으로는 은진체에서 시작해서 테이블들을 차례 차례 Unison의 그것으로 바꿔 나갔는데, 온갖 종류의 문제가 다 터졌다.
오픈타입 명세에는 전혀 기술되어 있지 않지만 구현체에 따라서 글꼴 테이블을 넣는 순서, 생략되어도 되는 필드, 생략될 수 없는 필드 등의 차이가 모두 다르다. 파이어폭스 같이 글꼴이 잘못되었으면 뭐가 틀렸는지 대강이나마 콘솔에 나오는 구현체는 정말로 축복받은 것이요, 필드 하나가 잘못된 거에 세 가지 모호한 오류를 내던 OS X의 서체 관리자부터 시작해서, 최악의 경우 뭐가 오류가 났는지 전혀 알 수 없는 윈도 글꼴 구현까지 다 처리해야 했다. 솔직히 내가 모르는 문제 더 많이 남아 있을 것이다…
비트맵 글꼴을 만들 때는 보통 행-열로 생각해서 왼쪽 위를 원점으로 잡곤 하지만, 트루타입에서는 물론 왼쪽 아래가 원점이다. 너무나도 당연한 것인데 미처 고려를 안 해서 나중에 꽤 삽질했다. (특히 문자 조합 시스템이 어중간하게 만들어져 있어서 더더욱)
구현에 따라서 조합 단계가 많으면 엄청나게 느려지는 경우가 있다. 내부 표현에서 의미론에 맞춰서 조합을 하는 경우가 많아서 테스트할 때 괴로웠는데, 나중에 불필요한 조합 규칙을 모두 인라이닝하는 코드를 도입해서 어느 정도 숨통이 트였다.
윤곽선을 제대로 따는 코드를 짜 놓고 나니 일부 획이 안 나오는 문제가 발생하기 시작했는데, 거두절미하고 결론부터 말하면 트루타입은 다각형을 그릴 때 non-zero winding rule을 사용하는데 맞추지 않아서였다. SVG도 같은 규칙을 쓰긴 하지만 윤곽선을 따기 전까지는 매 픽셀마다 도형을 그렸으니 자기 자신과 겹치는 도형을 그릴 일이 없었던 것. 그래서 winding number를 맞추려고 알고리즘을 짜느라 한 세월… 해 보면 알겠지만 생각 이상으로 어렵고 가장자리 케이스도 많아서 까다롭다. 제대로 짠 건지조차 의심스럽다.
윈도에서 정말 골때리는 문제가 하나 있었다. 유독 한글 첫 40문자(
가
부터갧
까지)만 글자가 안 그려지고 대체 글꼴로 바뀌어 버리는 것이었다. 이 동작이 보통 없는 글자가 대체 글꼴이나 대체 글리프로 바뀌는 것과는 완전 다른 동작이어서 매우 당황했는데, Uniscribe(윈도의 글꼴 렌더링 엔진) 샘플 코드까지 고쳐다가 테스트를 해 보니 Uniscribe의 일부 내부 엔진이 글리프 번호에 따라서 글리프는 있지만 문자 매핑만 씹어 버리는 괴상한 버그로 결론이 났다. (하필이면가
가 정확히 2048 - 40번 글리프였다!) 여전히 윈도 버그라고 믿어지진 않는데 동작이 그러하니 어쩌겠는가, 결국 한글만 순서를 바꿨다. 젠장.
그 밖에 다양한 호환성 문제가 있었지만 생략. 글꼴 만드는 것보다 글꼴을 플랫폼에 호환되게 만드는 게 훨씬 더 힘들다는 중요한 사실을 알게 되었다. 즉, 처음부터 오픈타입 글꼴로 만들려고 생각하지 않아서 여기까지 올 수 있었던 것이었다. 이 사실을 미리 알았으면 빠르게 포기하는 거였는데
2 글자들에 대한 노트들
어느 정도 글자를 그리고 나서 사람들한테 보여 주기 시작했는데, 그 때 받은 피드백을 바탕으로 + 내가 직접 Unison을 터미널 글꼴로 써 본 걸 바탕으로 조금 조금씩 글자들을 고치고 있다. 이 과정에서 결정해야 했던 것들을 모아 본다.
- 라틴 문자, 키릴 문자, 그리스 문자는 서로 구분하기 너무 힘들다. 근데 피드백 중에 이 세 문자들을 서로 구분이 되게 해 달라는 납득은 가면서도 충공깽한 요청이 있었다. 결국…

…난 최선을 다했다고 생각한다. (이마저도 라틴 T와 키릴 Т는 구분이 안 간다. 아오) 사실 이런 문제는 한글/한자 등에서도 계속 나타날 문제라서 각 문자별 가이드라인이 대강은 있지만 이 세 문자들은 글자도 많은데 겹치는 것도 많고… 아…
아르메니아 문자는 그냥 키릴 문자 다음 영역에 있어서 생각 없이 그리기 시작했는데, 완전 생각하지 못 한 복병을 하나 만났다. 아르메니아 영원 기호라고 불리는 커다란 그림인데… 저걸 16x16 비트맵에 끼워 넣을 생각을 하니 눈 앞이 깜깜해졌다. 뭐 어쩌겠나, 그려야지.
발음 구별 기호는 비트맵으로 그리기가 꽤 어렵다. 특히 비슷한 발음 구별 기호가 여럿 있는데 얘네들이 서로 중첩되어 나타나기까지 하는 경우… 일단 1픽셀 쓰는 것과 2픽셀 쓰는 것을 나누는 것으로 어느 정도 해결을 본 상태. 아, 그리고 얘네들은 글자와의 상대적인 위치가 엄청나게 중요해서 세부 조정도 필요하다. 피곤하다.
조합 시스템을 테스트하기 위해 비교적 초기에 점자와 육십사괘 문자들이 들어갔다. 얘네들이 BMP에 들어 있다는 것이 첫번째로 충공깽했고, 육십사괘 문자들이 모양 순서로 배치되어 있지 않다는 게 두번째로 충공깽…
한글 조합은 현재 초성 6벌, 중성 2벌, 종성 3벌이다. 조합 체계를 바꾸기 어려운 구조는 아니지만 옛한글(…) 같은 복병을 대비해서 너무 적지 않을 정도로만 유지하고 있다. 복잡한 글자들끼리 서로 구분이 안 가는 문제는 아직 고민 중.
한자는 조금 조금씩 그려 보고 있지만… 그리기 싫다. 일단 내부적으로 특수문자가 아닌 한자는 (다른 어지간한 문자와는 달리) 폭 1픽셀로 작업하기로 내정된 상태. 다만 링크 건 글자는 보통의 한자가 아니라 부수용 특수문자라서 2픽셀이다.
그리고 설마 눈치챈 사람이 있나 싶지만 맨 위에 있는 이미지에 있는 글자 중에 아직 작업 안 된 글자들이 몇 개 들어 있다(……). 없는 글자들은 그냥 대강 그려 넣었다(………).
3 앞으로
최초 목표는 ISO 8859-1을 커버하는 거였는데 (그 과정에서 겸사겸사 발음 구별 기호도 그리고) 이건 이미 완료되었다. 그럼 아마도 다음 목표는 WGL-4일텐데 이것도 90% 이상 완료된 상태이고, 그 다다음 목표는 IPA를 끝내고 한자를 제외한 KS X 1001 특수문자를 모두 그리는 것? 그 뒷일은 아직 생각하지 않았다. 어쩌면 정말로 한자를 그리기 시작할지도 모르겠지만;
재미로 시작하긴 했어도 각 문자들의 특성 같은 것을 몸으로 부딪혀 보면서 깨달아 보자는 나름 교육적인 목적도 가지고 있기 때문에 시간 날 때마다 계속 진행할 것 같다. 웹 글꼴로도 쓰려는 생각이 있는데, 현재 글꼴은 700KB 정도이긴 하지만 WOFF2로 압축하면 50KB(!!!!!)로 내려가기 때문에 이리 저리 쓸모 있지 않을까 싶기도 하다. 글꼴 디자인의 일관성을 위해서 그림까지 그려달라고는 안 하겠지만, 관심 있으신 분들의 피드백은 언제든지 환영.