WinForms .NET TextRendered.DrawText,混合粗体和常规类型剪裁和未对齐

时间:2014-02-26 19:00:43

标签: c# winforms gd gdi+

我正在覆盖一个列表框DrawItem事件,我需要突出显示单个字母,有时是整个单词。

我的代码工作得很好,除了粗体字母/单词没有与常规字母/单词垂直对齐,它们被移动了几个像素到底部,我玩格式化标记但仍然没有去。 / p>

private void lstOptions_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
    //Copy font from a textbox control placed on the form
    Font fontNormal = new Font(textBox1.Font, FontStyle.Regular);
    Font fontBold = new Font(textBox1.Font, FontStyle.Bold);

    Rectangle textPos = e.Bounds;

    const TextFormatFlags formatFlags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.PathEllipsis;
    StringFormat strFormat = (StringFormat)StringFormat.GenericTypographic.Clone();
    strFormat.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;

    //Background
    e.DrawBackground();

    SizeF textSize = e.Graphics.MeasureString("Los Angeles", fontNormal, textPos.Width, strFormat);
    lstOptions.ItemHeight = int.Parse(Math.Ceiling(textSize.Height).ToString());

    //Drawing "L" Regular
    textSize = TextRenderer.MeasureText("L", fontNormal, new Size(textPos.Width, textPos.Height), formatFlags);
    TextRenderer.DrawText(e.Graphics, "L", fontNormal, textPos, e.ForeColor, e.BackColor, formatFlags | TextFormatFlags.PreserveGraphicsClipping);
    textPos.X += MeasureText("L", fontNormal).Width;

    //Drawing "os" Bold
    textSize = TextRenderer.MeasureText("o", fontBold, new Size(textPos.Width, textPos.Height), formatFlags);
    TextRenderer.DrawText(e.Graphics, "o", fontBold, textPos, e.ForeColor, e.BackColor, formatFlags | TextFormatFlags.PreserveGraphicsClipping);
    textPos.X += MeasureText("o", fontBold).Width;

    //Drawing " Angel" Regular
    textSize = TextRenderer.MeasureText("s Ang", fontNormal, new Size(textPos.Width, textPos.Height), formatFlags);
    TextRenderer.DrawText(e.Graphics, "s Ang", fontNormal, textPos, e.ForeColor, e.BackColor, formatFlags | TextFormatFlags.PreserveGraphicsClipping);
    textPos.X += MeasureText("s Ang", fontNormal).Width;

    //Drawing "e" Bold
    textSize = TextRenderer.MeasureText("ele", fontBold, new Size(textPos.Width, textPos.Height), formatFlags);
    TextRenderer.DrawText(e.Graphics, "ele", fontBold, textPos, e.ForeColor, e.BackColor, formatFlags | TextFormatFlags.PreserveGraphicsClipping);
    textPos.X += MeasureText("ele", fontBold).Width;

    //Drawing "s" Regular
    textSize = TextRenderer.MeasureText("s", fontNormal, new Size(textPos.Width, textPos.Height), formatFlags);
    TextRenderer.DrawText(e.Graphics, "s", fontNormal, textPos, e.ForeColor, e.BackColor, formatFlags | TextFormatFlags.PreserveGraphicsClipping);
    textPos.X += MeasureText("s", fontNormal).Width;
}

public static Size MeasureText(string Text, Font Font)
{
    TextFormatFlags flags
      = TextFormatFlags.Left
      | TextFormatFlags.Top
      | TextFormatFlags.NoPadding
      | TextFormatFlags.NoPrefix;
    Size szProposed = new Size(int.MaxValue, int.MaxValue);
    Size sz1 = TextRenderer.MeasureText(".", Font, szProposed, flags);
    Size sz2 = TextRenderer.MeasureText(Text + ".", Font, szProposed, flags);
    return new Size(sz2.Width - sz1.Width, sz2.Height);
}

示例图片:

http://i59.tinypic.com/25kn983.jpg

1 个答案:

答案 0 :(得分:0)

我的最佳结果是使用此处在stackoverflow上找到的自定义度量函数实现的(无法找到问题的链接):

public static Size MeasureText(string Text, Font Font)
        {
            TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.Top
              | TextFormatFlags.NoPadding | TextFormatFlags.NoPrefix;

            StringFormat strFormat = (StringFormat)StringFormat.GenericDefault.Clone();
            strFormat.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;

            Size szProposed = new Size(int.MaxValue, int.MaxValue);

            Size sz1 = TextRenderer.MeasureText(".", Font, szProposed, flags);
            Size sz2 = TextRenderer.MeasureText(Text + ".", Font, szProposed, flags);

            if (Font.Bold)
                sz1.Width -= 1;

            return new Size(sz2.Width - sz1.Width, sz2.Height);
        }

这是非常接近的但是粗体字体仍然有一些剪辑,所以我决定抛弃粗体并使用下划线突出显示单词并且它看起来好多了:

Font fontMatch = new Font(this.Font, FontStyle.Underline);//Bold sucks on measuring the text