言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

フラップフォント問題を再び整理する。

問題。フラップの文字列が上2ドット切れる。

昨日の阿部さんとの遠隔ペアプロ(?)によって、問題の所在がだんだん明らかになる。たかが文字列を表示するだけにかなり多くのオブジェクトの助けを必要とするのだが、その協調が上手くいっていない。登場するクラスと主要な変数を紹介する。

  • StrikeFont : フォントを表現する最も単純なクラス。文字コードからフォームを生成する機能がある
    • ascent : 一番上からベースライン(例えば "p" なら丸い所の下端)までの長さ
    • descent : ベースラインから一番下までの長さ。フォントの高さは ascent + decsent で求まる。
    • fallBackFont : もし自分で表示できない場合に使う代理フォント
  • StrikeFontSet : 多言語対応フォント。現在の言語コードに応じてフォントを使い分ける。
    • fontArray : 実際に使うフォントが入っている。添え字は言語コード (leadingChar または encoding + 1)
  • TextStyle : 良くわからんがこれもフォントが複数入っている。
  • MultiNewParagraph : 矩形に収められたテキスト。
  • MultiDisplayScanner : 良くわからんが MultiNewParagraph を表示するのに使う。
  • TextLine : 整形された一行のテキスト。

さて、このフラップの場合、Accushi12(ascent=12 descent=3) の代理(fallBackFont)として Japanese10(ascent=10 descent=2) を使うのだが、直接の原因は MultiDisplayScanner >> setFont にある。

destY := lineY + line baseline - font ascent (表示開始高さ := 行の上端 + TextLine の baseline + フォントの ascent)

によって表示する y 座標を決定する際、TextLine の baseline (10 = ascent + 行間) が、代理フォントを含め、行で実際に使うフォントを全部調べて決定されるのにも関わらず、フォントの ascent (12) は代理フォントを考慮しない。なので、この場合表示開始高さが (行の上端 - 2) になり上が欠けるのだ。

結果的には、id:propella:20041216#p3 に書いたのと同じ代理フォントの ascent/descent に纏わる問題なのだが、この辺アドホックに修正していくと禍根を残しそうなのでゆっくり考える事にする。