I'm wanted to wrap text to draw it afterwards in my image. I tried as-cii's answer, but it didn't work in my case as expected. It always extends the given width of my line (maybe because I use it in combination with a Graphics object to draw the text in my image).
Furthermore his answer (and related ones) just work for > .NET 4 frameworks. In framework .NET 3.5 there isn't any Clear() function for StringBuilder objects. So here is an edited version:
public static List<string> WrapText(string text, double pixels, string fontFamily, float emSize)
{
string[] originalWords = text.Split(new string[] { " " },
StringSplitOptions.None);
List<string> wrappedLines = new List<string>();
StringBuilder actualLine = new StringBuilder();
double actualWidth = 0;
foreach (string word in originalWords)
{
string wordWithSpace = word + " ";
FormattedText formattedWord = new FormattedText(wordWithSpace,
CultureInfo.CurrentCulture,
System.Windows.FlowDirection.LeftToRight,
new Typeface(fontFamily), emSize, System.Windows.Media.Brushes.Black);
actualLine.Append(wordWithSpace);
actualWidth += formattedWord.Width;
if (actualWidth > pixels)
{
actualLine.Remove(actualLine.Length - wordWithSpace.Length, wordWithSpace.Length);
wrappedLines.Add(actualLine.ToString());
actualLine = new StringBuilder();
actualLine.Append(wordWithSpace);
actualWidth = 0;
actualWidth += formattedWord.Width;
}
}
if (actualLine.Length > 0)
wrappedLines.Add(actualLine.ToString());
return wrappedLines;
}
Because I'm working with a Graphics object I tried @Thorins solution. This worked for me much better, as it wraps my text right. But I made some changes so that you can give the method the required parameters. Also there was a bug: the last line was not added to the list, when the condition of the if-block in the for-loop was not reached. So you have to add this line afterwards. The edited code looks like:
public static List<string> WrapTextWithGraphics(Graphics g, string original, int width, Font font)
{
List<string> wrappedLines = new List<string>();
string currentLine = string.Empty;
for (int i = 0; i < original.Length; i++)
{
char currentChar = original[i];
currentLine += currentChar;
if (g.MeasureString(currentLine, font).Width > width)
{
// Exceeded length, back up to last space
int moveback = 0;
while (currentChar != ' ')
{
moveback++;
i--;
currentChar = original[i];
}
string lineToAdd = currentLine.Substring(0, currentLine.Length - moveback);
wrappedLines.Add(lineToAdd);
currentLine = string.Empty;
}
}
if (currentLine.Length > 0)
wrappedLines.Add(currentLine);
return wrappedLines;
}