123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- using System;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- namespace Microsoft.Windows.Forms
- {
- public static partial class RenderEngine
- {
- /// <summary>
- /// 创建路径。
- /// </summary>
- /// <param name="rect">矩形。</param>
- /// <returns>创建的路径。</returns>
- public static GraphicsPath CreateGraphicsPath(Rectangle rect)
- {
- return CreateGraphicsPath(rect.X, rect.Y, rect.Width, rect.Height);
- }
- /// <summary>
- /// 创建路径。
- /// </summary>
- /// <param name="pt">左上角。</param>
- /// <param name="sz">大小</param>
- /// <returns>创建的路径。</returns>
- public static GraphicsPath CreateGraphicsPath(Point pt, Size sz)
- {
- return CreateGraphicsPath(pt.X, pt.Y, sz.Width, sz.Height);
- }
- /// <summary>
- /// 创建路径。
- /// </summary>
- /// <param name="x">左上角水平坐标。</param>
- /// <param name="y">左上角垂直坐标</param>
- /// <param name="width">宽度。</param>
- /// <param name="height">高度。</param>
- /// <returns>创建的路劲。</returns>
- 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;
- }
- /// <summary>
- /// 创建路径。
- /// </summary>
- /// <param name="rect">用来创建路径的矩形。</param>
- /// <param name="cornerStyle">圆角弯曲样式。</param>
- /// <param name="roundStyle">圆角的样式。</param>
- /// <param name="radius">圆角半径。</param>
- /// <param name="correct">是否把矩形长宽减 1,以便画出边框。</param>
- /// <returns>创建的路径。</returns>
- 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;
- }
- /// <summary>
- /// 建立带有圆角样式和标题的路径。
- /// </summary>
- /// <param name="rect">用来简历路径的矩形。</param>
- /// <param name="style">圆角样式。</param>
- /// <param name="radius">圆角大小。</param>
- /// <param name="tabSize">标题大小。</param>
- /// <param name="tabRound">标题是否圆角。</param>
- /// <param name="tabRadius">标题圆角大小。</param>
- /// <param name="correct">是否把矩形长宽减 1,以便画出边框。</param>
- /// <returns>简历的路径。</returns>
- 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;
- }
- }
- }
|