FastReport

Форк
0
/
LineObject.cs 
232 строки · 8.0 Кб
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.ComponentModel;
5
using System.Drawing;
6
using System.Drawing.Drawing2D;
7
using FastReport.Utils;
8
using System.Linq;
9

10
namespace FastReport
11
{
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 set 
17
    /// 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>
20
    public partial class LineObject : ReportComponentBase
21
    {
22
        #region Fields
23
        private bool diagonal;
24
        private CapSettings startCap;
25
        private CapSettings endCap;
26
        private FloatCollection dashPattern;
27
        #endregion
28

29
        #region Properties
30
        /// <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")]
38
        public bool Diagonal
39
        {
40
            get { return diagonal; }
41
            set { diagonal = value; }
42
        }
43

44
        /// <summary>
45
        /// Gets or sets the start cap settings.
46
        /// </summary>
47
        [Category("Appearance")]
48
        public CapSettings StartCap
49
        {
50
            get { return startCap; }
51
            set { startCap = value; }
52
        }
53

54
        /// <summary>
55
        /// Gets or sets the end cap settings.
56
        /// </summary>
57
        [Category("Appearance")]
58
        public CapSettings EndCap
59
        {
60
            get { return endCap; }
61
            set { 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")]
72
        public FloatCollection DashPattern
73
        {
74
            get { return dashPattern; }
75
            set { dashPattern = value; }
76
        }
77
        #endregion
78

79
        #region Public Methods
80
        /// <inheritdoc/>
81
        public override void Assign(Base source)
82
        {
83
            base.Assign(source);
84

85
            LineObject src = source as LineObject;
86
            Diagonal = src.Diagonal;
87
            StartCap.Assign(src.StartCap);
88
            EndCap.Assign(src.EndCap);
89
            DashPattern.Assign(src.DashPattern);
90
        }
91

92
        /// <inheritdoc/>
93
        public override void Draw(FRPaintEventArgs e)
94
        {
95
            IGraphics g = e.Graphics;
96
            // draw marker when inserting a line
97
            if (Width == 0 && Height == 0)
98
            {
99
                g.DrawLine(Pens.Black, AbsLeft * e.ScaleX - 6, AbsTop * e.ScaleY, AbsLeft * e.ScaleX + 6, AbsTop * e.ScaleY);
100
                g.DrawLine(Pens.Black, AbsLeft * e.ScaleX, AbsTop * e.ScaleY - 6, AbsLeft * e.ScaleX, AbsTop * e.ScaleY + 6);
101
                return;
102
            }
103

104
            Report report = Report;
105
            if (report != null && report.SmoothGraphics)
106
            {
107
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
108
                g.SmoothingMode = SmoothingMode.AntiAlias;
109
            }
110

111
            Pen pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle);
112

113
            DrawUtils.SetPenDashPatternOrStyle(DashPattern, pen, Border);
114

115
            if (!Diagonal)
116
            {
117
                if (Math.Abs(Width) > Math.Abs(Height))
118
                    Height = 0;
119
                else
120
                    Width = 0;
121
            }
122

123
            float x1 = AbsLeft * e.ScaleX;
124
            float y1 = AbsTop * e.ScaleY;
125
            float x2 = (AbsLeft + Width) * e.ScaleX;
126
            float y2 = (AbsTop + Height) * e.ScaleY;
127

128
            if (StartCap.Style == CapStyle.None && EndCap.Style == CapStyle.None)
129
            {
130
                g.DrawLine(pen, x1, y1, x2, y2);
131
            }
132
            else
133
            {
134
                // draw line caps manually. It is necessary for correct svg rendering
135
                float angle = (float)(Math.Atan2(x2 - x1, y2 - y1) / Math.PI * 180);
136
                float len = (float)Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
137
                float scale = Border.Width * e.ScaleX;
138

139
                IGraphicsState state = g.Save();
140
                g.TranslateTransform(x1, y1);
141
                g.RotateTransform(-angle);
142
                float y = 0;
143
                GraphicsPath startCapPath = null;
144
                GraphicsPath endCapPath = null;
145
                float inset = 0;
146
                if (StartCap.Style != CapStyle.None)
147
                {
148
                    StartCap.GetCustomCapPath(out startCapPath, out inset);
149
                    y += inset * scale;
150
                }
151
                if (EndCap.Style != CapStyle.None)
152
                {
153
                    EndCap.GetCustomCapPath(out endCapPath, out inset);
154
                    len -= inset * scale;
155
                }
156
                g.DrawLine(pen, 0, y, 0, len);
157
                g.Restore(state);
158

159
                pen = e.Cache.GetPen(Border.Color, 1, Border.DashStyle);
160
                if (StartCap.Style != CapStyle.None)
161
                {
162
                    state = g.Save();
163
                    g.TranslateTransform(x1, y1);
164
                    g.RotateTransform(180 - angle);
165
                    g.ScaleTransform(scale, scale);
166
                    g.DrawPath(pen, startCapPath);
167
                    g.Restore(state);
168
                }
169
                if (EndCap.Style != CapStyle.None)
170
                {
171
                    state = g.Save();
172
                    g.TranslateTransform(x2, y2);
173
                    g.RotateTransform(-angle);
174
                    g.ScaleTransform(scale, scale);
175
                    g.DrawPath(pen, endCapPath);
176
                    g.Restore(state);
177
                }
178
            }
179

180
            if (report != null && report.SmoothGraphics && Diagonal)
181
            {
182
                g.InterpolationMode = InterpolationMode.Default;
183
                g.SmoothingMode = SmoothingMode.Default;
184
            }
185
        }
186

187
        /// <inheritdoc/>
188
        public override List<ValidationError> Validate()
189
        {
190
            List<ValidationError> listError = new List<ValidationError>();
191

192
            if (Height == 0 && Width == 0)
193
                listError.Add(new ValidationError(Name, ValidationError.ErrorLevel.Error, Res.Get("Messages,Validator,IncorrectSize"), this));
194

195
            if (Name == "")
196
                listError.Add(new ValidationError(Name, ValidationError.ErrorLevel.Error, Res.Get("Messages,Validator,UnnamedObject"), this));
197

198
            if (Parent is ReportComponentBase && !Validator.RectContainInOtherRect((Parent as ReportComponentBase).AbsBounds, this.AbsBounds))
199
                listError.Add(new ValidationError(Name, ValidationError.ErrorLevel.Error, Res.Get("Messages,Validator,OutOfBounds"), this));
200

201
            return listError;
202
        }
203

204
        /// <inheritdoc/>
205
        public override void Serialize(FRWriter writer)
206
        {
207
            Border.SimpleBorder = true;
208
            base.Serialize(writer);
209
            LineObject c = writer.DiffObject as LineObject;
210

211
            if (Diagonal != c.Diagonal)
212
                writer.WriteBool("Diagonal", Diagonal);
213
            StartCap.Serialize("StartCap", writer, c.StartCap);
214
            EndCap.Serialize("EndCap", writer, c.EndCap);
215
            if (DashPattern?.Count > 0)
216
                writer.WriteValue("DashPattern", DashPattern);
217
        }
218
        #endregion
219

220
        /// <summary>
221
        /// Initializes a new instance of the <see cref="LineObject"/> class with default settings.
222
        /// </summary>
223
        public LineObject()
224
        {
225
            startCap = new CapSettings();
226
            endCap = new CapSettings();
227
            FlagSimpleBorder = true;
228
            FlagUseFill = false;
229
            dashPattern = new FloatCollection();
230
        }
231
    }
232
}
233

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.