[英]Graphics.DrawString to multiple rectangles
我正在嘗試編寫一個需要在圖像上繪制字符串的函數。 圖像具有1-5個文本框,其中每個都有ax,y,寬度和高度。 這些詳細信息在我正在解析的XML文件中定義,因此我可以訪問每個框。
我的問題是我是否可以使用graphics.DrawString(或類似的方法)輕松地做到這一點。 下面的示例函數將創建一個具有指定的x,y,寬度,高度的矩形,然后在其中繪制一個字符串。 如果字符串不合適,它將被截斷。
public void DrawStringRectangleFormat(Graphics g)
{
// Create string to draw.
String drawString = "Sample Text is too long to fit into this tiny lil rectangle area right here";
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create rectangle for drawing.
float x = 150.0F;
float y = 150.0F;
float width = 200.0F;
float height = 50.0F;
RectangleF drawRect = new RectangleF(x, y, width, height);
// Set format of string.
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
// Draw string to screen.
g.DrawString(drawString, drawFont, drawBrush, drawRect, drawFormat);
}
我要代替它而不是被截斷,它會停在最后一個合適的單詞處,然后轉到下一個矩形(文本框)。 這樣,我可以使用所有可用的文本框。
已經有一種方法可以做到這一點嗎? 否則,我將需要實現自己的drawString方法。
好的,您要做的是循環遍歷字符串中的每個字符,並連接到最終字符串..因此,基本上是foreach(mystring中的char c)...然后使用measurestring,檢查字符串是否結束盒子的長度,如果是的話,從下一個矩形開始...
https://msdn.microsoft.com/zh-CN/library/6xe5hazb(v=vs.110).aspx
此解決方案使用StringFormat
的設置來確保對DrawString的每次調用僅繪制適合的單詞。 然后, Graphics.MeasureCharacterRanges
計算不適合該矩形的單詞,其余文本溢出到下一個布局矩形中。
您可能需要自定義如何將輸入字符串拆分為單詞。 現在,我只是將其在空白邊界處分開。
using System.Text.RegularExpressions;
using System.Drawing;
/// <summary>
/// Draw a string using one or more layout rectangles. Words which don't fit will overflow into the next layout rectangle.
/// </summary>
private static void DrawOverflowString(Graphics graphics, string drawString, RectangleF[] layoutRectangles, StringAlignment alignment)
{
var drawFont = new Font("Arial", 16.0f);
var black = new SolidBrush(Color.Black);
var format = new StringFormat()
{
Alignment = alignment,
Trimming = StringTrimming.Word,
FormatFlags = StringFormatFlags.LineLimit
};
var wordRegex = new Regex("[^\\s]+");
string remainingText = drawString;
foreach (var layoutRect in layoutRectangles)
{
// Draw everything that will fit into this text box
graphics.DrawString(remainingText, drawFont, black, layoutRect, format);
// calculate which words did not fit
var wordMatches = wordRegex.Matches(remainingText);
var ranges = wordMatches.OfType<Match>().Select(x => new CharacterRange(x.Index, x.Length)).ToArray();
format.SetMeasurableCharacterRanges(ranges);
var wordRegions = graphics.MeasureCharacterRanges(remainingText, drawFont, layoutRect, format);
var allfit = true;
for (int i = 0; i < wordRegions.Length; i++)
{
if (wordRegions[i].GetBounds(graphics).Width == 0.0f)
{
allfit = false;
remainingText = remainingText.Substring(wordMatches[i].Index);
break;
}
}
if (allfit)
break;
}
drawFont.Dispose();
black.Dispose();
}
protected override void OnPaint(PaintEventArgs e)
{
// Call the OnPaint method of the base class.
base.OnPaint(e);
List<Rectanglestring> testrecs = new List<Rectanglestring>();
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 12, 40, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring {targetrect= new Rectangle(0, 25, 35, 12),whattodraw="" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 35, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 45, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 65, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 85, 35, 12), whattodraw = "" });
testrecs.Add(new Rectanglestring { targetrect = new Rectangle(0, 95, 55, 12), whattodraw = "" });
string mystringtofit = "This is just an example";
foreach (Rectanglestring rect in testrecs)
{
for (int i = 0; i < mystringtofit.Length; i++)
{
if (mystringtofit[i] == ' ' && rect.whattodraw.Length > 0) break;
if (mystringtofit[i] == ' ') continue;
string teststring = rect.whattodraw + mystringtofit[i];
SizeF stringSize = stringSize = e.Graphics.MeasureString(teststring, new Font("Ariel", 12));
if (stringSize.Width >= rect.targetrect.Width) break;
rect.whattodraw += mystringtofit[i];
}
mystringtofit = mystringtofit.Substring(rect.whattodraw.Length);
if (mystringtofit.StartsWith(" "))
{
mystringtofit = mystringtofit.Substring(1);
}
e.Graphics.DrawString(rect.whattodraw, Font, new SolidBrush(ForeColor), rect.targetrect);
}
// Call methods of the System.Drawing.Graphics object.
}
public class Rectanglestring
{
public Rectangle targetrect = new Rectangle();
public string whattodraw = "";
}
這就是我所擁有的。 它做了我所描述的。 感謝您的回答。
public void DrawStringInTextboxes(string text, Graphics g)
{
String drawString = text;
PrivateFontCollection fontCollection = new PrivateFontCollection();
fontCollection.AddFontFile(System.Web.Hosting.HostingEnvironment.MapPath("~/Content/Fonts/Squidgingtons.ttf"));
var squidingtonsFontFamily = fontCollection.Families[0];
Font squidingtons = new Font(squidingtonsFontFamily, textParameters[0].MaxFontSize);
Font drawFont = new Font("Arial", 60);
SolidBrush drawBrush = new SolidBrush(Color.Black);
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
char[] delimiterChars = { ' ' };
string[] words = drawString.Split(delimiterChars);
string finalString = "";
int textBoxIndex = 0;
foreach (string word in words)
{
//set the dimensions for the first textbox and create a rectangle with those specifications.
float x = textParameters[textBoxIndex].Left;
float y = textParameters[textBoxIndex].Top;
float width = textParameters[textBoxIndex].Width;
float height = textParameters[textBoxIndex].Height;
RectangleF Rect = new RectangleF(x, y, width, height);
//if the current finalString + the next word fits in the current box, add the word to finalString.
if (g.MeasureString(finalString + word + " ", squidingtons).Width < textParameters[textBoxIndex].Width)
{
finalString = finalString + " " + word;
//if this is the last word, print the finalString and we are done.
if (word == words[words.Length - 1])
{
g.DrawString(finalString, squidingtons, drawBrush, Rect, drawFormat);
break;
}
}
//the current finalString + next word did not fit in the box. Draw what we have to the first box.
else {
g.DrawString(finalString, squidingtons, drawBrush, Rect, drawFormat);
//Hold onto the word that didnt fit. It will be the first word of the next box.
finalString = word;
if (textBoxIndex +1 >= textParameters.Length)
{
//if we are out of textboxes, we are done.
break;
}
else
{
//move on to the next textbox. The loop begins again with new specifications set for the textbox.
textBoxIndex++;
}
}
}
squidingtons.Dispose();
drawBrush.Dispose();
drawFont.Dispose();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.