123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650 |
- using System;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.ComponentModel;
- using FastReport.Utils;
- using System.Drawing.Design;
- namespace FastReport
- {
- /// <summary>
- /// Specifies the style of a border line.
- /// </summary>
- public enum LineStyle
- {
- /// <summary>
- /// Specifies a solid line.
- /// </summary>
- Solid,
- /// <summary>
- /// Specifies a line consisting of dashes.
- /// </summary>
- Dash,
- /// <summary>
- /// Specifies a line consisting of dots.
- /// </summary>
- Dot,
- /// <summary>
- /// Specifies a line consisting of a repeating pattern of dash-dot.
- /// </summary>
- DashDot,
- /// <summary>
- /// Specifies a line consisting of a repeating pattern of dash-dot-dot.
- /// </summary>
- DashDotDot,
- /// <summary>
- /// Specifies a double line.
- /// </summary>
- Double,
- /// <summary>
- /// Specifies a custom line.
- /// </summary>
- Custom
- }
- /// <summary>
- /// Specifies the sides of a border.
- /// </summary>
- [Flags]
- public enum BorderLines
- {
- /// <summary>
- /// Specifies no border lines.
- /// </summary>
- None = 0,
- /// <summary>
- /// Specifies the left border line.
- /// </summary>
- Left = 1,
- /// <summary>
- /// Specifies the right border line.
- /// </summary>
- Right = 2,
- /// <summary>
- /// Specifies the top border line.
- /// </summary>
- Top = 4,
- /// <summary>
- /// Specifies the bottom border line.
- /// </summary>
- Bottom = 8,
- /// <summary>
- /// Specifies all border lines.
- /// </summary>
- All = 15
- }
- /// <summary>
- /// Represents a single border line.
- /// </summary>
- [TypeConverter(typeof(FastReport.TypeConverters.FRExpandableObjectConverter))]
- public class BorderLine
- {
- #region Fields
- private Color color;
- private LineStyle style;
- private float width;
- #endregion
- #region Properties
- /// <summary>
- /// Gets or sets a color of the line.
- /// </summary>
- [Editor("FastReport.TypeEditors.ColorEditor, FastReport", typeof(UITypeEditor))]
- public Color Color
- {
- get { return color; }
- set { color = value; }
- }
- /// <summary>
- /// Gets or sets a style of the line.
- /// </summary>
- [DefaultValue(LineStyle.Solid)]
- [Editor("FastReport.TypeEditors.LineStyleEditor, FastReport", typeof(UITypeEditor))]
- public LineStyle Style
- {
- get { return style; }
- set { style = value; }
- }
- /// <summary>
- /// Gets or sets a width of the line, in pixels.
- /// </summary>
- [DefaultValue(1f)]
- public float Width
- {
- get { return width; }
- set { width = value; }
- }
- internal DashStyle DashStyle
- {
- get
- {
- DashStyle[] styles = new DashStyle[] {
- DashStyle.Solid, DashStyle.Dash, DashStyle.Dot, DashStyle.DashDot, DashStyle.DashDotDot, DashStyle.Solid };
- return styles[(int)Style];
- }
- }
- #endregion
- #region Private Methods
- private bool ShouldSerializeColor()
- {
- return Color != Color.Black;
- }
- internal bool ShouldSerialize()
- {
- return Width != 1 || Style != LineStyle.Solid || Color != Color.Black;
- }
- #endregion
- #region Public Methods
- internal BorderLine Clone()
- {
- BorderLine result = new BorderLine();
- result.Assign(this);
- return result;
- }
- internal void Assign(BorderLine src)
- {
- Color = src.Color;
- Style = src.Style;
- Width = src.Width;
- }
- /// <inheritdoc/>
- public override bool Equals(object obj)
- {
- BorderLine line = obj as BorderLine;
- return line != null && Width == line.Width && Color == line.Color && Style == line.Style;
- }
- /// <inheritdoc/>
- public override int GetHashCode()
- {
- return Color.GetHashCode() ^ Style.GetHashCode() ^ Width.GetHashCode();
- }
- internal void Draw(FRPaintEventArgs e, float x, float y, float x1, float y1,
- bool reverseGaps, bool gap1, bool gap2)
- {
- IGraphics g = e.Graphics;
- int penWidth = (int)Math.Round(Width * e.ScaleX);
- if (penWidth <= 0)
- penWidth = 1;
- using (Pen pen = new Pen(Color, penWidth))
- {
- pen.DashStyle = DashStyle;
- pen.StartCap = LineCap.Square;
- pen.EndCap = LineCap.Square;
- if (pen.DashStyle != DashStyle.Solid)
- {
- float patternWidth = 0;
- foreach (float w in pen.DashPattern)
- patternWidth += w * pen.Width;
- if (y == y1)
- pen.DashOffset = (x - ((int)(x / patternWidth)) * patternWidth) / pen.Width;
- else
- pen.DashOffset = (y - ((int)(y / patternWidth)) * patternWidth) / pen.Width;
- }
- if (Style != LineStyle.Double)
- g.DrawLine(pen, x, y, x1, y1);
- else
- {
- // we have to correctly draw inner and outer lines of a double line
- float g1 = gap1 ? pen.Width : 0;
- float g2 = gap2 ? pen.Width : 0;
- float g3 = -g1;
- float g4 = -g2;
- if (reverseGaps)
- {
- g1 = -g1;
- g2 = -g2;
- g3 = -g3;
- g4 = -g4;
- }
- if (x == x1)
- {
- g.DrawLine(pen, x - pen.Width, y + g1, x1 - pen.Width, y1 - g2);
- g.DrawLine(pen, x + pen.Width, y + g3, x1 + pen.Width, y1 - g4);
- }
- else
- {
- g.DrawLine(pen, x + g1, y - pen.Width, x1 - g2, y1 - pen.Width);
- g.DrawLine(pen, x + g3, y + pen.Width, x1 - g4, y1 + pen.Width);
- }
- }
- }
- }
- internal void Serialize(FRWriter writer, string prefix, BorderLine c)
- {
- if (Color != c.Color)
- writer.WriteValue(prefix + ".Color", Color);
- if (Style != c.Style)
- writer.WriteValue(prefix + ".Style", Style);
- if (Width != c.Width)
- writer.WriteFloat(prefix + ".Width", Width);
- }
- public BorderLine()
- {
- color = Color.Black;
- width = 1;
- }
- #endregion
- }
- /// <summary>
- /// Represents a border around the report object.
- /// </summary>
- /// <remarks>
- /// Border consists of four lines. Each line has own color, style and width. Lines are accessible through
- /// <see cref="LeftLine"/>, <see cref="RightLine"/>, <see cref="TopLine"/>, <see cref="BottomLine"/> properties.
- /// <para/>
- /// To turn on and off the lines, use the <see cref="Lines"/> property. To set the same color, style or width
- /// for each line, use <see cref="Color"/>, <see cref="Style"/>, <see cref="Width"/> properties of the <b>Border</b>.
- /// </remarks>
- [TypeConverter(typeof(FastReport.TypeConverters.FRExpandableObjectConverter))]
- [Editor("FastReport.TypeEditors.BorderEditor, FastReport", typeof(UITypeEditor))]
- public class Border
- {
- #region Fields
- private bool shadow;
- private float shadowWidth;
- private Color shadowColor;
- private BorderLines lines;
- private BorderLine leftLine;
- private BorderLine topLine;
- private BorderLine rightLine;
- private BorderLine bottomLine;
- private bool simpleBorder;
- #endregion
- #region Properties
- /// <summary>
- /// Gets or sets a color of the border.
- /// </summary>
- /// <remarks>
- /// This property actually returns a color of the <see cref="LeftLine"/>. When you assign a value
- /// to this property, the value will be set to each border line.
- /// </remarks>
- [Editor("FastReport.TypeEditors.ColorEditor, FastReport", typeof(UITypeEditor))]
- public Color Color
- {
- get { return leftLine.Color; }
- set
- {
- leftLine.Color = value;
- rightLine.Color = value;
- topLine.Color = value;
- bottomLine.Color = value;
- }
- }
- /// <summary>
- /// Gets or sets a value determines whether to draw a shadow.
- /// </summary>
- [DefaultValue(false)]
- public bool Shadow
- {
- get { return shadow; }
- set { shadow = value; }
- }
- /// <summary>
- /// Gets or sets a shadow width, in pixels.
- /// </summary>
- [DefaultValue(4f)]
- public float ShadowWidth
- {
- get { return shadowWidth; }
- set { shadowWidth = value; }
- }
- /// <summary>
- /// Gets or sets a shadow color.
- /// </summary>
- [Editor("FastReport.TypeEditors.ColorEditor, FastReport", typeof(UITypeEditor))]
- public Color ShadowColor
- {
- get { return shadowColor; }
- set { shadowColor = value; }
- }
- /// <summary>
- /// Gets or sets a style of the border.
- /// </summary>
- /// <remarks>
- /// This property actually returns a style of the <see cref="LeftLine"/>. When you assign a value
- /// to this property, the value will be set to each border line.
- /// </remarks>
- [DefaultValue(LineStyle.Solid)]
- [Editor("FastReport.TypeEditors.LineStyleEditor, FastReport", typeof(UITypeEditor))]
- public LineStyle Style
- {
- get { return leftLine.Style; }
- set
- {
- leftLine.Style = value;
- rightLine.Style = value;
- topLine.Style = value;
- bottomLine.Style = value;
- }
- }
- /// <summary>
- /// Gets or sets a visible lines of a border.
- /// </summary>
- [DefaultValue(BorderLines.None)]
- [Editor("FastReport.TypeEditors.BorderLinesEditor, FastReport", typeof(UITypeEditor))]
- public BorderLines Lines
- {
- get { return lines; }
- set { lines = value; }
- }
- /// <summary>
- /// Gets or sets a width of the border, in pixels.
- /// </summary>
- /// <remarks>
- /// This property actually returns a width of the <see cref="LeftLine"/>. When you assign a value
- /// to this property, the value will be set to each border line.
- /// </remarks>
- [DefaultValue(1f)]
- public float Width
- {
- get { return leftLine.Width; }
- set
- {
- leftLine.Width = value;
- rightLine.Width = value;
- topLine.Width = value;
- bottomLine.Width = value;
- }
- }
- /// <summary>
- /// Gets or sets the left line of the border.
- /// </summary>
- public BorderLine LeftLine
- {
- get { return leftLine; }
- set { leftLine = value; }
- }
- /// <summary>
- /// Gets or sets the top line of the border.
- /// </summary>
- public BorderLine TopLine
- {
- get { return topLine; }
- set { topLine = value; }
- }
- /// <summary>
- /// Gets or sets the right line of the border.
- /// </summary>
- public BorderLine RightLine
- {
- get { return rightLine; }
- set { rightLine = value; }
- }
- /// <summary>
- /// Gets or sets the bottom line of the border.
- /// </summary>
- public BorderLine BottomLine
- {
- get { return bottomLine; }
- set { bottomLine = value; }
- }
- /// <summary>
- /// Gets or sets a value determines that <b>Border</b> must serialize only one line.
- /// </summary>
- /// <remarks>
- /// This property is for internal use only.
- /// </remarks>
- [Browsable(false)]
- public bool SimpleBorder
- {
- get { return simpleBorder; }
- set { simpleBorder = value; }
- }
- internal DashStyle DashStyle
- {
- get { return leftLine.DashStyle; }
- }
- #endregion
- #region Private Methods
- private bool ShouldSerializeLeftLine()
- {
- return LeftLine.ShouldSerialize();
- }
- private bool ShouldSerializeTopLine()
- {
- return TopLine.ShouldSerialize();
- }
- private bool ShouldSerializeRightLine()
- {
- return RightLine.ShouldSerialize();
- }
- private bool ShouldSerializeBottomLine()
- {
- return BottomLine.ShouldSerialize();
- }
- private bool ShouldSerializeColor()
- {
- return Color != Color.Black;
- }
- private bool ShouldSerializeShadowColor()
- {
- return ShadowColor != Color.Black;
- }
- #endregion
- #region Internal Methods
- internal void ZoomBorder(float zoom)
- {
- LeftLine.Width *= zoom;
- if (leftLine.Width > 0 && leftLine.Width < 1)
- LeftLine.Width = 1;
- RightLine.Width *= zoom;
- if (rightLine.Width > 0 && rightLine.Width < 1)
- RightLine.Width = 1;
- TopLine.Width *= zoom;
- if (topLine.Width > 0 && topLine.Width < 1)
- TopLine.Width = 1;
- BottomLine.Width *= zoom;
- if (bottomLine.Width > 0 && bottomLine.Width < 1)
- BottomLine.Width = 1;
- }
- #endregion
- #region Public Methods
- /// <summary>
- /// Creates the exact copy of this <b>Border</b>.
- /// </summary>
- /// <returns>A copy of this border.</returns>
- public Border Clone()
- {
- Border result = new Border(this);
- return result;
- }
- /// <inheritdoc/>
- public override bool Equals(object obj)
- {
- Border b = obj as Border;
- return b != null && Lines == b.Lines &&
- LeftLine.Equals(b.LeftLine) && TopLine.Equals(b.TopLine) &&
- RightLine.Equals(b.RightLine) && BottomLine.Equals(b.BottomLine) &&
- Shadow == b.Shadow && ShadowColor == b.ShadowColor && ShadowWidth == b.ShadowWidth;
- }
- /// <inheritdoc/>
- public override int GetHashCode()
- {
- return Lines.GetHashCode() ^ (Shadow.GetHashCode() + 16) ^ ShadowColor.GetHashCode() ^
- (ShadowWidth.GetHashCode() + 32) ^ (LeftLine.GetHashCode() << 1) ^ (TopLine.GetHashCode() << 2) ^
- (RightLine.GetHashCode() << 3) ^ (BottomLine.GetHashCode() << 4);
- }
- /// <summary>
- /// Serializes the border.
- /// </summary>
- /// <param name="writer">Writer object.</param>
- /// <param name="prefix">Border property name.</param>
- /// <param name="c">Another Border to compare with.</param>
- /// <remarks>
- /// This method is for internal use only.
- /// </remarks>
- public void Serialize(FRWriter writer, string prefix, Border c)
- {
- if (Shadow != c.Shadow)
- writer.WriteBool(prefix + ".Shadow", Shadow);
- if (ShadowWidth != c.ShadowWidth)
- writer.WriteFloat(prefix + ".ShadowWidth", ShadowWidth);
- if (ShadowColor != c.ShadowColor)
- writer.WriteValue(prefix + ".ShadowColor", ShadowColor);
- if (!SimpleBorder)
- {
- if (Lines != c.Lines)
- writer.WriteValue(prefix + ".Lines", Lines);
- if (Lines != BorderLines.None || Color != Color.Black)
- {
- if (LeftLine.Equals(RightLine) && LeftLine.Equals(TopLine) && LeftLine.Equals(BottomLine) &&
- c.LeftLine.Equals(c.RightLine) && c.LeftLine.Equals(c.TopLine) && c.LeftLine.Equals(c.BottomLine))
- LeftLine.Serialize(writer, prefix, c.LeftLine);
- else
- {
- LeftLine.Serialize(writer, prefix + ".LeftLine", c.LeftLine);
- TopLine.Serialize(writer, prefix + ".TopLine", c.TopLine);
- RightLine.Serialize(writer, prefix + ".RightLine", c.RightLine);
- BottomLine.Serialize(writer, prefix + ".BottomLine", c.BottomLine);
- }
- }
- }
- else
- LeftLine.Serialize(writer, prefix, c.LeftLine);
- }
- /// <summary>
- /// Draw the border using draw event arguments and specified bounding rectangle.
- /// </summary>
- /// <param name="e">Draw event arguments.</param>
- /// <param name="rect">Bounding rectangle.</param>
- /// <remarks>
- /// This method is for internal use only.
- /// </remarks>
- public void Draw(FRPaintEventArgs e, RectangleF rect)
- {
- IGraphics g = e.Graphics;
- rect.X *= e.ScaleX;
- rect.Y *= e.ScaleY;
- rect.Width *= e.ScaleX;
- rect.Height *= e.ScaleY;
- if (Shadow)
- {
- //int d = (int)Math.Round(ShadowWidth * e.ScaleX);
- //Pen pen = e.Cache.GetPen(ShadowColor, d, DashStyle.Solid);
- //g.DrawLine(pen, rect.Right + d / 2, rect.Top + d, rect.Right + d / 2, rect.Bottom);
- //g.DrawLine(pen, rect.Left + d, rect.Bottom + d / 2, rect.Right + d, rect.Bottom + d / 2);
- float d = ShadowWidth * e.ScaleX;
- Brush brush = e.Cache.GetBrush(ShadowColor);
- g.FillRectangle(brush, rect.Left + d, rect.Bottom, rect.Width, d);
- g.FillRectangle(brush, rect.Right, rect.Top + d, d, rect.Height);
- }
- if (Lines != BorderLines.None)
- {
- // draw full frame as a rectangle with solid line only. Non-solid lines
- // should be drawn separately to avoid overlapping effect
- if (Lines == BorderLines.All && LeftLine.Equals(TopLine) && LeftLine.Equals(RightLine) &&
- LeftLine.Equals(BottomLine) && LeftLine.Style == LineStyle.Solid)
- {
- Pen pen = e.Cache.GetPen(LeftLine.Color, (int)Math.Round(LeftLine.Width * e.ScaleX), LeftLine.DashStyle);
- g.DrawRectangle(pen, rect.Left, rect.Top, rect.Width, rect.Height);
- }
- else
- {
- if ((Lines & BorderLines.Left) != 0)
- LeftLine.Draw(e, rect.Left, rect.Top, rect.Left, rect.Bottom,
- true, (Lines & BorderLines.Top) != 0, (Lines & BorderLines.Bottom) != 0);
- if ((Lines & BorderLines.Right) != 0)
- RightLine.Draw(e, rect.Right, rect.Top, rect.Right, rect.Bottom,
- false, (Lines & BorderLines.Top) != 0, (Lines & BorderLines.Bottom) != 0);
- if ((Lines & BorderLines.Top) != 0)
- TopLine.Draw(e, rect.Left, rect.Top, rect.Right, rect.Top,
- true, (Lines & BorderLines.Left) != 0, (Lines & BorderLines.Right) != 0);
- if ((Lines & BorderLines.Bottom) != 0)
- BottomLine.Draw(e, rect.Left, rect.Bottom, rect.Right, rect.Bottom,
- false, (Lines & BorderLines.Left) != 0, (Lines & BorderLines.Right) != 0);
- }
- }
- }
- #endregion
- /// <summary>
- /// Initializes a new instance of the <see cref="Border"/> class with default settings.
- /// </summary>
- public Border()
- {
- leftLine = new BorderLine();
- topLine = new BorderLine();
- rightLine = new BorderLine();
- bottomLine = new BorderLine();
- shadowWidth = 4;
- shadowColor = Color.Black;
- }
- private Border(Border src)
- {
- lines = src.Lines;
- shadow = src.Shadow;
- shadowColor = src.ShadowColor;
- shadowWidth = src.ShadowWidth;
- leftLine = src.LeftLine.Clone();
- topLine = src.TopLine.Clone();
- rightLine = src.RightLine.Clone();
- bottomLine = src.BottomLine.Clone();
- //Fix 1513
- //Width = src.Width;
- //1513
- }
- }
- }
|