【问题标题】:How to reliably determine the width of a character in C#?如何可靠地确定 C# 中字符的宽度?
【发布时间】:2023-03-31 12:15:01
【问题描述】:

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

【问题讨论】:

  • 有很多占用0空间的unicode字形。例如,Unicode 中有it.wikipedia.org/wiki/Combining_Diacritical_Marks 块,它由叠加到前一个字形上的字形组成。作为另一个旁注,许多 unicode 字形由两个 C# char 组成(所有非 BMP 字形,代码 > 0xFFFF 的字形)。遗憾的是 .NET 中的 Regex 不支持 Unicode 的非 BMP 部分
  • 您是否考虑过使用Graphics.MeasureStringTextRenderer.MeasureText 渲染字符并测量结果?
  • @timur 我正在编写的应用程序是一个控制台应用程序。渲染它然后测量文本太重了。

标签: c# unicode fonts width fixed-width


【解决方案1】:

根据 .NET 文档,如果您知道使用的字体1,您可以使用您的字体的GlyphTypeface APIget the "AdvanceWidths" of each glyph

您仍然必须使用字体中的字形索引来映射字符。您可以使用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] 要获取当前控制台的字体详细信息,我建议阅读以下问题:Get current console font info

相关问题:How to find exact size for an arbitrary glyph in WPF?

【讨论】:

    【解决方案2】:

    我也在寻找相同问题的答案……但我没有找到。 顺便说一句,我终于写了一个库来获取字符长度(使用Console.Write()和Console.CursorLeft生成显示字符长度的范围信息,然后转换为C#代码,当获取字符长度时,使用二进制搜索更高的速度)

    nuget: NullLib.ConsoleEx 项目:https://github.com/SlimeNull/NullLib.ConsoleEx

    【讨论】:

    • 这看起来很有趣!我会看看。感谢分享!
    猜你喜欢
    • 1970-01-01
    • 2022-07-16
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多