한글을 위한 fontconfig 설정하기


Hacking Log
6 minute read

최근 노트북에 Manjaro Linux를 다시 설치했는데, 한글 글꼴 처리가 영 아쉬워서 삽질을 하다가 알게 된 깨달음을 간단히 적어봅니다.

fontconfig란?

Linux GUI 환경에서 글꼴 선택을 제어할 수 있는 라이브러리입니다. fontconfig 설정만 만져주면 각종 X-Window 어플리케이션 전반에서 글꼴을 가져다 쓰는 방법과 렌더링 정책을 바꿀 수 있습니다. 예를 들자면 이런 것들이 가능합니다:

  • serif, sans-serif, monospace와 같은 별명(Alias)에 대해 실제로 사용할 글꼴을 지정합니다.
  • Noto Sans 글꼴을 사용할 때, 알파벳은 Noto Sans 그대로 사용하지만 한글은 KoPub돋움을 사용하도록 합니다.
  • 리눅스에는 없는 굴림 글꼴을 찾게 되면 나눔고딕을 대신 사용합니다.
  • 특정 글꼴에 한정하여 힌팅 설정을 바꿉니다.

fontconfig의 한글 찾아 삼만리

Manjaro KDE 환경의 기본 글꼴은 Noto Sans입니다. 이 글꼴은 라틴 계열 문자에 대한 글꼴은 담고 있지만, 한글은 담고 있지 않습니다. 한글을 담고 있는 글꼴은 Noto Sans CJK KR입니다. 이 두 글꼴은 완전히 별개의 글꼴입니다. 하지만 Noto Sans에 없는 한글 글꼴을 굳이 대신하자면 Noto Sans CJK KR이 가장 적절한 선택일 것 같군요.

그렇다면 Manjaro KDE는 한글이 등장했을 때 Noto Sans CJK KR을 사용할까요? 아닙니다. 기본 설정값에 따르면 fontconfig는 Noto Sans에 대해 다음과 같이 동작하고 있습니다:

  1. 가능한 한 Noto Sans 글꼴을 사용합니다.
  2. Noto Sans에 정의되지 않은 문자가 등장한다면, sans-serif 글꼴을 사용합니다.
  3. 사실 sans-serif는 실존하지 않는 가상의 글꼴입니다. 이 글꼴의 존재는 fontconfig의 설정 파일에 의해 만들어집니다. 보다 자세히 설명드리면, sans-serif 글꼴은 자신이 지명되었을 때 대신할 수십 수백개의 글꼴 후보가 있고 fontconfig는 이를 순서대로 하나씩 시도해 보도록 되어 있습니다.
  4. 비 라틴계열 문자에 대한 후보군은 /etc/fonts/conf.d/65-nonlatin.conf에 정의되어 있습니다. 여기에 따르면 한글 글꼴을 다음 순서대로 시도합니다:
    1. NanumGothic(나눔고딕)
    2. UnDotum(은돋움)
    3. Baekmuk Dotum(백묵돋움)
    4. Baekmuk Gulim(백묵굴림)

따라서, Noto Sans를 사용할 때 한글 글꼴로는 아마도 나눔고딕을 사용하게 되겠군요. 정말 생각지도 않은 결과입니다.

이 문제를 해결하기 위해서는 설정을 우리가 직접 손 봐줘야 합니다. 하지만 앞서 말한 65-nonlatin.conf를 직접 수정하는 것은 좋지 않습니다. 이것은 fontconfig 패키지가 설치될 때 함께 딸려온 것이고, 이후에 fontconfig 패키지가 업그레이드되기라도 한다면 설정을 또 초기화해버릴 테니까요. 우리 취향에 맞도록 별도의 설정 파일을 만들어야 합니다.

사실, fontconfig는 사용자 개인화를 위한 준비가 되어 있습니다. /etc/fonts/local.conf가 바로 그것입니다. 여기에 여러분만의 개인적인 설정을 작성하면 fontconfig가 이를 알아차리고 반영하게 됩니다. 아마 여러분에겐 저 파일이 없으실 겁니다. 이럴 때는 Kate와 같은 텍스트 편집기로 새로 만들어 주시면 됩니다.

