내 게임에서 몇 가지 외부 폰트를 사용한다. 익히 알려진 구글의 Noto sans와 Let’s go digital regular가 그것이다.
엊그제 UI레이어 코드 버그를 잡으면서 UWP빌드도 업데이트를 했다. 테스트 해보니 잘 도는거 같은데 뭔가 이상하다. Let’s go digital regular폰트가 제대로 나오지 않는다. 이게 8세그먼트 숫자로 표시되는 폰트인데 그냥 쌩 숫자로 나오네.
코드를 뒤져보니 UI코드 문제가 아니고 처음부터 폰트를 로드하는 부분을 주석처리 해놓고 있었다.왜냐하면 win32빌드에서 사용하는 AddFontResourceEx()함수를 UWP빌드에선 사용할 수 없었으니까. 초기엔 UWP빌드로 돌아가게 만드는것만으로도 벅차서 나중에 처리하자고 미뤄놨던 모양이다. 근데 왜 여지껏 눈에 안띄었지…?
하여간 눈에 띈 김에 이것도 제대로 처리해보자..라고 생각을 해서 이리저리 찾아봤다. uwp custom font로 검색해봐야 안나온다. 그런 문서는 없으니까.
겨우 스택오버플로우에서 DWrite에서 커스텀 폰트를 사용하는 방법에 대한 짤막한 글을 발견했다. 내 엔진의 UWP빌드는 폰트 처리에 DirectWrite를 사용한다. 일단 이건 실마리가 됐다.
DWrite custom font로 검색해보면 MSDN문서가 하나 나온다.
https://docs.microsoft.com/en-us/windows/win32/directwrite/custom-font-sets-win10
여기 예제를 참고해서 IDWriteFontSet까진 얻었는데 이걸 DWrite의 폰트 렌더링에 적용하는 방법은 없다.
인텔리센스의 도움을 받아가며 장님 문고리 잡듯 더듬더듬 DWrite관련 COM인터페이스를 뒤져서 IDWriteFactory3::CreateFontCollectionFromFontSet함수를 찾아냈다.
- MSDN 예제에서 IDWriteFontSet객체를 얻어오는데 이걸 CreateFontCollectionFromFontSet()에 넣어서 IDWriteFontCollection1 객체를 얻는다.
- DWrite의 폰트객체에 해당하는 IDWriteTextFormat객체를 생성할때 CreateTextFormat()함수를 호출한다. 이때 IDWriteFontCollection1객체를 넣어주면 IDWriteFontCollection1에 등록된 폰트를 참조하게 된다.
이렇게 해서 Noto sans와 Let’s go digital폰트를 UWP빌드에 적용시켰다. 기술 자체는 별것도 없지만 이 중간 과정에서 엄청 헤맸다. 망할. 정확한 자료가 있어야 말이지. IDWriteFactory3::CreateFontCollectionFromFontSet()를 찾아보면 MSDN에 딸랑 한줄 적혀있다.
“Create a weight/width/slope tree from a set of fonts”라고.
이 삽질을 하면서 찾아보면 문서들이 다 이런식이다.
난 COM스타일에 거부감이 있는것도 아니고 AddFontResourceEx()한줄로 끝날 일을 대여섯개 이상의 함수와 50줄 이상으로 늘려놨다고 화를 내는것도 아니다.
ㅅㅂ. 문서는 제대로 적어놔야 할거 아냐. 이러니 윈도우 개발자가 줄어들지.
아니 뭐 ‘너희 하찮은 것들은 윈도우 네이티브 개발하지 말라’는 MS의 뜻을 이해하지 못한 내 잘못인지도 모르겠다.
D3D12도 그렇고 문서 개같아서 정말 고생 많이 했고 지금도 고생 많이 하고 있다. D3D12도 빡신데 심지어 MS에서도 이제 밀 생각이 없는 UWP의, 그 안에서도 특히 마이너한 C++ 게임 개발을 하니 아주 주옥 같다.
사실 UWP는 이제 할 이유가 없다. 그래도 엑박에서 내 게임 한번 돌려보려고 이 ㅈㄹ을 떠는건데. 나같은 변방의 인디 개발자에게는 ID@XBOX는 어디 독수리성운 가야 구경할 수 있는 희귀한 아이템일뿐이다. 그러니 환상종이라 불리는 XBOX Series X를 손에 넣더라도 내 게임을 돌려보려면 3등 시민인 UWP API로 어떻게든 게임 빌드를 유지하지 않으면 안된다. 안그래도 전의 상실인데 MS하는 짓거리 보면 정말 하기 싫어지네.
빌어먹을 MS. 엿이나 처먹어라.