harfbuzzでAlabia語レンダリング

今回はRTLのレンダリングをやってみた。右寄せではなく、Right to Left、つまり右から左に書くarabia語などのレンダリングなど。(「はちにんこ」、みたいな。)

普通に hb_buffer_set_direction( buffer, HB_DIRECTION_LTR ); でやればいいだけなんだけど。この指定を行った場合、普通にイテレーションすると、文末から順番に表示されることになる。普段のLTRのロジックでレンダリングした場合は左寄せになる。改行もいれると、文末から文頭へと表示されて、一応RTLになってるんだけど、基準点によるレンダリングが難しい。(boundingboxを計算しているが2回計算することになり効率が悪い。)

そこで、レンダリングロジックでリバースイテレーションすると、右寄せになり、改行順も正しくなる。注意点はレンダリングとペンの位置の計算順。

LTRの場合は :  レンダリング( PenX+OffsetX ) -> ペン移動( PenX += AdvanceX )
の順で描画を行っていくが、リバースの場合はAdvanceXが示す値がそのキャラクター自身のPEN移動となる。
よってRTLの場合は :  ペン移動( PenX -= AdvanceX ) -> レンダリング( PenX+OffsetX )
このようにレンダリングすることで右寄せとなり、正確に表示された。

ここまででharfbuzzのLTRは完了。日本語や英語についてはリガチャも含めて綺麗に表示された。次にアラビア語を入れてみる。表示結果は以下のとおり。アラビア語でググって出てきた文章なのでなんて書いてあるかは知らない(過激な言葉だったらどうしよう)そして、これがぜんぜん正しいのかも分からないけど、元のタイポグラフィと比べるとおかしい。

スクリーンショット-2013-11-15-11a.46

テキストレイアウトでは色々必要とされる機能があってそれが各言語によって用意されている。これらはiso15924のタグで用意されていて、harfBuzzでもこのコードからスクリプトを適用することができる。
http://www.microsoft.com/typography/otspec/scripttags.htm
アラビア語を指定する場合は
hb_buffer_set_script(buffer,HB_SCRIPT_ARABIC);
これは、hb-common.hで定義されている。この指定を行うと、下記の通り。バラバラだった文字が組み合わされ、それっぽくなった。これは単純なリガチャではなく、合字のような機能だと思う。スクリプトは標準ではLatin用とかになってるのかなー。

スクリーンショット-2013-11-15-11.46

hb_buffer_guess_segment_propertiesみたいなのもあるんだけどうまくは行かなかった。
それで、今回は混合フォントのレンダリングクラスを書いているんだけど、フォント毎に”arab”とかiso15924を調べて指定するのはなんか面倒。なんとかフォントファイルからscript tagを調べられないかと、色々試行錯誤してみた。

まずはどこにタグがあるのかを調べる。
http://kanji-database.sourceforge.net/fonts/opentype.html
これによると
GSUB、GPOS、JSTFの第一層にある。まだ、頭のなかにopentypeの構造がぼんやりとしかイメージできていないので、どこやねんそれと思いながら試行錯誤してみた。結果、こんなかんじでよさげだなぁと。自信はないけど。

unsigned int cntGSUB = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, NULL, NULL);
hb_tag_t* listGSub = NULL;
listGSub = (hb_tag_t*) malloc(cntGSUB * sizeof(hb_tag_t));
hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &cntGSUB, lstGSub);
hb_script_t script = hb_script_from_iso15924_tag(*lstGSub);
free(listGSub);

大概のフォントは複数のスクリプト値が入っている。秀英体とかだと6ことか入ってたりする。で、どれを初期値にするのかというのが問題になるんだけど、どうやら一番はじめのものがデフォルトレイアウトとして使えそう。アラビア語の traditional arabicフォントも一番目に HB_SCRIPT_ARABIC が入っていた。上の例はHB_OT_TAG_GSUBだけだけど、GPOSのみということもありえるのでJSTFも含めて調べておく必要がある。それで取れなければHB_OT_TAG_INVALIDとかにしておけば、上手いことやってくれそうな気がした。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です