Hatena::Groupsubtech

ういはるかぜの化学

Sunday, January 22, 2012

[]Metro style appsと解像度画面サイズと画面解像度 19:00 Metro style appsと解像度と画面サイズと画面解像度 - ういはるかぜの化学 を含むブックマーク はてなブックマーク - Metro style appsと解像度と画面サイズと画面解像度 - ういはるかぜの化学

このエントリの内容はWindows Developer Previewの仕様を元にしています。今後Betaリリース時には変更される可能性があることに注意してください。

Metro style appsの解像度に合わせたスケーリング - ういはるかぜの化学 - subtech でスケーリングについて書きましたが、その拡大率が決定される条件がちょっと謎な感じに見えます。たとえば同じ画面解像度1920x1080でも10.6インチ23インチとで拡大率が違うわけです。

しかVAIO Z(13インチ, 1920x1080)にWindows Developer Previewをインストールするとなぜかシステム解像度(以前からあるあのDPI設定)がデフォルトで120dpiになっています。その割にはMetro style appsはスケーリングしません。どうも画面サイズ(物理的な画面サイズ)をWindows側で把握してコントロールしているような感じです。

画面サイズの取得なんてとれるのかなと思って調べてみるとno titleというWin32 APIにVERTSIZE,HORZSIZEを渡すと取れそうなのですがいろいろなところでまともな値は返さない(物理サイズの参考にはならない)という声も見かけます

まあそうはいっても他に見当たらないのでコードを書いてとりあえず試してみました。

https://gist.github.com/1656292

書いたコードVAIO L (24インチ, 1920x1080)で実行したところ530x300mmという値が返ってきました。24インチ16:9で53.13cm x 29.89cmぐらいらしいのでだいたいあってそうです。ならばとVAIO Z (13インチ, 1920x1080)で試してみると今度は290x160mmという値が返ってきました。やっぱりちゃんと動いているっぽいです。

Windows 7で動かすと677x381mmという明らかに変な値が出てくることからWindows 8からまともに機能するようになったようです。

というわけでこれをシミュレータで動かしたりして、さらにそのサイズからDPIを求めたりしてまとめたのが以下の表です。

環境 画面サイズ(インチ) Windowsが把握している画面サイズ 画面解像度 画面サイズと画面解像度で求めたDPI 拡大率
VAIO L 24 530x300mm 1920x1080 約92dpi x 91dpi 100%
VAIO Z 13 290x160mm 1920x1080 約168dpi x 171dpi 100%
シミュレーター 10.6 132x235mm 1366x768 約148dpi 100%
1920x1080 約207dpi 140%
2560x1440 約276dpi 180%
12 1280x800 162x258mm 約126dpi 100%
23 286x509mm 1920x1080 約96dpi 100%
27 336x598mm 2560x1440 約109dpi 100%

これでどういう意味があるかと言うと、どうもWindows 810.6インチ(1366x768)をスタンダード スレートと定義しているらしく(ガイドラインの一番上の図がそんな感じ)そこを基準にいろいろ決まっているようです。

たとえば10.6インチの1920x1080では140%に拡大されるのに13インチで1920x1080のVAIO Zでは何も起こらないのは、

  • 10.6インチの1920x1080は約207dpiで140%の拡大率
  • 拡大率140%は約207dpiが基準になり、それを超えると適用される
  • VAIO Zでは約170dpi前後ぐらいしかないので100%の域になる

となっていると推測できます画面サイズで決定されるので拡大率にシステムDPI設定は考慮されないことになります

これで画面解像度だけで拡大率が決まるわけではない理由がなんとなくわかりました。

CSSメディアクエリーで使われていた謎のdpi

MSDNガイドラインでは以下のようなメディアクエリーの例が書かれていました(微妙に間違ってるので直してますけど…)。

/* CSS - 拡大率に応じてリモートの画像を読み込む */
@media all and (max-resolution: 134dpi){
    /* 100%の拡大率のとき100%用の画像 */
    .imageBackground {
        background-image: url('http://www.fabrikam.com/foo.png?s=100');
    }
}
@media all and (min-resolution: 135dpi) {
    /* 140%の拡大率のとき140%用の画像 */
    .imageBackground {
        background-image: url('http://www.fabrikam.com/foo.png?s=140');
    }
}
@media all and (min-resolution: 173dpi) {
    /* 180%の拡大率のとき180%用の画像 */
      /* MSDNのサンプルでは174dpiになっているが173dpiでないと動かない */
    .imageBackground {
        background-image: url('http://www.fabrikam.com/foo.png?s=180');
    }
}

134dpi、135dpi、173dpiとありますがこれは100%を96dpiとしたときの値です。つまり

  • 96dpi * 100% = 96dpi
  • 96dpi * 140% = 134.40dpi (135dpi)
  • 96dpi * 180% = 172.8dpi (173dpi)

となりますWindowsは96dpiが標準解像度となっているのでそれが基準になっているのですね。

CSS定義例で言うと

  • 一つ目はmax-resolution:134dpiなので134dpiまでなので135dpi(140%)にならない範囲ぎりぎり→100%
  • 二つ目min-resolution:135dpiなので140%の時の135dpi以上
  • 三つ目はmin-resolution:173dpiなので180%の時の173dpi以上

適用されることになるわけです。

ちなみにこのDPI値はHTML+JavaScriptなMetro style appsではwindow.screen.deviceXDPIとして取得できます。WinRTを経由してもWindows.Graphics.Display.DisplayProperties.LogicalDpiプロパティを使うことで取得できます

が、なぜか180%の時の値が違います。deviceXDPIは173を返しますがLogicalDpiは174を返します。MSDNメディアクエリーの例に174dpiと書いてあったのはWinRTの値が元なのではないかと思います。実際ダウンロードできるサンプルコードの方では173dpiになっています。まあ計算しても違うわけですしWinRTのバグのような気がします。

f:id:mayuki:20120122185111p:image

というわけでスケーリング周りを調べたらなかなかややこしかったですという話でした。

トラックバック - http://subtech.g.hatena.ne.jp/mayuki/20120122