using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Microsoft.Windows.Forms
{
public static partial class RenderEngine
{
///
/// 创建路径。
///
/// 矩形。
/// 创建的路径。
public static GraphicsPath CreateGraphicsPath(Rectangle rect)
{
return CreateGraphicsPath(rect.X, rect.Y, rect.Width, rect.Height);
}
///
/// 创建路径。
///
/// 左上角。
/// 大小
/// 创建的路径。
public static GraphicsPath CreateGraphicsPath(Point pt, Size sz)
{
return CreateGraphicsPath(pt.X, pt.Y, sz.Width, sz.Height);
}
///
/// 创建路径。
///
/// 左上角水平坐标。
/// 左上角垂直坐标
/// 宽度。
/// 高度。
/// 创建的路劲。
public static GraphicsPath CreateGraphicsPath(int x, int y, int width, int height)
{
Point[] points = new Point[4];
points[0] = new Point(x, y);
points[1] = new Point(x + width, y);
points[2] = new Point(x + width, y + height);
points[3] = new Point(x, y + height);
GraphicsPath shape = new GraphicsPath();
shape.AddPolygon(points);
return shape;
}
///
/// 创建路径。
///
/// 用来创建路径的矩形。
/// 圆角弯曲样式。
/// 圆角的样式。
/// 圆角半径。
/// 是否把矩形长宽减 1,以便画出边框。
/// 创建的路径。
public static GraphicsPath CreateGraphicsPath(Rectangle rect, CornerStyle cornerStyle, RoundStyle roundStyle, float radius, bool correct)
{
//-----------------校准-----------------
if (correct)
{
rect.Width--;
rect.Height--;
}
//-----------------定义返回值-----------------
GraphicsPath path = new GraphicsPath();
//-----------------特殊情况处理-----------------
if (float.IsNaN(radius) || radius <= 0f)
{
path.AddRectangle(rect);
return path;
}
//-----------------临时变量定义-----------------
float diameter = radius * 2;//直径
float halfWidth = rect.Width / 2f;//宽度一半
float halfHeight = rect.Height / 2f;//高度一半
PointF ptMiddleCenter = new PointF(rect.X + halfWidth, rect.Y + halfHeight);//中心点
float lrDegrees = 0f;//半径大于半高,圆心角
float lrOffset = 0f;//半径大于半高,圆弧到边距离
if ((roundStyle & RoundStyle.All) != 0 && radius > halfHeight)
{
double lrRadian = Math.Acos((radius - halfHeight) / radius);//弧度
lrDegrees = (float)MathEx.ToDegrees(lrRadian);//角度
lrOffset = (float)(radius * Math.Sin(lrRadian));
}
float tbDegrees = 0f;//半径大于半宽,圆心角
float tbOffset = 0f;//半径大于办宽,圆弧到边距离
if ((roundStyle & RoundStyle.All) != 0 && radius > halfWidth)
{
double tbRadian = Math.Acos((radius - halfWidth) / radius);//弧度
tbDegrees = (float)MathEx.ToDegrees(tbRadian);//角度
tbOffset = (float)(radius * Math.Sin(tbRadian));
}
//临时变量
PointF ptBegin;
PointF ptEnd;
#region 左上
if ((roundStyle & RoundStyle.TopLeft) == 0)//直角
{
if ((cornerStyle & CornerStyle.LeftIn) != 0)
{
ptBegin = new PointF(rect.X + radius, ptMiddleCenter.Y);
ptEnd = new PointF(rect.X, rect.Y);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.LeftOut) != 0)
{
ptBegin = new PointF(rect.X, ptMiddleCenter.Y);
ptEnd = new PointF(rect.X + radius, rect.Y);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.TopIn) != 0)
{
ptBegin = new PointF(rect.X, rect.Y);
ptEnd = new PointF(ptMiddleCenter.X, rect.Y + radius);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.TopOut) != 0)
{
ptBegin = new PointF(rect.X, rect.Y + radius);
ptEnd = new PointF(ptMiddleCenter.X, rect.Y);
path.AddLine(ptBegin, ptEnd);
}
else
{
ptBegin = ptEnd = new PointF(rect.X, rect.Y);
path.AddLine(ptBegin, ptEnd);
}
}
else//圆角
{
if ((cornerStyle & CornerStyle.LeftIn) != 0)
{
if (radius > halfHeight)
path.AddArc(rect.X - radius, rect.Y, diameter, diameter, 270 + lrDegrees, -lrDegrees);
else
path.AddArc(rect.X - radius, rect.Y, diameter, diameter, 0, -90);
}
else if ((cornerStyle & CornerStyle.LeftOut) != 0)
{
if (radius > halfHeight)
path.AddArc(rect.X - (radius - lrOffset), rect.Y, diameter, diameter, 270 - lrDegrees, lrDegrees);
else
path.AddArc(rect.X, rect.Y, diameter, diameter, 180, 90);
}
else if ((cornerStyle & CornerStyle.TopIn) != 0)
{
if (radius > halfWidth)
path.AddArc(rect.X, rect.Y - radius, diameter, diameter, 180, -tbDegrees);
else
path.AddArc(rect.X, rect.Y - radius, diameter, diameter, 180, -90);
}
else if ((cornerStyle & CornerStyle.TopOut) != 0)
{
if (radius > halfWidth)
path.AddArc(rect.X, rect.Y - (radius - tbOffset), diameter, diameter, 180, tbDegrees);
else
path.AddArc(rect.X, rect.Y, diameter, diameter, 180, 90);
}
else
{
path.AddArc(rect.X, rect.Y, diameter, diameter, 180, 90);
}
}
#endregion
#region 右上
if ((roundStyle & RoundStyle.TopRight) == 0)
{
if ((cornerStyle & CornerStyle.RightIn) != 0)
{
ptBegin = new PointF(rect.Right, rect.Y);
ptEnd = new PointF(rect.Right - radius, ptMiddleCenter.Y);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.RightOut) != 0)
{
ptBegin = new PointF(rect.Right - radius, rect.Y);
ptEnd = new PointF(rect.Right, ptMiddleCenter.Y);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.TopIn) != 0)
{
ptBegin = new PointF(ptMiddleCenter.X, rect.Y + radius);
ptEnd = new PointF(rect.Right, rect.Y);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.TopOut) != 0)
{
ptBegin = new PointF(ptMiddleCenter.X, rect.Y);
ptEnd = new PointF(rect.Right, rect.Y + radius);
path.AddLine(ptBegin, ptEnd);
}
else//矩形
{
ptBegin = ptEnd = new PointF(rect.Right, rect.Y);
path.AddLine(ptBegin, ptEnd);
}
}
else
{
if ((cornerStyle & CornerStyle.RightIn) != 0)
{
if (radius > halfHeight)
path.AddArc(rect.Right - radius, rect.Y, diameter, diameter, 270, -lrDegrees);
else
path.AddArc(rect.Right - radius, rect.Y, diameter, diameter, 270, -90);
}
else if ((cornerStyle & CornerStyle.RightOut) != 0)
{
if (radius > halfHeight)
path.AddArc(rect.Right - radius - lrOffset, rect.Y, diameter, diameter, 270, lrDegrees);
else
path.AddArc(rect.Right - diameter, rect.Y, diameter, diameter, 270, 90);
}
else if ((cornerStyle & CornerStyle.TopIn) != 0)
{
if (radius > halfWidth)
path.AddArc(rect.Right - diameter, rect.Y - radius, diameter, diameter, tbDegrees, -tbDegrees);
else
path.AddArc(rect.Right - diameter, rect.Y - radius, diameter, diameter, 90, -90);
}
else if ((cornerStyle & CornerStyle.TopOut) != 0)
{
if (radius > halfWidth)
path.AddArc(rect.Right - diameter, rect.Y - (radius - tbOffset), diameter, diameter, 360 - tbDegrees, tbDegrees);
else
path.AddArc(rect.Right - diameter, rect.Y, diameter, diameter, 270, 90);
}
else
{
path.AddArc(rect.Right - diameter, rect.Y, diameter, diameter, 270, 90);
}
}
#endregion
#region 右下
if ((roundStyle & RoundStyle.BottomRight) == 0)
{
if ((cornerStyle & CornerStyle.RightIn) != 0)
{
ptBegin = new PointF(rect.Right - radius, ptMiddleCenter.Y);
ptEnd = new PointF(rect.Right, rect.Bottom);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.RightOut) != 0)
{
ptBegin = new PointF(rect.Right, ptMiddleCenter.Y);
ptEnd = new PointF(rect.Right - radius, rect.Bottom);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.BottomIn) != 0)
{
ptBegin = new PointF(rect.Right, rect.Bottom);
ptEnd = new PointF(ptMiddleCenter.X, rect.Bottom - radius);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.BottomOut) != 0)
{
ptBegin = new PointF(rect.Right, rect.Bottom - radius);
ptEnd = new PointF(ptMiddleCenter.X, rect.Bottom);
path.AddLine(ptBegin, ptEnd);
}
else//矩形
{
ptBegin = ptEnd = new PointF(rect.Right, rect.Bottom);
path.AddLine(ptBegin, ptEnd);
}
}
else
{
if ((cornerStyle & CornerStyle.RightIn) != 0)
{
if (radius > halfHeight)
path.AddArc(rect.Right - radius, rect.Bottom - diameter, diameter, diameter, 90 + lrDegrees, -lrDegrees);
else
path.AddArc(rect.Right - radius, rect.Bottom - diameter, diameter, diameter, 180, -90);
}
else if ((cornerStyle & CornerStyle.RightOut) != 0)
{
if (radius > halfHeight)
path.AddArc(rect.Right - radius - lrOffset, rect.Bottom - diameter, diameter, diameter, 90 - lrDegrees, lrDegrees);
else
path.AddArc(rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);
}
else if ((cornerStyle & CornerStyle.BottomIn) != 0)
{
if (radius > halfWidth)
path.AddArc(rect.Right - diameter, rect.Bottom - radius, diameter, diameter, 0, -tbDegrees);
else
path.AddArc(rect.Right - diameter, rect.Bottom - radius, diameter, diameter, 0, -90);
}
else if ((cornerStyle & CornerStyle.BottomOut) != 0)
{
if (radius > halfWidth)
path.AddArc(rect.Right - diameter, rect.Bottom - radius - tbOffset, diameter, diameter, 0, tbDegrees);
else
path.AddArc(rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);
}
else
{
path.AddArc(rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);
}
}
#endregion
#region 左下
if ((roundStyle & RoundStyle.BottomLeft) == 0)
{
if ((cornerStyle & CornerStyle.LeftIn) != 0)
{
ptBegin = new PointF(rect.X, rect.Bottom);
ptEnd = new PointF(rect.X + radius, ptMiddleCenter.Y);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.LeftOut) != 0)
{
ptBegin = new PointF(rect.X + radius, rect.Bottom);
ptEnd = new PointF(rect.X, ptMiddleCenter.Y);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.BottomIn) != 0)
{
ptBegin = new PointF(ptMiddleCenter.X, rect.Bottom - radius);
ptEnd = new PointF(rect.X, rect.Bottom);
path.AddLine(ptBegin, ptEnd);
}
else if ((cornerStyle & CornerStyle.BottomOut) != 0)
{
ptBegin = new PointF(ptMiddleCenter.X, rect.Bottom);
ptEnd = new PointF(rect.X, rect.Bottom - radius);
path.AddLine(ptBegin, ptEnd);
}
else
{
ptBegin = ptEnd = new PointF(rect.X, rect.Bottom);
path.AddLine(ptBegin, ptEnd);
}
}
else
{
if ((cornerStyle & CornerStyle.LeftIn) != 0)
{
if (radius > halfHeight)
path.AddArc(rect.X - radius, rect.Bottom - diameter, diameter, diameter, 90, -lrDegrees);
else
path.AddArc(rect.X - radius, rect.Bottom - diameter, diameter, diameter, 90, -90);
}
else if ((cornerStyle & CornerStyle.LeftOut) != 0)
{
if (radius > halfHeight)
path.AddArc(rect.X - (radius - lrOffset), rect.Bottom - diameter, diameter, diameter, 90, lrDegrees);
else
path.AddArc(rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);
}
else if ((cornerStyle & CornerStyle.BottomIn) != 0)
{
if (radius > halfWidth)
path.AddArc(rect.X, rect.Bottom - radius, diameter, diameter, 180 + tbDegrees, -tbDegrees);
else
path.AddArc(rect.X, rect.Bottom - radius, diameter, diameter, 270, -90);
}
else if ((cornerStyle & CornerStyle.BottomOut) != 0)
{
if (radius > halfWidth)
path.AddArc(rect.X, rect.Bottom - radius - tbOffset, diameter, diameter, 180 - tbDegrees, tbDegrees);
else
path.AddArc(rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);
}
else
{
path.AddArc(rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);
}
}
#endregion
//闭合返回
path.CloseFigure();
return path;
}
///
/// 建立带有圆角样式和标题的路径。
///
/// 用来简历路径的矩形。
/// 圆角样式。
/// 圆角大小。
/// 标题大小。
/// 标题是否圆角。
/// 标题圆角大小。
/// 是否把矩形长宽减 1,以便画出边框。
/// 简历的路径。
public static GraphicsPath CreateGroupBoxTabGraphicsPath(Rectangle rect, RoundStyle style, float radius, Size tabSize, bool tabRound, float tabRadius, bool correct)
{
//校正
if (correct)
{
rect.Width--;
rect.Height--;
}
style = (float.IsNaN(radius) || radius <= 0f) ? RoundStyle.None : style;
tabRound = (float.IsNaN(tabRadius) || tabRadius <= 0f) ? false : tabRound;
//定义
GraphicsPath path = new GraphicsPath();
Rectangle tabRect = new Rectangle(rect.Location, tabSize);
float diameter = radius * 2;
float tabDiameter = tabRadius * 2;
Point pt;
//左上
if ((style & RoundStyle.TopLeft) == 0)
{
pt = new Point(rect.X, rect.Y);
path.AddLine(pt, pt);
}
else
{
path.AddArc(rect.X, rect.Y, diameter, diameter, 180, 90);
}
//Tab右上
if (tabRound)
{
if (tabRadius > tabRect.Height)//不到90度
{
double radians = Math.Acos((tabRadius - tabRect.Height) / tabRadius);
path.AddArc((float)(tabRect.Right - tabRadius * Math.Sin(radians) - tabRadius),
tabRect.Y, tabDiameter, tabDiameter, 270, (float)MathEx.ToDegrees(radians));
}
else//到90度
{
path.AddArc(tabRect.Right - tabDiameter, tabRect.Y, tabDiameter, tabDiameter, 270, 90);
//Tab右下
pt = new Point(tabRect.Right, tabRect.Bottom);
path.AddLine(pt, pt);
}
}
else
{
pt = new Point(tabRect.Right, tabRect.Y);
path.AddLine(pt, pt);
//Tab右下
pt = new Point(tabRect.Right, tabRect.Bottom);
path.AddLine(pt, pt);
}
//右上
if ((style & RoundStyle.TopRight) == 0)
{
pt = new Point(rect.Right, tabRect.Bottom);
path.AddLine(pt, pt);
}
else
{
path.AddArc(rect.Right - diameter, tabRect.Bottom, diameter, diameter, 270, 90);
}
//右下
if ((style & RoundStyle.BottomRight) == 0)
{
pt = new Point(rect.Right, rect.Bottom);
path.AddLine(pt, pt);
}
else
{
path.AddArc(rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);
}
//左下
if ((style & RoundStyle.BottomLeft) == 0)
{
pt = new Point(rect.X, rect.Bottom);
path.AddLine(pt, pt);
}
else
{
path.AddArc(rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);
}
//闭合返回
path.CloseFigure();
return path;
}
}
}