투루타입 글꼴로 한글을 XmbDrawString 로 출력시 문제점

체스맨의 이미지

XCreateFontSet 으로 폰트셋을 만들어서, XmbDrawString 으로 출력하는 방법을 테스트하고 있습니다. X 윈도에서 한글 출력은 예전에 XDrawString16 으로 해본 정도인데, 좀 더 나은 방법으로 해보는 중인데요...

1. 만일 폰트셋을 다음과 같이 지정하면
"-*-*-*-*-*-*-24-*-*-*-*-*-*-*"
misc 비트맵 한글 폰트가 사용되지만, 한글은 제대로 보입니다. 그래서, 일단은 문자열이나 iconv 에 문제가 있지는 않은 것 같습니다.

2. 폰트셋에 다음과 같이 트루타입 글꼴을 적용했습니다.
"-*-gulim-*-*-*-*-32-*-*-*-*-*-*-*"
이 폰트는 윈도의 gulim.ttc 를 X 윈도에서 사용하는 것입니다.

이 경우, "안녕" 이라고 쓰면, 보통 한글 폰트가 없는 상태에서 출력되듯, ">H3g" 라고 보입니다. 물론 영문은 잘 출력되구요.

3. 트루타입 글꼴을 적용할 경우, XCreateFontSet 함수는 다음과 같은 문자셋이 없다고 알려줍니다.
JISX0208.1983-0, KSC5601.1987-0, GB2312.1980-0, JISX0201.1976-0

그래서 예상컨데, 한글 폰트가 없는 상태처럼 인식 돼 있는 것 같은데요... 위와 같은 문자셋에 해당하는 폰트가 gulim.ttc 로 부터 만들어진 폰트리스트에 없는 것 같습니다.

4. 반면 현재와 같은 상태로도 오페라 브라우저는 gulim 폰트를 사용해서, 한글을 잘 출력하고 있습니다.

한글 출력 관련 지식이 미천해서, 힌트가 될 조언을 주시면 도움이 많이 될 것 같습니다... 꼭 위와 같은 방법이 아니더라도, 다른 한글(다국어) 출력의 정석에 해당하는 방법이 있는 지 모르겠네요.

wkpark의 이미지

오페라같은 경우는 자체적으로 글꼴처리를 하겠죠. 모질라도 마찬가지고요.

Xmb*String() 계열을 쓰신다면 xlsfonts등을 써서 진짜 글꼴이 등록이 된건지 확인해보시길. 제가보기엔 gulim글꼴이 등록되지 않은 것 같습니다.

온갖 참된 삶은 만남이다 --Martin Buber

체스맨의 이미지

답변 주셔서 감사합니다...

오페라는 qt 의 텍스트 렌더 루틴을 사용하는 것 같습니다.

qt 소스를 검색해봤는데, xlib 용 텍스트 렌더 루틴은 오직 XDrawString16 만 호출되는 것 같습니다. 뭔가 잘 못 했는진 몰라도 이 함수 한 개만 찾을 수 있었습니다.

한글 출력은 어쨌든 성공은 했는데, 일관적인 방법은 찾지 못했습니다. 만일 qt 가 XDrawString16 만으로 모든 출력을 구현할 수 있었다면, 어떻게 그랬는지 감이 잘 안오네요. 현재까지 제 테스트 결과 입니다.

1. ksc5601.1987 폰트를 사용하면, 오직 XmbDrawString 으로만 한글을 출력할 수 있었고, iconv 를 사용하여 현재 설정된 locale 이 사용하는 문자 코드로 인코딩을 해줘야 제대로 출력이 됐습니다. 예를 들어, ko_KR.UTF-8 이면 UTF-8 로, ko_KR.euckr 이면 EUC-KR 로 원본 문자열을 인코딩 해줘야 제대로 출력이 됐습니다.

