FastReport
232 строки · 8.0 Кб
1using System;2using System.Collections.Generic;3using System.Text;4using System.ComponentModel;5using System.Drawing;6using System.Drawing.Drawing2D;7using FastReport.Utils;8using System.Linq;9
10namespace FastReport11{
12/// <summary>13/// Represents a line object.14/// </summary>15/// <remarks>16/// Use the <b>Border.Width</b>, <b>Border.Style</b> and <b>Border.Color</b> properties to set17/// the line width, style and color. Set the <see cref="Diagonal"/> property to <b>true</b>18/// if you want to show a diagonal line.19/// </remarks>20public partial class LineObject : ReportComponentBase21{22#region Fields23private bool diagonal;24private CapSettings startCap;25private CapSettings endCap;26private FloatCollection dashPattern;27#endregion28
29#region Properties30/// <summary>31/// Gets or sets a value indicating that the line is diagonal.32/// </summary>33/// <remarks>34/// If this property is <b>false</b>, the line can be only horizontal or vertical.35/// </remarks>36[DefaultValue(false)]37[Category("Appearance")]38public bool Diagonal39{40get { return diagonal; }41set { diagonal = value; }42}43
44/// <summary>45/// Gets or sets the start cap settings.46/// </summary>47[Category("Appearance")]48public CapSettings StartCap49{50get { return startCap; }51set { startCap = value; }52}53
54/// <summary>55/// Gets or sets the end cap settings.56/// </summary>57[Category("Appearance")]58public CapSettings EndCap59{60get { return endCap; }61set { endCap = value; }62}63
64/// <summary>65/// Gets or sets collection of values for custom dash pattern.66/// </summary>67/// <remarks>68/// Each element should be a non-zero positive number.69/// If the number is negative or zero, that number is replaced by one.70/// </remarks>71[Category("Appearance")]72public FloatCollection DashPattern73{74get { return dashPattern; }75set { dashPattern = value; }76}77#endregion78
79#region Public Methods80/// <inheritdoc/>81public override void Assign(Base source)82{83base.Assign(source);84
85LineObject src = source as LineObject;86Diagonal = src.Diagonal;87StartCap.Assign(src.StartCap);88EndCap.Assign(src.EndCap);89DashPattern.Assign(src.DashPattern);90}91
92/// <inheritdoc/>93public override void Draw(FRPaintEventArgs e)94{95IGraphics g = e.Graphics;96// draw marker when inserting a line97if (Width == 0 && Height == 0)98{99g.DrawLine(Pens.Black, AbsLeft * e.ScaleX - 6, AbsTop * e.ScaleY, AbsLeft * e.ScaleX + 6, AbsTop * e.ScaleY);100g.DrawLine(Pens.Black, AbsLeft * e.ScaleX, AbsTop * e.ScaleY - 6, AbsLeft * e.ScaleX, AbsTop * e.ScaleY + 6);101return;102}103
104Report report = Report;105if (report != null && report.SmoothGraphics)106{107g.InterpolationMode = InterpolationMode.HighQualityBicubic;108g.SmoothingMode = SmoothingMode.AntiAlias;109}110
111Pen pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle);112
113DrawUtils.SetPenDashPatternOrStyle(DashPattern, pen, Border);114
115if (!Diagonal)116{117if (Math.Abs(Width) > Math.Abs(Height))118Height = 0;119else120Width = 0;121}122
123float x1 = AbsLeft * e.ScaleX;124float y1 = AbsTop * e.ScaleY;125float x2 = (AbsLeft + Width) * e.ScaleX;126float y2 = (AbsTop + Height) * e.ScaleY;127
128if (StartCap.Style == CapStyle.None && EndCap.Style == CapStyle.None)129{130g.DrawLine(pen, x1, y1, x2, y2);131}132else133{134// draw line caps manually. It is necessary for correct svg rendering135float angle = (float)(Math.Atan2(x2 - x1, y2 - y1) / Math.PI * 180);136float len = (float)Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));137float scale = Border.Width * e.ScaleX;138
139IGraphicsState state = g.Save();140g.TranslateTransform(x1, y1);141g.RotateTransform(-angle);142float y = 0;143GraphicsPath startCapPath = null;144GraphicsPath endCapPath = null;145float inset = 0;146if (StartCap.Style != CapStyle.None)147{148StartCap.GetCustomCapPath(out startCapPath, out inset);149y += inset * scale;150}151if (EndCap.Style != CapStyle.None)152{153EndCap.GetCustomCapPath(out endCapPath, out inset);154len -= inset * scale;155}156g.DrawLine(pen, 0, y, 0, len);157g.Restore(state);158
159pen = e.Cache.GetPen(Border.Color, 1, Border.DashStyle);160if (StartCap.Style != CapStyle.None)161{162state = g.Save();163g.TranslateTransform(x1, y1);164g.RotateTransform(180 - angle);165g.ScaleTransform(scale, scale);166g.DrawPath(pen, startCapPath);167g.Restore(state);168}169if (EndCap.Style != CapStyle.None)170{171state = g.Save();172g.TranslateTransform(x2, y2);173g.RotateTransform(-angle);174g.ScaleTransform(scale, scale);175g.DrawPath(pen, endCapPath);176g.Restore(state);177}178}179
180if (report != null && report.SmoothGraphics && Diagonal)181{182g.InterpolationMode = InterpolationMode.Default;183g.SmoothingMode = SmoothingMode.Default;184}185}186
187/// <inheritdoc/>188public override List<ValidationError> Validate()189{190List<ValidationError> listError = new List<ValidationError>();191
192if (Height == 0 && Width == 0)193listError.Add(new ValidationError(Name, ValidationError.ErrorLevel.Error, Res.Get("Messages,Validator,IncorrectSize"), this));194
195if (Name == "")196listError.Add(new ValidationError(Name, ValidationError.ErrorLevel.Error, Res.Get("Messages,Validator,UnnamedObject"), this));197
198if (Parent is ReportComponentBase && !Validator.RectContainInOtherRect((Parent as ReportComponentBase).AbsBounds, this.AbsBounds))199listError.Add(new ValidationError(Name, ValidationError.ErrorLevel.Error, Res.Get("Messages,Validator,OutOfBounds"), this));200
201return listError;202}203
204/// <inheritdoc/>205public override void Serialize(FRWriter writer)206{207Border.SimpleBorder = true;208base.Serialize(writer);209LineObject c = writer.DiffObject as LineObject;210
211if (Diagonal != c.Diagonal)212writer.WriteBool("Diagonal", Diagonal);213StartCap.Serialize("StartCap", writer, c.StartCap);214EndCap.Serialize("EndCap", writer, c.EndCap);215if (DashPattern?.Count > 0)216writer.WriteValue("DashPattern", DashPattern);217}218#endregion219
220/// <summary>221/// Initializes a new instance of the <see cref="LineObject"/> class with default settings.222/// </summary>223public LineObject()224{225startCap = new CapSettings();226endCap = new CapSettings();227FlagSimpleBorder = true;228FlagUseFill = false;229dashPattern = new FloatCollection();230}231}232}
233