삽질하는플머

예상못한 복병. 중국어와 베트남어.

탐구생활/Uniscribe

가벼운 마음으로 중국 야후에 들러서 간체 몇 개를 복사해 찍어보았다. 결과는 허거덩~~



기껏 만들어 둔 폰트링크와 폴백은 다 건너뛰고 뜬금없이 등장한 네모박스라니...
코드를 따라가보니 굴림체에서 중국어 간체에 대해 ScriptShape 가 무조건 성공했다는 결과를 낸다.
글립에는 네모만 달랑 던져놓고 말이다.

꼽사리로 집어넣었던 베트남어 역시 굴림체에서 성공으로 리턴. 결과는 네모박스. 장난하냐???

ScriptShape 를 처리하기 전에 ScriptItemize 결과값에 대해 MLang으로 미리 체크해서 폰트변경이 필요하면 그만큼 ItemRun 을 나눠주기로 결정. Shape 루프에서 폰트 링크와 폴백을 처리하지 않고 Shape 전단계에서 폰트 링크를 처리하고 링크에 실패한 ItemRun 만 Shape 중간에 폴백을 시도한다.

이 경우 힌두어의 공백문자가 자체적인 넓적한 공백 대신 기본폰트의 공백으로 대체되는 문제가 생겨난다. 하지만 이건 나름 장점이 될 수 있겠다. 공백문자를 폰트별로 준비하지 않고 기준폰트의 글립만 사용하게 되므로 메모리를 절약할 수 있으니까.

또 한가지 문제는, 아랍어같은 RTL 문자열에서 중간에 들어간 공백이 ScriptShape를 거치면서 LTR로 속성이 바뀐다는 것이다. 이때문에 기껏 잡아줬던 아랍어의 레이아웃이 예전처럼 틀어져버린다. 고민하다가 Shape - Layout 의 순서를 Layout - Shape 로 뒤집어주니 해결된다. 혹시나싶어 catch22.net 의 강좌를 열어보니 거기도 Itemize - Layout - Shape 순서로 되어있군. 나 뭐한거지...

아무튼 구덩이 두 개 새로 파주니 이제야 제대로 동작하는 중국어와 베트남어.



어제까지 작업으로 대충 리서치는 마무리된 줄 알았는데... 앞으로 또 무슨 문제가 튀어나오려나...


한가지 팁. ScriptShape 사용중에 표준컨트롤을 참조하게되면 얼토당토않은 에러가 발생한다. 폰트 폴백 만들기가 귀찮아서 리치에디트 컨트롤을 써먹어보려고 잔머리 굴리다 Uniscribe가 이상하게 동작하는 바람에 실패를 했는데, 폴백폰트 목록을 리스트박스에 임시로 넣어두고 꺼내려고 하니 동일한 문제가 생긴다. 유니스크라이브 루프 내에서는 윈도컨트롤에 접근하지 말자.


아랍어 글립 조립하고 VisualToLogical 적용하기.

탐구생활/Uniscribe
공백이 삽입된 힌두어를 MLang 으로 폰트링크 시도할 때, GetCodePages() 함수가 힌두어영역 전체를 판단하지 못하는 문제 때문에 소중한 여가시간이 홀라당 날아가버렸다. 으으 짜증나...

아무튼 힌두어와 태국어, 아랍어와 영문으로 구성된 유니코드 문자열을 VisualToLogical 정보에 따라 찍어보았다.
이제 "아랍 - 숫자 - 영문" 으로 구성된 문장도  표시될 때는 "숫자 - 아랍 - 영문" 으로 보여진다.





처음 구조를 고민할 때는 GetGlyphOutline() API 에서 얻은 글립메트릭스 정보를 사용하려고 했는데, 아랍어의 gmCellIncX 값이 이상하게 나온다. 태국어와 힌두어는 아무 문제 없었는데...

