using System; using System.Drawing; using System.Drawing.Drawing2D; namespace Chess.Extensions { public static class GraphicsExtensions { private static GraphicsPath GenerateRoundedRectangle( this Graphics graphics, RectangleF rectangle, float radius) { float diameter; GraphicsPath path = new GraphicsPath(); if (radius <= 0.0F) { path.AddRectangle(rectangle); path.CloseFigure(); return path; } else { if (radius >= (Math.Min(rectangle.Width, rectangle.Height)) / 2.0) return graphics.GenerateCapsule(rectangle); diameter = radius * 2.0F; SizeF sizeF = new SizeF(diameter, diameter); RectangleF arc = new RectangleF(rectangle.Location, sizeF); path.AddArc(arc, 180, 90); arc.X = rectangle.Right - diameter; path.AddArc(arc, 270, 90); arc.Y = rectangle.Bottom - diameter; path.AddArc(arc, 0, 90); arc.X = rectangle.Left; path.AddArc(arc, 90, 90); path.CloseFigure(); } return path; } private static GraphicsPath GenerateCapsule( this Graphics graphics, RectangleF baseRect) { float diameter; RectangleF arc; GraphicsPath path = new GraphicsPath(); try { if (baseRect.Width > baseRect.Height) { diameter = baseRect.Height; SizeF sizeF = new SizeF(diameter, diameter); arc = new RectangleF(baseRect.Location, sizeF); path.AddArc(arc, 90, 180); arc.X = baseRect.Right - diameter; path.AddArc(arc, 270, 180); } else if (baseRect.Width < baseRect.Height) { diameter = baseRect.Width; SizeF sizeF = new SizeF(diameter, diameter); arc = new RectangleF(baseRect.Location, sizeF); path.AddArc(arc, 180, 180); arc.Y = baseRect.Bottom - diameter; path.AddArc(arc, 0, 180); } else path.AddEllipse(baseRect); } catch { path.AddEllipse(baseRect); } finally { path.CloseFigure(); } return path; } /// /// Draws a rounded rectangle specified by a pair of coordinates, a width, a height and the radius /// for the arcs that make the rounded edges. /// /// System.Drawing.Pen that determines the color, width and style of the rectangle. /// The x-coordinate of the upper-left corner of the rectangle to draw. /// The y-coordinate of the upper-left corner of the rectangle to draw. /// Width of the rectangle to draw. /// Height of the rectangle to draw. /// The radius of the arc used for the rounded edges. public static void DrawRoundedRectangle( this Graphics graphics, Pen pen, float x, float y, float width, float height, float radius) { RectangleF rectangle = new RectangleF(x, y, width, height); GraphicsPath path = graphics.GenerateRoundedRectangle(rectangle, radius); SmoothingMode old = graphics.SmoothingMode; graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.DrawPath(pen, path); graphics.SmoothingMode = old; } /// /// Draws a rounded rectangle specified by a pair of coordinates, a width, a height and the radius /// for the arcs that make the rounded edges. /// /// System.Drawing.Pen that determines the color, width and style of the rectangle. /// The x-coordinate of the upper-left corner of the rectangle to draw. /// The y-coordinate of the upper-left corner of the rectangle to draw. /// Width of the rectangle to draw. /// Height of the rectangle to draw. /// The radius of the arc used for the rounded edges. public static void DrawRoundedRectangle( this Graphics graphics, Pen pen, int x, int y, int width, int height, int radius) { graphics.DrawRoundedRectangle( pen, Convert.ToSingle(x), Convert.ToSingle(y), Convert.ToSingle(width), Convert.ToSingle(height), Convert.ToSingle(radius)); } /// /// Fills the interior of a rounded rectangle specified by a pair of coordinates, a width, a height /// and the radius for the arcs that make the rounded edges. /// /// System.Drawing.Brush that determines the characteristics of the fill. /// The x-coordinate of the upper-left corner of the rectangle to fill. /// The y-coordinate of the upper-left corner of the rectangle to fill. /// Width of the rectangle to fill. /// Height of the rectangle to fill. /// The radius of the arc used for the rounded edges. public static void FillRoundedRectangle( this Graphics graphics, Brush brush, float x, float y, float width, float height, float radius) { RectangleF rectangle = new RectangleF(x, y, width, height); GraphicsPath path = graphics.GenerateRoundedRectangle(rectangle, radius); SmoothingMode old = graphics.SmoothingMode; graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.FillPath(brush, path); graphics.SmoothingMode = old; } /// /// Fills the interior of a rounded rectangle specified by a pair of coordinates, a width, a height /// and the radius for the arcs that make the rounded edges. /// /// System.Drawing.Brush that determines the characteristics of the fill. /// The x-coordinate of the upper-left corner of the rectangle to fill. /// The y-coordinate of the upper-left corner of the rectangle to fill. /// Width of the rectangle to fill. /// Height of the rectangle to fill. /// The radius of the arc used for the rounded edges. public static void FillRoundedRectangle( this Graphics graphics, Brush brush, int x, int y, int width, int height, int radius) { graphics.FillRoundedRectangle( brush, Convert.ToSingle(x), Convert.ToSingle(y), Convert.ToSingle(width), Convert.ToSingle(height), Convert.ToSingle(radius)); } public static void DrawParagraph(this Graphics graphics, string s, Font font, Brush brush, float x, float y) { graphics.DrawParagraph(s, font, brush, x, y, StringFormat.GenericDefault); } public static void DrawParagraph(this Graphics graphics, string s, Font font, Brush brush, float x, float y, StringFormat format) { string[] split = s.Split(new string[] { "\n" }, StringSplitOptions.None); int dy = (int)font.GetHeight(graphics) * 1; int offy = 0; foreach (var str in split) { graphics.DrawString(str, font, brush, x, y + offy, format); offy += dy; } } public static int ParagraphHeight(this Graphics graphics, string s, Font font) { string[] split = s.Split(new string[] { "\n" }, StringSplitOptions.None); int dy = (int)font.GetHeight(graphics) * 1; int offy = 0; foreach (var str in split) { offy += dy; } return offy; } } }