Я пишу программу на C# и использую шрифт фиксированной ширины для отображения всего. В этом шрифте каждый символ Unicode занимает либо ширину 1 символа, либо ширину 2 символа. В программе есть функция, которая должна определить, какой именно символ занимает ширину 1 символа или ширину 2 символа. Сначала я использую регулярное выражение [^\x00-\xFF]
для решения проблемы. Если символ соответствует ему, он занимает ширину 1 символа, в противном случае - ширину 2 символа. Но позже я обнаружил, что это неправильно. Например, эти символы ┌─┬┐│├┼┤┴┘
не попадают в диапазон [^\x00-\xFF]
, но все они занимают ширину в 1 символ. Я хочу знать в С#, как определить, что конкретный символ занимает 1 ширину символа или 2 при использовании шрифта фиксированной ширины?
Вы рассматривали возможность рендеринга символов и измерения результата с помощью Graphics.MeasureString или TextRenderer.MeasureText?
@timur Приложение, которое я пишу, представляет собой консольное приложение. Отрисовывать его, а затем измерять текст слишком тяжело.
Согласно документации .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?
Я также ищу ответ на тот же вопрос... но я его не нашел. кстати, я, наконец, пишу библиотеку для получения длины символа (создайте информацию о диапазоне, которая показывает длину символа, используйте Console.Write() и Console.CursorLeft, а затем преобразуйте в код С#, когда получите длину символа, используйте двоичный поиск для выше скорость)
nuget: NullLib.ConsoleEx Проект: https://github.com/SlimeNull/NullLib.ConsoleEx
Это выглядит интересно! Я взгляну. Спасибо, что поделился!
Есть много глифов Юникода, которые занимают 0 пробелов. Например, в Юникоде есть блок it.wikipedia.org/wiki/Combining_Diacritical_Marks, состоящий из глифов, наложенных на предыдущий глиф. В качестве еще одного замечания, многие глифы Unicode состоят из двух символов C#
char
(все глифы, отличные от BMP, с кодом > 0xFFFF). К сожалению,Regex
в .NET не поддерживает не-BMP часть Unicode.