파일 내용은 이렇게 작성하시면 됩니다. 내친 김에 Noto Serif도 함께 설정해 보았습니다:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
	<alias>
		<family>Noto Serif</family>
		<accept>
			<family>Noto Serif CJK KR</family>
		</accept>
	</alias>
	
	<alias>
		<family>Noto Sans</family>
		<accept>
			<family>Noto Sans CJK KR</family>
		</accept>
	</alias>
</fontconfig>

이 설정 파일의 구체적인 문법에 대해서는 fontconfig 매뉴얼을 참조해 주세요. 여기서는 핵심만 간단히 얘기하겠습니다.

<alias> 태그는 글꼴 대체 규칙을 하나 만들겠다는 의미입니다. 대체하고자 하는 원본 글꼴의 이름을 바로 아래에 있는 <family> 태그에서 지정합니다. 이 원본 글꼴을 대체할 대상은 <accept> 태그 아래에다 늘어놓습니다. Noto Sans에 없는 글꼴은(12번 줄) Noto Sans CJK KR로 대체하겠다고(14번 줄) 지정했네요.

<accept> 대신에 쓸 수 있는 규칙으로는 <prefer><default>가 있습니다. <prefer>는 원본 글꼴보다도 우선해서 사용하라는 의미이고, <default>는 아무것도 대신할 수 있는 게 없을 때 이걸 쓰라는 의미입니다.

이제 파일을 저장하고 재부팅해 주시면 Noto Sans와 Noto Sans CJK KR을 버무려 쓰게 됩니다.

Noto Sans + Noto Sans CJK KR = EPIC FAIL

‘위메프’와 ‘뽐뿌’ 글자가 위로 쏠려서 렌더링된 것이 보이시나요? 이는 Noto Sans CJK KR 글꼴의 문제로 보입니다. 글꼴 디자인 과정에 위쪽의 여백은 없고 아래쪽은 넘치게 만들어 놓은 것 같습니다. 결국 Noto Sans CJK KR 글꼴부터가 별로 좋은 녀석은 아니었던 거죠.

역시 오픈소스 주류가 아닌 변방의 나라는 서글픈 게 많습니다. 하지만 우리는 답을 찾을 것이다.

Noto Sans + KoPub돋움 = Profit!!

결국 이 문제는 Noto Sans에 어울릴 만한 좋은 한글 글꼴을 찾으면 해결되는 것입니다. 추천드릴 만한 산세리프 계열 글꼴로는 나눔바른고딕이나 KoPub돋움이 있습니다. 저는 개인 취향에 따라 KoPub돋움을 사용하겠습니다.

먼저 글꼴을 설치해야 합니다. KoPub돋움은 한국출판인회의에서 전자책 분야 진흥을 위해 무료 사용으로 배포하고 있습니다(링크). 제공하는 글꼴이 여러가지로 있습니다. 한 가지 분류로는 World가 붙은 것과 그렇지 않은 것인데요, 일반 글꼴은 한글과 영어만 대응하고 있다면 World 글꼴은 일본어, 라틴어 등등 다양한 언어의 문자를 추가 지원하는 글꼴입니다. 또 다른 분류로는 윈도우용OS X용이 있는데, 실상은 윈도우용=ttf, OS X용=otf 입니다. otf 글꼴은 글꼴 이름 꼬리에 _Pro가 붙어 있습니다.

저는 Manjaro 리눅스를 사용하기 때문에, 이걸 한국출판인회의 공식 사이트가 아닌 AUR에서 받아서 설치하였습니다. 우분투 등의 배포판을 사용하시는 분들께서는 아마 공식 사이트에서 직접 받아 설치하셔야 할 겁니다.

