(原創)高DPI適配經驗系列:(三)字型與字號、縮放錨點

leslie_xin發表於2021-05-24

一、前言

程式最基本的元素,就是文字,也就是字型。如果程式未進行高DPI的適配,最直觀的感受便是字型的模糊。所以本篇便來說一下高DPI適配中的字型問題。
高DPI的適配,簡單來說便是便是根據不同的DPI對尺寸和位置進行調整,那麼就需要一個錨點,所有的尺寸和位置的變化都以此錨點為基準進行調整。

相信看完的你,一定會有所收穫!

本文地址:https://www.cnblogs.com/lesliexin/p/14801347.html


二、字型字號與尺寸

WinForm程式,預設是支援系統的自動縮放處理的,只是處理的縮放效果比較爛,唯一的優點是保證了字型的清晰。
而我們進行高DPI適配時,正是基於其“字型是清晰”這一點。
首先,先說結論:在不同的DPI下,字型的尺寸是不同的,但是字號是相同的。帶來的效果就是在不同的DPI下,字型在視覺上是一樣大的。

對比圖1:(解析度:1080P,DPI:96)
image

對比圖2:(解析度:4K,DPI:192)
image

通過以上兩圖,我們會發現,在不同的DPI下,字型的字號是不同的,但是字型的尺寸卻不一樣。

這裡不妨擴充套件一下,在DPI=192中的字型尺寸,如果是在DPI=96下,需要多大字號的字型才能達到這樣的尺寸呢?

我看下截圖:(解析度:1080P,DPI:96)
image

可以看到,當DPI=96時,字型字號=18時,我們獲得的尺寸即為在DPI=192時字型字號為9時的尺寸。
這裡可以使用“DPI變大了2倍,字號也要變2倍”這種直觀的推理來解釋,事實也確實如此,不過只限於一些標準字型。


三、字串尺寸計算的兩種方式

在計算字串的尺寸時,有兩種方式:一是使用TextRenderer.MeasureText去計算;二是使用Graphics.MeasureString去計算。
相同點:
1,兩都計算出的結果都是“自適應DPI的”,也就是說在不同的DPI下,相同的字串與字型計算出的尺寸是不一樣的。
不同點:
1,TextRenderer.MeasureText計算出的結果是包含一些“空白”的,其計算出來的尺寸與Label控制元件當AutoSize=true時的尺寸是一致的。
2,Graphics.MeasureString計算出的結果會去掉這些“空白”,計算的尺寸是“剛好”能包含住字串。

所以在高DPI適配時,我會使用TextRenderer.MeasureText來計算尺寸,並以此為錨點


四、高DPI適配錨點

高DPI的適配,簡單來說便是便是根據不同的DPI對尺寸和位置進行調整,那麼就需要一個錨點,所有的尺寸和位置的變化都以此錨點為基準進行調整。
而我們的錨點,便是字型尺寸
舉些例子:
1,原生控制元件。系統會自動進行縮放,但是大都只會對控制元件的“高度”進行自動調整,而寬度卻不會變化 。
2,固定寬度。在程式中,很難避免不用到絕對尺寸,如圖片、列表等,那麼就涉及到這個絕對尺寸在不同DPI下的變化。
3,控制元件高度。對於一些高度不會變化的控制元件,或者需要指定控制元件高度時,需要計算出此高度在不同DPI下的變化,比如說需要讓按鈕的高度能顯示全按鈕文字。

解決方法:
首先,我們需要知道在96DPI時,此寬度能顯示多少個字元。
其次,則非96DPI時,使用前面的TextRenderer.MeasureText方法計算出這些個字元所佔的寬度。
最後,計算出來的寬度即是此DPI下與96DPI下視覺效果一致的寬度。
同理,高度也一樣。

這也就是我們進行高DPI適配的錨點。

-[END]-

相關文章