Попытка получить ширину строки в C# для имитации словарной и текстовой позиции (теперь она написана в richTextBox).Странное поведение при вычислении ширины строки в пикселях для моделирования переноса слов
Размер richTextBox составляет 555x454 px, и я использую моноширинный шрифт Courier New 12pt.
Я пробовал TextRenderer.MeasureText()
а также Graphics.MeasureString()
методов.
TextRenderer
возвращал более крупные значения, чем Graphics
, поэтому текст, который обычно помещается в одну строку, мой код должен быть завернут в другую строку.
Но с использованием Graphics
мой код определил, что конкретная строка короче, чем она напечатана в оригинальном richTextBox, поэтому она была перенесена на следующую строку в неправильном месте.
Во время отладки я выяснил, что рассчитанная ширина отличается, что странно, потому что я использую моноширинный шрифт, поэтому ширина должна быть одинаковой для всех символов. Но я получаю что-то вроде этого от Graphics.MeasureString()
(пример .: '' - 5.33333254, 'S' - 15.2239571, '\ r' - 5.328125).
Как я могу точно вычислить ширину строки с помощью C# и таким образом смоделировать перенос слов и определить определенные текстовые позиции в пикселях?
Почему ширина шрифта различна при использовании моноширинного шрифта?
Примечание: Я работаю над личным проектом отслеживания глаз, и я хочу определить, где были размещены отдельные фрагменты текста во время эксперимента, поэтому я могу рассказать, какие слова были пользователем. Напр. в момент времени t
пользователь смотрел на точку [256,350] px, и я знаю, что на этом месте есть вызов метода WriteLine
. Мой целевой визуальный стимул - это исходный код с отступами, вкладками, окончаниями строк, размещенными в некоторой редактируемой текстовой области (в будущем, возможно, простой простой редактор исходного кода).
Вот мой код:
//before method call
var font = new Font("Courier New", 12, GraphicsUnit.Point);
var graphics = this.CreateGraphics();
var wrapped = sourceCode.WordWrap(font, 555, graphics);
public static List<string> WordWrap(this string sourceCode, Font font, int width, Graphics g)
{
var wrappedText = new List<string>(); // output
var actualLine = new StringBuilder();
var actualWidth = 0.0f; // temp var for computing actual string length
var lines = Regex.Split(sourceCode, @"(?<=\r\n)"); // split input to lines and maintain line ending \r\n where they are
string[] wordsOfLine;
foreach (var line in lines)
{
wordsOfLine = Regex.Split(line, @"(|\t)").Where(s => !s.Equals("")).ToArray(); // split line by tabs and spaces and maintain delimiters separately
foreach (string word in wordsOfLine)
{
var wordWidth = g.MeasureString(word, font).Width; // compute width of word
if (actualWidth + wordWidth > width) // if actual line width is grather than width of text area
{
wrappedText.Add(actualLine.ToString()); // add line to list
actualLine.Clear(); // clear StringBuilder
actualWidth = 0; // zero actual line width
}
actualLine.Append(word); // add word to actual line
actualWidth += wordWidth; // add word width to actual line width
}
if (actualLine.Length > 0) // if there is something in actual line add it to list
{
wrappedText.Add(actualLine.ToString());
}
actualLine.Clear(); // clear vars
actualWidth = 0;
}
return wrappedText;
}
Это довольно сложно. RichTextBox предназначен только для тестирования.И более того, я держу его разделенным. Будет одно приложение (возможно, какой-то редактор исходного кода в Интернете, но теперь просто простой RichTextBox) и другое отдельное приложение, которое будет обрабатывать автономные данные, собранные в первом приложении. – Gondil
Да, я понимаю, что это сложно, но насколько я понимаю вашу конечную цель, как вы говорите, «поэтому я могу сказать, на какие слова был пользователь». На веб-странице подход с вычислением размера текста и симуляцией переноса слов является более сложным из-за разных разрешений экрана, разных браузеров, различных настроек масштабирования и т. Д. И т. Д. Вот почему я считаю, что легче получить текст, используя определенную точку на экране. Для Интернета этот подход обсуждался здесь: http://stackoverflow.com/questions/2444430/how-to-get-a-word-under-cursor-using-javascript – Pasick