GraphicsPath消除文本边框

时间:2014-03-13 10:27:23

标签: c# winforms drawing gdi+

我正在使用GraphicsPath对象在矩形中绘制文本。矩形比文本大,我想在任何矩形的角落中绘制文本,也希望在其边缘的中心绘制文本。

我遇到的问题是,当我绘制路径时,源矩形周围会留下一个边框。我希望能够消除该边框并使文本触及其边界矩形。

这是我的代码:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    var g = e.Graphics;
    g.SmoothingMode = SmoothingMode.HighQuality;

    Rectangle textRect = new Rectangle(100, 100, 150, 150);
    Font f = new Font("Arial", 16);
    float emSize = f.Height * f.FontFamily.GetCellAscent(f.Style) /
               f.FontFamily.GetEmHeight(f.Style);

    foreach (StringAlignment lineAlignment in Enum.GetValues(typeof(StringAlignment)))
    {
        foreach (StringAlignment alignment in Enum.GetValues(typeof(StringAlignment)))
        {
            StringFormat sf = new StringFormat() { LineAlignment = lineAlignment, Alignment = alignment };
            using (GraphicsPath gp = new GraphicsPath())
            {
                gp.AddString("txt", f.FontFamily, (int)f.Style, emSize, textRect, sf);
                RectangleF bounds = gp.GetBounds();
                g.FillPath(Brushes.Black, gp);
                g.DrawRectangle(Pens.Red, Rectangle.Round(bounds));
            }
        }
    }          

    g.DrawRectangle(Pens.Blue, textRect);
}

结果如下:

Result

基本上,我希望红色矩形(及其包含的文字)触摸蓝色矩形,并消除它们之间的边界。另外,我需要使用GraphicsPath而不是DrawString

1 个答案:

答案 0 :(得分:1)

我最终编写了一个辅助方法来计算矩形的偏移量并在绘制之前翻译文本。这是我写的方法:

private PointF FixAlignment(RectangleF parentRect, RectangleF childRect,
    StringAlignment lineAlignment, StringAlignment alignment)
{
    float xOffset = 0;
    float yOffset = 0;

    switch (lineAlignment)
    {
        case StringAlignment.Near:
            yOffset = parentRect.Top - childRect.Top;
            break;
        case StringAlignment.Far:
            yOffset = parentRect.Bottom - childRect.Bottom;
            break;
    }

    switch (alignment)
    {
        case StringAlignment.Near:
            xOffset = parentRect.Left - childRect.Left;
            break;
        case StringAlignment.Far:
            xOffset = parentRect.Right - childRect.Right;
            break;
    }

    return new PointF(xOffset, yOffset);
}

我在Form1_Paint方法中使用它,如下所示:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    var g = e.Graphics;
    g.SmoothingMode = SmoothingMode.HighQuality;

    Rectangle textRect = new Rectangle(100, 100, 150, 150);
    Font f = new Font("Arial", 16);
    float emSize = f.Height * f.FontFamily.GetCellAscent(f.Style) /
               f.FontFamily.GetEmHeight(f.Style);

    foreach (StringAlignment lineAlignment in Enum.GetValues(typeof(StringAlignment)))
    {
        foreach (StringAlignment alignment in Enum.GetValues(typeof(StringAlignment)))
        {
            StringFormat sf = new StringFormat() { LineAlignment = lineAlignment, Alignment = alignment };
            using (GraphicsPath gp = new GraphicsPath())
            {
                gp.AddString("txt", f.FontFamily, (int)f.Style, emSize, textRect, sf);
                RectangleF bounds = gp.GetBounds();

                // Calculate the rectangle offset
                PointF offset = FixAlignment(textRect, bounds, lineAlignment, alignment);
                // Translate using the offset
                g.TranslateTransform(offset.X, offset.Y);
                g.FillPath(Brushes.Black, gp);
                g.DrawRectangle(Pens.Red, Rectangle.Round(bounds));

                // Translate back to the original location
                g.TranslateTransform(-offset.X, -offset.Y);
            }
        }
    }

    g.DrawRectangle(Pens.Blue, textRect);
}

结果如下:

Result