首页 > 解决方案 > StringFormat.Trimming 改变文本的垂直位置

问题描述

这是用于打印页面上的页眉/页脚。下面的代码正在绘制页眉/页脚的左侧和中心部分(我省略了绘制右侧的代码)并简化了逻辑以更好地说明问题。StringTrimming.EllipsisPath这个想法是标题的中心部分优先,如果中心太大而无法容纳,则左右将被修剪。这一切都有效,除了每当修剪发生时,GDI+ 正在垂直移动修剪的文本。

编辑:我写了一个专门的示例来说明这个问题,因为我的原始帖子对人们来说不够清楚。这是示例的完整代码。这是一个使用 VS19 创建的 .NET Framework Winforms 应用程序。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
        Font font = new Font("Century Gothic", 24F, FontStyle.Regular, GraphicsUnit.Point);
        string demo = "[Emergency 123]";

        StringFormat fmtTrimmed = new StringFormat(StringFormat.GenericTypographic)
        {
            Alignment = StringAlignment.Near,
            LineAlignment = StringAlignment.Near,
            Trimming = StringTrimming.EllipsisCharacter,
        };

        StringFormat fmtNotTrimmed = new StringFormat(StringFormat.GenericTypographic)
        {
            Alignment = StringAlignment.Center,
            LineAlignment = StringAlignment.Near,
        };

        try
        {
            Rectangle boundsHeader = new Rectangle(10, 10, this.ClientSize.Width - 20, (int)font.GetHeight() + 8);
            SizeF textSize = e.Graphics.MeasureString(demo, font, boundsHeader.Size, fmtNotTrimmed);

            boundsHeader.Inflate(1, 1);
            e.Graphics.DrawRectangle(Pens.Blue, boundsHeader);

            float textCenterBounds = (boundsHeader.Width - textSize.Width) / 2;
            e.Graphics.DrawRectangle(Pens.Green, boundsHeader.X + textCenterBounds, boundsHeader.Y, textSize.Width, textSize.Height);
            e.Graphics.DrawString(demo, font, Brushes.Black, boundsHeader, fmtNotTrimmed);

            RectangleF boundsLeft = new RectangleF(boundsHeader.X, boundsHeader.Y, textCenterBounds, boundsHeader.Height);
            SizeF sizeLeft = e.Graphics.MeasureString(demo, font, boundsLeft.Size, fmtTrimmed);

            e.Graphics.DrawRectangle(Pens.Red, boundsLeft.X, boundsLeft.Y, boundsLeft.Width, textSize.Height);
            e.Graphics.DrawString(demo, font, Brushes.Black, boundsLeft, fmtTrimmed);
        }
        finally
        {
            font.Dispose();
            fmtTrimmed.Dispose();
            fmtNotTrimmed.Dispose();
        }
    }

在这里,应用程序显示如果left不发生修剪的大小,则垂直正确对齐: 在此处输入图像描述

如果leftis 具有发生修剪的长度(注意省略号),则垂直对齐会略微向上移动(注意代码用于Form1_Resize调整矩形大小)。 在此处输入图像描述

通过查看 、 和 括号,您可以最清楚地看到这y一点g

我已经尝试了, 和的所有组合StringTrimming,但无法解决这个问题。请注意,在当前实现中,我还尝试使 Rectangle 的高度为 0。如果是字体高度、或更大,则会出现同样的问题。LineAlignmentFormatFlagsbounds.HeightsizeCenter.Height

我不敢相信这是 GDI+ 中的错误,所以我一定是做错了什么。许多搜索和重新阅读文档都没有帮助。我无计可施。

编辑:根据@HansPassant 下面的评论,我发现不同的字体表现不同。在上面的图片中,我使用的是“Microsoft Sans Serif”。

我已经确定某些字体比其他字体差。例如,如果我将上面的代码更改为24F用作字体大小,我无法使用Microsoft Sans Serif) 重现它。

我还确定并且StringTrimming.Character所有行为都以相同的方式进行(因此省略号字符似乎不是原因)。StringTrimming.ElipsisCharacterStringTrimming.ElipsisPath

Century Gothic编辑:在这里使用常规 显示另一个示例:在此处输入图像描述

编辑:此示例说明e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasLineAlignment = StringAlignment.Far. 在此处输入图像描述

标签: c#.netwinformsstring-formattinggdi+

解决方案


推荐阅读