Пример #1
0
 public void PlotWaveform()
 {
     ICFunction[] cft = ComplexFunctions;
     if (cft == null) return;
     int nPlots = 0;
     foreach (ICFunction icf in cft) if (icf.Name.Equals("Plot")) nPlots++;
     double[][] x = new double[nPlots][];
     double[][] y = new double[nPlots][];
     Color[] colors = new Color[nPlots];
     ZedGraph.Symbol[] symbols = new ZedGraph.Symbol[nPlots];
     string[] labels = new string[nPlots];
     nPlots = 0;
     for (int i = 0; i < cft.Length; i++)
     {
         CDoubleArray cd = cft[i].Eval();
         if (cft[i].GetType().Name.Equals("Plot"))
         {
             Plot plot = cft[i] as Plot;
             if (cd != null)
             {
                 x[nPlots] = cd.Real;
                 y[nPlots] = cd.Imag;
                 labels[nPlots] = plot.Legend;
                 symbols[nPlots] = GraphSymbol.GetSymbol(plot.SymbolString, plot.LineColor);
                 colors[nPlots] = plot.LineColor;
             }
             nPlots++;
         }
     }
     base.PlotWaveform(x, y, labels.ToArray(), colors, symbols);
 }
Пример #2
0
        public void PlotWaveform()
        {
            ICFunction[] cft = ComplexFunctions;
            if (cft == null)
            {
                return;
            }
            int nPlots = 0;

            foreach (ICFunction icf in cft)
            {
                if (icf.Name.Equals("Plot"))
                {
                    nPlots++;
                }
            }
            double[][]        x       = new double[nPlots][];
            double[][]        y       = new double[nPlots][];
            Color[]           colors  = new Color[nPlots];
            ZedGraph.Symbol[] symbols = new ZedGraph.Symbol[nPlots];
            string[]          labels  = new string[nPlots];
            nPlots = 0;
            for (int i = 0; i < cft.Length; i++)
            {
                CDoubleArray cd = cft[i].Eval();
                if (cft[i].GetType().Name.Equals("Plot"))
                {
                    Plot plot = cft[i] as Plot;
                    if (cd != null)
                    {
                        x[nPlots]       = cd.Real;
                        y[nPlots]       = cd.Imag;
                        labels[nPlots]  = plot.Legend;
                        symbols[nPlots] = GraphSymbol.GetSymbol(plot.SymbolString, plot.LineColor);
                        colors[nPlots]  = plot.LineColor;
                    }
                    nPlots++;
                }
            }
            base.PlotWaveform(x, y, labels.ToArray(), colors, symbols);
        }
Пример #3
0
 public static Symbol GetSymbol(string s, Color color)
 {
     if (s.Equals("None")) return new Symbol(SymbolType.None, color);
     Dictionary<string, GraphicsPath> symbols = UserSymbols;
     if (symbols.ContainsKey(s))
     {
         Symbol ret = new Symbol(SymbolType.UserDefined, color);
         ret.UserSymbol = symbols[s];
         return ret;
     }
     if (s.Equals("Square")) return new Symbol(SymbolType.Square, color);
     if (s.Equals("Circle")) return new Symbol(SymbolType.Circle, color);
     if (s.Equals("Diamond")) return new Symbol(SymbolType.Diamond, color);
     if (s.Equals("HDash")) return new Symbol(SymbolType.HDash, color);
     if (s.Equals("Plus")) return new Symbol(SymbolType.Plus, color);
     if (s.Equals("Star")) return new Symbol(SymbolType.Star, color);
     if (s.Equals("Triangle")) return new Symbol(SymbolType.Triangle, color);
     if (s.Equals("TriangleDown")) return new Symbol(SymbolType.TriangleDown, color);
     if (s.Equals("UserDefined")) return new Symbol(SymbolType.UserDefined, color);
     if (s.Equals("VDash")) return new Symbol(SymbolType.VDash, color);
     if (s.Equals("XCross")) return new Symbol(SymbolType.XCross, color);
     return new Symbol(SymbolType.Default, color);
 }
Пример #4
0
		/// <summary>
		/// Create a new <see cref="LineItem"/>, specifying only the legend <see cref="CurveItem.Label" />.
		/// </summary>
		/// <param name="label">The _label that will appear in the legend.</param>
		public LineItem(string label) : base(label)
		{
			_symbol = new Symbol();
			_line = new Line();
		}
