ShapeObject.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.ComponentModel;
  5. using FastReport.Utils;
  6. namespace FastReport
  7. {
  8. /// <summary>
  9. /// Specifies a kind of the shape.
  10. /// </summary>
  11. public enum ShapeKind
  12. {
  13. /// <summary>
  14. /// Specifies a rectangle shape.
  15. /// </summary>
  16. Rectangle,
  17. /// <summary>
  18. /// Specifies a round rectangle shape.
  19. /// </summary>
  20. RoundRectangle,
  21. /// <summary>
  22. /// Specifies an ellipse shape.
  23. /// </summary>
  24. Ellipse,
  25. /// <summary>
  26. /// Specifies a triangle shape.
  27. /// </summary>
  28. Triangle,
  29. /// <summary>
  30. /// Specifies a diamond shape.
  31. /// </summary>
  32. Diamond
  33. }
  34. /// <summary>
  35. /// Represents a shape object.
  36. /// </summary>
  37. /// <remarks>
  38. /// Use the <see cref="ShapeKind"/> property to specify a shape. To set the width, style and color of the
  39. /// shape's border, use the <b>Border.Width</b>, <b>Border.Style</b> and <b>Border.Color</b> properties.
  40. /// </remarks>
  41. public partial class ShapeObject : ReportComponentBase
  42. {
  43. #region Fields
  44. private ShapeKind shape;
  45. private float curve;
  46. #endregion
  47. #region Properties
  48. /// <summary>
  49. /// Gets or sets a shape kind.
  50. /// </summary>
  51. [DefaultValue(ShapeKind.Rectangle)]
  52. [Category("Appearance")]
  53. public ShapeKind Shape
  54. {
  55. get { return shape; }
  56. set { shape = value; }
  57. }
  58. /// <summary>
  59. /// Gets or sets a shape curvature if <see cref="ShapeKind"/> is <b>RoundRectangle</b>.
  60. /// </summary>
  61. /// <remarks>
  62. /// 0 value means automatic curvature.
  63. /// </remarks>
  64. [DefaultValue(0f)]
  65. [Category("Appearance")]
  66. public float Curve
  67. {
  68. get { return curve; }
  69. set { curve = value; }
  70. }
  71. #endregion
  72. #region Private Methods
  73. #if MONO
  74. private GraphicsPath GetRoundRectPath(float x, float y, float x1, float y1, float radius)
  75. {
  76. GraphicsPath gp = new GraphicsPath();
  77. if (radius < 1)
  78. radius = 1;
  79. gp.AddLine(x + radius, y, x1 - radius, y);
  80. gp.AddArc(x1 - radius - 1, y, radius + 1, radius + 1, 270, 90);
  81. gp.AddLine(x1, y + radius, x1, y1 - radius);
  82. gp.AddArc(x1 - radius - 1, y1 - radius - 1, radius + 1, radius + 1, 0, 90);
  83. gp.AddLine(x1 - radius, y1, x + radius, y1);
  84. gp.AddArc(x, y1 - radius - 1, radius + 1, radius + 1, 90, 90);
  85. gp.AddLine(x, y1 - radius, x, y + radius);
  86. gp.AddArc(x, y, radius, radius, 180, 90);
  87. gp.CloseFigure();
  88. return gp;
  89. }
  90. #else
  91. private GraphicsPath GetRoundRectPath(float x, float y, float x1, float y1, float radius)
  92. {
  93. GraphicsPath gp = new GraphicsPath();
  94. if (radius < 1)
  95. radius = 1;
  96. gp.AddArc(x1 - radius - 1, y, radius + 1, radius + 1, 270, 90);
  97. gp.AddArc(x1 - radius - 1, y1 - radius - 1, radius + 1, radius + 1, 0, 90);
  98. gp.AddArc(x, y1 - radius - 1, radius + 1, radius + 1, 90, 90);
  99. gp.AddArc(x, y, radius, radius, 180, 90);
  100. gp.CloseFigure();
  101. return gp;
  102. }
  103. #endif
  104. #endregion
  105. #region Public Methods
  106. /// <inheritdoc/>
  107. public override void Assign(Base source)
  108. {
  109. base.Assign(source);
  110. ShapeObject src = source as ShapeObject;
  111. Shape = src.Shape;
  112. Curve = src.Curve;
  113. }
  114. /// <inheritdoc/>
  115. public override void Draw(FRPaintEventArgs e)
  116. {
  117. if (Math.Abs(Width) < 1 || Math.Abs(Height) < 1)
  118. return;
  119. IGraphics g = e.Graphics;
  120. float x = (AbsLeft + Border.Width / 2) * e.ScaleX;
  121. float y = (AbsTop + Border.Width / 2) * e.ScaleY;
  122. float dx = (Width - Border.Width) * e.ScaleX - 1;
  123. float dy = (Height - Border.Width) * e.ScaleY - 1;
  124. float x1 = x + dx;
  125. float y1 = y + dy;
  126. Pen pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle);
  127. Brush brush = null;
  128. if (Fill is SolidFill)
  129. brush = e.Cache.GetBrush((Fill as SolidFill).Color);
  130. else
  131. brush = Fill.CreateBrush(new RectangleF(x, y, dx, dy), e.ScaleX, e.ScaleY);
  132. Report report = Report;
  133. if (report != null && report.SmoothGraphics && Shape != ShapeKind.Rectangle)
  134. {
  135. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  136. g.SmoothingMode = SmoothingMode.AntiAlias;
  137. }
  138. switch (Shape)
  139. {
  140. case ShapeKind.Rectangle:
  141. g.FillAndDrawRectangle(pen, brush, x, y, dx, dy);
  142. break;
  143. case ShapeKind.RoundRectangle:
  144. float min = Math.Min(dx, dy);
  145. if (curve == 0)
  146. min = min / 4;
  147. else
  148. min = Math.Min(min, curve * e.ScaleX * 10);
  149. GraphicsPath gp = GetRoundRectPath(x, y, x1, y1, min);
  150. g.FillAndDrawPath(pen, brush, gp);
  151. gp.Dispose();
  152. break;
  153. case ShapeKind.Ellipse:
  154. g.FillAndDrawEllipse(pen, brush, x, y, dx, dy);
  155. break;
  156. case ShapeKind.Triangle:
  157. PointF[] triPoints = {
  158. new PointF(x1, y1), new PointF(x, y1), new PointF(x + dx / 2, y), new PointF(x1, y1) };
  159. g.FillAndDrawPolygon(pen, brush, triPoints);
  160. break;
  161. case ShapeKind.Diamond:
  162. PointF[] diaPoints = {
  163. new PointF(x + dx / 2, y), new PointF(x1, y + dy / 2), new PointF(x + dx / 2, y1),
  164. new PointF(x, y + dy / 2) };
  165. g.FillAndDrawPolygon(pen, brush, diaPoints);
  166. break;
  167. }
  168. if (!(Fill is SolidFill))
  169. brush.Dispose();
  170. if (report != null && report.SmoothGraphics)
  171. {
  172. g.InterpolationMode = InterpolationMode.Default;
  173. g.SmoothingMode = SmoothingMode.Default;
  174. }
  175. }
  176. /// <inheritdoc/>
  177. public override void Serialize(FRWriter writer)
  178. {
  179. Border.SimpleBorder = true;
  180. base.Serialize(writer);
  181. ShapeObject c = writer.DiffObject as ShapeObject;
  182. if (Shape != c.Shape)
  183. writer.WriteValue("Shape", Shape);
  184. if (Curve != c.Curve)
  185. writer.WriteFloat("Curve", Curve);
  186. }
  187. #endregion
  188. /// <summary>
  189. /// Initializes a new instance of the <see cref="ShapeObject"/> class with default settings.
  190. /// </summary>
  191. public ShapeObject()
  192. {
  193. shape = ShapeKind.Rectangle;
  194. FlagSimpleBorder = true;
  195. }
  196. }
  197. }