最近、新しいアプリを作成しています。今どきのアプリは高DPI対応は必須なので、もちろん、高DPI対応もします。タイミングもちょうどよいので、デスクトップアプリの高DPI対応について投稿します。
Windows PCの高DPI化
Windows PCにつながるディスプレイは、30年前であれば640×480, 800×600などの解像度でした。しかし、現在では、1980×1080(フルHD), 2880×1920(4K), 3960×2160など高解像度化が進んでいます。高解像度になっても画面サイズ(ディスプレイの物理サイズ)はあまり変わっていません。これは高DPI化が進んでいることになります。
高DPI化が進むということは、一つのピクセルサイズが小さくなっていることを表します。そのため、OSおよびアプリが何も対応しないと、アプリのUIなどがとても小さく表示され、ユーザーはUIを認識できなくなります。
Windowsの高DPI対応を理解するうえで、DPIとディスプレイスケール率という言葉の理解が欠かせません。まずは、この二つの言葉について説明します。
DPI
DPIとは、Dots Per Inch(ドットパーインチ)の略であり、1インチ(25.4mm)当たりに何ドットあるかを示すときに使われる単位です。例えば96DPIなら1インチ当たり96ドットなので、1ドットは約0.265mmの大きさとなります。DPI値は、ディスプレイなどの表示装置の物理的サイズとその解像度により決まります。
例として私が使用しているディスプレイの一つの4K対応の28インチワイド型ディスプレイ(LCD-M4K282XB)の場合で計算してみます。
液晶パネル | |
---|---|
パネルタイプ | TFT28型ワイド LEDパネル/非光沢/TNパネル |
最大表示解像度 | 3840×2160 |
画素ピッチ(mm×mm) | 0.16(H)×0.16(V) |
表示面積(mm×mm) | 620.93(H)×341.28(V) |
横方向のDPI値は
3840 [dots] / 620.93 [mm] * 25.4 [mm/inch] = 157.08 [dots/inch]
となり157.08DPIです。縦方向のDPI値は
2160 [dots] / 341.28 [mm] * 25.4 [mm/inch] = 160.76 [dots/inch]
となり160.76DPIとなります。平均すると158.92DPIです。なお、液晶パネルの仕様には、画素ピッチの情報もあります。この値からDPI値を計算すると縦横ともに
25.4 [mm/inch] / 0.16 [mm/dot] = 158.75 [dots/inch]
となり158.75DPIとなります。
ディスプレイスケール率
WindowsのUIでは、DPIを扱うときにディスプレイスケール率という値を使います。このディスプレイスケール率は、96DPIを基準(100%)としたパーセントの値です。したがって、96DPI, 120DPI, 144DPIに対応するディスプレイスケール率は100%, 125%, 150%となります。
Windowsが96DPIを基準とすることは、初期Windows(30年以上前です)のころに決められました。当時のMacintosh(現在のアップルのMacです)では、フォントサイズを表すポイントと1対1で対応するように72DPIを基準としていました。しかし、通常のフォントサイズとして使用されていた10ポイントの場合、画面上でも10ピクセルとなります。英小文字の場合は、高さが半分となるので、5ピクセルとなります。5ピクセルの英小文字は識別性が悪くなります。そのため、後発のWindowsでは4/3倍(1.33倍)した96DPIが使われました。これにより10ポイントの英文字は13ピクセル。英小文字は6ピクセルとなり識別性も上がります。
現在ではWindows PCに使われるディスプレイはブラウン管から液晶や有機ELに替わりました。液晶や有機ELでは、技術革新により、高解像度化も進みました。現在のWindows PCのディスプレイの解像度はほとんどがフルHD(1920×1080)以上です。
この結果、今どきのWindows PCでは、デフォルトのディスプレイスケール率が100%のものは少なくなりました。125%や150%だけでなく、200%や300%など大きな値がデフォルト値となっているものもあります。
ディスプレイスケール率 | 対応するDPI | ディスプレイの例 |
---|---|---|
100% | 96DPI | Acer Aspore 1 (1366×768, 11.6inch) ideapad 320 (1366×768, 15.6inch) FMV LIFEBOOK (1366×768, 15.6inch) ROG STRIX GL (1920×1080, 17.3inch) 外部LCD (2560×1440, 27inch) |
125% | 120DPI | VAIO A12 (1920×1080, 12.5inch) ROG Zephyrus G (1920×1080, 15.6inch) ThinkPad E585 (1920×1080, 15.6inch) LAVIE Direct NEXT (1920×1080, 15.6inch) |
150% | 144DPI | DELL XPS 139360 (1920×1080, 13.3inch) dynabook RZ (1920×1080, 13.3inch) Mouse LuvBook (1920×1080, 13.3inch) ZenBook Pro 14 (1920×1080, 14inch) Surface Go (1800x1200, 10inch) Surface Pro 3 (2160x1440, 12inch) Surface Laptop 3 (2496×1664, 15inch) 外部LCD (3840×2160, 28inch) |
175% | 168DPI | |
200% | 192DPI | Surface Pro 6 (2736×1824, 12.3inch) Surface Pro X (2880×1920, 13inch) Surface Book 2 (3000×2000, 13.5inch) |
300% | 288DPI | Dell Inspiron 13 (3840×2160, 13.3inch) |
400% | 384DPI |
この表の中で一つだけ異質のものがあります。 VAIO A12 (1920×1080, 12.5inch)です。このインチサイズでこの解像度であれば、176DPIとなるので、デフォルト値は150%または175%となるはずですが、125%となっています。VAIO(株)は出荷時に設定を間違えたのでしょうか。実際、同じ解像度(1920×1080)で、インチサイズが大きいほかのWindows PCのデフォルト値は150%以上となっています。
Windows 10でのディスプレイスケール率の設定
Windows 10において、デフォルトのディスプレイスケール率の値は、ディスプレイのインチサイズと解像度から計算されたDPIに従って、自動的に設定されます。通常はデフォルトのままでよいのですが、ユーザーの希望の値に変更することができます。
Windows 10では「設定→システム→ディスプレイ」で、ディスプレイスケール率の値の確認および変更ができます。
Windowsの高DPI対応
Windowsは、初期のころからディスプレイスケール率の値の変更に対応していました。しかし、Windows Vistaまでは、ディスプレイの実際のDPI値が何であろうと、Windows上のDPIスケール値のデフォルト値は常に100%(96DPI)でした。
そのため、高DPIのディスプレイをつなぐと、同じ物理ピクセル数の画像などは、物理的な表示サイズは小さくなりました。高DPIのディスプレイをつないだときには、ユーザーがWindowsのディスプレイスケール率の値を変更する必要がありました。
Windows Vista以降、ディスプレイスケール率の値の変更時の挙動やデフォルト値など、高DPIに関するOS側の機能は徐々に改善されていきました。
各WindowsにおけるOS側の対応状況をまとめると以下の通りです。
Windowsのバージョン | OSの対応レベル | ディプレイ スケール率のデフォルト値 | 変更時に必要な操作 | 複数ディスプレイへの対応 | 高DPI非対応アプリへのOSの対応 |
---|---|---|---|---|---|
Windows XP | System Monitor | 100%(96DPI) | システムの再起動 | システム全体で一つの設定値 | なし |
Windows Vista | ↑ | ↑ | ↑ | ↑ | DPI仮想化 |
Windows 7 | ↑ | 自動設定(ディスプレイのEDIDに依存) | ユーザーのサインアウト | ↑ | ↑ |
Windows 8.0 | ↑ | ↑ | ↑ | ↑ | ↑ |
Windows 8.1 | Per Monitor | ↑ | なし(即時反映) | ディスプレイ毎に個別の設定値 | ↑ |
Windows 10 1607以前 | ↑ | ↑ | ↑ | ↑ | ↑ |
Windows 10 1703以降 | Per Monitor V2 | ↑ | ↑ | ↑ | ↑ |
OS側の対応レベル
OS側のディスプレイスケール率の対応状況としては以下の通り3種類あります。
- System Monitor
- Per Monitor
- Per Monitor V2
System Monitor
System Monitorでは、ディスプレイスケール率の値をシステムで一つのみ持つことができます。DPI値が異なる複数のディスプレイをつないでいた時にも同じディスプレイスケール率が使用されます。Windows 7以降ではディスプレイスケール率のデフォルト値が自動的に設定されますが、System Monitorの場合(Windows 7/8.0の場合)は、プライマリーディスプレイ(一つ目のディスプレイ。ノートパソコンであれば内蔵ディスプレイ)に適したディスプレイスケール率が設定されます。
このタイプのWindowsでは、ディスプレイスケール率の変更したとき、その値を反映されるためには、システムの再起動または、ユーザーのサインアウトが必要となります。
Per Monitor
Per Monitorでは、システムにつながっているディスプレイ毎に独立したディスプレイスケール率の値を持つことができます。アプリのウィンドウには存在するディスプレイによって、異なるディスプレイスケール率が設定されることになります。
このタイプのWindowsでは、ディスプレイスケール率の値を変更したとき、その値はすぐに反映されます。反映するためにシステムの再起動やユーザーのサインアウトは必要ありません。
Per Monitor V2
Per Monitor V2では、Per Monitorと同様にシステムにつながっているディスプレイ毎に独立したディスプレイスケール率の値を持つことができます。
Per Monitorと異なるのは、ウィンドウの非クライアント領域(タイトルバーなど)の高DPI対応がWindows側(シェル側)で自動的に行われることです。そのため、アプリ側ではアプリ内の描画領域の高DPI対応に専念できます。
Windowsの高DPI非対応アプリへの対応
Windows XPやWindows Vistaのころは、ディスプレイスケール率のデフォルト値が常に100%(96DPI)でした。そのため、高DPIに対応しているアプリはあまりありませんでした。
ディスプレイスケール率が自動的に適切な値に設定されないため、高DPIのディスプレイをつなぐと小さく表示されました。高DPIに対応しているアプリが少なかったため、たとえ、Windowsのディスプレイスケール率の値の設定を100%より大きい値にしても、アプリ内の表示領域は、小さいままなものが多いです。
ディスプレイ側の高DPI化はどんどん進みましたが、高DPIに対応しているアプリが少ないため、このアプリが小さく表示されることの問題が顕在化しました。そのため、Windows Vistaでは、アプリ側が高DPIへの対応が完了するまでの補完機能として、DPI仮想化が実装されました。
WindowsのDPI仮想化
Windows Vistaで導入されたDPI仮想化は、アプリが高DPI対応できないときにアプリごとに適用されます。
DPI仮想化では、大まかにOSは以下の振る舞いをします。
- アプリが描画した絵を、OS側が拡大して表示します。
- マウスなどの入力座標などは直接アプリに伝えるのではなく縮小してアプリに伝えます
このときOSはディスプレイスケール率の値で拡大や縮小をします。高DPIに対応できていないアプリは、常に100%(96DPI)を前提にしているので、これらの処理で、見た目上のサイズは、高DPIに対応できます。
ただし、OS側でアプリの描画を拡大して表示しているので、拡大処理によって、絵がぼやけることがあります。Windows VistaのDPI仮想化では、アプリ側の描画を単純に拡大表示しているため、UI部品や文字などすべてがぼやける原因となりました。
後継のWindowsのDPI仮想化は、アプリの描画をキャッシュするときに工夫などをして進化しています。たとえば、アプリが文字を文字描画のAPIを使用して描画しているときは、文字については拡大後のサイズをもとに描画・キャッシュします。その結果、拡大表示されたときでも、文字がぼやけなくなります。
このようにOS側でもDPI仮想化の機能を追加して、高DPIに非対応のアプリの対策をしています。
次回はアプリ側の高DPI対応の概要について投稿したいと思います。
“デスクトップアプリの高DPI対応 #1 – 高DPI対応とは” への1件の返信