2. 윈도용 gulim.ttc 로부터 설정한 투루타입 폰트는 iso10646 폰트를 사용하면 한글을 출력할 수 있었고, 이 때는 XmbDrawString 으로 출력하는 방법은 찾지 못했습니다. 하지만, XDrawString16 으로는 출력이 가능했고, iconv 를 이용해서 UCS-2BE 로 원본 문자열을 인코딩 해줘야 제대로 출력이 됐습니다.

제가 qt 소스를 제대로 검색했다면, qt 는 XDrawString16 만으로 모두 구현한게 아닌가 싶은 생각이 듭니다. 오페라 바이너리 파일의 문자열을 검색해보니, XDrawString, XDrawString16 및 QT 의 drawTextItem ( 소스를 검색해보면, 최종적으로 XDrawString16 을 호출하는 메소드 ) 는 발견이 됐고, XmbDrawString 이나 Xutf8DrawString 은 발견이 되지 않았습니다. 하지만, 오페라는 어떤 한글 폰트든 잘 그려내고 있습니다.

저도 일관된 출력 방법을 찾고 싶은데, 뭔가 조언이 될만한 게 있으시면 알려주셨으면 합니다.

Orion Project : http://orionids.org

krisna의 이미지

X11에서 트루타입을 X core font를 사용하여 출력하는 것은 과거의 방법입니다.
현재는 대부분 Xft를 사용하고 있습니다 아마 Qt도 Xft를 사용하고 있을 것입니다.

/usr/include/X11/Xft/Xft.h 를 참조하세요.

굳이 과거의 X core font를 사용하실 것이라면 FontSet을 지정하실때 사용하실 폰트가 인스톨되어 있는지 확인 하셔야 할 것입니다. xlsfonts나 xfontsel를 사용하셔서 지정된 인코딩의 폰트가 존재하는 지 확인하세요.

X11환경에서 트루타입을 출력하실 것이라면, pango를 사용하실 것을 추천합니다.
그렇지 않다면, cairo나 Xft를 사용하시는 것이 좋을 것입니다.
X core font를 이용하게 되면 안티앨리아싱이 안됩니다.

체스맨의 이미지

음... 그렇군요. 저는 Xft 란게 있다는 것 정도만 알고 있었는데, 그냥 X 의 표준 API 에 기능들이 잘 흡수돼있는 걸로 알고 있었습니다. 그건 아닌가보네요.

그런데, 현재 qt-x11-opensource-src-4.3.4 에서 xft 를 키워드로 찾은 결과는 다음과 같습니다. 현재 리눅스 설치해서 쓰는 노트북 사양이 열악해서, qt 소스는 별도의 윈도 PC 에 풀어놓고 검색했습니다. 그래서 경로가 좀 그렇습니다.

C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\3rdparty\freetype\include\freetype\ftlcdfil.h(76):   *     This filter corresponds to the original libXft color filter.  It
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\3rdparty\freetype\src\cache\ftcmru.h(56):#define  xxFT_DEBUG_ERROR
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\gui\kernel\qapplication_x11.cpp(1642):        getXDefault("Xft", FC_DPI, &dpi);
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\gui\kernel\qapplication_x11.cpp(1650):        getXDefault("Xft", FC_SCALE, &fc_scale);
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\gui\kernel\qapplication_x11.cpp(1680):            getXDefault("Xft", FC_RGBA, &subpixel);
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\gui\kernel\qapplication_x11.cpp(1683):        getXDefault("Xft", FC_ANTIALIAS, &X11->fc_antialias);
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\gui\kernel\qapplication_x11.cpp(1685):        getXDefault("Xft", FC_HINT_STYLE, &X11->fc_hint_style);
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\gui\kernel\qapplication_x11.cpp(1688):        // ###### these are implemented by Xft, not sure we need them
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\gui\kernel\qapplication_x11.cpp(1689):        getXDefault("Xft", FC_AUTOHINT, &X11->fc_autohint);
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\gui\kernel\qapplication_x11.cpp(1690):        getXDefault("Xft", FC_HINTING, &X11->fc_autohint);
C:\DEVEL\QT-X11-OPENSOURCE-SRC-4.3.4\src\gui\kernel\qapplication_x11.cpp(1691):        getXDefault("Xft", FC_MINSPACE, &X11->fc_autohint);

