我有一个C GDI+绘制字符串函数的问题——我无法得到绘制字符串的确切大小——没有内部前导和外部前导,只有em高度。微软提供的字体/字符串度量api似乎总是输出一个比文本图形大几个像素的边框,即使我去掉了内部前导。

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.Clear(Color.Black);
        String text = "The quick brown fox jumps over the lazy dog";
        Font font = new System.Drawing.Font(FontFamily.GenericSerif, 24);
        float internalLeading = font.Size * (font.FontFamily.GetCellAscent(font.Style) + font.FontFamily.GetCellDescent(font.Style) - font.FontFamily.GetEmHeight(font.Style)) / font.FontFamily.GetEmHeight(font.Style);
        StringFormat format = StringFormat.GenericTypographic;
        format.Trimming = StringTrimming.None;
        format.FormatFlags = StringFormatFlags.NoWrap;
        System.Drawing.RectangleF rect = new System.Drawing.RectangleF(0, 0, pictureBox1.Width,pictureBox1.Height);
        System.Drawing.CharacterRange[] ranges = { new System.Drawing.CharacterRange(0, text.Length) };
        System.Drawing.Region[] boundings = new System.Drawing.Region[1];
        format.SetMeasurableCharacterRanges(ranges);
        boundings = g.MeasureCharacterRanges(text, font, rect, format);
        rect = boundings[0].GetBounds(g);
        g.DrawString(text, font, new SolidBrush(Color.Red), new RectangleF(0,0,rect.Width,rect.Height), format);
        g.DrawRectangle(Pens.Yellow, rect.X, rect.Y + internalLeading, rect.Width, rect.Height - internalLeading);
    }

输出如下所示。我们可以看到在文本和边框的上边缘之间仍然有一些像素。
我可以通过读取图像中的像素来获得绘制字符串的精确大小,并自己计算边界框。但它是缓慢的。我能知道有没有一个简单的方法来解决这个问题吗?

最佳答案

gdi+处理的不仅仅是英语,而且行的高度是固定的(想象一下,如果每一行都是该行文本的高度,会有多可怕)。
边界框还包含可以修饰这些字符的各种变音符号,包括英语中类似的东西,如COÖPERATE
见:
请注意,diaresis(the¨)几乎不在边界框内,ˇ显然在外部,但是在底部,有足够的空间来容纳q。给什么?好吧,MeasureString的意思是文本格式化,而不是获取文本可能呈现的最小矩形-这当然会因为不应该改变文本对齐方式的事情而变得更加复杂,例如使用cleartype。
这个函数是建立在这样一个假设之上的:你非常喜欢有相同高度的行——这就是所有文本通常的呈现方式。
直接引用MSDN:
measurestring方法设计用于单独的字符串,并且在字符串前后包含少量的额外空间,以允许悬置标志符号。另外,drawstring方法调整glyph点以优化显示质量,并且显示的字符串可能比measurestring报告的要窄。

关于c# - GDI +,从图形DrawString()中删除空白,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30317408/

10-13 06:23