Пример #5
0
 /// <summary>
 /// Default constructor that sets the
 /// <see cref="Color"/> as specified, and the remaining
 /// <see cref="ErrorBar"/> properties to default
 /// values as defined in the <see cref="Default"/> class.
 /// </summary>
 /// <param name="color">A <see cref="Color"/> value indicating
 /// the color of the symbol
 /// </param>
 public ErrorBar( Color color )
 {
     this.symbol = new Symbol( Default.Type, color );
     this.symbol.Size = Default.Size;
     this.color = color;
     this.penWidth = Default.PenWidth;
     this.isVisible = Default.IsVisible;
 }
Пример #6
0
 /// <summary>
 /// The Copy Constructor
 /// </summary>
 /// <param name="rhs">The <see cref="ErrorBar"/> object from which to copy</param>
 public ErrorBar( ErrorBar rhs )
 {
     color = rhs.Color;
     isVisible = rhs.IsVisible;
     penWidth = rhs.PenWidth;
     this.symbol = (Symbol) rhs.Symbol.Clone();
 }
Пример #7
0
 /// <summary>
 /// The Copy Constructor
 /// </summary>
 /// <param name="rhs">The Symbol object from which to copy</param>
 public Symbol( Symbol rhs )
 {
     _size = rhs.Size;
     _type = rhs.Type;
     _isAntiAlias = rhs._isAntiAlias;
     _isVisible = rhs.IsVisible;
     _fill = rhs.Fill.Clone();
     _border = rhs.Border.Clone();
 }
Пример #8
0
 /// <summary>
 /// Create a new <see cref="LineItem"/>, specifying only the legend label for the bar.
 /// </summary>
 /// <param name="label">The label that will appear in the legend.</param>
 public LineItem( string label )
     : base(label)
 {
     this.symbol = new Symbol();
     this.line = new Line();
 }
Пример #9
0
		/// <summary>
		/// Constructor for deserializing objects
		/// </summary>
		/// <param name="info">A <see cref="SerializationInfo"/> instance that defines the serialized data
		/// </param>
		/// <param name="context">A <see cref="StreamingContext"/> instance that contains the serialized data
		/// </param>
		protected ErrorBar( SerializationInfo info, StreamingContext context )
		{
			// The schema value is just a file version parameter.  You can use it to make future versions
			// backwards compatible as new member variables are added to classes
			int sch = info.GetInt32( "schema" );

			_isVisible = info.GetBoolean( "isVisible" );
			_color = (Color) info.GetValue( "color", typeof(Color) );
			_penWidth = info.GetSingle( "penWidth" );
			_symbol = (Symbol) info.GetValue( "symbol", typeof(Symbol) );
		}
Пример #10
0
		/// <summary>
		/// Default constructor that sets the
		/// <see cref="Color"/> as specified, and the remaining
		/// <see cref="ErrorBar"/> properties to default
		/// values as defined in the <see cref="Default"/> class.
		/// </summary>
		/// <param name="color">A <see cref="Color"/> value indicating
		/// the color of the symbol
		/// </param>
		public ErrorBar( Color color )
		{
			_symbol = new Symbol( Default.Type, color );
			_symbol.Size = Default.Size;
			_color = color;
			_penWidth = Default.PenWidth;
			_isVisible = Default.IsVisible;
		}
Пример #11
0
        public void PlotWaveform(double[] X, double[] Y, Color color, string label, Symbol symbol)
        {
            if (X == null || X.Length < 1 || Y == null || X.Length != Y.Length) return;

            if (symbol == null) symbol = new Symbol(SymbolType.None, color);
            float lineWidth = (float)mLineWidth;

            // If way too many samples, decimate it down.
            if (X.Length > MaxSamples)
            {
                decimation = X.Length / MaxSamples;
                double[] temp = new double[X.Length / decimation];
                for (int i = 0; i < temp.Length; i++)
                    temp[i] = X[i * decimation];
                X = temp;
                temp = new double[Y.Length / decimation];
                for (int i = 0; i < temp.Length; i++)
                    temp[i] = Y[i * decimation];
                Y = temp;
            }
            else
                decimation = 1;

            if (!ShowLegend) label = "";
            LineItem li = new LineItem(label, X, Y, color, SymbolType.UserDefined, lineWidth);
            li.Symbol = symbol;

            AddCurve(li);
        }
Пример #12
0
 public void PlotWaveform(double[][] X, double[][] Y, string[] labels = null, Color[] colors = null, Symbol[] symbols = null)
 {
     if (X.Length < 1 || Y.Length < 1) return;
     Clear();
     for (int i = 0; i < Math.Max(X.Length, Y.Length); i++)
     {
         double[] x = X[0];
         if (i < X.Length) x = X[i];
         double[] y = Y[0];
         if (i < Y.Length) y = Y[i];
         Color color = ColorList[i % ColorList.Length];
         if (colors != null && colors.Length > i && colors[i] != Plot.DefaultColor) color = colors[i];
         string label = " ";
         if (labels != null && labels.Length > i) label = labels[i];
         Symbol s = new Symbol(SymbolType.None, color);
         if (symbols != null && symbols.Length > i) s = symbols[i];
         double sc = 1, os = 0;
         y = scaleYAxis(y, i,out sc, out os);
         if (EnableScaling)
             label += "  [*" + sc + "+" + os + "]";
         PlotWaveform(x, y, color,label, s);
     }
     DisplayCurves();
 }
Пример #13
0
 /// <summary>
 /// Local dispose method
 /// </summary>
 /// <param name="bDisposing">if disposing is required</param>
 protected virtual void Dispose(bool bDisposing)
 {
     if (!m_bDisposed)
     {
         if (bDisposing)
         {
             if (_symbol != null)
             {
                 _symbol.Dispose();
                 _symbol = null;
             }
         }
         m_bDisposed = true;
     }
 }
Пример #14
0
        private void DrawPoints(GraphPane pane, int maxX, int maxY, LineItem curve, IPointList points, IGraphics g, Symbol source, float scaleFactor, int minX, int minY, bool[,] isPixelDrawn)
        {
            double curX;
            double curY;
            int tmpX;
            int tmpY;
            double lowVal;
            if ( points != null && ( _border.IsVisible || _fill.IsVisible ) )
            {
                SmoothingMode sModeSave = g.SmoothingMode;
                if ( _isAntiAlias )
                    g.SmoothingMode = SmoothingMode.HighQuality;

                // For the sake of speed, go ahead and create a solid brush and a pen
                // If it's a gradient fill, it will be created on the fly for each symbol
                //SolidBrush	brush = new SolidBrush( this.fill.Color );

                using ( Pen pen = source._border.GetPen( pane, scaleFactor ) )
                using ( GraphicsPath path = MakePath( g, scaleFactor ) )
                {
                    RectangleF rect = path.GetBounds();

                    using ( Brush brush = source.Fill.MakeBrush( rect ) )
                    {
                        ValueHandler valueHandler = new ValueHandler( pane, false );
                        Scale xScale = curve.GetXAxis( pane ).Scale;
                        Scale yScale = curve.GetYAxis( pane ).Scale;

                        bool xIsLog = xScale.IsLog;
                        bool yIsLog = yScale.IsLog;
                        bool xIsOrdinal = xScale.IsAnyOrdinal;

                        double xMin = xScale.Min;
                        double xMax = xScale.Max;

                        // Loop over each defined point
                        for ( int i = 0; i < points.Count; i++ )
                        {
                            // Check that this symbol should be shown, if not, then continue to the next symbol
                            if(!points[i].ShowSymbol)
                            {
                                continue;
                            }

                            // Get the user scale values for the current point
                            // use the valueHandler only for stacked types
                            if ( pane.LineType == LineType.Stack )
                            {
                                valueHandler.GetValues( curve, i, out curX, out lowVal, out curY );
                            }
                                // otherwise, just access the values directly.  Avoiding the valueHandler for
                                // non-stacked types is an optimization to minimize overhead in case there are
                                // a large number of points.
                            else
                            {
                                curX = points[i].X;
                                if ( curve is StickItem )
                                    curY = points[i].Z;
                                else
                                    curY = points[i].Y;
                            }

                            // Any value set to double max is invalid and should be skipped
                            // This is used for calculated values that are out of range, divide
                            //   by zero, etc.
                            // Also, any value <= zero on a log scale is invalid

                            if ( curX != PointPair.Missing &&
                                 curY != PointPair.Missing &&
                                 !System.Double.IsNaN( curX ) &&
                                 !System.Double.IsNaN( curY ) &&
                                 !System.Double.IsInfinity( curX ) &&
                                 !System.Double.IsInfinity( curY ) &&
                                 ( curX > 0 || !xIsLog ) &&
                                 ( !yIsLog || curY > 0.0 ) &&
                                 ( xIsOrdinal || ( curX >= xMin && curX <= xMax ) ) )
                            {
                                // Transform the user scale values to pixel locations
                                tmpX = (int) xScale.Transform( curve.IsOverrideOrdinal, i, curX );
                                tmpY = (int) yScale.Transform( curve.IsOverrideOrdinal, i, curY );

                                // Maintain an array of "used" pixel locations to avoid duplicate drawing operations
                                if ( tmpX >= minX && tmpX <= maxX && tmpY >= minY && tmpY <= maxY ) // guard against the zoom-in case
                                {
                                    if ( isPixelDrawn[tmpX, tmpY] )
                                        continue;
                                    isPixelDrawn[tmpX, tmpY] = true;
                                }

                                // If the fill type for this symbol is a Gradient by value type,
                                // the make a brush corresponding to the appropriate current value
                                if ( _fill.IsGradientValueType || _border._gradientFill.IsGradientValueType )
                                {
                                    using ( Brush tBrush = _fill.MakeBrush( rect, points[i] ) )
                                    using ( Pen tPen = _border.GetPen( pane, scaleFactor, points[i] ) )
                                        this.DrawSymbol( g, tmpX, tmpY, path, tPen, tBrush );
                                }
                                else
                                {
                                    // Otherwise, the brush is already defined
                                    // Draw the symbol at the specified pixel location
                                    this.DrawSymbol( g, tmpX, tmpY, path, pen, brush );
                                }
                            }
                        }
                    }
                }

                g.SmoothingMode = sModeSave;
            }
        }
Пример #15
0
		/// <summary>
		/// Create a new <see cref="LineItem"/> using the specified properties.
		/// </summary>
		/// <param name="label">The _label that will appear in the legend.</param>
		/// <param name="points">A <see cref="IPointList"/> of double precision value pairs that define
		/// the X and Y values for this curve</param>
		/// <param name="color">A <see cref="Color"/> value that will be applied to
		/// the <see cref="Line"/> and <see cref="Symbol"/> properties.
		/// </param>
		/// <param name="symbolType">A <see cref="SymbolType"/> enum specifying the
		/// type of symbol to use for this <see cref="LineItem"/>.  Use <see cref="SymbolType.None"/>
		/// to hide the symbols.</param>
		/// <param name="lineWidth">The width (in points) to be used for the <see cref="Line"/>.  This
		/// width is scaled based on <see cref="PaneBase.CalcScaleFactor"/>.  Use a value of zero to
		/// hide the line (see <see cref="ZedGraph.LineBase.IsVisible"/>).</param>
		public LineItem(string label, IPointList points, Color color, SymbolType symbolType, float lineWidth)
			: base(label, points)
		{
			_line = new Line(color);
			if (lineWidth == 0)
				_line.IsVisible = false;
			else
				_line.Width = lineWidth;

			_symbol = new Symbol(symbolType, color);
		}
Пример #16
0
 /// <summary>
 /// The Copy Constructor
 /// </summary>
 /// <param name="rhs">The Symbol object from which to copy</param>
 public Symbol( Symbol rhs )
 {
     size = rhs.Size;
     type = rhs.Type;
     isVisible = rhs.IsVisible;
     fill = (Fill) rhs.Fill.Clone();
     border = (Border) rhs.Border.Clone();
 }
Пример #17
0
		/// <summary>
		/// Constructor for deserializing objects
		/// </summary>
		/// <param name="info">A <see cref="SerializationInfo"/> instance that defines the serialized data
		/// </param>
		/// <param name="context">A <see cref="StreamingContext"/> instance that contains the serialized data
		/// </param>
		protected LineItem(SerializationInfo info, StreamingContext context) : base(info, context)
		{
			// The schema value is just a file version parameter.  You can use it to make future versions
			// backwards compatible as new member variables are added to classes
			int sch = info.GetInt32("schema2");

			_symbol = (Symbol) info.GetValue("symbol", typeof (Symbol));
			_line = (Line) info.GetValue("line", typeof (Line));
		}
Пример #18
0
 /// <summary>
 /// The Copy Constructor
 /// </summary>
 /// <param name="rhs">The <see cref="LineItem"/> object from which to copy</param>
 public FilledLineItem(FilledLineItem rhs)
     : base(rhs)
 {
     _symbol = new Symbol( rhs.Symbol );
     _line = new FilledLine( rhs.FilledLine );
     LowerPoints = rhs.LowerPoints;
 }
Пример #19
0
		/// <summary>
		/// The Copy Constructor
		/// </summary>
		/// <param name="rhs">The <see cref="ErrorBar"/> object from which to copy</param>
		public ErrorBar( ErrorBar rhs )
		{
			_color = rhs.Color;
			_isVisible = rhs.IsVisible;
			_penWidth = rhs.PenWidth;
			_symbol = rhs.Symbol.Clone();
		}
Пример #20
0
        /// <summary>
        /// Create a new <see cref="FilledLineItem"/> using the specified properties.
        /// </summary>
        /// <param name="label">The _label that will appear in the legend.</param>
        /// <param name="upperPoints">A <see cref="IPointList"/> of double precision value pairs that define
        /// the X and upper Y values for this curve</param>
        /// <param name="lowerPoints">A <see cref="IPointList"/> of double precision value pairs that define
        /// the X and lower Y values for this curve</param>
        /// <param name="color">A <see cref="System.Drawing.Color"/> value that will be applied to
        /// the <see cref="Line"/> and <see cref="Symbol"/> properties.
        /// </param>
        /// <param name="symbolType">A <see cref="SymbolType"/> enum specifying the
        /// type of symbol to use for this <see cref="LineItem"/>.  Use <see cref="SymbolType.None"/>
        /// to hide the symbols.</param>
        /// <param name="lineWidth">The width (in points) to be used for the <see cref="Line"/>.  This
        /// width is scaled based on <see cref="PaneBase.CalcScaleFactor"/>.  Use a value of zero to
        /// hide the line (see <see cref="ZedGraph.LineBase.IsVisible"/>).</param>
        public FilledLineItem( string label, IPointList upperPoints, IPointList lowerPoints, System.Drawing.Color color, SymbolType symbolType, float lineWidth )
            : base(label)
        {
            Points = upperPoints ?? new PointPairList();
            LowerPoints = lowerPoints ?? new PointPairList();

            _line = new FilledLine( color );
            if ( lineWidth == 0 )
                _line.IsVisible = false;
            else
                _line.Width = lineWidth;

            _symbol = new Symbol( symbolType, color );
        }
Пример #21
0
 /// <summary>
 /// The Copy Constructor
 /// </summary>
 /// <param name="rhs">The <see cref="LineItem"/> object from which to copy</param>
 public LineItem( LineItem rhs )
     : base(rhs)
 {
     symbol = new Symbol( rhs.Symbol );
     line = new Line( rhs.Line );
 }
Пример #22
0
        /// <summary>
        /// The Copy Constructor
        /// </summary>
        /// <param name="rhs">The Symbol object from which to copy</param>
        public Symbol( Symbol rhs )
        {
            _size = rhs.Size;
            _type = rhs.Type;
            _isAntiAlias = rhs._isAntiAlias;
            _isVisible = rhs.IsVisible;
            _fill = rhs.Fill.Clone();
            _border = rhs.Border.Clone();

            if ( rhs.UserSymbol != null )
                _userSymbol = rhs.UserSymbol.Clone() as GraphicsPath;
            else
                _userSymbol = null;
        }
Пример #23
0
 /// <summary>
 /// Create a new <see cref="LineItem"/> using the specified properties.
 /// </summary>
 /// <param name="label">The label that will appear in the legend.</param>
 /// <param name="points">A <see cref="PointPairList"/> of double precision value pairs that define
 /// the X and Y values for this curve</param>
 /// <param name="color">A <see cref="Color"/> value that will be applied to
 /// the <see cref="Line"/> and <see cref="Symbol"/> properties.
 /// </param>
 /// <param name="symbolType">A <see cref="SymbolType"/> enum specifying the
 /// type of symbol to use for this <see cref="LineItem"/> </param>
 public LineItem( string label, PointPairList points, Color color, SymbolType symbolType )
     : base(label, points)
 {
     line = new Line( color );
     this.symbol = new Symbol( symbolType, color );
 }