이제 local.conf는 이렇게 바뀝니다:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
	<alias>
		<family>Noto Serif</family>
		<accept>
        	<family>KoPubWorldBatang</family>
			<family>Noto Serif CJK KR</family>
		</accept>
	</alias>
	
	<alias>
		<family>Noto Sans</family>
		<accept>
        	<family>KoPubWorldDotum</family>
			<family>Noto Sans CJK KR</family>
		</accept>
	</alias>
</fontconfig>

<accept> 안에서 Noto Sans CJK KR에 앞서 KoPubWorldDotum을 추가하였습니다. 이제 KoPub돋움을 먼저 시도하고, 그 다음에 Noto Sans CJK KR을 시도하게 됩니다.

그 결과는 다음과 같습니다. 만세!

sans-serif에 Noto Sans를 추가하자

이제 중요한 건 다 해결이 되었습니다만, 조금 아쉬운 부분이 남았습니다. Noto Sans가 아닌 sans-serif로 글꼴을 지정하게 되면 또 다시 나눔고딕이 등장한다는 것이지요.

그냥 sans-serifNoto Sans를 쓰면 안 될까요?

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
	<alias>
		<family>Noto Serif</family>
		<accept>
			<family>KoPubWorldBatang</family>
			<family>Noto Serif CJK KR</family>
		</accept>
	</alias>
	
	<alias>
		<family>Noto Sans</family>
		<accept>
			<family>KoPubWorldDotum</family>
			<family>Noto Sans CJK KR</family>
		</accept>
	</alias>
	
	<alias>
		<family>serif</family>
		<prefer>
			<family>Noto Serif</family>
			<family>KoPubWorldBatang</family>
			<family>Noto Serif CJK KR</family>
		</prefer>
	</alias>
	
	<alias>
		<family>sans-serif</family>
		<prefer>
			<family>Noto Sans</family>
			<family>KoPubWorldDotum</family>
			<family>Noto Sans CJK KR</family>
		</prefer>
	</alias>
</fontconfig>

serif, sans-serif에 대한 <alias>를 추가하였습니다. <prefer>를 사용한 것에 주의하시기 바랍니다. 그리고 Noto Sans 규칙에서 이미 지정했던 KoPubWorldDotumNoto Sans CJK KR을 다시 추가해 주었다는 점에도(24, 25번 줄) 주의해 주세요.

원래대로라면 Noto Sans만 추가하면 끝나야 했습니다. 이렇게요:

  1. sans-serif 글꼴을 사용하려고 시도합니다.
  2. Noto Sans<prefer>의 가장 처음에 있으므로 이 글꼴을 쓰려고 합니다.
  3. 그러고 보니 Noto Sans에도 규칙이 있습니다.
  4. 규칙에 따라 KoPub돋움을 사용합니다.

하지만 이게 생각대로 동작하지 않습니다. 여기에 대한 제 추측은 이렇습니다. 우리의 local.conf에 앞서서 /etc/fonts/conf.d/45-noto-sans.conf가 먼저 적용되는데요, 여기에 따르면 Noto Sans의 <default>sans-serif입니다. 즉 이렇게 되는 거지요:

  1. 45-noto-sans.conf에 따르면 Noto Sans의 최종 대체제는 sans-serif입니다.
  2. 이 상황에서 sans-serif를 사용하려고 시도합니다.
  3. 우리의 local.conf에 따르면 sans-serif의 첫 번째 타자는 Noto Sans입니다.
  4. 근데 1번 규칙에 따라 Noto Sans는 sans-serif를 사용할 지도 모릅니다!
  5. 무한한 꼬리물기가 발생할 수 있다는 걸 깨달은 fontconfig는 나중에 등장한 규칙인 local.conf의 규칙을 무시합니다.

그래서 어쩔 수 없이 sans-serif에 KoPub돋움과 Noto Sans CJK KR에 대한 줄을 다시 써 준 것입니다. 아쉽네요.

fontconfig, Linux, 한글, 한국어, 글꼴, GUI, Noto, Noto Sans, KoPub돋움