2025/3/30(日)

libfontlistの開発を進めた。基礎は大体終わった。

Windowsにおけるシステムフォント取得が重い問題について、地道に実測して調べたところIDWriteFontList::GetFontIDWriteFont::CreateFontFaceが主たるボトルネックとなっていることが分かった。そしていつも重い訳でもなく、フォントファミリから初めてそのフォントを読み込むときなどに重くなっている。

正直改善策がよく分からないので一旦放置する。ChatGPTに意見を求めてみたところ、CreateFontFaceの代替としてレジストリHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fontsの直接参照などを提案されたが、さすがに邪道を感じる。

Linuxはfontconfigを使う。頑張ったらどうにかなった。結構いろいろ情報が取れるっぽいことが分かった。

最後はMacOSだが、CoreTextなるAPIを使うらしい。かなり慣習が違うので手間取ったが、気合でなんとかした。こちらも気合で割となんとかなった。

CoreTextの問題はフォントの太さ情報で、-1.0~+1.0で取れるとかいういかれたAPIをしている。0.0が標準なのはいいがそれ以外の一切が「Thin」「Bold」といった一般的な太さ名称と対応付けられない。諦めるしかないんか。

あとCoreFoundationなるフレームワーク自体も勘所がよく分からなかった。ありとあらゆる型がCFHogeRefという型にラップされている。C++で触っているのがおかしいのであって、何か本来もっと高レイヤな別言語で触るものを無理やり直接触っている感じが拭えない。

代表的なそれとしてCFStringRefがあるのだが、CFStringGetCStringでC文字列に変換できる。これはこちらでバッファを用意してあげてそこに書き込ませるタイプだ。一方でもう一つ、CFStringGetCStringPtrなる関数もある。こいつはC文字列へのポインタを返してくれる。余計なメモリアロケーションを避ける意味で後者の方が良いかと思っていたがこれは罠だった。前者はバッファサイズさえ足りてれば問題ない一方で後者はちょいちょい失敗する。死ねばいいのに。

Categories: