|
|
直接完善TextParseReturnValue这个类之前的GetFixedTextLines ()和FixText ()换行对英文比较友好 对中文支持较差 导致的问题就是莫名奇妙的地方换行
特别是GetFixedTextLines ()的段落文本换行
包括战役描述 频道/房间聊天等
以下是论坛里相关的问题贴
https://bbs.ra2diy.com/forum.php?mod=viewthread&tid=25113
https://bbs.ra2diy.com/forum.php?mod=viewthread&tid=19882
以下换行已修好 段首的缩进是打了丑陋的空格
代码由AI进行完善 有其它问题自行修复
public static List<string> GetFixedTextLines(SpriteFont spriteFont, int width, string text, bool splitWords = true, bool keepBlankLines = false)
{
if (string.IsNullOrEmpty(text))
return new List<string>();
List<string> result = new List<string>();
string[] lines = text.Replace("\r", "").Split('\n');
HashSet<char> punctuation = new HashSet<char> { '.', '。', ',', ',', ';', ';', '!', '!', '?', '?' };
foreach (string line in lines)
{
if (keepBlankLines && string.IsNullOrEmpty(line))
{
result.Add("");
continue;
}
if (string.IsNullOrWhiteSpace(line))
continue;
StringBuilder current = new StringBuilder();
float currentW = 0f;
for (int i = 0; i < line.Length; i++)
{
char c = line;
float cw = spriteFont.MeasureString(c.ToString()).X;
float testW = currentW + cw;
bool isPunc = punctuation.Contains(c);
if (testW > width && current.Length > 0 && !isPunc)
{
result.Add(current.ToString().TrimEnd());
current.Clear();
currentW = 0f;
}
current.Append(c);
currentW += cw;
}
string final = current.ToString().TrimEnd();
if (!string.IsNullOrEmpty(final))
result.Add(final);
}
if (splitWords)
{
List<string> finalResult = new List<string>(result.Count);
foreach (string line in result)
{
if (string.IsNullOrEmpty(line))
{
finalResult.Add("");
continue;
}
if (spriteFont.MeasureString(line).X <= width)
{
finalResult.Add(line);
continue;
}
StringBuilder sb = new StringBuilder();
float w = 0f;
for (int i = 0; i < line.Length; i++)
{
char c = line;
float cw = spriteFont.MeasureString(c.ToString()).X;
bool isPunc = punctuation.Contains(c);
if (w + cw > width && sb.Length > 0 && !isPunc)
{
finalResult.Add(sb.ToString());
sb.Clear();
w = 0f;
}
sb.Append(c);
w += cw;
}
if (sb.Length > 0)
finalResult.Add(sb.ToString());
}
result = finalResult;
}
return result;
}
public static TextParseReturnValue FixText(SpriteFont spriteFont, int width, string text)
{
if (string.IsNullOrEmpty(text))
return new TextParseReturnValue(string.Empty, 0);
StringBuilder processedText = new StringBuilder();
int lineCount = 0;
string[] originalLines = text.Replace("\r", "").Split(new[] { '\n' }, StringSplitOptions.None);
float indentWidth = spriteFont.MeasureString(" ").X;
float spaceWidth = spriteFont.MeasureString(" ").X;
HashSet<char> punctuation = new HashSet<char> { '.', '。', ',', ',', ';', ';', '!', '!', '?', '?' };
foreach (string originalLine in originalLines)
{
if (string.IsNullOrWhiteSpace(originalLine))
{
processedText.AppendLine();
lineCount++;
continue;
}
string[] words = originalLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (words.Length == 0)
{
processedText.AppendLine();
lineCount++;
continue;
}
StringBuilder currentLine = new StringBuilder();
float currentWidth = 0f;
bool needIndent = true;
foreach (string word in words)
{
float wordWidth = spriteFont.MeasureString(word).X;
float requiredWidth = currentWidth + (currentLine.Length > 0 ? spaceWidth : 0) + wordWidth;
if (needIndent)
requiredWidth += indentWidth;
if (requiredWidth <= width)
{
if (needIndent)
{
currentLine.Append(" ");
currentWidth += indentWidth;
needIndent = false;
}
if (currentLine.Length > 0)
currentLine.Append(' ');
currentLine.Append(word);
currentWidth += (currentLine.Length > 1 ? spaceWidth : 0) + wordWidth;
}
else
{
if (currentLine.Length > 0)
{
processedText.AppendLine(currentLine.ToString());
lineCount++;
currentLine.Clear();
currentWidth = 0f;
needIndent = false;
}
if (wordWidth > width)
{
StringBuilder charBuf = new StringBuilder();
float charBufWidth = 0f;
bool firstCharLine = true;
for (int i = 0; i < word.Length; i++)
{
char c = word;
float cw = spriteFont.MeasureString(c.ToString()).X;
bool isPunc = punctuation.Contains(c);
float test = charBufWidth + cw;
if (firstCharLine)
test += indentWidth;
if (test > width && charBuf.Length > 0 && !isPunc)
{
if (firstCharLine)
{
charBuf.Insert(0, " ");
charBufWidth += indentWidth;
firstCharLine = false;
}
processedText.AppendLine(charBuf.ToString());
lineCount++;
charBuf.Clear();
charBufWidth = 0f;
}
if (firstCharLine)
{
charBuf.Append(" ");
charBufWidth += indentWidth;
firstCharLine = false;
}
charBuf.Append(c);
charBufWidth += cw;
}
if (charBuf.Length > 0)
{
currentLine.Append(charBuf);
currentWidth = charBufWidth;
needIndent = false;
}
}
else
{
currentLine.Append(" ");
currentLine.Append(word);
currentWidth = indentWidth + wordWidth;
needIndent = false;
}
}
}
if (currentLine.Length > 0)
{
processedText.AppendLine(currentLine.ToString());
lineCount++;
}
}
if (processedText.Length > 0)
processedText.Length -= Environment.NewLine.Length;
return new TextParseReturnValue(processedText.ToString(), lineCount);
}
|
|