其他分享
首页 > 其他分享> > 我如何确定要在矩形中绘制的文本的高度?

我如何确定要在矩形中绘制的文本的高度?

作者:互联网

我试图在带有GDI的矩形中绘制一些文本,如这篇Microsoft文章中所述:https://msdn.microsoft.com/en-us/library/baw6k39s(v=vs.110).aspx.

指定所需的宽度后,文本会自动按预期自动换行到下一行.问题是,我需要设置矩形的高度,以使文本完全适合该框,没有被截断但没有多余的空格.在这种情况下,使用值进行尝试和错误测试将根本无法进行,因为文本将不断更改.

我实现了一种解决方案,它通过向其添加换行符然后测量高度来模拟渲染时文本的损坏.但这似乎不起作用,并且框的高度通常具有大量的尾随空白(似乎与文本的数量呈正线性关系).

问题:

enter image description here

我的代码如下:

public void setBreakLen() { //determines how many chars fit on each line (note: using a FIXED WIDTH FONT) 
  double cwidth = TextRenderer.MeasureText("h", font).Width;
  breakLen = (int)((double)box.Width / (double)cwidth);
}



public void updateHeight() { //should tell me what the height of the box should be to fit perfectly
  StringBuilder sb = new StringBuilder(text);
  int numAppended = 0;
  for (int i = 0; i < text.Length; i++) {
      if ((i + 1) % breakLen == 0) {
          sb.Insert((i + 1 + numAppended), "\n");
          numAppended += 1;
       }
   }

   Size s = TextRenderer.MeasureText(sb.ToString(), font);
   height = s.Height;
   box = new Rectangle(x, y, width, height);
}

但是,这似乎有些矫kill过正,必须有更好的方法.
因此,我想这实际上是一个分为两个部分的问题.

>如何使当前的解决方案有效?
>有没有更好的方法
去做这个?

注意:
使用调试器,我确定breaklen变量是正确的.它读取11,并且每行上有11个字符.

我还检查了其他具有固定宽度字体的字符(Consolas系列),它们都产生相同的中断长度.这是StringBuilder如何处理换行符的问题吗?我通常使用Java而不是C#,因此我对流等并不熟悉.

编辑:
绘图代码如下:

g2d.DrawString(m.text, m.font, Brushes.Blue, m.box);
g2d.DrawRectangle(Pens.Black, Rectangle.Round(m.box));

编辑2:
我尝试使用MeasureText函数的重载Size参数实现此辅助解决方案.不管字符串的长度如何,每次都只返回19,这似乎为单行返回了正确的高度.

    Size s = TextRenderer.MeasureText(text, font, new Size(width, 0));//i also tried MaxInt
    height = s.Height;
    Console.WriteLine(height);
    box = new Rectangle(x, y, width, height);

解决方法:

尝试下面的代码.我只是将代码合并到一个函数中以使其运行.您可以看到更改.您必须使用MeasureString而不是MeasureText.看到我得到的输出
enter image description here

Font font = new Font(FontFamily.GenericSansSerif, 12.0F, FontStyle.Bold);

int x = 10, y = 10, width = 120, height = 30, breakLen = 0;
Rectangle box;
string text = "THIS BOX IS TOO TALL!!!";

private void DrawRectangle()
{
    box = new Rectangle(x, y, width, height);

    using (Graphics g = this.CreateGraphics())
    {
        double cwidth = g.MeasureString("h", SystemFonts.DefaultFont).Width;
        breakLen = (int)((double)box.Width / (double)cwidth);

        StringBuilder sb = new StringBuilder(text);
        int numAppended = 0;

        for (int i = 0; i < text.Length; i++)
        {
            if ((i + 1) % breakLen == 0)
            {
                sb.Insert((i + 1 + numAppended), "\n");
                numAppended += 1;
            }
        }

        Size s = TextRenderer.MeasureText(sb.ToString(), font);
        height = s.Height;
        box = new Rectangle(x, y, width, height);

        Pen pen = new Pen(Color.Black, 2);
        g.DrawString(sb.ToString(), font, Brushes.Blue, box);
        g.DrawRectangle(pen, box);
        pen.Dispose();
    }
}

标签:gdi-2,c,winforms
来源: https://codeday.me/bug/20191111/2022457.html