しらいとブログ

ネットで検索してもなかなか出てこないIT情報を独自にまとめています

「WinFont+」開発記録 Part 2

前回のalpha1ではDirect2Dを使っていましたが、今回はDirect2Dを使わずに自分でGDIに描画するようにしました。DirectWriteにはラスタライズ機能とレンダリング機能があるのですが、ラスタライズ機能のみを使用することになります。

実はChromeと同じ手法だったりします。Chromeは自分でガンマ補正(おそらくsRGB)してるので黒い文字が薄くなりますが、それが無ければ本当はキレイに表示されるのです。

ところで、このDirectWriteのラスタライズ機能なのですが、Windows 8.1より前のバージョンでは機能が少なくてほとんど調整できません。そのためalpha2からはWindows8.1以降必須となります。

さて、Direct2Dでレンダリングしていた部分を「DirectWriteでラスタライズ+自分でGDIに描画」に置き換えてみたのですが、すごいことがわかりました。

まず、Direct2Dを使わず自分でGDIに描画するので、「DirectWrite→Direct2D→GDI」の流れが「DirectWrite→ビットマップ配列→GDI」に変わって速度が上がりました。2倍くらい速くなっています。

次に、全体の処理時間のうち、DirectWriteのラスタライズ処理とGDIの描画処理のどちらに時間がかかっているのか調べてみました。普通に測っても面白くないので、文字を拡大してラスタライズ→ニアレストネイバー(最速)で縮小→GDIで描画という処理を拡大率を変えながらやっています。

縦横2倍(面積4倍)→1倍と大して変わらない
縦横3倍(面積9倍)→1倍と大して変わらない
縦横6倍(面積36倍)→alpha1と同じくらい
縦横8倍(面積64倍)→alpha1より2倍くらい遅い

結論、DirectWriteのラスタライズはめちゃくちゃ速い。

大雑把に見積もると全体の30分の1程度の時間しかかかっていません。しかもこれ、高速化の余地がまだ残っています。これだけ速いなら大きめにラスタライズして何かフィルターでもかけてから縮小しても十分速そうです。

早速やってみました。

縦横3倍の面積9倍でラスタライズした後、ぼかしフィルターをかけてから縮小しています。そうすると通常より薄くなるので濃さを1.5倍にしています。

もうこれでいいんじゃないでしょうか。

処理量が9倍でも速度はほとんど変わらないし、サブピクセルレンダリングにもそのまま使えるし、画面を回転させてる人向けの縦方向のサブピクセルレンダリングにもそのまま対応できるし。あとは濃さを調整する機能を工夫すれば十分使える気がします。

今回配布するalpha2は上のスクリーンショットを撮るのに使ったものと全く同じです。
Windows 8.1以降じゃないと動きません。
ガンマ値や濃さは調整できません。
alpha1のバグは基本的にそのまま残っています。
コードはコメントを抜いて500行程度。

Download

WinFont+_alpha02
WinFont+_alpha02
(予備)

動作保証はしませんが、MacTypeレジストリモードにしてMacTypeのDLLをWinFont+に置き換えると、ほぼ全てのソフトに適用できます。