在文本上具有光晕或光晕效果的winform标签



以下方法是winform标签继承类的一部分。目标是在文本上产生光晕或光晕效果。到目前为止,效果实际上只是一个轮廓。它值得保留,因为它还不错,但还没有出现。

protected override void OnPaint(PaintEventArgs e)
{
if (this.Text.Length == 0) return;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
Rectangle rc = new Rectangle(ClientRectangle.X + Padding.Left,
ClientRectangle.Y + Padding.Top,
ClientRectangle.Width - (Padding.Left + Padding.Right),
ClientRectangle.Height - (Padding.Top + Padding.Bottom));
StringFormat fmt = new StringFormat(StringFormat.GenericTypographic)
{
Alignment = TextAlign == ContentAlignment.TopLeft || TextAlign == ContentAlignment.MiddleLeft || TextAlign == ContentAlignment.BottomLeft
? StringAlignment.Near
: TextAlign == ContentAlignment.TopCenter || TextAlign == ContentAlignment.MiddleCenter || TextAlign == ContentAlignment.BottomCenter
? StringAlignment.Center
: StringAlignment.Far
};
if ((haloSize < 1) | (haloColor == Color.Transparent))
{
using (var brush = new SolidBrush(this.ForeColor))
{
e.Graphics.DrawString(Text, Font, brush, rc, fmt);
}
}
else
{
using (var path = new GraphicsPath())
using (var halopen = new Pen(new SolidBrush(this.haloColor), haloSize) { LineJoin = LineJoin.Round })
using (var brush = new SolidBrush(ForeColor))
{
if (fmt.Alignment == StringAlignment.Center) rc.X += rc.Width / 2;
if (fmt.Alignment == StringAlignment.Far) rc.X += rc.Width;
path.AddString(Text, Font.FontFamily, (int)Font.Style, rc.Height, rc.Location, fmt);
//path.AddString(Text, Font.FontFamily, (int)Font.Style, rc.Height, rc, fmt);
e.Graphics.DrawPath(halopen, path);
e.Graphics.FillPath(brush, path);
}
}
}

两个问题。

  1. 为什么使用AddStringRectangle注释掉的行不起作用,而使用Point却起作用
  2. 光晕效果可以通过逐渐减小笔刷大小和颜色变化来实现,但这感觉就像发明了一个新的轮子。有没有一种简单的方法可以做到这一点,或者已经有了一个开源库
  1. 原始的addstring对于盒子来说太大了。我认为它取消了抽签,因为它在剪辑
  2. 多过程可以工作并生成渐变,但速度可能不够快,无法在辉光中添加闪烁效果

光晕/光晕效果为恰好与文本原色匹配的背景图像提供了良好的对比度。这基本上是针对目标的,但对标签太长的文本没有任何作用。我可以稍后补充。

protected override void OnPaint(PaintEventArgs e)
{
if (this.Text.Length == 0) return;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
e.Graphics.CompositingMode = CompositingMode.SourceOver;
Rectangle rc = new Rectangle(ClientRectangle.X + Padding.Left,
ClientRectangle.Y + Padding.Top,
ClientRectangle.Width - (Padding.Left + Padding.Right),
ClientRectangle.Height - (Padding.Top + Padding.Bottom));
StringFormat fmt = new StringFormat(StringFormat.GenericTypographic)
{
Alignment = TextAlign == ContentAlignment.TopLeft || TextAlign == ContentAlignment.MiddleLeft || TextAlign == ContentAlignment.BottomLeft
? StringAlignment.Near
: TextAlign == ContentAlignment.TopCenter || TextAlign == ContentAlignment.MiddleCenter || TextAlign == ContentAlignment.BottomCenter
? StringAlignment.Center
: StringAlignment.Far
};
float EmSize = rc.Height * 0.70f //Font.SizeInPoints  disreguard fontsize and fit height of label
* (Font.FontFamily.GetCellAscent(Font.Style) + Font.FontFamily.GetCellDescent(Font.Style))
/ Font.FontFamily.GetEmHeight(Font.Style);
using (var path = new GraphicsPath())
using (var brush = new SolidBrush(ForeColor))
{
path.AddString(Text, Font.FontFamily, (int)Font.Style, EmSize, rc, fmt);
if ((haloSize > 0) & (haloColor != Color.Transparent))
{
using (var halopen = new Pen(new SolidBrush(Color.FromArgb(255 / (int)haloSize, haloColor)), haloSize) { LineJoin = LineJoin.Round })
{
for (int i = (int)haloSize; i > 0; --i)
{
halopen.Width = i;
e.Graphics.DrawPath(halopen, path);
}
}
}
e.Graphics.FillPath(brush, path);
}
}

最新更新