【问题标题】:How to get the part of string fitted in a rectangle layout by text renderer如何通过文本渲染器获取适合矩形布局的字符串部分
【发布时间】:2015-06-03 13:37:06
【问题描述】:

我正在尝试在位图上绘制字符串,但如果文本太长,文本渲染器可能会剪切部分文本。如果我能找到文本的哪一部分是写的,我可以将其余部分写在另一个位图上。

C# 中是否有任何文本渲染函数,因此它可以获取文本和建议的布局矩形并返回在布局矩形中写入(拟合)的字符串数量?

string fittedString = TextRenderer.DrawText(graphics, text, rectangle);

如果没有,最简单的方法是什么?

【问题讨论】:

  • 这是 WPF 还是 WinForms 项目?
  • @Dialectus Winform,我在标签中提到过,但我认为没有区别
  • 你为什么不简单地在里面放一个面板和一个标签?

标签: c# winforms text-rendering


【解决方案1】:

TextRenderer.MeasureText(...) 方法返回一个Size 值,该值确定绘制文本所需的大小。但是,此方法要求将文本绘制在单行上。 TextFormatFlags.WordBreak 选项可以将文本包装在建议的布局中。

我们将建议布局的宽度设置为目标矩形宽度,并在循环中测量此布局中呈现的主要文本的子字符串的大小。如果该方法返回的size.Height 超过了我们目标矩形的高度,那么我们停止并返回索引。

    int HowManyChars(Font font, string text, Rectangle r)
    {
        int i = 0;
        for (; i < text.Length; i++)
        {
            string str = text.Substring(0, i);
            var size = TextRenderer.MeasureText(str, font, 
new Size(r.Width, 0), TextFormatFlags.WordBreak);


            if (size.Height > r.Height)
                break;

        }
        return i;
    }

【讨论】:

    【解决方案2】:

    我不知道,但您可以通过在循环中对字符串的每个字符调用 MeasureText() 并在变量中总结返回的宽度(例如 W)来获得近似值。当您的总和超过目标矩形的宽度时,您只需在单独的变量中选择该行的最大值字符高度,例如 H。到达每一行的末尾时,您在H 中添加当前行高度的最大值。

    您一直这样做,直到H 的值超过目标矩形的高度。这只是适合您矩形的字符数。

    类似这样的东西(手写,请调整):

    int HowManyChars(Graphics g, Font font, string text, Rectangle r)
    {
        float W=0, H=0, MaxH=0;
    
        int i=0;
    
        for(i=0; i< text.Length; i++)
        {
            var sz = g.MeasureString(text[i].ToString(), font);
            W+= sz.Width;
    
           if(W > r.Width) 
           {
               W=sz.Width;
               H+=MaxH;
               MaxH = 0;
               if(H>r.Height) break;
           }
           else
           {
               if(sz.Height > MaxH) MaxH = sz.Height;
           }
        }
    
        return i;
    }
    

    【讨论】:

    • 谢谢,这似乎是一个很有前途的解决方案!
    • 非常感谢,难道你不能确定MeasureString的建议布局并检查它是否写成功吗?
    • @Ahmad:不,我害怕。您将无法从DrawText() 电话中获取该信息。顺便说一句,如果您需要在文本布局上达到那种精确度,最好不要自己编写每个字符(使用类似于我上面写的代码并调用DrawString() 而不是MeasureString())。不过要小心外面的龙。您需要处理悬垂的字符、字距调整、黑盒拟合以及如果您需要精确控制则不需要。
    • @Ahmad:自从我使用Graphics 进行文本渲染以来已经有一段时间了,所以我花了一些时间来恢复我的记忆。我刚刚记得有一个内置函数可能完全符合您的要求:尝试使用Graphics.MeasureCharacterRanges()。它可以接受一个字符串并返回有关Region 对象数组中每个字符的布局信息。
    • 根据您最初的想法,我用不同的方法编写了一个不同的函数
    猜你喜欢
    • 2012-05-12
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 2021-05-26
    • 1970-01-01
    相关资源
    最近更新 更多