我正在使用C#WinForms和GDI +做一些我希望不会有太多问题的事情,但......
我基本上是在一个矩形内绘制一个字符串,该字符串中有突出显示的部分。这一切都可以在一行打印时正常工作,但在尝试将文本包装到矩形中的下一行时我遇到了问题。
使用的算法如下: -
将字符串拆分为高亮显示的集合,而不是突出显示。
Do
If Highlightedtext Then
DrawString(HighLightedText);
Move X position forward to next character space
Else
DrawString(NormalText);
Move X position forward to next character space
End If
Loop
我会把代码放进去,但它很麻烦而且很长(我维护它)。它会打印出来查找文本是否是一个突出显示的字符串,因为如果它太长,它会将它包装在矩形的边界内而不会出现问题。如果它是多次突出显示并且字符串大于矩形,它将在它之外写...这是因为“向前移动X位置......”只是移动了有问题的矩形!
我想基本上移动文本在原始矩形内打印的点,如果需要换行则将其打印在下一行。任何人都可以协助吗?真是太痛苦了!
答案 0 :(得分:1)
我已经设法通过让我的函数一次做一个字符来对此进行排序。
为此,我创建了一个函数来获取一个布尔值的数组(这是字符串本身的长度),它将任何突出显示的字符设置为true。
private bool[] Get_CharacterArray(string text)
{
// Declare the length of the array, all set to false
bool[] characters = new bool[text.Length];
// Get the matching points
List<Point> wordLocs = FindMatchingTerms(text);
wordLocs.Sort(PointComparison);
int position = 0;
foreach (Point loc in wordLocs)
{
// We're only setting the array for matched points
for (position = loc.X; position <= loc.Y; position++)
{
characters[position] = true;
}
}
// Return the array
return characters;
}
(FindMatchingTerms()是一个函数,它将查找字符串并返回找到的集合中的匹配项。)
然后我循环这个数组以将其绘制到屏幕,但跟踪我的矩形边框宽度。当它减小到相关尺寸时,我将绘图的位置重置回到开始,然后将起始Y位置向下移动一点。
private void RenderFormattedText(Graphics g, RectangleF bounds, string text, string matchText, Font font, Color colour, bool alignTextToTop)
{
const string spaceCharacter = " ";
const string hyphenCharacter = "-";
Font fr = null;
Font fi = null;
try
{
// Get teh matching characters.
bool[] charactersMatched = Get_CharacterArray(text);
// Setup the fonts and bounds.
fr = new Font(font.FontFamily, font.Size, FontStyle.Regular);
fi = new Font(font.FontFamily, font.Size, FontStyle.Bold | FontStyle.Underline);
SizeF fontSize = g.MeasureString(text, fi, 0, StringFormat.GenericTypographic);
RectangleF area = bounds;
// Loop all the characters of the phrase
for (int pos = 0; pos < charactersMatched.Length; pos++)
{
// Draw the character in the appropriate style.
string output = text.Substring(pos, 1);
if (charactersMatched[pos])
{
area.X += DrawFormattedText(g, area, output, fi, colour);
}
else
{
area.X += DrawFormattedText(g, area, output, fr, colour);
}
// Are we towards the end of the line?
if (area.X > (bounds.X + bounds.Width - 1))
{
// are we in the middle of a word?
string preOutput = spaceCharacter;
string postOutput = spaceCharacter;
// Get at the previous character and after character
preOutput = text.Substring(pos - 1, 1);
if ((pos + 1) <= text.Length)
{
postOutput = text.Substring(pos + 1, 1);
}
// Are we in the middle of a word? if so, hyphen it!
if (!preOutput.Equals(spaceCharacter) && !postOutput.Equals(spaceCharacter))
{
if (charactersMatched[pos])
{
area.X += DrawFormattedText(g, area, hyphenCharacter, fi, colour);
}
else
{
area.X += DrawFormattedText(g, area, hyphenCharacter, fr, colour);
}
}
}
// Are we at the end of the line?
if (area.X > (bounds.X + bounds.Width))
{
area.X = bounds.X;
area.Y += fontSize.Height + 2;
}
}
}
finally
{
fr.Dispose();
fi.Dispose();
}
}
希望其他人会发现这个有用:)我在那里有一些常量用于spaceCharacter和hypenCharacter,这应该是自我解释的!有自定义函数来绘制字符串,但它应该有意义,希望它可以帮助其他任何人。