제 생각으론, 위 코드들에서 xft 의 렌더 함수가 직접 호출었다고 생각하기가 어려워 보입니다.

현재 오페라 브라우저의 한글 출력 상태를 보면, 영문 폰트는 anti-aliasing 이 되는 중인 것 같고, 한글 폰트나 일어 폰트에 대해서는 그렇지 않은 것 같습니다...

현재 제 테스트 상태는, 일단 한글은 출력이 됐습니다. 그래서 폰트가 없는 상태는 아닌데, 일관적인 출력 방법을 찾지 못했습니다. XmbDrawString 을 qt 나 opera 가 쓰지 않고 있는 것으로 추측되는데도, 이들은 어떤 폰트든 잘 출력하고 있는데, 저는 경우에 따라 XmbDrawString 또는 XDrawString16 을 사용해야 하고, 현재 qt 소스에서는 iconv_open 의 to 인자에 사용되지 않는 것 같은, UCS-2BE 같은 코드 형식을 사용해야만 윈도 트루타입 폰트가 제대로 표시되는 등입니다.

Orion Project : http://orionids.org

krisna의 이미지

그래서 소스를 좀 봤습니다. Qt 3에서는 Xft로 그리는 것 같고, Qt 4에서는 XRender와 FreeType을 이용하는 것 같군요. (src/gui/text 부분을 참고)
이전에는 Xft를 사용하는 코드가 많았지만, 이제는 그렇지도 않은 것 같습니다.
물론 cairo도 Xft를 사용하고 있지 않구요. cairo도 Freetype으로 글리프 정보를 로딩하여 XRender로 그리는 것 같습니다. Xft도 내부적으로는 결국 freetype으로 로딩한 정보를 XRender로 그리게 됩니다.

어떻게 되었든 현재로서는 가장 손쉽게 트루타입 폰트를 X에서 출력하는 방법은 cairo를 쓰는 것입니다.
또는 Xft를 사용할 수도 있구요. 그러나 Qt나 cairo와 같이 저수준으로 접근하는 위의 방법을 따라가는 것은 좀 어렵지 않나 생각합니다.

그러나 cairo나 Xft를 사용하기 어렵고 굳이 Xlib의 interface를 사용해야 한다면
C language X interface 매뉴얼을 참고하셔서 텍스트 렌더링을 하시기 바랍니다.

http://www.xfree86.org/current/xlib.pdf

Xmb 함수 계열은 로캘 인코딩에 따른 스트링을 전달해 주어야 작동합니다.
폰트셋은 "*,*" 과같이 리스트로 전달해주는 것이 좋습니다.
폰트셋에서 문자셋이 없다고 나온다면 나머지 인코딩을 제공하는 폰트가 로딩될 수 있도록 해야 합니다.

체스맨의 이미지

아래 그림은 현재 오페라를 실행했을때 문자열 출력 상태입니다. 영문 폰트는 anti-aliasing 이 적용된 것으로 보이고, 한글은 그렇지 않습니다.

아래 그림은 /usr/lib/libXft* 를 /tmp 로 옮겨 놓은 상태에서 오페라를 실행했을때 문자열 출력 상태입니다. 이들 라이브러리가 없어도 한글은 잘 출력되고 있습니다. 현재 오페라 설정은, 메뉴를 제외한 모든 폰트를 굴림으로 설정했습니다.