잠시 고민하다가 ScriptPlace() 함수에서 얻은 글립의 너비를 적용하였더니 제대로 표시된다.
게임내에서 단순한 출력만 원한다면, LTR / RTL 신경쓸 것 없이 단순히 글립을 조립해서 VisualToLogical 정보대로 뿌려주기만 하면 되겠군...

아직 만들지 않은 구조지만, 머리속에서 자꾸 갈아엎게되니 그것도 나름 스트레스...

아랍어는 숫자도 골떄려~

탐구생활/Uniscribe

유니코드 문자열 내에 "아랍어 | 숫자 | 영문" 순서로 들어있는 경우 화면표시는 "숫자 | 아랍어 | 영문" 이 된다.
생각해보면 어차피 아랍사람들도 숫자를 사용할 테고...이 경우 자기네 어순 배열에 맞게 적어갈 것이다. 물론 전체적으로는 RTL로 진행하다가 숫자부분만 LTR로... 날 죽여라~~~ 

ScriptLayout 이 원래 이 일을 해 주어야 하는데... 처음에 호출하는 ScriptItemize 의 인자값인 SCRIPT_CONTROL 과 SCRIPT_STATE 에 뭔가 비밀이 있을 것 같아 이리저리 뜯어맞춰봐도 제대로 된 표시를 얻을 수 없었다.

우연히 읽게 된 재미난 문서.
http://maxradi.us/documents/uniscribe/

MSDN에는 SCRIPT_CONTROL 값 대신 NULL을 넘겨도 관계없다고 되어있지만, 실제 이렇게 할 경우 RTL 정보를 제대로 얻을 수 없다는 언급이 있다. 응?? RTL?? 난 지금까지 catch22.net 의 강좌대로 클러스터의 요소가 배열증가에 따라 감소하는지 여부로 RTL을 판단했었는데??

아무튼 시키는대로 0으로 초기화한 구조체를 넘겨주니까, ScriptItemize로 얻은 ItemRun 의 ScriptAnalysis 정보에 fRTL 값이 제대로 설정된다. 그리고 그 옆에 fLayoutRTL 이라는 플래그도 눈에 띄네~~ 오오~~ 이거 혹시 이거 레이아웃에 쓰이는 RTL 정보 아냐??

ScriptLayout을 호출할 때 지금까지 썼던 ScriptAnalysis 의 uBidiLevel 대신 이 fLayoutRTL 을 넘겨줘 보았다. uBidiLevel은 ScriptItemize 호출시 SCRIPT_STATE에 지정한 값이 그대로 튀어나오길래 이상하다고 생각하고 있었거덩. 이렇게 하니 제대로 된 LogiclaToVisual 정보가 뽑힌다. 뒷발로 쥐밟은 격이지만 아무튼 만쉐~~!!



밑에 작은 숫자로 찍힌 값이 실제로 찍어야 하는 ItemRun의 순서.
저녁먹기 전까지 최대의 고민이었던 공백분해도 자연스러워졌다.


이제 각 ItemRun을 이 순서대로 재배치해서 찍어주면 일단 출력은 마무리된다. 그룹화된 클러스터 정보를 기반으로 캐릭, 단어, 줄바꿈까지 구현하면 대충 쓸만해 질 것이다.

체력고갈이다. 오늘은 그만 달리자...
 

오늘도 변함없이 유니스크라이브 삽질.

탐구생활/Uniscribe
회사일에 밀려서 시간내기가 힘들지만, 아무튼 간만에 달려보는 유니스크라이브.
아직 클러스터 적용은 하지 않았고 유니스크라이브로 변환한 글립을 단순히 비주얼 순서대로 찍어본 상태.
때문에 아랍어같은 RTL 문자열에서 공백위치가 반대로 되어있고 겹침글자 처리도 조금 어색하다.


뒷부분의 콘솔은 얻어낸 글립의 정보를 열심히 찍고 있는 중. 다행히 약간만 가공하면 텍스쳐로 쓰기 딱 좋게 나와준다.

