using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; using Microsoft.Drawing; using Microsoft.Windows.Forms.Layout; namespace Microsoft.Windows.Forms { public static partial class RenderEngine { /// /// 围绕rect的中心将坐标系顺时针旋转degrees角度,返回新坐标系矩形 /// /// 绘图对象 /// 要旋转的矩形 /// 角度 /// 内容旋转,绘图区域不旋转 /// 新坐标系矩形 public static Rectangle RotateRect(Graphics g, Rectangle rect, float degrees, bool fit) { g.RotateTransform(degrees, MatrixOrder.Append);//围绕中心原点旋转 g.TranslateTransform(rect.X + rect.Width / 2, rect.Y + rect.Height / 2, MatrixOrder.Append);//平移原点 if (fit) { decimal decLessStraigntAngle = Math.Abs((decimal)degrees) % 180m;//取绝对值后除以180的余数,小于平角的角度 return ((decLessStraigntAngle >= 0 && decLessStraigntAngle <= 45) || (decLessStraigntAngle >= 135 && decLessStraigntAngle <= 180)) ? new Rectangle(-rect.Width / 2, -rect.Height / 2, rect.Width, rect.Height) : new Rectangle(-rect.Height / 2, -rect.Width / 2, rect.Height, rect.Width);//新坐标系矩形 } else { return new Rectangle(-rect.Width / 2, -rect.Height / 2, rect.Width, rect.Height); } } /// /// 开始绘制字符串(画布无限制),并返回路径区域和字符串大小.注意不要修改返回的矩形和字符串大小,在EndDrawString中需要传回.必须与EndDrawString成对出现. /// /// 绘图对象 /// 字符串 /// 字体 /// 字符串大小 /// 字符串路径区域 public static Rectangle BeginDrawString(Graphics g, string s, Font font, out Size strSize) { using (StringFormat sf = DefaultTheme.StringFormat) { strSize = Size.Ceiling(g.MeasureString(s, font, PointF.Empty, sf)); using (GraphicsPath path = new GraphicsPath()) { path.AddString(s, font.FontFamily, (int)font.Style, g.DpiY * font.SizeInPoints / 72f, Point.Empty, sf); return Rectangle.Round(path.GetBounds()); } } } /// /// 开始绘制字符串(画布有限制),并返回路径区域和字符串大小.注意不要修改返回的矩形和字符串大小,在EndDrawString中需要传回.必须与EndDrawString成对出现. /// /// 绘图对象 /// 字符串 /// 字体 /// 限制矩形 /// 字符串大小 /// 字符串路径区域 public static Rectangle BeginDrawString(Graphics g, string s, Font font, Rectangle layoutRectangle, out Size strSize) { using (StringFormat sf = DefaultTheme.StringFormat) { strSize = Size.Ceiling(g.MeasureString(s, font, layoutRectangle.Size, sf)); using (GraphicsPath path = new GraphicsPath()) { path.AddString(s, font.FontFamily, (int)font.Style, g.DpiY * font.SizeInPoints / 72f, layoutRectangle, sf); return Rectangle.Round(path.GetBounds()); } } } /// /// 正式绘制字符串.与BeginDrawString成对出现 /// /// 绘图对象 /// 字符串 /// 字体 /// 画刷 /// 画布区域 /// 对齐方式 /// 字符串路径区域,BeginDrawString(...)返回值 /// 字符串大小,BeginDrawString(...)返回值 public static void EndDrawString(Graphics g, string s, Font font, Brush brush, Rectangle layoutRectangle, ContentAlignment align, Rectangle pathBounds, Size strSize) { layoutRectangle = LayoutUtils.Align(pathBounds.Size, layoutRectangle, align); #if DEBUG g.DrawRectangle(SystemPens.ControlDarkDark, layoutRectangle); #endif layoutRectangle.Offset(-pathBounds.X, -pathBounds.Y); layoutRectangle.Size = strSize; using (StringFormat sf = DefaultTheme.StringFormat) { g.DrawString(s, font, brush, layoutRectangle, sf); } } /// /// 精确绘制字符串 /// /// 绘图对象 /// 字符串 /// 字体 /// 画刷 /// 绘制区域 /// 对齐方式 public static void DrawString(Graphics g, string s, Font font, Brush brush, Rectangle layoutRectangle, ContentAlignment align) { Size strSize; Rectangle pathBounds = BeginDrawString(g, s, font, layoutRectangle, out strSize); EndDrawString(g, s, font, brush, layoutRectangle, align, pathBounds, strSize); } /// /// 绘制背景图 /// /// 绘图上下文 /// 背景图 /// 绘制区域 /// 背景图布局方式 public static void DrawBackgroundImage(Graphics g, Image image, Rectangle rect, ImageLayout layout) { if (image == null) return; switch (layout) { case ImageLayout.None: g.DrawImageUnscaled(image, rect.Location); break; case ImageLayout.Tile: using (Brush brush = new TextureBrush(image, WrapMode.Tile)) { g.FillRectangle(brush, rect); } break; case ImageLayout.Center: int x = rect.Left + (rect.Width - image.Width) / 2; int y = rect.Top + (rect.Height - image.Height) / 2; g.DrawImageUnscaled(image, x, y); break; case ImageLayout.Stretch: g.DrawImage(image, rect); break; case ImageLayout.Zoom: float xscale = (float)rect.Width / (float)image.Width; float yscale = (float)rect.Height / (float)image.Height; float scale = Math.Min(xscale, yscale); int width = (int)(((float)image.Width) * scale); int height = (int)(((float)image.Height) * scale); x = rect.Left + (rect.Width - width) / 2; y = rect.Top + (rect.Height - height) / 2; g.DrawImage(image, x, y, width, height); break; default: break; } } /// /// 绘制九宫格背景图 /// /// 绘图上下文 /// 背景图 /// 目标区域 /// 九宫格划分,左 /// 九宫格划分,上 /// 九宫格划分,右 /// 九宫格划分,下 /// 九宫格背景图布局方式 public static void DrawBackgroundImage9(Graphics g, Image image, Rectangle rect, int left, int top, int right, int bottom, ImageLayout9 layout) { if (image == null || !RectangleEx.IsVisible(rect)) return; //基本 int nSrcWidth = image.Width; int nSrcHeight = image.Height; int nDestWidth = rect.Width; int nDestHeight = rect.Height; //左上 Rectangle rcSrcTopLeft = new Rectangle(0, 0, left, top); Rectangle rcDestTopLeft = new Rectangle(rect.X, rect.Y, left, top); //上 Rectangle rcSrcTop = new Rectangle(rcSrcTopLeft.Right, rcSrcTopLeft.Y, nSrcWidth - left - right, top); Rectangle rcDestTop = new Rectangle(rcDestTopLeft.Right, rcDestTopLeft.Y, nDestWidth - left - right, top); //右上 Rectangle rcSrcTopRight = new Rectangle(rcSrcTop.Right, rcSrcTop.Y, right, top); Rectangle rcDestTopRight = new Rectangle(rcDestTop.Right, rcDestTop.Y, right, top); //右 Rectangle rcSrcRight = new Rectangle(rcSrcTopRight.X, rcSrcTopRight.Bottom, right, nSrcHeight - top - bottom); Rectangle rcDestRight = new Rectangle(rcDestTopRight.X, rcDestTopRight.Bottom, right, nDestHeight - top - bottom); //右下 Rectangle rcSrcBottomRight = new Rectangle(rcSrcRight.X, rcSrcRight.Bottom, right, bottom); Rectangle rcDestBottomRight = new Rectangle(rcDestRight.X, rcDestRight.Bottom, right, bottom); //下 Rectangle rcSrcBottom = new Rectangle(rcSrcTop.X, rcSrcBottomRight.Y, rcSrcTop.Width, bottom); Rectangle rcDestBottom = new Rectangle(rcDestTop.X, rcDestBottomRight.Y, rcDestTop.Width, bottom); //左下 Rectangle rcSrcBottomLeft = new Rectangle(rcSrcTopLeft.X, rcSrcBottom.Y, left, bottom); Rectangle rcDestBottomLeft = new Rectangle(rcDestTopLeft.X, rcDestBottom.Y, left, bottom); //左 Rectangle rcSrcLeft = new Rectangle(rcSrcBottomLeft.X, rcSrcRight.Y, left, rcSrcRight.Height); Rectangle rcDestLeft = new Rectangle(rcDestBottomLeft.X, rcDestRight.Y, left, rcDestRight.Height); //中 Rectangle rcSrcMiddle = new Rectangle(rcSrcTop.X, rcSrcLeft.Y, rcSrcTop.Width, rcSrcLeft.Height); Rectangle rcDestMiddle = new Rectangle(rcDestTop.X, rcDestLeft.Y, rcDestTop.Width, rcDestLeft.Height); //左上 if (RectangleEx.IsVisible(rcSrcTopLeft)) { g.DrawImage(image, rcDestTopLeft, rcSrcTopLeft, GraphicsUnit.Pixel); } //上 if (RectangleEx.IsVisible(rcSrcTop) && RectangleEx.IsVisible(rcDestTop)) { if ((layout & ImageLayout9.TopTile) == 0)//拉伸 { g.DrawImage(image, rcDestTop, rcSrcTop, GraphicsUnit.Pixel); } else//平铺 { using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcTop)) { brush.TranslateTransform(rcDestTop.X, rcDestTop.Y); g.FillRectangle(brush, rcDestTop); } } } //右上 if (RectangleEx.IsVisible(rcSrcTopRight)) { g.DrawImage(image, rcDestTopRight, rcSrcTopRight, GraphicsUnit.Pixel); } //右 if (RectangleEx.IsVisible(rcSrcRight) && RectangleEx.IsVisible(rcDestRight)) { if ((layout & ImageLayout9.RightTile) == 0)//拉伸 { g.DrawImage(image, rcDestRight, rcSrcRight, GraphicsUnit.Pixel); } else//平铺 { using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcRight)) { brush.TranslateTransform(rcDestRight.X, rcDestRight.Y); g.FillRectangle(brush, rcDestRight); } } } //右下 if (RectangleEx.IsVisible(rcSrcBottomRight)) { g.DrawImage(image, rcDestBottomRight, rcSrcBottomRight, GraphicsUnit.Pixel); } //下 if (RectangleEx.IsVisible(rcSrcBottom) && RectangleEx.IsVisible(rcDestBottom)) { if ((layout & ImageLayout9.BottomTile) == 0)//拉伸 { g.DrawImage(image, rcDestBottom, rcSrcBottom, GraphicsUnit.Pixel); } else//平铺 { using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcBottom)) { brush.TranslateTransform(rcDestBottom.X, rcDestBottom.Y); g.FillRectangle(brush, rcDestBottom); } } } //左下 if (RectangleEx.IsVisible(rcSrcBottomLeft)) { g.DrawImage(image, rcDestBottomLeft, rcSrcBottomLeft, GraphicsUnit.Pixel); } //左 if (RectangleEx.IsVisible(rcSrcLeft) && RectangleEx.IsVisible(rcDestLeft)) { if ((layout & ImageLayout9.LeftTile) == 0)//拉伸 { g.DrawImage(image, rcDestLeft, rcSrcLeft, GraphicsUnit.Pixel); } else//平铺 { using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcLeft)) { brush.TranslateTransform(rcDestLeft.X, rcDestLeft.Y); g.FillRectangle(brush, rcDestLeft); } } } //中间 if (RectangleEx.IsVisible(rcSrcMiddle) && RectangleEx.IsVisible(rcDestMiddle)) { if ((layout & ImageLayout9.MiddleTile) == 0)//拉伸 { g.DrawImage(image, rcDestMiddle, rcSrcMiddle, GraphicsUnit.Pixel); } else//平铺 { using (TextureBrush brush = new TextureBrush(image, WrapMode.Tile, rcSrcMiddle)) { brush.TranslateTransform(rcDestMiddle.X, rcDestMiddle.Y); g.FillRectangle(brush, rcDestMiddle); } } } } /// /// 绘制边框 /// /// 绘图对象 /// 画笔 /// 矩形区域 /// 边框样式 /// 圆角弯曲样式 /// 圆角样式 /// 圆角半径 /// 是否减小一个像素 public static void DrawBorder(Graphics g, Pen pen, Rectangle rect, BorderVisibleStyle borderStyle, CornerStyle cornerStyle, RoundStyle roundStyle, float radius, bool correct) { //-----------------不绘制----------------- if (borderStyle == BorderVisibleStyle.None) return; //-----------------校准----------------- if (correct) { rect.Width--; rect.Height--; } //-----------------特殊情况处理----------------- if (float.IsNaN(radius) || radius <= 0f) { //-----------------全边----------------- if (borderStyle == BorderVisibleStyle.All) { g.DrawRectangle(pen, rect); return; } cornerStyle = CornerStyle.None; roundStyle = RoundStyle.None; } //-----------------临时变量定义----------------- 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 ptBeginTopLeft; PointF ptEndTopLeft; PointF ptBeginTopRight; PointF ptEndTopRight; PointF ptBeginBottomRight; PointF ptEndBottomRight; PointF ptBeginBottomLeft; PointF ptEndBottomLeft; #region 计算左上端点 if ((roundStyle & RoundStyle.TopLeft) == 0)//直角 { if ((cornerStyle & CornerStyle.LeftIn) != 0) { ptBeginTopLeft = new PointF(rect.X + radius, ptMiddleCenter.Y); ptEndTopLeft = new PointF(rect.X, rect.Y); } else if ((cornerStyle & CornerStyle.LeftOut) != 0) { ptBeginTopLeft = new PointF(rect.X, ptMiddleCenter.Y); ptEndTopLeft = new PointF(rect.X + radius, rect.Y); } else if ((cornerStyle & CornerStyle.TopIn) != 0) { ptBeginTopLeft = new PointF(rect.X, rect.Y); ptEndTopLeft = new PointF(ptMiddleCenter.X, rect.Y + radius); } else if ((cornerStyle & CornerStyle.TopOut) != 0) { ptBeginTopLeft = new PointF(rect.X, rect.Y + radius); ptEndTopLeft = new PointF(ptMiddleCenter.X, rect.Y); } else { ptBeginTopLeft = ptEndTopLeft = new PointF(rect.X, rect.Y); } } else//圆角 { if ((cornerStyle & CornerStyle.LeftIn) != 0) { if (radius > halfHeight) { ptBeginTopLeft = new PointF(rect.X + lrOffset, ptMiddleCenter.Y); ptEndTopLeft = new PointF(rect.X, rect.Y); } else { ptBeginTopLeft = new PointF(rect.X + radius, rect.Y + radius); ptEndTopLeft = new PointF(rect.X, rect.Y); } } else if ((cornerStyle & CornerStyle.LeftOut) != 0) { if (radius > halfHeight) { ptBeginTopLeft = new PointF(rect.X, ptMiddleCenter.Y); ptEndTopLeft = new PointF(rect.X + lrOffset, rect.Y); } else { ptBeginTopLeft = new PointF(rect.X, rect.Y + radius);//same ptEndTopLeft = new PointF(rect.X + radius, rect.Y);//same } } else if ((cornerStyle & CornerStyle.TopIn) != 0) { if (radius > halfWidth) { ptBeginTopLeft = new PointF(rect.X, rect.Y); ptEndTopLeft = new PointF(ptMiddleCenter.X, rect.Y + tbOffset); } else { ptBeginTopLeft = new PointF(rect.X, rect.Y); ptEndTopLeft = new PointF(rect.X + radius, rect.Y + radius); } } else if ((cornerStyle & CornerStyle.TopOut) != 0) { if (radius > halfWidth) { ptBeginTopLeft = new PointF(rect.X, rect.Y + tbOffset); ptEndTopLeft = new PointF(ptMiddleCenter.X, rect.Y); } else { ptBeginTopLeft = new PointF(rect.X, rect.Y + radius);//same ptEndTopLeft = new PointF(rect.X + radius, rect.Y);//same } } else { ptBeginTopLeft = new PointF(rect.X, rect.Y + radius);//same ptEndTopLeft = new PointF(rect.X + radius, rect.Y);//same } } #endregion #region 计算右上端点 if ((roundStyle & RoundStyle.TopRight) == 0) { if ((cornerStyle & CornerStyle.RightIn) != 0) { ptBeginTopRight = new PointF(rect.Right, rect.Y); ptEndTopRight = new PointF(rect.Right - radius, ptMiddleCenter.Y); } else if ((cornerStyle & CornerStyle.RightOut) != 0) { ptBeginTopRight = new PointF(rect.Right - radius, rect.Y); ptEndTopRight = new PointF(rect.Right, ptMiddleCenter.Y); } else if ((cornerStyle & CornerStyle.TopIn) != 0) { ptBeginTopRight = new PointF(ptMiddleCenter.X, rect.Y + radius); ptEndTopRight = new PointF(rect.Right, rect.Y); } else if ((cornerStyle & CornerStyle.TopOut) != 0) { ptBeginTopRight = new PointF(ptMiddleCenter.X, rect.Y); ptEndTopRight = new PointF(rect.Right, rect.Y + radius); } else { ptBeginTopRight = ptEndTopRight = new PointF(rect.Right, rect.Y); } } else { if ((cornerStyle & CornerStyle.RightIn) != 0) { if (radius > halfHeight) { ptBeginTopRight = new PointF(rect.Right, rect.Y); ptEndTopRight = new PointF(rect.Right - lrOffset, ptMiddleCenter.Y); } else { ptBeginTopRight = new PointF(rect.Right, rect.Y); ptEndTopRight = new PointF(rect.Right - radius, rect.Y + radius); } } else if ((cornerStyle & CornerStyle.RightOut) != 0) { if (radius > halfHeight) { ptBeginTopRight = new PointF(rect.Right - lrOffset, rect.Y); ptEndTopRight = new PointF(rect.Right, ptMiddleCenter.Y); } else { ptBeginTopRight = new PointF(rect.Right - radius, rect.Y);//same ptEndTopRight = new PointF(rect.Right, rect.Y + radius);//same } } else if ((cornerStyle & CornerStyle.TopIn) != 0) { if (radius > halfWidth) { ptBeginTopRight = new PointF(ptMiddleCenter.X, rect.Y + tbOffset); ptEndTopRight = new PointF(rect.Right, rect.Y); } else { ptBeginTopRight = new PointF(rect.Right - radius, rect.Y + radius); ptEndTopRight = new PointF(rect.Right, rect.Y); } } else if ((cornerStyle & CornerStyle.TopOut) != 0) { if (radius > halfWidth) { ptBeginTopRight = new PointF(ptMiddleCenter.X, rect.Y); ptEndTopRight = new PointF(rect.Right, rect.Y + tbOffset); } else { ptBeginTopRight = new PointF(rect.Right - radius, rect.Y);//same ptEndTopRight = new PointF(rect.Right, rect.Y + radius);//same } } else { ptBeginTopRight = new PointF(rect.Right - radius, rect.Y);//same ptEndTopRight = new PointF(rect.Right, rect.Y + radius);//same } } #endregion #region 计算右下端点 if ((roundStyle & RoundStyle.BottomRight) == 0) { if ((cornerStyle & CornerStyle.RightIn) != 0) { ptBeginBottomRight = new PointF(rect.Right - radius, ptMiddleCenter.Y); ptEndBottomRight = new PointF(rect.Right, rect.Bottom); } else if ((cornerStyle & CornerStyle.RightOut) != 0) { ptBeginBottomRight = new PointF(rect.Right, ptMiddleCenter.Y); ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom); } else if ((cornerStyle & CornerStyle.BottomIn) != 0) { ptBeginBottomRight = new PointF(rect.Right, rect.Bottom); ptEndBottomRight = new PointF(ptMiddleCenter.X, rect.Bottom - radius); } else if ((cornerStyle & CornerStyle.BottomOut) != 0) { ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - radius); ptEndBottomRight = new PointF(ptMiddleCenter.X, rect.Bottom); } else { ptBeginBottomRight = ptEndBottomRight = new PointF(rect.Right, rect.Bottom); } } else { if ((cornerStyle & CornerStyle.RightIn) != 0) { if (radius > halfHeight) { ptBeginBottomRight = new PointF(rect.Right - lrOffset, ptMiddleCenter.Y); ptEndBottomRight = new PointF(rect.Right, rect.Bottom); } else { ptBeginBottomRight = new PointF(rect.Right - radius, rect.Bottom - radius); ptEndBottomRight = new PointF(rect.Right, rect.Bottom); } } else if ((cornerStyle & CornerStyle.RightOut) != 0) { if (radius > halfHeight) { ptBeginBottomRight = new PointF(rect.Right, ptMiddleCenter.Y); ptEndBottomRight = new PointF(rect.Right - lrOffset, rect.Bottom); } else { ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - radius);//same ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom);//same } } else if ((cornerStyle & CornerStyle.BottomIn) != 0) { if (radius > halfWidth) { ptBeginBottomRight = new PointF(rect.Right, rect.Bottom); ptEndBottomRight = new PointF(ptMiddleCenter.X, rect.Bottom - tbOffset); } else { ptBeginBottomRight = new PointF(rect.Right, rect.Bottom); ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom - radius); } } else if ((cornerStyle & CornerStyle.BottomOut) != 0) { if (radius > halfWidth) { ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - tbOffset); ptEndBottomRight = new PointF(ptMiddleCenter.X, rect.Bottom); } else { ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - radius);//same ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom);//same } } else { ptBeginBottomRight = new PointF(rect.Right, rect.Bottom - radius);//same ptEndBottomRight = new PointF(rect.Right - radius, rect.Bottom);//same } } #endregion #region 计算左下端点 if ((roundStyle & RoundStyle.BottomLeft) == 0) { if ((cornerStyle & CornerStyle.LeftIn) != 0) { ptBeginBottomLeft = new PointF(rect.X, rect.Bottom); ptEndBottomLeft = new PointF(rect.X + radius, ptMiddleCenter.Y); } else if ((cornerStyle & CornerStyle.LeftOut) != 0) { ptBeginBottomLeft = new PointF(rect.X + radius, rect.Bottom); ptEndBottomLeft = new PointF(rect.X, ptMiddleCenter.Y); } else if ((cornerStyle & CornerStyle.BottomIn) != 0) { ptBeginBottomLeft = new PointF(ptMiddleCenter.X, rect.Bottom - radius); ptEndBottomLeft = new PointF(rect.X, rect.Bottom); } else if ((cornerStyle & CornerStyle.BottomOut) != 0) { ptBeginBottomLeft = new PointF(ptMiddleCenter.X, rect.Bottom); ptEndBottomLeft = new PointF(rect.X, rect.Bottom - radius); } else { ptBeginBottomLeft = ptEndBottomLeft = new PointF(rect.X, rect.Bottom); } } else { if ((cornerStyle & CornerStyle.LeftIn) != 0) { if (radius > halfHeight) { ptBeginBottomLeft = new PointF(rect.Left, rect.Bottom); ptEndBottomLeft = new PointF(rect.Left + lrOffset, ptMiddleCenter.Y); } else { ptBeginBottomLeft = new PointF(rect.Left, rect.Bottom); ptEndBottomLeft = new PointF(rect.Left + radius, rect.Bottom - radius); } } else if ((cornerStyle & CornerStyle.LeftOut) != 0) { if (radius > halfHeight) { ptBeginBottomLeft = new PointF(rect.Left + lrOffset, rect.Bottom); ptEndBottomLeft = new PointF(rect.Left, ptMiddleCenter.Y); } else { ptBeginBottomLeft = new PointF(rect.Left + radius, rect.Bottom);//same ptEndBottomLeft = new PointF(rect.Left, rect.Bottom - radius);//same } } else if ((cornerStyle & CornerStyle.BottomIn) != 0) { if (radius > halfWidth) { ptBeginBottomLeft = new PointF(ptMiddleCenter.X, rect.Bottom - tbOffset); ptEndBottomLeft = new PointF(rect.Left, rect.Bottom); } else { ptBeginBottomLeft = new PointF(rect.Left + radius, rect.Bottom - radius); ptEndBottomLeft = new PointF(rect.Left, rect.Bottom); } } else if ((cornerStyle & CornerStyle.BottomOut) != 0) { if (radius > halfWidth) { ptBeginBottomLeft = new PointF(ptMiddleCenter.X, rect.Bottom); ptEndBottomLeft = new PointF(rect.Left, rect.Bottom - tbOffset); } else { ptBeginBottomLeft = new PointF(rect.Left + radius, rect.Bottom);//same ptEndBottomLeft = new PointF(rect.Left, rect.Bottom - radius);//same } } else { ptBeginBottomLeft = new PointF(rect.Left + radius, rect.Bottom);//same ptEndBottomLeft = new PointF(rect.Left, rect.Bottom - radius);//same } } #endregion #region 绘制左边 if ((borderStyle & BorderVisibleStyle.Left) != 0) { g.DrawLine(pen, ptEndBottomLeft, ptBeginTopLeft); } #endregion #region 绘制左上角 if ((borderStyle & BorderVisibleStyle.Left) != 0 || (borderStyle & BorderVisibleStyle.Top) != 0) { if ((roundStyle & RoundStyle.TopLeft) == 0) { g.DrawLine(pen, ptBeginTopLeft, ptEndTopLeft); } else { if ((cornerStyle & CornerStyle.LeftIn) != 0) { if (radius > halfHeight) g.DrawArc(pen, rect.X - radius, rect.Y, diameter, diameter, 270 + lrDegrees, -lrDegrees); else g.DrawArc(pen, rect.X - radius, rect.Y, diameter, diameter, 0, -90); } else if ((cornerStyle & CornerStyle.LeftOut) != 0) { if (radius > halfHeight) g.DrawArc(pen, rect.X - (radius - lrOffset), rect.Y, diameter, diameter, 270 - lrDegrees, lrDegrees); else g.DrawArc(pen, rect.X, rect.Y, diameter, diameter, 180, 90);//same } else if ((cornerStyle & CornerStyle.TopIn) != 0) { if (radius > halfWidth) g.DrawArc(pen, rect.X, rect.Y - radius, diameter, diameter, 180, -tbDegrees); else g.DrawArc(pen, rect.X, rect.Y - radius, diameter, diameter, 180, -90); } else if ((cornerStyle & CornerStyle.TopOut) != 0) { if (radius > halfWidth) g.DrawArc(pen, rect.X, rect.Y - (radius - tbOffset), diameter, diameter, 180, tbDegrees); else g.DrawArc(pen, rect.X, rect.Y, diameter, diameter, 180, 90);//same } else { g.DrawArc(pen, rect.X, rect.Y, diameter, diameter, 180, 90);//same } } } #endregion #region 绘制上边 if ((borderStyle & BorderVisibleStyle.Top) != 0) { g.DrawLine(pen, ptEndTopLeft, ptBeginTopRight); } #endregion #region 绘制右上角 if ((borderStyle & BorderVisibleStyle.Top) != 0 || (borderStyle & BorderVisibleStyle.Right) != 0) { if ((roundStyle & RoundStyle.TopRight) == 0) { g.DrawLine(pen, ptBeginTopRight, ptEndTopRight); } else { if ((cornerStyle & CornerStyle.RightIn) != 0) { if (radius > halfHeight) g.DrawArc(pen, rect.Right - radius, rect.Y, diameter, diameter, 270, -lrDegrees); else g.DrawArc(pen, rect.Right - radius, rect.Y, diameter, diameter, 270, -90); } else if ((cornerStyle & CornerStyle.RightOut) != 0) { if (radius > halfHeight) g.DrawArc(pen, rect.Right - radius - lrOffset, rect.Y, diameter, diameter, 270, lrDegrees); else g.DrawArc(pen, rect.Right - diameter, rect.Y, diameter, diameter, 270, 90);//same } else if ((cornerStyle & CornerStyle.TopIn) != 0) { if (radius > halfWidth) g.DrawArc(pen, rect.Right - diameter, rect.Y - radius, diameter, diameter, tbDegrees, -tbDegrees); else g.DrawArc(pen, rect.Right - diameter, rect.Y - radius, diameter, diameter, 90, -90); } else if ((cornerStyle & CornerStyle.TopOut) != 0) { if (radius > halfWidth) g.DrawArc(pen, rect.Right - diameter, rect.Y - (radius - tbOffset), diameter, diameter, 360 - tbDegrees, tbDegrees); else g.DrawArc(pen, rect.Right - diameter, rect.Y, diameter, diameter, 270, 90);//same } else { g.DrawArc(pen, rect.Right - diameter, rect.Y, diameter, diameter, 270, 90);//same } } } #endregion #region 绘制右边 if ((borderStyle & BorderVisibleStyle.Right) != 0) { g.DrawLine(pen, ptEndTopRight, ptBeginBottomRight); } #endregion #region 绘制右下角 if ((borderStyle & BorderVisibleStyle.Right) != 0 || (borderStyle & BorderVisibleStyle.Bottom) != 0) { if ((roundStyle & RoundStyle.BottomRight) == 0) { g.DrawLine(pen, ptBeginBottomRight, ptEndBottomRight); } else { if ((cornerStyle & CornerStyle.RightIn) != 0) { if (radius > halfHeight) g.DrawArc(pen, rect.Right - radius, rect.Bottom - diameter, diameter, diameter, 90 + lrDegrees, -lrDegrees); else g.DrawArc(pen, rect.Right - radius, rect.Bottom - diameter, diameter, diameter, 180, -90); } else if ((cornerStyle & CornerStyle.RightOut) != 0) { if (radius > halfHeight) g.DrawArc(pen, rect.Right - radius - lrOffset, rect.Bottom - diameter, diameter, diameter, 90 - lrDegrees, lrDegrees); else g.DrawArc(pen, rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);//same } else if ((cornerStyle & CornerStyle.BottomIn) != 0) { if (radius > halfWidth) g.DrawArc(pen, rect.Right - diameter, rect.Bottom - radius, diameter, diameter, 0, -tbDegrees); else g.DrawArc(pen, rect.Right - diameter, rect.Bottom - radius, diameter, diameter, 0, -90); } else if ((cornerStyle & CornerStyle.BottomOut) != 0) { if (radius > halfWidth) g.DrawArc(pen, rect.Right - diameter, rect.Bottom - radius - tbOffset, diameter, diameter, 0, tbDegrees); else g.DrawArc(pen, rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);//same } else { g.DrawArc(pen, rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);//same } } } #endregion #region 绘制下边 if ((borderStyle & BorderVisibleStyle.Bottom) != 0) { g.DrawLine(pen, ptEndBottomRight, ptBeginBottomLeft); } #endregion #region 绘制左下角 if ((borderStyle & BorderVisibleStyle.Bottom) != 0 || (borderStyle & BorderVisibleStyle.Left) != 0) { if ((roundStyle & RoundStyle.BottomLeft) == 0) { g.DrawLine(pen, ptBeginBottomLeft, ptEndBottomLeft); } else { if ((cornerStyle & CornerStyle.LeftIn) != 0) { if (radius > halfHeight) g.DrawArc(pen, rect.X - radius, rect.Bottom - diameter, diameter, diameter, 90, -lrDegrees); else g.DrawArc(pen, rect.X - radius, rect.Bottom - diameter, diameter, diameter, 90, -90); } else if ((cornerStyle & CornerStyle.LeftOut) != 0) { if (radius > halfHeight) g.DrawArc(pen, rect.X - (radius - lrOffset), rect.Bottom - diameter, diameter, diameter, 90, lrDegrees); else g.DrawArc(pen, rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);//same } else if ((cornerStyle & CornerStyle.BottomIn) != 0) { if (radius > halfWidth) g.DrawArc(pen, rect.X, rect.Bottom - radius, diameter, diameter, 180 + tbDegrees, -tbDegrees); else g.DrawArc(pen, rect.X, rect.Bottom - radius, diameter, diameter, 270, -90); } else if ((cornerStyle & CornerStyle.BottomOut) != 0) { if (radius > halfWidth) g.DrawArc(pen, rect.X, rect.Bottom - radius - tbOffset, diameter, diameter, 180 - tbDegrees, tbDegrees); else g.DrawArc(pen, rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);//same } else { g.DrawArc(pen, rect.X, rect.Bottom - diameter, diameter, diameter, 90, 90);//same } } } #endregion } /// /// 绘制模糊特效,颜色需要带alpha通道 /// /// 绘图对象 /// 区域 /// 颜色(带alpha通道) public static void DrawAeroBlur(Graphics g, Rectangle rect, Color color) { using (Brush brush = new SolidBrush(color)) { g.FillRectangle(brush, rect); } } /// /// 绘制玻璃效果,颜色需要带alpha通道 /// /// 绘图对象 /// 区域 /// 中心颜色(带alpha通道) /// 周围颜色(带alpha通道) public static void DrawAeroGlass(Graphics g, Rectangle rect, Color centerColor, Color surroundColor) { using (GraphicsPath path = new GraphicsPath()) { path.AddEllipse(rect); using (PathGradientBrush brush = new PathGradientBrush(path)) { brush.CenterColor = centerColor; brush.SurroundColors = new Color[] { surroundColor }; brush.CenterPoint = new PointF(rect.X + rect.Width / 2, rect.Y + rect.Height / 2); g.FillPath(brush, path); } } } /// /// 绘制对号(按比例) /// /// 绘图对象 /// 绘图区域 /// 颜色 public static void DrawCheck(Graphics g, Rectangle rect, Color color) { rect.Width--; rect.Height--; int width = rect.Width; int height = rect.Height; int l = rect.X; int t = rect.Y; int r = rect.Right; int b = rect.Bottom; PointF[] points = new PointF[3]; points[0] = new PointF(l + width * 0.2f, t + height * 0.522f);//左 points[1] = new PointF(l + width * 0.422f, b - height * 0.251f);//中 points[2] = new PointF(r - width * 0.204f, t + height * 0.208f);//右 using (Pen pen = new Pen(color, Math.Max(2f, Math.Min(rect.Width, rect.Height) * 0.15f))) { using (new SmoothingModeGraphics(g)) { g.DrawLines(pen, points); } } } /// /// 绘制叉号(按比例) /// /// 绘图对象 /// 绘图区域 /// 颜色 public static void DrawCross(Graphics g, Rectangle rect, Color color) { rect.Width--; rect.Height--; int width = rect.Width; int height = rect.Height; int l = rect.X; int t = rect.Y; int r = rect.Right; int b = rect.Bottom; float offset = 0.2f; PointF[] points = new PointF[2]; points[0] = new PointF(l + offset * width, t + offset * height); points[1] = new PointF(r - offset * width, b - offset * height); PointF[] points1 = new PointF[2]; points1[0] = new PointF(r - offset * width, t + offset * height); points1[1] = new PointF(l + offset * width, b - offset * height); using (Pen pen = new Pen(color, Math.Max(2f, Math.Min(rect.Width, rect.Height) / 6f))) { using (new SmoothingModeGraphics(g)) { g.DrawLines(pen, points); g.DrawLines(pen, points1); } } } /// /// 绘制省略号(按比例) /// /// 绘图对象 /// 绘图区域 /// 颜色 public static void DrawEllipsis(Graphics g, Rectangle rect, Color color) { rect.Width--; rect.Height--; float d = Math.Max(3f, rect.Width / 6f); float t = rect.Y + (rect.Height - d) / 2f; float leftl = rect.X + d; float midl = rect.X + (rect.Width - d) / 2f; float rightl = rect.Right - d - d; using (Brush brush = new SolidBrush(color)) { using (new SmoothingModeGraphics(g)) { g.FillEllipse(brush, leftl, t, d, d); g.FillEllipse(brush, midl, t, d, d); g.FillEllipse(brush, rightl, t, d, d); } } } /// /// 绘制箭头(按比例) /// /// 绘图对象 /// 绘图区域 /// 颜色 /// 方向 public static void DrawArrow(Graphics g, Rectangle rect, Color color, ArrowDirection direction) { rect.Width--; rect.Height--; int width = rect.Width; int height = rect.Height; int l = rect.X; int t = rect.Y; int r = rect.Right; int b = rect.Bottom; //以朝下的为准定义以下变量 float offsetL = 0.24f; float offsetT = 0.33f; float offsetB = 0.27f; PointF[] points = new PointF[3]; ; switch (direction) { case ArrowDirection.Left: points[0] = new PointF(l + width * offsetB, t + height * 0.5f); points[1] = new PointF(r - width * offsetT, t + height * offsetL); points[2] = new PointF(r - width * offsetT, b - height * offsetL); break; case ArrowDirection.Up: points[0] = new PointF(l + width * 0.5f, t + height * offsetB); points[1] = new PointF(r - width * offsetL, b - height * offsetT); points[2] = new PointF(l + width * offsetL, b - height * offsetT); break; case ArrowDirection.Right: points[0] = new PointF(l + width * offsetT, t + height * offsetL); points[1] = new PointF(r - width * offsetB, t + height * 0.5f); points[2] = new PointF(l + width * offsetT, b - height * offsetL); break; default: points[0] = new PointF(l + width * offsetL, t + height * offsetT); points[1] = new PointF(r - width * offsetL, t + height * offsetT); points[2] = new PointF(l + width * 0.5f, b - height * offsetB); break; } using (Brush brush = new SolidBrush(color)) { using (new SmoothingModeGraphics(g, SmoothingMode.AntiAlias)) { using (new PixelOffsetModeGraphics(g, PixelOffsetMode.Default)) { g.FillPolygon(brush, points); } } } } /// /// 绘制箭头(可选大小) /// /// 绘图对象 /// 区域 /// 颜色 /// 箭头方向 /// 大小样式 public static void DrawArrow(Graphics g, Rectangle rect, Color color, ArrowDirection direction, SizeStyle style) { Point point = new Point(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2)); Point[] points = null; switch (style) { case SizeStyle.Tiny: switch (direction) { case ArrowDirection.Left: points = new Point[] { new Point(point.X + 1, point.Y - 2), new Point(point.X + 1, point.Y + 2), new Point(point.X - 1, point.Y) }; break; case ArrowDirection.Up: points = new Point[] { new Point(point.X - 2, point.Y + 1), new Point(point.X + 2, point.Y + 1), new Point(point.X, point.Y - 2) }; break; case ArrowDirection.Right: points = new Point[] { new Point(point.X - 1, point.Y - 2), new Point(point.X - 1, point.Y + 2), new Point(point.X + 1, point.Y) }; break; default: points = new Point[] { new Point(point.X - 1, point.Y - 1), new Point(point.X + 2, point.Y - 1), new Point(point.X, point.Y + 1) }; break; } break; case SizeStyle.Small: switch (direction) { case ArrowDirection.Left: points = new Point[] { new Point(point.X + 2, point.Y - 3), new Point(point.X + 2, point.Y + 3), new Point(point.X - 1, point.Y) }; break; case ArrowDirection.Up: points = new Point[] { new Point(point.X - 3, point.Y + 2), new Point(point.X + 3, point.Y + 2), new Point(point.X, point.Y - 2) }; break; case ArrowDirection.Right: points = new Point[] { new Point(point.X - 1, point.Y - 3), new Point(point.X - 1, point.Y + 3), new Point(point.X + 2, point.Y) }; break; default: points = new Point[] { new Point(point.X - 2, point.Y - 1), new Point(point.X + 3, point.Y - 1), new Point(point.X, point.Y + 2) }; break; } break; case SizeStyle.Normal: switch (direction) { case ArrowDirection.Left: points = new Point[] { new Point(point.X + 2, point.Y - 4), new Point(point.X + 2, point.Y + 4), new Point(point.X - 2, point.Y) }; break; case ArrowDirection.Up: points = new Point[] { new Point(point.X - 4, point.Y + 2), new Point(point.X + 5, point.Y + 2), new Point(point.X, point.Y - 3) }; break; case ArrowDirection.Right: points = new Point[] { new Point(point.X - 2, point.Y - 4), new Point(point.X - 2, point.Y + 4), new Point(point.X + 2, point.Y) }; break; default: points = new Point[] { new Point(point.X - 3, point.Y - 2), new Point(point.X + 4, point.Y - 2), new Point(point.X, point.Y + 2) }; break; } break; case SizeStyle.Large: switch (direction) { case ArrowDirection.Left: points = new Point[] { new Point(point.X + 3, point.Y - 5), new Point(point.X + 3, point.Y + 5), new Point(point.X - 2, point.Y) }; break; case ArrowDirection.Up: points = new Point[] { new Point(point.X - 5, point.Y + 3), new Point(point.X + 6, point.Y + 3), new Point(point.X, point.Y - 3) }; break; case ArrowDirection.Right: points = new Point[] { new Point(point.X - 2, point.Y - 5), new Point(point.X - 2, point.Y + 5), new Point(point.X + 3, point.Y) }; break; default: points = new Point[] { new Point(point.X - 4, point.Y - 2), new Point(point.X + 5, point.Y - 2), new Point(point.X, point.Y + 3) }; break; } break; case SizeStyle.Huge: switch (direction) { case ArrowDirection.Left: points = new Point[] { new Point(point.X + 3, point.Y - 6), new Point(point.X + 3, point.Y + 6), new Point(point.X - 3, point.Y) }; break; case ArrowDirection.Up: points = new Point[] { new Point(point.X - 6, point.Y + 3), new Point(point.X + 7, point.Y + 3), new Point(point.X, point.Y - 4) }; break; case ArrowDirection.Right: points = new Point[] { new Point(point.X - 3, point.Y - 6), new Point(point.X - 3, point.Y + 6), new Point(point.X + 3, point.Y) }; break; default: points = new Point[] { new Point(point.X - 5, point.Y - 3), new Point(point.X + 6, point.Y - 3), new Point(point.X, point.Y + 3) }; break; } break; default: break; } using (Brush brush = new SolidBrush(color)) { using (new SmoothingModeGraphics(g, SmoothingMode.None)) { using (new PixelOffsetModeGraphics(g, PixelOffsetMode.Default)) { g.FillPolygon(brush, points); } } } } } }