using CommonLang; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using CommonLang.Vector; using System.Windows.Forms; namespace CommonFroms.Drawing { public static class DrawingUtils { public static void DrawCross(Graphics g, Pen pen, float cx, float cy, float cr) { g.DrawLine(pen, cx - cr, cy, cx + cr, cy); g.DrawLine(pen, cx, cy - cr, cx, cy + cr); } public static void DrawFan(Graphics g, Pen pen, float direction, float range, float angle) { if (angle != 0) { float startRadians = direction - angle / 2; float endRadians = direction + angle / 2; g.DrawArc(pen, -range, -range, range * 2, range * 2, CMath.RadiansToDegrees(startRadians), CMath.RadiansToDegrees(angle)); g.DrawLine(pen, 0, 0, (float)Math.Cos(startRadians) * range, (float)Math.Sin(startRadians) * range); g.DrawLine(pen, 0, 0, (float)Math.Cos(endRadians) * range, (float)Math.Sin(endRadians) * range); } else { g.DrawLine(pen, 0, 0, (float)Math.Cos(direction) * range, (float)Math.Sin(direction) * range); } } public static void FillFan(Graphics g, Brush pen, float direction, float range, float angle) { float startRadians = direction - angle / 2; float endRadians = direction + angle / 2; g.FillPie(pen, -range, -range, range * 2, range * 2, CMath.RadiansToDegrees(startRadians), CMath.RadiansToDegrees(angle)); } /// /// 画粗线条 /// /// /// /// /// /// public static void DrawLineRect(Graphics g, Pen pen, float sx, float sy, float dx, float dy, float line_r) { float direction = MathVector.getDegree(sx, sy, dx, dy); Vector2 s_l = new Vector2(sx, sy); Vector2 s_r = new Vector2(sx, sy); Vector2 d_l = new Vector2(dx, dy); Vector2 d_r = new Vector2(dx, dy); MathVector.movePolar(s_l, direction + CMath.PI_DIV_2, line_r); MathVector.movePolar(d_l, direction + CMath.PI_DIV_2, line_r); MathVector.movePolar(s_r, direction - CMath.PI_DIV_2, line_r); MathVector.movePolar(d_r, direction - CMath.PI_DIV_2, line_r); g.DrawLine(pen, s_l.X, s_l.Y, d_l.X, d_l.Y); g.DrawLine(pen, s_r.X, s_r.Y, d_r.X, d_r.Y); g.DrawLine(pen, s_l.X, s_l.Y, s_r.X, s_r.Y); g.DrawLine(pen, d_l.X, d_l.Y, d_r.X, d_r.Y); } public static void FillLineRect(Graphics g, Brush brush, float sx, float sy, float dx, float dy, float line_r) { float direction = MathVector.getDegree(sx, sy, dx, dy); Vector2 s_l = new Vector2(sx, sy); Vector2 s_r = new Vector2(sx, sy); Vector2 d_l = new Vector2(dx, dy); Vector2 d_r = new Vector2(dx, dy); MathVector.movePolar(s_l, direction + CMath.PI_DIV_2, line_r); MathVector.movePolar(d_l, direction + CMath.PI_DIV_2, line_r); MathVector.movePolar(s_r, direction - CMath.PI_DIV_2, line_r); MathVector.movePolar(d_r, direction - CMath.PI_DIV_2, line_r); g.FillPolygon(brush, new PointF[] { new PointF(s_l.X, s_l.Y), new PointF(s_r.X, s_r.Y), new PointF(d_r.X, d_r.Y), new PointF(d_l.X, d_l.Y) }, System.Drawing.Drawing2D.FillMode.Winding); } /// /// 画圆角粗线条 /// /// /// /// /// /// /// /// public static void DrawLineRoundRect(Graphics g, Pen pen, float sx, float sy, float dx, float dy, float line_r) { float direction = MathVector.getDegree(sx, sy, dx, dy); float r = line_r; float size = r * 2; Vector2 s_l = new Vector2(sx, sy); Vector2 s_r = new Vector2(sx, sy); Vector2 d_l = new Vector2(dx, dy); Vector2 d_r = new Vector2(dx, dy); MathVector.movePolar(s_l, direction + CMath.PI_DIV_2, r); MathVector.movePolar(d_l, direction + CMath.PI_DIV_2, r); MathVector.movePolar(s_r, direction - CMath.PI_DIV_2, r); MathVector.movePolar(d_r, direction - CMath.PI_DIV_2, r); g.DrawLine(pen, s_l.X, s_l.Y, d_l.X, d_l.Y); g.DrawLine(pen, s_r.X, s_r.Y, d_r.X, d_r.Y); float angle = CMath.RadiansToDegrees(direction); g.DrawArc(pen, sx - r, sy - r, size, size, angle + 180 - 90, 180); g.DrawArc(pen, dx - r, dy - r, size, size, angle + 360 - 90, 180); } public static void FillLineRoundRect(Graphics g, Brush brush, float sx, float sy, float dx, float dy, float line_r) { float direction = MathVector.getDegree(sx, sy, dx, dy); float r = line_r; float size = r * 2; Vector2 s_l = new Vector2(sx, sy); Vector2 s_r = new Vector2(sx, sy); Vector2 d_l = new Vector2(dx, dy); Vector2 d_r = new Vector2(dx, dy); MathVector.movePolar(s_l, direction + CMath.PI_DIV_2, r); MathVector.movePolar(d_l, direction + CMath.PI_DIV_2, r); MathVector.movePolar(s_r, direction - CMath.PI_DIV_2, r); MathVector.movePolar(d_r, direction - CMath.PI_DIV_2, r); g.FillPolygon(brush, new PointF[] { new PointF(s_l.X, s_l.Y), new PointF(s_r.X, s_r.Y), new PointF(d_r.X, d_r.Y), new PointF(d_l.X, d_l.Y) }, System.Drawing.Drawing2D.FillMode.Winding); float angle = CMath.RadiansToDegrees(direction); g.FillPie(brush, sx - r, sy - r, size, size, angle + 180 - 90, 180); g.FillPie(brush, dx - r, dy - r, size, size, angle + 360 - 90, 180); } public static PointF[] GenCursor(float sx, float sy, float dx, float dy, float width, float cursor_width, float cursor_height) { if (cursor_width < width) cursor_width = width; float ox = sx - dx; float oy = sy - dy; float ds = CMath.getDistance(sx, sy, dx, dy); float hw = width / 2f; float cw = cursor_width / 2; float od = (float)Math.Atan2(oy, ox); PointF sC = new Point(0, 0); PointF sL = new PointF(-hw, 0); PointF sR = new PointF(+hw, 0); PointF dC = new PointF(0, ds); PointF dL = new PointF(-hw, ds - cursor_height); PointF dR = new PointF(+hw, ds - cursor_height); PointF dLL = new PointF(-cw, ds - cursor_height); PointF dRR = new PointF(+cw, ds - cursor_height); PointF[] points = new PointF[] { sC, sL, dL, dLL, dC, dRR, dR, sR, sC }; for (int i = 0; i < points.Length; i++) { float x = points[i].X; float y = points[i].Y; MathVector.rotate(ref x, ref y, 0, 0, od + CMath.PI_DIV_2); points[i].X = x + sx; points[i].Y = y + sy; } return points; } public static void FillCursor(Graphics g, Brush brush, float sx, float sy, float dx, float dy, float width, float cursor_width = 0, float cursor_height = 0) { PointF[] points = GenCursor(sx, sy, dx, dy, width, cursor_width, cursor_height); System.Drawing.Drawing2D.GraphicsState gs = g.Save(); try { g.FillPolygon(brush, points); } finally { g.Restore(gs); } } public static void DrawCursor(Graphics g, Pen pen, float sx, float sy, float dx, float dy, float width, float cursor_width = 0, float cursor_height = 0) { PointF[] points = GenCursor(sx, sy, dx, dy, width, cursor_width, cursor_height); System.Drawing.Drawing2D.GraphicsState gs = g.Save(); try { g.DrawPolygon(pen, points); } finally { g.Restore(gs); } } } public abstract class Drawable { public int spacing = 2; public StringFormat format = new StringFormat(StringFormat.GenericDefault); public Font font = Form.DefaultFont; public AnchorStyles anchor = AnchorStyles.Left | AnchorStyles.Top; public virtual float Draw(Graphics g, float sx, float sy, float sw, float sh) { sx = sx - (((anchor & AnchorStyles.Right) != 0) ? sw : 0); sy = sy - (((anchor & AnchorStyles.Bottom) != 0) ? sh : 0); float x = sx + spacing; float y = sy + spacing; float w = sw - (spacing << 1); float h = sh - (spacing << 1); var clip = new RectangleF(x, y, w, h); g.SetClip(clip); try { DrawSelf(g, x, y, w, h); } finally { g.ResetClip(); } return ((anchor & AnchorStyles.Bottom) != 0) ? -sh : sh; } protected abstract void DrawSelf(Graphics g, float x, float y, float w, float h); } public class GaugeRectFan : Drawable { public Brush body_brush = new SolidBrush(Color.FromArgb(0xFF, 0x40, 0x40, 0x40)); public Brush border_brush = new SolidBrush(Color.Gray); public Brush cd_brush = new SolidBrush(Color.FromArgb(0x80, 0xFF, 0xFF, 0xFF)); public Brush text_brush = new SolidBrush(Color.White); public int border = 1; public string text1; public string text2; public float percent; public GaugeRectFan SetText(string t1, string t2) { this.text1 = t1; this.text2 = t2; return this; } public GaugeRectFan SetPercent(float pct) { this.percent = pct; return this; } protected override void DrawSelf(Graphics g, float x, float y, float w, float h) { g.FillRectangle(border_brush, x, y, w, h); x += border; y += border; w -= (border << 1); h -= (border << 1); g.FillRectangle(body_brush, x, y, w, h); if (percent > 0f && percent < 1f) { g.FillPie(cd_brush, x - w, y - h, w * 3, h * 3, -90, 360 * percent); } if (!string.IsNullOrEmpty(text1) && string.IsNullOrEmpty(text2)) { format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; g.DrawString(text1, font, text_brush, x, y + border, StringFormat.GenericDefault); } else { x += 1; y += 1; w -= 2; h -= 2; if (!string.IsNullOrEmpty(text1)) { format.Alignment = StringAlignment.Near; format.LineAlignment = StringAlignment.Near; g.DrawString(text1, font, text_brush, x, y + border, StringFormat.GenericDefault); } if (!string.IsNullOrEmpty(text2)) { format.Alignment = StringAlignment.Near; format.LineAlignment = StringAlignment.Far; g.DrawString(text2, font, text_brush, new RectangleF(x, y, w, h - border), format); } } } } public class GaugeStrip : Drawable { public Brush back_brush = new SolidBrush(Color.FromArgb(0xFF, 0x40, 0x40, 0x40)); public Brush cd_brush = new SolidBrush(Color.FromArgb(0xA0, 0x20, 0xFF, 0x20)); public Brush text_brush = new SolidBrush(Color.White); public int border = 1; public string text; public float percent; public GaugeStrip SetText(string t) { this.text = t; return this; } public GaugeStrip SetPercent(float pct) { this.percent = pct; return this; } public override float Draw(Graphics g, float sx, float sy, float sw, float sh) { var trect = g.MeasureString(text, font); sw = Math.Max(sw, trect.Width + (spacing << 1) + 2); sh = Math.Max(sh, trect.Height + (spacing << 1) + 2); return base.Draw(g, sx, sy, sw, sh); } protected override void DrawSelf(Graphics g, float x, float y, float w, float h) { g.FillRectangle(back_brush, x, y, w, h); x += border; y += border; w -= (border << 1); h -= (border << 1); if (percent > 0f && percent < 1f) { g.FillRectangle(cd_brush, x, y, w * percent, h); } g.DrawString(text, font, text_brush, x + 1, y + 1, format); } } public class TextLine : Drawable { public string text; public Brush text_brush = new SolidBrush(Color.White); public TextLine SetText(string t) { this.text = t; return this; } public override float Draw(Graphics g, float sx, float sy, float sw, float sh) { var trect = g.MeasureString(text, font); sw = Math.Max(sw, trect.Width + (spacing << 1)); sh = Math.Max(sh, trect.Height + (spacing << 1)); return base.Draw(g, sx, sy, sw, sh); } protected override void DrawSelf(Graphics g, float x, float y, float w, float h) { g.DrawString(text, font, text_brush, x, y, format); } } public class TextRect : Drawable { public string text; public Brush text_brush = new SolidBrush(Color.White); public TextRect SetText(string t) { this.text = t; return this; } public override float Draw(Graphics g, float sx, float sy, float sw, float sh) { var trect = g.MeasureString(text, font, (int)sw - (spacing << 1)); sw = Math.Max(sw, trect.Width + (spacing << 1)); sh = Math.Max(sh, trect.Height + (spacing << 1)); return base.Draw(g, sx, sy, sw, sh); } protected override void DrawSelf(Graphics g, float x, float y, float w, float h) { g.DrawString(text, font, text_brush, new RectangleF(x, y, w, h), format); } } }