<commit_before>// ********************************************************************************************************
// Product Name: DotSpatial.Symbology.dll
// Description:  Contains the business logic for symbology layers and symbol categories.
// ********************************************************************************************************
// The contents of this file are subject to the MIT License (MIT)
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
// http://dotspatial.codeplex.com/license
//
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
// ANY KIND, either expressed or implied. See the License for the specific language governing rights and
// limitations under the License.
//
// The Original Code is from MapWindow.dll version 6.0
//
// The Initial Developer of this Original Code is <NAME>. Created 4/28/2009 2:18:29 PM
//
// Contributor(s): (Open source contributors should list themselves and their modifications here).
//
// ********************************************************************************************************

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using DotSpatial.Data;
using DotSpatial.Serialization;
using DotSpatial.Topology;
using Point = System.Drawing.Point;

namespace DotSpatial.Symbology
{
    /// <summary>
    /// LineSymbolizer
    /// </summary>
    [Serializable]
    public class LineSymbolizer : FeatureSymbolizer, ILineSymbolizer
    {
        #region Private Variables

        private IList<IStroke> _strokes;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new instance of LineSymbolizer
        /// </summary>
        public LineSymbolizer()
        {
            _strokes = new CopyList<IStroke> { new SimpleStroke() };
        }

        /// <summary>
        /// Creates a new set of cartographic lines that together form a line with a border.  Since a compound
        /// pen is used, it is possible to use this to create a transparent line with just two border parts.
        /// </summary>
        /// <param name="fillColor">The fill color for the line</param>
        /// <param name="borderColor">The border color of the line</param>
        /// <param name="width">The width of the entire line</param>
        /// <param name="dash">The dash pattern to use</param>
        /// <param name="caps">The style of the start and end caps</param>
        public LineSymbolizer(Color fillColor, Color borderColor, double width, DashStyle dash, LineCap caps)
        {
            _strokes = new CopyList<IStroke>();
            ICartographicStroke bs = new CartographicStroke(borderColor)
                                         {
                                             Width = width,
                                             StartCap = caps,
                                             EndCap = caps,
                                             DashStyle = dash,
                                         };
            _strokes.Add(bs);

            ICartographicStroke cs = new CartographicStroke(fillColor)
                                         {
                                             StartCap = caps,
                                             EndCap = caps,
                                             DashStyle = dash,
                                             Width = width - 2,
                                         };
            _strokes.Add(cs);
        }

        /// <summary>
        /// Creates a new instance of a LineSymbolizer using the various strokes to form a
        /// composit symbol.
        /// </summary>
        /// <param name="strokes"></param>
        public LineSymbolizer(IEnumerable<IStroke> strokes)
        {
            _strokes = new CopyList<IStroke>();
            foreach (var stroke in strokes)
            {
                _strokes.Add(stroke);
            }
        }

        /// <summary>
        /// Creates a new instance of LineSymbolizer for handling selections.
        /// </summary>
        /// <param name="selected">Boolean, true if this should be symbolized like a selected line.</param>
        public LineSymbolizer(bool selected)
        {
            _strokes = new CopyList<IStroke> { selected ? new CartographicStroke(Color.Cyan) : new CartographicStroke() };
        }

        /// <summary>
        /// Creates a new LineSymbolizer with a single layer with the specified color and width.
        /// </summary>
        /// <param name="color">The color</param>
        /// <param name="width">The line width</param>
        public LineSymbolizer(Color color, double width)
        {
            _strokes = new CopyList<IStroke> { new SimpleStroke(width, color) };
        }