Пример #24
0
        private void DrawPoints(GraphPane pane, int maxX, int maxY, LineItem curve, IPointList points, IGraphics g, Symbol source, float scaleFactor, int minX, int minY, bool[,] isPixelDrawn)
        {
            double curX;
            double curY;
            int    tmpX;
            int    tmpY;
            double lowVal;

            if (points != null && (_border.IsVisible || _fill.IsVisible))
            {
                SmoothingMode sModeSave = g.SmoothingMode;
                if (_isAntiAlias)
                {
                    g.SmoothingMode = SmoothingMode.HighQuality;
                }

                // For the sake of speed, go ahead and create a solid brush and a pen
                // If it's a gradient fill, it will be created on the fly for each symbol
                //SolidBrush	brush = new SolidBrush( this.fill.Color );

                using (Pen pen = source._border.GetPen(pane, scaleFactor))
                    using (GraphicsPath path = MakePath(g, scaleFactor))
                    {
                        RectangleF rect = path.GetBounds();

                        using (Brush brush = source.Fill.MakeBrush(rect))
                        {
                            ValueHandler valueHandler = new ValueHandler(pane, false);
                            Scale        xScale       = curve.GetXAxis(pane).Scale;
                            Scale        yScale       = curve.GetYAxis(pane).Scale;

                            bool xIsLog     = xScale.IsLog;
                            bool yIsLog     = yScale.IsLog;
                            bool xIsOrdinal = xScale.IsAnyOrdinal;

                            double xMin = xScale.Min;
                            double xMax = xScale.Max;

                            // Loop over each defined point
                            for (int i = 0; i < points.Count; i++)
                            {
                                // Check that this symbol should be shown, if not, then continue to the next symbol
                                if (!points[i].ShowSymbol)
                                {
                                    continue;
                                }

                                // Get the user scale values for the current point
                                // use the valueHandler only for stacked types
                                if (pane.LineType == LineType.Stack)
                                {
                                    valueHandler.GetValues(curve, i, out curX, out lowVal, out curY);
                                }
                                // otherwise, just access the values directly.  Avoiding the valueHandler for
                                // non-stacked types is an optimization to minimize overhead in case there are
                                // a large number of points.
                                else
                                {
                                    curX = points[i].X;
                                    if (curve is StickItem)
                                    {
                                        curY = points[i].Z;
                                    }
                                    else
                                    {
                                        curY = points[i].Y;
                                    }
                                }

                                // Any value set to double max is invalid and should be skipped
                                // This is used for calculated values that are out of range, divide
                                //   by zero, etc.
                                // Also, any value <= zero on a log scale is invalid

                                if (curX != PointPair.Missing &&
                                    curY != PointPair.Missing &&
                                    !System.Double.IsNaN(curX) &&
                                    !System.Double.IsNaN(curY) &&
                                    !System.Double.IsInfinity(curX) &&
                                    !System.Double.IsInfinity(curY) &&
                                    (curX > 0 || !xIsLog) &&
                                    (!yIsLog || curY > 0.0) &&
                                    (xIsOrdinal || (curX >= xMin && curX <= xMax)))
                                {
                                    // Transform the user scale values to pixel locations
                                    tmpX = (int)xScale.Transform(curve.IsOverrideOrdinal, i, curX);
                                    tmpY = (int)yScale.Transform(curve.IsOverrideOrdinal, i, curY);

                                    // Maintain an array of "used" pixel locations to avoid duplicate drawing operations
                                    if (tmpX >= minX && tmpX <= maxX && tmpY >= minY && tmpY <= maxY)   // guard against the zoom-in case
                                    {
                                        if (isPixelDrawn[tmpX, tmpY])
                                        {
                                            continue;
                                        }
                                        isPixelDrawn[tmpX, tmpY] = true;
                                    }

                                    // If the fill type for this symbol is a Gradient by value type,
                                    // the make a brush corresponding to the appropriate current value
                                    if (_fill.IsGradientValueType || _border._gradientFill.IsGradientValueType)
                                    {
                                        using (Brush tBrush = _fill.MakeBrush(rect, points[i]))
                                            using (Pen tPen = _border.GetPen(pane, scaleFactor, points[i]))
                                                this.DrawSymbol(g, tmpX, tmpY, path, tPen, tBrush);
                                    }
                                    else
                                    {
                                        // Otherwise, the brush is already defined
                                        // Draw the symbol at the specified pixel location
                                        this.DrawSymbol(g, tmpX, tmpY, path, pen, brush);
                                    }
                                }
                            }
                        }
                    }

                g.SmoothingMode = sModeSave;
            }
        }