폰트폴백은 일단, MLang 을 이용한 폰트링크를 일차로 시도하고 여기서 실패할 경우 예약된 폴백 리스트를 사용하는 방법을 쓰기로 함. 아랍어는 MLang 에 의해 Arial 로 잘 링크되지만 힌두어는 그렇지 않기 때문에...

힌두어가 들어간 Mangal 폰트를 폴백리스트로 지정하고 테스트.
문자열은 catch22.net 의 강좌에서 가져옴. 무슨 뜻인지는 당연히 모름.



태국어는 MLang 에 의해 Tahoma 로 링크된다.



오호, 대충 그럴듯해~~~


그나저나 네시간 동안 작성한 유효 코드가 달랑 이백줄 이라니...
구현해야 할 기능은 산더미인데... 갈 길이 멀구먼~~~

유니스크라이브, Uniscribe 개삽질 중...

탐구생활/Uniscribe

유니스크라이브의 ScriptString API 는 참 쓰기도 좋고 예쁘고 편리한데...
아무리 뒤져봐도 글립단위 캐싱에 쓸만한 정보는 없다.
결국 저수준 함수들을 사용해야 하는데... 폰트폴백에서 절망중.

http://lists.cairographics.org/archives/cairo/2005-January/002901.html
폰트폴백 메커니즘을 알 수 있는 뾰족한 방법은 없다는 야그.
때문에 다른 어플들은 다음과 같은 방법을 사용한단다.

1. Pango: config 파일에 폴백폰트 목록을 가진다.
2. OpenOffice 폴백폰트의 구성가능한 리스트를 저장하는 것으로 보임.
3. SWT (from Eclipse) MS의 MLang DLL을 사용한다. 링킹 메커니즘 적용.

일단 위에서 언급된 MLang 이라는 지원병의 힘을 빌어 폰트링크에 의한 폰트폴백을 구현해 본다.
아직 유니스크라이브의 클러스터 정렬을 적용하지 않은 상태라 단어단위로 배치가 뒤틀린 상태임.

파란색이 GDI 함수에 의한 일반적인 폰트폴백. 굴림 21포인트.
빨간색이 MLang 의 폰트링크에 의한 폰트폴백. 마찬가지로 굴림 21포인트. 
MLang의 경우 아랍어를 Arial 로 링크하게 되는데, 정작 굴림에서 링크되는 저 폰트는 뭔지 모르겠다.
미묘한 차이는 있지만 그럭저럭 비슷해보이니 일단 폴백은 이 정도에서 마무리 짓자.

이 외에도 Uniscribe 의 ScriptString 폴백과 차이점을 든다면,
  Uniscribe : FixedSys 로 설정시 폴백이 되지 않는다. 메모장도 이와 동일. 
  MLang : FixedSys 로 설정해도 폴백폰트를 얻을 수 있다. 워드패드와 동일. 

중국어 간체를 섞어서 찍어본 화면.
여러 국가의 폰트가 섞여있을 때는 DrawText 와 비교해 MLang 폰트링크의 품질이 훨씬 보기 좋다.



약 1년의 시차를 두고 비슷한 고민을 하던 분이 GPG에 계셨음. 
http://j.mp/dn5TkB

불행히도 GPG가 닫혀버려 더이상 토론이 불가능한 상태. ㅠㅠ;;
작년 5월 글인데... 얼마나 외로우셨을까... ㅠㅠ;;



-----------
2010.6.30
류광님이 GPG에 트랙백 지원을 시작하셨다.
지원 계기가 이 글 때문이라는 언급을 주셨는데... 이런 곳까지 오시다니... 어흙~!
http://www.gpgstudy.com/forum/viewtopic.php?topic=25208

조 위에 축약한 글의 원 URL. 이걸 적어줘야 스팸트랙백이 안된다고 한다.
http://www.gpgstudy.com/forum/viewtopic.php?topic=23337