本文主要采用 GlyphTypeface 类尝试获取每个字符的宽度和高度的值,尽管这个方法和最终 WPF 布局使用的文本的宽度和高度是不相同的,但是依然可以作为参考

获取系统字体文件夹的文件

系统字体文件夹放在 @"C:\Windows\Fonts" 本文不讨论用户的系统盘放在其他盘里面

使用 Directory.GetFiles 可以获取所有字体文件

   var fileList = Directory.GetFiles(@"C:\Windows\Fonts", "*.ttf");

通过 *.ttf 可以限定只获取 ttf 文件

创建 GlyphTypeface 对象

通过 Uri 传入文件路径可以创建

            foreach (var font in fileList)
            {
                var uri = new Uri(font);
                GlyphTypeface g = new GlyphTypeface(uri);
            }

获取定义的字符的宽度和高度比例

需要注意的是一个字体文件也许会包含多个不同的 FontFamily 因此 FontFamily 创建的时候还需要传入名字进去

            foreach (var font in fileList)
            {
                var uri = new Uri(font);
                GlyphTypeface g = new GlyphTypeface(uri);

                var charList = g.AdvanceHeights.Keys;

                foreach (var fontName in g.FamilyNames.Values)
                {
                    var fontFamily = new FontFamily(uri, fontName);

                    var fontSize = 10;

                    foreach (var c in charList)
                    {
                        var w = g.AdvanceWidths[c];
                        var h = g.AdvanceHeights[c];

                    }
                }
            }

这里拿到的 w 和 h 就是宽度和高度比例

注意,这个值和最终文本渲染字符大小没有很本质的关系

以下是我提供的一些测试的值,我隐藏了最终渲染字符的大小计算方法,此方法是团队内部 文本框3.0 计算方法,此库可以做出比 PPT 文本框差的多的效果

		size	{1.95666666666667,11.84}	System.Windows.Size
		w	0.466796875	double
		h	0.9443359375	double
		hw	6.0511073253833052	double
		wh	0.165259009009009	double

其中 hw 和 wh 的计算方法如下

var hw = size.Height / size.Width;
var wh = size.Width / size.Height;

GlyphTypeface Class (System.Windows.Media)

如果需要设置 FontWeight 等影响,可以使用先创建 Typeface 的方法,请看下面代码

var typeface = new Typeface(fontFamily, fontStyle, fontWeight, FontStretches.Normal);
typeface.TryGetGlyphTypeface(out GlyphTypeface glyph);
// 如果 TryGetGlyphTypeface 创建失败,那么就是缺少字体等,可以尝试使用微软雅黑等默认字体

上面代码获取 glyph 就可以使用和上文相同的方法获取文本字符宽度


本文会经常更新,请阅读原文: https://blog.lindexi.com/post/WPF-%E8%8E%B7%E5%8F%96%E6%9C%AC%E6%9C%BA%E6%89%80%E6%9C%89%E5%AD%97%E4%BD%93%E6%8B%BF%E5%88%B0%E6%AF%8F%E4%B8%AA%E5%AD%97%E7%AC%A6%E7%9A%84%E5%AE%BD%E5%BA%A6%E5%92%8C%E9%AB%98%E5%BA%A6.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者前往 CSDN 关注我的主页

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

以下是广告时间

推荐关注 Edi.Wang 的公众号

欢迎进入 Eleven 老师组建的 .NET 社区