如何在C#中可靠地确定字符宽度?

5
我正在编写一个C#程序,使用等宽字体来显示所有内容。在这种字体下,每个Unicode字符都会占据1个字符宽度或者2个字符宽度。在程序中,有一个需要确定特定字符占据1个字符宽度还是2个字符宽度的功能。起初我使用正则表达式[^\x00-\xFF]来解决问题。如果一个字符匹配了它,那么它就占据1个字符宽度,否则就是2个字符宽度。但后来我发现这不正确。例如,这些字符┌─┬┐│├┼┤┴┘不属于[^\x00-\xFF]范围,但它们都只占用1个字符宽度。我想知道在使用等宽字体时如何在C#中确定特定字符的占用宽度是1个字符还是2个字符?

1
有许多Unicode字形占用0空间。例如,Unicode中有一个https://it.wikipedia.org/wiki/Combining_Diacritical_Marks块,由叠加在前一个字形上的字形组成。另外,许多Unicode字形由两个C#`char`(所有非BMP字形,即代码> 0xFFFF的字形)组成。遗憾的是,.NET中的Regex不支持Unicode的非BMP部分。 - xanatos
你是否考虑使用Graphics.MeasureString或者TextRenderer.MeasureText来渲染字符并测量结果? - timur
@timur 我正在编写的应用程序是一个控制台应用程序。渲染它,然后测量文本太重了。 - Just a learner
2个回答

1
我也在寻找同样的问题答案......但我还没有找到。 顺便说一句,我最终写了一个库来获取字符长度(生成一个范围信息,显示字符长度使用Console.Write()和Console.CursorLeft,然后转换为C#代码,在获取字符长度时,使用二分查找以提高速度)。
nuget:NullLib.ConsoleEx 项目:https://github.com/SlimeNull/NullLib.ConsoleEx

这看起来很有趣!我会去看一看。谢谢分享! - Just a learner

-1
根据.NET文档,如果您知道所使用的字体1,您可以使用GlyphTypeface API来获取字体中每个字形的"AdvanceWidths"(高级宽度)
您仍然需要将字符映射到字体中的字形索引。您可以使用CharacterToGlyphMap来完成此操作。
var character = 'x';

GlyphTypeface glyphTypeface = new GlyphTypeface(new Uri("file:///C:\\WINDOWS\\Fonts\\Kooten.ttf"));

var index = glyphTypeface.CharacterToGlyphMap[character];
var width = glyphTypeface.AdvanceWidths[index];

[1] 要获取当前控制台的字体详细信息,我建议阅读以下问题:获取当前控制台字体信息

相关问题:如何在WPF中找到任意字形的精确大小?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接