WPFにおけるフォントサイズの指定

WPF Text Measurement Units – WPF Text Blog



たとえばWPFで下記のようにTextBlockのフォントサイズを24と指定した場合、Windowsフォームで24ポイントと指定したときとは大きさが異なることに気が付くかと思います。


XAML

<TextBlock Text="グレープシティ" FontSize="24"/>


これは、WPFではフォントサイズを含めたすべてのサイズ指定のデフォルトがデバイスに依存しないピクセルとなっているためです。「デバイス非依存ピクセル(DIU)」については後程解説しますので、まずは単位の指定方法を見てみましょう。


XAMLで記述する場合、下記のように数字の後に単位を付加するだけでポイントやセンチといった単位でサイズを指定することができます。


XAML
<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Text" Value="グレープシティ"/>
        </Style>
    </StackPanel.Resources>
    <TextBlock FontSize="36"/>
    <TextBlock FontSize="36px"/>
    <TextBlock FontSize="36pt"/>
    <TextBlock FontSize="0.36in"/>
    <TextBlock FontSize="0.36cm"/>
</StackPanel>

TextBlock.FontSize プロパティ (System.Windows.Controls)
単位指定子 px、in、cm、pt のいずれかが後に続く、上に挙げた double 値。



結果は下の画面のようになり、"24pt"と記述したものがWindowsフォームの24ポイントと同じ大きさになっているはずです。





コードからピクセル以外で指定する場合には、FontSizeConverterを使用します。


Visual BasicWPF

Dim fontSizeConv As New FontSizeConverter()
textBlock1.FontSize = CType(fontSizeConv.ConvertFromString("24pt"), Double)


なお、Windowsフォームでも下記のようなコードでピクセルでフォントサイズを指定することが可能です。


Visual BasicWindowsフォーム)
Label1.Font = New Font("MS UI Gothic", 24.0F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel)

GraphicsUnit 列挙型 (System.Drawing)



Silverlightの場合、デフォルトのピクセル以外で指定する方法は機能的にサポートされていません。都度自分で計算するか、そのようなコンバーターを作成する必要があります。

HugeDomains.com - AlanLe.com is for sale (Alan Le)

Point (pt) Pixel (px)
7pt 9.333
8pt 10.666
9pt 12
10pt 13.333
11pt 14.666
12pt 16
13pt 17.333
14pt 18.666
15pt 20



「デバイス非依存ピクセル


「デバイス非依存ピクセル」という表現は分かりづらいので、「物理ピクセルに依存しない単位」と理解すればよいのではないかと思います。ここでいう物理ピクセルとはようするにモニタ上の1ピクセルのことです。そして、WPFにおけるピクセルという単位、つまりデバイス非依存ピクセルの大きさは、1/96インチと決められています。

WPF の概要 | Microsoft Docs
WPF のグラフィックス システムにおける基本単位は、デバイス非依存ピクセルです。これは、実際の画面解像度に関係なく 1/96 インチであり、解像度およびデバイスに依存しないレンダリングの基礎となります。 デバイスに依存しない各ピクセルは、レンダリング先のシステムのドット/インチ (dpi) 設定に合わせて自動的にスケーリングされます。



つまり、画面のDPIがデフォルトの96DPIであった場合、1デバイス非依存ピクセルは1物理ピクセルとなります。そしてデバイス非依存ピクセルは画面のDPIが変わっても1/96インチのままです。つまり、画面のDPIが120DPIの環境の場合、1デバイスピクセルは120/96(1.25)物理ピクセルとなります。


ようするに、画面のDPIに比例してWPFのすべてのグラフィックスサイズはスケーリングされます。「それってWindowsフォームでも同じでは?」と思った方。正解です。結局のところ、ユーザーにとっては機能的に大きな違いはありません。
ただし、その仕組みは大きく異なります。Windowsフォームの自動スケーリングは、開発時点のDPIを記録しておき実行時にその環境合わせてリサイズするという動作となっています。つまり、Windowsフォームのピクセルはイコール物理ピクセルなので、96DPIの環境で100ピクセルだった幅は120DPIの環境では125ピクセルになっています(厳密には、AutoScaleModeプロパティの設定値がFontかDpiかで動作は異なりますが、画面のDPIを大きくするとシステムフォントも大きくなりますのでそれほど大きな差はないかと思います)。

Windows フォームにおける自動スケーリング | Microsoft Docs



このことは非常に簡単なコードで確認することができます。


Visual BasicWindowsフォーム)

Label1.Text = Button1.Width.ToString()


96DPI環境での実行結果



120DPI環境での実行結果



Visual BasicWPF
TextBlock1.Text = Button1.Width.ToString()


96DPI環境での実行結果



120DPI環境での実行結果



参考情報

Sign in to your Microsoft account


「Major な Measure」わんくま同盟 東京勉強会 #16



なお、Silverlightはこのようなスケーリングは一切行われません。Silverlightピクセルはイコール物理ピクセルであり、実行時に画面のDPIに合わせてリサイズされるということもありません。