        /// <summary>
        /// Creates a line symbolizer that has a width that is scaled in proportion to the specified envelope as 1/100th of the
        /// width of the envelope.
        /// </summary>
        /// <param name="env"></param>
        /// <param name="selected"></param>
        public LineSymbolizer(IEnvelope env, bool selected)
        {
            _strokes = new CopyList<IStroke>();
            ICartographicStroke myStroke = new CartographicStroke();
            if (selected) myStroke.Color = Color.Cyan;
            myStroke.Width = 1;
            _strokes.Add(myStroke);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Draws a line instead of a rectangle
        /// </summary>
        /// <param name="g"></param>
        /// <param name="target"></param>
        public override void Draw(Graphics g, Rectangle target)
        {
            foreach (var stroke in _strokes)
            {
                using(var p = stroke.ToPen(1))
                    g.DrawLine(p, new Point(target.X, target.Y + target.Height / 2), new Point(target.Right, target.Y + target.Height / 2));
            }
        }

        /// <summary>
        /// Sequentially draws all of the strokes using the specified graphics path.
        /// </summary>
        /// <param name="g">The graphics device to draw to</param>
        /// <param name="gp">The graphics path that describes the pathway to draw</param>
        /// <param name="scaleWidth">The double scale width that when multiplied by the width gives a measure in pixels</param>
        public virtual void DrawPath(Graphics g, GraphicsPath gp, double scaleWidth)
        {
            foreach (var stroke in _strokes)
            {
                using(var p = stroke.ToPen(scaleWidth))
                    g.DrawPath(p, gp);
            }
        }

        /// <summary>
        /// Gets  the color of the top-most stroke.
        /// </summary><commit_msg>added LineSymbolizer constructor with 2 LineCaps<commit_after>// ********************************************************************************************************
// Product Name: DotSpatial.Symbology.dll
// Description:  Contains the business logic for symbology layers and symbol categories.
// ********************************************************************************************************
// The contents of this file are subject to the MIT License (MIT)
// you may not use this file except in compliance with the License. You may obtain a copy of the License at
// http://dotspatial.codeplex.com/license
//
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
// ANY KIND, either expressed or implied. See the License for the specific language governing rights and
// limitations under the License.
//
// The Original Code is from MapWindow.dll version 6.0
//
// The Initial Developer of this Original Code is <NAME>. Created 4/28/2009 2:18:29 PM
//
// Contributor(s): (Open source contributors should list themselves and their modifications here).
//
// ********************************************************************************************************

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using DotSpatial.Data;
using DotSpatial.Serialization;
using DotSpatial.Topology;
using Point = System.Drawing.Point;

namespace DotSpatial.Symbology
{
    /// <summary>
    /// LineSymbolizer
    /// </summary>
    [Serializable]
    public class LineSymbolizer : FeatureSymbolizer, ILineSymbolizer
    {
        #region Private Variables

        private IList<IStroke> _strokes;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new instance of LineSymbolizer
        /// </summary>
        public LineSymbolizer()
        {
            _strokes = new CopyList<IStroke> { new SimpleStroke() };
        }

        /// <summary>
        /// Creates a new set of cartographic lines that together form a line with a border.  Since a compound
        /// pen is used, it is possible to use this to create a transparent line with just two border parts.
        /// </summary>
        /// <param name="fillColor">The fill color for the line</param>
        /// <param name="borderColor">The border color of the line</param>
        /// <param name="width">The width of the entire line</param>
        /// <param name="dash">The dash pattern to use</param>
        /// <param name="caps">The style of the start and end caps</param>
        public LineSymbolizer(Color fillColor, Color borderColor, double width, DashStyle dash, LineCap caps)
            : this(fillColor, borderColor, width, dash, caps, caps) { }

        /// <summary>
        /// Creates a new set of cartographic lines that together form a line with a border.  Since a compound
        /// pen is used, it is possible to use this to create a transparent line with just two border parts.
        /// </summary>
        /// <param name="fillColor">The fill color for the line</param>
        /// <param name="borderColor">The border color of the line</param>
        /// <param name="width">The width of the entire line</param>
        /// <param name="dash">The dash pattern to use</param>
        /// <param name="startCap">The style of the start cap</param>
        /// <param name="endCap">The style of the end cap</param>
        public LineSymbolizer(Color fillColor, Color borderColor, double width, DashStyle dash, LineCap startCap, LineCap endCap)
        {
            _strokes = new CopyList<IStroke>();
            ICartographicStroke bs = new CartographicStroke(borderColor)
                                         {
                                             Width = width,
                                             StartCap = startCap,
                                             EndCap = endCap,
                                             DashStyle = dash,
                                         };
            _strokes.Add(bs);

            ICartographicStroke cs = new CartographicStroke(fillColor)
                                         {
                                             StartCap = startCap,
                                             EndCap = endCap,
                                             DashStyle = dash,
                                             Width = width - 2,
                                         };
            _strokes.Add(cs);
        }

        /// <summary>
        /// Creates a new instance of a LineSymbolizer using the various strokes to form a
        /// composit symbol.
        /// </summary>
        /// <param name="strokes"></param>
        public LineSymbolizer(IEnumerable<IStroke> strokes)
        {
            _strokes = new CopyList<IStroke>();
            foreach (var stroke in strokes)
            {
                _strokes.Add(stroke);
            }
        }

        /// <summary>
        /// Creates a new instance of LineSymbolizer for handling selections.
        /// </summary>
        /// <param name="selected">Boolean, true if this should be symbolized like a selected line.</param>
        public LineSymbolizer(bool selected)
        {
            _strokes = new CopyList<IStroke> { selected ? new CartographicStroke(Color.Cyan) : new CartographicStroke() };
        }

        /// <summary>
        /// Creates a new LineSymbolizer with a single layer with the specified color and width.
        /// </summary>
        /// <param name="color">The color</param>
        /// <param name="width">The line width</param>
        public LineSymbolizer(Color color, double width)
        {
            _strokes = new CopyList<IStroke> { new SimpleStroke(width, color) };
        }

        /// <summary>
        /// Creates a line symbolizer that has a width that is scaled in proportion to the specified envelope as 1/100th of the
        /// width of the envelope.
        /// </summary>
        /// <param name="env"></param>
        /// <param name="selected"></param>
        public LineSymbolizer(IEnvelope env, bool selected)
        {
            _strokes = new CopyList<IStroke>();
            ICartographicStroke myStroke = new CartographicStroke();
            if (selected) myStroke.Color = Color.Cyan;
            myStroke.Width = 1;
            _strokes.Add(myStroke);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Draws a line instead of a rectangle
        /// </summary>
        /// <param name="g"></param>
        /// <param name="target"></param>
        public override void Draw(Graphics g, Rectangle target)
        {
            foreach (var stroke in _strokes)
            {
                using (var p = stroke.ToPen(1))
                    g.DrawLine(p, new Point(target.X, target.Y + target.Height / 2), new Point(target.Right, target.Y + target.Height / 2));
            }
        }

        /// <summary>
        /// Sequentially draws all of the strokes using the specified graphics path.
        /// </summary>
        /// <param name="g">The graphics device to draw to</param>
        /// <param name="gp">The graphics path that describes the pathway to draw</param>
        /// <param name="scaleWidth">The double scale width that when multiplied by the width gives a measure in pixels</param>
        public virtual void DrawPath(Graphics g, GraphicsPath gp, double scaleWidth)
        {
            foreach (var stroke in _strokes)
            {
                using (var p = stroke.ToPen(scaleWidth))
                    g.DrawPath(p, gp);
            }
        }

        /// <summary>
        /// Gets  the color of the top-most stroke.
        /// </summary>
{'fraction_non_alphanumeric': 0.13788187372708757, 'fraction_numerical': 0.0033265444670739987, 'mean_word_length': 1.8000380155863904, 'pattern_counts': {'":': 0, '<': 139, '<?xml version=': 0, '>': 139, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 42, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '517892', 'n_tokens_mistral': 3580, 'n_tokens_neox': 3404, 'n_words': 1213}