モノトーンの伝説日記

Apex Legends, Splatoon, Programming, and so on...

<mini> WPF を使って 150% スケーリング環境で美しく見せるコツ。

 どうもっす。今日は 150% スケーリング環境でも美しくレンダリングさせるコツみたいなのを紹介するっす。

 まず次の画像見てください。

f:id:mntone:20150629085703p:plain

 某 Chrome フレームワークです。拡大して見てもらうとわかりますが、1 px 線と 2 px 線が混じって見苦しい…問題が発生していると思います。これは演算の関係上どうしようもない点で

 round \left( 1.0 \times 1.5 \right) = 2

となるわけですが、レイアウトシステムによる配置が Snap できていないとなぜか 1 px になったりします。もちろん全部 2 px になるのがこの計算式上理想なのですが、WPF の特性上無限に細かいピクセルを想定しており、レイアウトがその仮想スクリーン上で行われるわけで、場合によってデバイスにフィットさせると、

下0.25px
1.0px
上0.25px

みたいな結果をレンダリングするとき、上下の境界線がおそらく切り取られて 1 px になるんだと思います。

 ところで、150% の GDI レンダリングはどうなっているか知っていますか? 150% スケーリングにおける GDI の Visual Style は実は境界線に 1 px を採用しています。ここで、あるトリックを行うと、WPF でもこれを再現できるうえ、上記のゆらぎの問題が解消できるという一石二鳥なトリックがあります。

 round \left( 0.99 \times 1.5 \right) = round \left( 1.485 \right) = 1.0

小数第一位を四捨五入しますからこれであってます。ピクセルの揺らぎも 1.485 あるので必ず 1 px に収束してくれるという便利な値です。試したことはないのですが、250% スケーリング環境も揺らぎなく動く数値なんじゃないんでしょうか。

 ということで、1 ではなく .99 を指定するのはちょっと心苦しい気がしますが、このような UI 上のレンダリングの揺らぎが見えるよりよほど美しい値だと思うので、比較的最近は .99 を指定して WPF のアプリを作ってます。

 よかったらこのトリックを使ってみてください。

 以下は今私が手直ししている Fluent の Ribbon Framework のスクリーンショットです。150% 環境で撮影しています。

f:id:mntone:20150629090606p:plain

 Fluent Ribbon Framework は GitHub および NuGet から

追記

はい、これは事実です。あくまでこの記事の主眼は 150% における揺らぎの解消および、150% で 2 px は太すぎるという個人の主観が入っていることもお忘れなく。

f:id:mntone:20150629130454p:plain

COM Ribbon および Window border です。Window border は 3 px を除きスケーリングされます。