How to draw shadow of arc?

I

idiot

Because the backgroud color of the form is white, when I use
SmoothingMode.AntiAlias, the color of shadow seems gradient to white color.
But if I don't use SmoothingMode.AntiAlias, there are white gap between four
arc.

Here is the source code:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Drawing2D;

namespace WindowsApplication1
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panelContent;
private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

private void InitializeComponent()
{
this.panelContent = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panelContent
//
this.panelContent.Location = new System.Drawing.Point(88, 56);
this.panelContent.Name = "panelContent";
this.panelContent.Size = new System.Drawing.Size(272, 120);
this.panelContent.TabIndex = 0;
this.panelContent.Paint += new
System.Windows.Forms.PaintEventHandler(this.panelContent_Paint);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(448, 277);
this.Controls.Add(this.panelContent);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Form1";
this.Paint += new
System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.ResumeLayout(false);

}

[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void panelContent_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
System.Drawing.Drawing2D.GraphicsPath path = new GraphicsPath();

int width = this.panelContent.Width - 1;
int height = this.panelContent.Height - 1;
path.StartFigure();
path.AddLine(16, 0, width - 16, 0);
path.AddArc(width - 32, 0, 32, 32, 270, 90);
path.AddLine(width, 16, width, height - 16);
path.AddArc(width - 32, height - 32, 32, 32, 0, 90);
path.AddLine(width - 16, height, 16, height);
path.AddArc(0, height - 32, 32, 32, 90, 90);
path.AddLine(0, height - 16, 0, 16);
path.AddArc(0, 0, 32, 32, 180, 90);
path.CloseFigure();

Brush b = new SolidBrush(Color.FromArgb(239, 239, 239));
e.Graphics.FillPath(b, path);
b.Dispose();
Pen parc = new Pen(Brushes.LightGray, 1);
parc.LineJoin = LineJoin.Round;
e.Graphics.DrawPath(parc, path);

for(int i=0;i<4;i++)
{
Pen p1 = new Pen(Color.FromArgb(132 + 30*i, 132 + 30*i, 132 + 30*i));
e.Graphics.DrawArc(p1, this.panelContent.Width - 32 + i,
this.panelContent.Height - 32 + i, 32, 32, 0, 90);
p1.Dispose();
}
}

private void Form1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{

e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
for(int i=0;i<4;i++)
{
Pen p1 = new Pen(Color.FromArgb(132 + 30*i, 132 + 30*i, 132 + 30*i));
e.Graphics.DrawLine(p1, this.panelContent.Right + i,
this.panelContent.Top + 16 + i,
this.panelContent.Right + i, this.panelContent.Bottom - 13 + i);
e.Graphics.DrawLine(p1, this.panelContent.Left + 16 + i,
this.panelContent.Bottom + i,
this.panelContent.Right - 13 + i, this.panelContent.Bottom + i);
e.Graphics.DrawArc(p1, this.panelContent.Right - 32 + i,
this.panelContent.Bottom - 32 + i, 32, 32, 0, 90);
p1.Dispose();
}
}
}
}
 
S

Stoitcho Goutsev \(100\)

Hi,

1. You draw the shadow as adjacent 1-pixel-wide lines and arcs. You can
expect that these line will perfectly touch each other. I'd suggest to use
wider pen. 2-pixel pen do the trick pretty good.
2. You need to use antialiasing otherwise you are going to het juggy edges.
3. You draw the shadow on the form and the rowding of the panel on the
panel. The panel itself is rectangular so its bottom-right edge obscures
part of the shadow and it looks ugly.
My suggestions:
- Draw everything on one level - e.g. the form, if it's possible
- Cut the panel in the desired shape - use the Control.Region property.
Cutting doesn't produce that smooth edges, but I think it can be masked
somehow.
- Or the easiest is to use Transparent color for the panel's background.
It wors pretty well on .NET 2.0 (haven't tested on .NET1.x thought)
4. There is a code at the end of the panel's paint
for(int i=0;i<4;i++)
{
Pen p1 = new Pen(Color.FromArgb(132 + 30*i, 132 + 30*i, 132 + 30*i));
e.Graphics.DrawArc(p1, this.panelContent.Width - 32 + i,
this.panelContent.Height - 32 + i, 32, 32, 0, 90);
p1.Dispose();
}

I think you've tried to cover the defects on the bottom-right corner of the
shadow, but you don't need this anymore.


--
HTH
Stoitcho Goutsev (100)



idiot said:
Because the backgroud color of the form is white, when I use
SmoothingMode.AntiAlias, the color of shadow seems gradient to white
color.
But if I don't use SmoothingMode.AntiAlias, there are white gap between
four
arc.

Here is the source code:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Drawing2D;

namespace WindowsApplication1
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel panelContent;
private System.ComponentModel.Container components = null;

public Form1()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

private void InitializeComponent()
{
this.panelContent = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panelContent
//
this.panelContent.Location = new System.Drawing.Point(88, 56);
this.panelContent.Name = "panelContent";
this.panelContent.Size = new System.Drawing.Size(272, 120);
this.panelContent.TabIndex = 0;
this.panelContent.Paint += new
System.Windows.Forms.PaintEventHandler(this.panelContent_Paint);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(448, 277);
this.Controls.Add(this.panelContent);
this.Name = "Form1";
this.StartPosition =
System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Form1";
this.Paint += new
System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.ResumeLayout(false);

}

[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void panelContent_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
System.Drawing.Drawing2D.GraphicsPath path = new GraphicsPath();

int width = this.panelContent.Width - 1;
int height = this.panelContent.Height - 1;
path.StartFigure();
path.AddLine(16, 0, width - 16, 0);
path.AddArc(width - 32, 0, 32, 32, 270, 90);
path.AddLine(width, 16, width, height - 16);
path.AddArc(width - 32, height - 32, 32, 32, 0, 90);
path.AddLine(width - 16, height, 16, height);
path.AddArc(0, height - 32, 32, 32, 90, 90);
path.AddLine(0, height - 16, 0, 16);
path.AddArc(0, 0, 32, 32, 180, 90);
path.CloseFigure();

Brush b = new SolidBrush(Color.FromArgb(239, 239, 239));
e.Graphics.FillPath(b, path);
b.Dispose();
Pen parc = new Pen(Brushes.LightGray, 1);
parc.LineJoin = LineJoin.Round;
e.Graphics.DrawPath(parc, path);

for(int i=0;i<4;i++)
{
Pen p1 = new Pen(Color.FromArgb(132 + 30*i, 132 + 30*i, 132 + 30*i));
e.Graphics.DrawArc(p1, this.panelContent.Width - 32 + i,
this.panelContent.Height - 32 + i, 32, 32, 0, 90);
p1.Dispose();
}
}

private void Form1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{

e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
for(int i=0;i<4;i++)
{
Pen p1 = new Pen(Color.FromArgb(132 + 30*i, 132 + 30*i, 132 + 30*i));
e.Graphics.DrawLine(p1, this.panelContent.Right + i,
this.panelContent.Top + 16 + i,
this.panelContent.Right + i, this.panelContent.Bottom - 13 + i);
e.Graphics.DrawLine(p1, this.panelContent.Left + 16 + i,
this.panelContent.Bottom + i,
this.panelContent.Right - 13 + i, this.panelContent.Bottom + i);
e.Graphics.DrawArc(p1, this.panelContent.Right - 32 + i,
this.panelContent.Bottom - 32 + i, 32, 32, 0, 90);
p1.Dispose();
}
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top