아래 그림은 제가 gulim 폰트를 써서 출력을 테스트해 본 결과입니다. 여기서 "KLDP" 문자열을 출력할 때 사용된 폰트와 위의 첫 이미지에서 KLDP 문자열을 출력할 때 사용된 폰트가 서로 다르다는 것을 알 수 있습니다. 두번째 이미지와는 같은 폰트로 생각이 됩니다만, 크기를 맞춰서 한번에 그린 것 같지는 않습니다.

그래서 예상컨데, 오페라 또는 qt 는 영문과 한글을 서로 다른 폰트를 써서 렌더링 하고 있고, anti-aliasing 이 적용된 것은 트루 타입이 아닌 영문 폰트쪽에만 해당하는 것 같습니다... ( 두번째 그림의 영문 폰트는 anti-aliasing 이 적용된 경우처럼 윤곽이 흐릿하지 않습니다. ) 그리고 한글은 Xft API 를 써서 출력한 것이 아닌 것 같습니다.

댓글 첨부 파일: 
첨부파일 크기
Image icon noxft.png2.53 KB
Image icon withxft.png6.33 KB
Image icon engfnt.png500바이트

Orion Project : http://orionids.org

krisna의 이미지

두번째 그림의 영문도 굴림은 아닌 것 같습니다. fontset에 지정된 영문 폰트로 그려진 것 같군요. 크기가 달라서 발생한 것이 아닐 것입니다. xfontsel 프로그램을 사용하시면 저 영문 폰트를 x core font에서 확인 하실 수 있을 것입니다. 아마도 schumacher clean 같군요.

리눅스에서 트루타입 글꼴을 어떻게 설정하는지 관련 문서를 좀 찾아 보시는 것이 좋겠습니다.
같은 폰트 출력루틴을 사용하더라도 글꼴에 따라서, 글자 크기에 따라서 anti-aliasing이 적용되지 않을 수 있습니다.

체스맨의 이미지

답변 감사드립니다. 여러 정보들이 도움이 되었습니다. 그리고, 어느 정도 정리가 되어갑니다.

우선 외부 라이브러리 사용은, Xlib 만으로 구현하는 것 보다는 훨씬 용이할 것으로 생각하고, 일단은 최소의 외부라이브러리를 사용하는 것을 목표로 하고 있습니다.

ksc5601 의 경우 검색에서 쉽게 찾을 수 있는 것처럼, EUC-KR 코드에서 상위 비트를 클리어하면, XDrawString16 함수로 출력이 가능합니다. 제 이전의 테스트에서 안됐던 것은, 제 실수였는데, vim 이 EUC-KR 문자열을 잘 못 저장했거나, 어디서는 잘못 변경되어 저장된 탓이었던 것 같습니다. 아마, qt 나 오페라도 이와 유사한 작업은 하고 있을 것이라 생각합니다.

XChar2b c;
c.byte1 = s[i] & ~0x80;
c.byte2 = s[i+1] & ~0x80;

gulim.tcc 로부터 얻은 iso10646 은 리틀엔디안일 것이기 때문에, UCS-2BE 로 해야 된다는 것이 의아했으나, UCS-2LE 로 하고, ksc5601 과는 반대로 순서를 뒤바꿔 저장해주면 되기 때문에 그런 정도로 정리할 생각입니다.

iconv( ... );
...
XChar2b c;
c.byte2 = s[i];
c.byte1 = s[i+1];

Orion Project : http://orionids.org

체스맨의 이미지

한가지 궁금한 점이 더 남은 것은, iso10646 트루타입 폰트인 경우, XDrawString16 으로 문자열을 렌더링하기 위해 항상 USC-2 로 인코딩하면 되는 것인지 하는 문제입니다.

제게 다른 트루타입 폰트가 없어서 윈도용 폰트 말고 다른 폰트를 구해서 테스트 해봐야 할 것 같습니다... 혹시 이 부분에 대해 아시는 분은 알려주시면 도움이 되겠습니다. 관련된 포괄적 정보를 알 수 있으면 좋겠네요.

Orion Project : http://orionids.org

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.