using System; using System.Drawing; using System.Drawing.Drawing2D; using System.ComponentModel; using FastReport.Utils; namespace FastReport { /// /// Specifies a kind of the shape. /// public enum ShapeKind { /// /// Specifies a rectangle shape. /// Rectangle, /// /// Specifies a round rectangle shape. /// RoundRectangle, /// /// Specifies an ellipse shape. /// Ellipse, /// /// Specifies a triangle shape. /// Triangle, /// /// Specifies a diamond shape. /// Diamond } /// /// Represents a shape object. /// /// /// Use the property to specify a shape. To set the width, style and color of the /// shape's border, use the Border.Width, Border.Style and Border.Color properties. /// public partial class ShapeObject : ReportComponentBase { #region Fields private ShapeKind shape; private float curve; #endregion #region Properties /// /// Gets or sets a shape kind. /// [DefaultValue(ShapeKind.Rectangle)] [Category("Appearance")] public ShapeKind Shape { get { return shape; } set { shape = value; } } /// /// Gets or sets a shape curvature if is RoundRectangle. /// /// /// 0 value means automatic curvature. /// [DefaultValue(0f)] [Category("Appearance")] public float Curve { get { return curve; } set { curve = value; } } #endregion #region Private Methods #if MONO private GraphicsPath GetRoundRectPath(float x, float y, float x1, float y1, float radius) { GraphicsPath gp = new GraphicsPath(); if (radius < 1) radius = 1; gp.AddLine(x + radius, y, x1 - radius, y); gp.AddArc(x1 - radius - 1, y, radius + 1, radius + 1, 270, 90); gp.AddLine(x1, y + radius, x1, y1 - radius); gp.AddArc(x1 - radius - 1, y1 - radius - 1, radius + 1, radius + 1, 0, 90); gp.AddLine(x1 - radius, y1, x + radius, y1); gp.AddArc(x, y1 - radius - 1, radius + 1, radius + 1, 90, 90); gp.AddLine(x, y1 - radius, x, y + radius); gp.AddArc(x, y, radius, radius, 180, 90); gp.CloseFigure(); return gp; } #else private GraphicsPath GetRoundRectPath(float x, float y, float x1, float y1, float radius) { GraphicsPath gp = new GraphicsPath(); if (radius < 1) radius = 1; gp.AddArc(x1 - radius - 1, y, radius + 1, radius + 1, 270, 90); gp.AddArc(x1 - radius - 1, y1 - radius - 1, radius + 1, radius + 1, 0, 90); gp.AddArc(x, y1 - radius - 1, radius + 1, radius + 1, 90, 90); gp.AddArc(x, y, radius, radius, 180, 90); gp.CloseFigure(); return gp; } #endif #endregion #region Public Methods /// public override void Assign(Base source) { base.Assign(source); ShapeObject src = source as ShapeObject; Shape = src.Shape; Curve = src.Curve; } /// public override void Draw(FRPaintEventArgs e) { if (Math.Abs(Width) < 1 || Math.Abs(Height) < 1) return; IGraphics g = e.Graphics; float x = (AbsLeft + Border.Width / 2) * e.ScaleX; float y = (AbsTop + Border.Width / 2) * e.ScaleY; float dx = (Width - Border.Width) * e.ScaleX - 1; float dy = (Height - Border.Width) * e.ScaleY - 1; float x1 = x + dx; float y1 = y + dy; Pen pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle); Brush brush = null; if (Fill is SolidFill) brush = e.Cache.GetBrush((Fill as SolidFill).Color); else brush = Fill.CreateBrush(new RectangleF(x, y, dx, dy), e.ScaleX, e.ScaleY); Report report = Report; if (report != null && report.SmoothGraphics && Shape != ShapeKind.Rectangle) { g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.SmoothingMode = SmoothingMode.AntiAlias; } switch (Shape) { case ShapeKind.Rectangle: g.FillAndDrawRectangle(pen, brush, x, y, dx, dy); break; case ShapeKind.RoundRectangle: float min = Math.Min(dx, dy); if (curve == 0) min = min / 4; else min = Math.Min(min, curve * e.ScaleX * 10); GraphicsPath gp = GetRoundRectPath(x, y, x1, y1, min); g.FillAndDrawPath(pen, brush, gp); gp.Dispose(); break; case ShapeKind.Ellipse: g.FillAndDrawEllipse(pen, brush, x, y, dx, dy); break; case ShapeKind.Triangle: PointF[] triPoints = { new PointF(x1, y1), new PointF(x, y1), new PointF(x + dx / 2, y), new PointF(x1, y1) }; g.FillAndDrawPolygon(pen, brush, triPoints); break; case ShapeKind.Diamond: PointF[] diaPoints = { new PointF(x + dx / 2, y), new PointF(x1, y + dy / 2), new PointF(x + dx / 2, y1), new PointF(x, y + dy / 2) }; g.FillAndDrawPolygon(pen, brush, diaPoints); break; } if (!(Fill is SolidFill)) brush.Dispose(); if (report != null && report.SmoothGraphics) { g.InterpolationMode = InterpolationMode.Default; g.SmoothingMode = SmoothingMode.Default; } } /// public override void Serialize(FRWriter writer) { Border.SimpleBorder = true; base.Serialize(writer); ShapeObject c = writer.DiffObject as ShapeObject; if (Shape != c.Shape) writer.WriteValue("Shape", Shape); if (Curve != c.Curve) writer.WriteFloat("Curve", Curve); } #endregion /// /// Initializes a new instance of the class with default settings. /// public ShapeObject() { shape = ShapeKind.Rectangle; FlagSimpleBorder = true; } } }