2024年5月5日日曜日

fontconv で ligatures font をサポートした

fontconv を大幅に更新して、ligatures font をサポートしました。

fontconv

ligatures font の解析の仕方は Read ligature from a font #384 が参考になります。 他にも Ligatures #194 が参考になるのですが、getLigatures() は low level 実装のため、 応用的な解析には使いにくい問題があります。addLigature() は参考になります。

更新するにあたっては、そもそも ligatures font の仕組みからわかっていなかったので、コードを動かしながら仕組みを調査しました。 home という ligatures を定義するとき、その一文字ずつ (h, o, m, e) に Glyph 定義をしているようです。 その後それら Glyph へのインデックスを配列として ligatures を定義します。 Material Icons などでは ASCII 文字列を使って ligatures を定義していますが、ASCII 文字列の Glyph の Path は空で良いようです。 ただ svg2ttf は空だとバグるので、その修正で多少時間が掛かりました。

つまり ligatures font を新規作成しようとする時の作成フローは以下になりそうです。
  1. ligature 文字列の中でまだ登録されていない Glyph を空の Glyph として登録する
  2. 利用する Glyph をリストアップして登録する
  3. Glyph に適用する ligature 文字列をリストアップする
  4. ligature 文字列のインデックスを利用して ligature を登録する
フォントの仕組み上、毎回ゼロから作らないといけないのが難点ですが、思ったより簡単でした。 まず上述のコードは無駄がたくさんあって遅いので高速化し、ttf2svg の実装が ligatures font を想定していなかったので改良しました。 そして機能を使いやすくするために --remove-ligatures オプションを付けました。 オプションなしだと ligatures は残しますが、付けるとファイルサイズを考慮して削除します。 ついでなので、さらなる最適化を考慮して以下のオプションを加えました。
--ligature <str> (ligature を利用したサブセット化)
--ligature-file <path> (ligature を利用したサブセット化)
--name <str> (glyph-name を利用したサブセット化)
--name-file <path> (glyph-name を利用したサブセット化)
フォント最適化でよく使いそうな機能はだいたい実装したつもりです。 まだ多少実装したいことはありますが、フォント最適化ツールとしてはだいたい完成かな?

0 件のコメント: