Recherche de la largeur de chaîne en C# pour simuler l'enveloppe de texte et la position du texte (maintenant écrit dans richTextBox).Comportement étrange lors du calcul de la largeur de chaîne en pixels pour la simulation d'enveloppement de mots
La taille de richTextBox est 555x454 px et j'utilise la police à espacement fixe Courier New 12pt. J'ai essayé TextRenderer.MeasureText()
et Graphics.MeasureString()
méthodes.
TextRenderer
retournait des valeurs plus grandes que Graphics
alors le texte qui correspond normalement à une ligne, mon code déterminé devrait être enveloppé à l'autre ligne. En revanche, en utilisant Graphics
, mon code a déterminé qu'une chaîne particulière est plus courte que celle imprimée dans l'original richTextBox, donc elle a été enroulée à la ligne suivante au mauvais endroit. Pendant le débogage, j'ai découvert que les largeurs calculées diffèrent, ce qui est étrange car j'utilise une police à espacement fixe, donc les largeurs devraient être les mêmes pour tous les caractères. Mais je reçois quelque chose comme ça de Graphics.MeasureString()
(exemple: '' - 5.33333254, 'S' - 15.2239571, '\ r' - 5.328125). Comment puis-je calculer avec précision la largeur de chaîne avec C# et simuler ainsi le retour à la ligne et déterminer des positions de texte particulières en pixels?
Pourquoi la largeur diffère-t-elle en caractères différents lors de l'utilisation d'une police monopolaire? Remarque: Je travaille sur un projet personnel de suivi des yeux et je veux déterminer où des morceaux de texte particuliers ont été placés pendant l'expérience afin que je puisse dire sur quels mots l'utilisateur regardait. Par ex. à l'heure t
l'utilisateur cherchait sur le point [256,350] px et je sais qu'à cet endroit il y a appel de la méthode WriteLine
. Mon stimulus visuel cible est le code source, avec des retraits, des tabulations, des fins de ligne, placés dans une zone de texte modifiable (dans le futur peut-être un simple éditeur de code source en ligne).
Voici mon code:
//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;
}
C'est plus difficile. RichTextBox est juste à des fins de test.Et d'ailleurs je le garde séparé. Il y aura une application (probablement un éditeur de code source en ligne - mais maintenant simple RichTextBox), et une autre application séparée qui traitera les données hors ligne rassemblées dans la première application. – Gondil
Oui, je comprends que c'est compliqué, mais pour autant que je comprenne votre objectif final, comme vous le dites, "afin que je puisse dire sur quels mots était l'utilisateur à la recherche". Sur une page Web, une approche avec le calcul de la taille du texte et la simulation d'un mot d'emballage est beaucoup plus compliquée en raison de différentes résolutions d'écran, différents navigateurs, différents paramètres de zoom et ainsi de suite. C'est pourquoi je pense qu'il est plus facile d'obtenir du texte en utilisant un certain point sur un écran. Pour le web cette approche a été discutée ici: http://stackoverflow.com/questions/2444430/how-to-get-a-word-under-cursor-using-javascript – Pasick