Open4

Rust ネイティブでフォントを描画するまでのメモ

白山風露白山風露

前提

  • winit
    • クロスプラットフォームのウィンドウ操作ライブラリ
    • とりあえずウィンドウ作りたいなら使っとけ
  • gfx
    • クロスプラットフォームのグラフィックライブラリ
    • Vulkanに寄せたAPI
    • ほぼunsafe。むちゃくちゃ使いづらい。もちろんそれだけ柔軟ではあるが直接使うのは避けたほうがいい
  • wgpu
    • WebGLの次世代WebグラフィックAPIとして策定中のWebGPUのRust実装
    • もちろんgfxにがっつり依存している
    • リポジトリ名はwgpuだがクレート名はwgpu-coreとwgpu-types(ややこしい)
  • wgpu-rs
    • Web APIの実装であるところのwgpuにNative Rustから使うインターフェイスを用意したというなんだか因果が逆転したようなライブラリ
      • まあWASIとかの例もあるしね
    • Webと名はつくがネイティブで完結している
    • でもwasm+WebGLバックエンドでも動く(はず。試してない)というさらなる逆転
      • ブラウザ側にちゃんとした実装がないけど将来はブラウザのWebGPUをつかうようにもできるはず?
    • リポジトリ名はwgpu-rsだがクレート名はwgpu(だからややこしいんだよ!)

ここらへんの巨人の肩に乗っていく予定

白山風露白山風露

フォント系クレート

  • ttf-parser
    • ゼロコスト(バッファの動的確保一切なし)でOpenTypeをパースできるすごいやつだよ
      • 各テーブルのパースはスライスを取り回しながら遅延評価
      • 純粋にメモリ上のファイルをパースする機能だけ
    • OpenType完全サポートと言うわけではなく対応していないテーブルもある
      • スライスとして取り出すことは可能
  • font-kit
    • servoプロジェクトの一部。フォントファミリ名からファイルの解決からラスタライズまでできる
    • なお私は後述のab_glyphを使っているのでファイル名の解決用としてだけ使っている
  • rustybuzz
    • harfbuzzのport(実装はpure rust)
    • ttf-parserがサポートしていないGSUBやGPOSなどを使って縦書きやリガチャーの情報を取り出せる
  • ab_glyph
    • フォントのラスタライズを行う
    • ほぼラスタライズの機能だけであり、文字からグリフへのマッピングなども最低限の機能しか備えていない
      • ので前述のrustybuzzであらかじめ取得したグリフを渡す運用
  • glyph_brush
    • ab_glyphのラスタライズをキャッシュするライブラリ
  • wgpu_glyph
    • wgpu上でglyph_brushを利用してグリフを描画するライブラリ
白山風露白山風露

ttf_parser::Faceを共有できないか?

rustybuzzもab_glyphも内部でttf_parser::Faceを使っているので一度パースしたものを使い回せないかと思ったがどうもそういう機能はないらしい。
そもそもttf-parserは遅延評価しながらパースするので、読み込み時のパースはせいぜいテーブル一覧を取ってくる程度で2回繰り返したところでどうということはない。

白山風露白山風露

フォントファイルはメモリマップトファイルで読み込むと良さそう

memmapクレートを使うと良い