Graphics.DrawString为多个矩形

时间:2016-11-30 19:05:26

标签: c# .net drawstring

我正在尝试编写一个需要将字符串绘制到图像的函数。图像具有1-5个文本框,每个文本框都有x,y,宽度和高度。这些细节在我正在解析的XML文件中定义,因此我可以访问每个框。

我的问题是我是否可以使用graphics.DrawString(或类似的)方法轻松完成此操作。下面的示例函数将创建一个具有指定的x,y,width,height的矩形,然后在其中绘制一个字符串。如果字符串不适合,则会截断。

    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方法。

4 个答案:

答案 0 :(得分:1)

好的,您需要做的是遍历字符串中的每个字符串,并连接到最终的字符串.. 所以基本上foreach(mysc中的char c)... 然后使用measuretring,检查字符串是否超过框长度,如果是,则从下一个矩形开始...

https://msdn.microsoft.com/en-us/library/6xe5hazb(v=vs.110).aspx

答案 1 :(得分:1)

此解决方案使用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();
}

答案 2 :(得分:1)

        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 = "";
    }

答案 3 :(得分:0)

这就是我所拥有的。它做我所描述的。谢谢你的回答。

    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();
    }