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;
}
}
}