/// <summary>
        /// Draws line segments defined by points (0,1) (2,3) (4,5) etc.
        /// This should have better performance than calling DrawLine for each segment.
        /// </summary>
        /// <param name="points">The points.</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="thickness">The stroke thickness (in device independent units, 1/96 inch).</param>
        /// <param name="edgeRenderingMode">The edge rendering mode.</param>
        /// <param name="dashArray">The dash array (in device independent units, 1/96 inch).</param>
        /// <param name="lineJoin">The line join type.</param>
        public override void DrawLineSegments(
            IList <ScreenPoint> points,
            OxyColor stroke,
            double thickness,
            EdgeRenderingMode edgeRenderingMode,
            double[] dashArray,
            LineJoin lineJoin)
        {
            if (UseStreamGeometry)
            {
                DrawLineSegmentsByStreamGeometry(points, stroke, thickness, edgeRenderingMode, dashArray, lineJoin);
                return;
            }

            bool aliased = edgeRenderingMode == EdgeRenderingMode.PreferSpeed;

            Path         path         = null;
            PathGeometry pathGeometry = null;

            var count = 0;

            for (int i = 0; i + 1 < points.Count; i += 2)
            {
                if (path == null)
                {
                    path = CreateAndAdd <Path>();
                    SetStroke(path, stroke, thickness, edgeRenderingMode, lineJoin, dashArray, 0);
                    pathGeometry = new PathGeometry();
                }

                var figure = new PathFigure {
                    StartPoint = ToPoint(points[i], aliased), IsClosed = false
                };
                figure.Segments.Add(new LineSegment {
                    Point = ToPoint(points[i + 1], aliased)
                });
                pathGeometry.Figures.Add(figure);

                count++;

                // Must limit the number of figures, otherwise drawing errors...
                if (count > MaxFiguresPerGeometry || dashArray != null)
                {
                    path.Data = pathGeometry;
                    path      = null;
                    count     = 0;
                }
            }

            if (path != null)
            {
                path.Data = pathGeometry;
            }
        }
        ///<inheritdoc/>
        public override void DrawPolygons(
            IList <IList <ScreenPoint> > polygons,
            OxyColor fill,
            OxyColor stroke,
            double thickness,
            EdgeRenderingMode edgeRenderingMode,
            double[] dashArray,
            LineJoin lineJoin)
        {
            if (UseStreamGeometry)
            {
                DrawPolygonsByStreamGeometry(polygons, fill, stroke, thickness, edgeRenderingMode, dashArray, lineJoin);
                return;
            }

            Path         path         = null;
            PathGeometry pathGeometry = null;
            var          count        = 0;

            Func <ScreenPoint, Point> toPointFunc;

            if (edgeRenderingMode == EdgeRenderingMode.PreferSpeed) // aliased
            {
                toPointFunc = ToPixelAlignedPoint;
            }
            else
            {
                toPointFunc = ToPoint;
            }

            bool   isSolid     = !fill.IsUndefined();
            IBrush cachedBrush = null;

            if (isSolid)
            {
                cachedBrush = GetCachedBrush(fill);
            }

            foreach (var polygon in polygons)
            {
                if (path == null)
                {
                    path = CreateAndAdd <Path>();
                    SetStroke(path, stroke, thickness, edgeRenderingMode, lineJoin, dashArray, 0);
                    if (isSolid)
                    {
                        path.Fill = cachedBrush;
                    }

                    pathGeometry = new PathGeometry {
                        FillRule = FillRule.NonZero
                    };
                }

                PathFigure figure = null;
                var        first  = true;
                foreach (var p in polygon)
                {
                    if (first)
                    {
                        figure = new PathFigure
                        {
                            StartPoint = toPointFunc(p),
                            IsFilled   = isSolid,
                            IsClosed   = true
                        };
                        pathGeometry.Figures.Add(figure);

                        first = false;
                    }
                    else
                    {
                        figure.Segments.Add(new LineSegment {
                            Point = toPointFunc(p)
                        });
                    }
                }

                count++;

                // Must limit the number of figures, otherwise drawing errors...
                if (count > MaxFiguresPerGeometry)
                {
                    path.Data = pathGeometry;
                    path      = null;
                    count     = 0;
                }
            }

            if (path != null)
            {
                path.Data = pathGeometry;
            }
        }
        private void DrawPolygonsByStreamGeometry(
            IList <IList <ScreenPoint> > polygons,
            OxyColor fill,
            OxyColor stroke,
            double thickness,
            EdgeRenderingMode edgeRenderingMode,
            double[] dashArray,
            LineJoin lineJoin)
        {
            Path                  path           = null;
            StreamGeometry        streamGeometry = null;
            StreamGeometryContext sgc            = null;
            var count = 0;

            Func <ScreenPoint, Point> toPointFunc;

            if (edgeRenderingMode == EdgeRenderingMode.PreferSpeed) // aliased
            {
                toPointFunc = ToPixelAlignedPoint;
            }
            else
            {
                toPointFunc = ToPoint;
            }

            bool   isSolid     = !fill.IsUndefined();
            IBrush cachedBrush = null;

            if (isSolid)
            {
                cachedBrush = GetCachedBrush(fill);
            }

            foreach (var polygon in polygons)
            {
                if (path == null)
                {
                    path = CreateAndAdd <Path>();
                    SetStroke(path, stroke, thickness, edgeRenderingMode, lineJoin, dashArray, 0);
                    if (isSolid)
                    {
                        path.Fill = cachedBrush;
                    }

                    streamGeometry = new StreamGeometry();
                    sgc            = streamGeometry.Open();
                    sgc.SetFillRule(FillRule.NonZero);
                }

                var first = true;
                foreach (var p in polygon)
                {
                    if (first)
                    {
                        sgc.BeginFigure(toPointFunc(p), isSolid);
                        first = false;
                    }
                    else
                    {
                        sgc.LineTo(toPointFunc(p));
                    }
                }

                sgc.EndFigure(true);

                count++;

                // Must limit the number of figures, otherwise drawing errors...
                if (count > MaxFiguresPerGeometry)
                {
                    sgc.Dispose();
                    path.Data = streamGeometry;
                    path      = null;
                    count     = 0;
                }
            }

            if (path != null)
            {
                sgc.Dispose();
                path.Data = streamGeometry;
            }
        }
        private void DrawEllipsesByStreamGeometry(
            IList <OxyRect> rects,
            OxyColor fill,
            OxyColor stroke,
            double thickness,
            EdgeRenderingMode edgeRenderingMode,
            double[] dashArray,
            LineJoin lineJoin)
        {
            const double ratio = 0.55228475; // (Math.Sqrt(2) - 1.0) * 4.0 / 3.0;

            Path                  path           = null;
            StreamGeometry        streamGeometry = null;
            StreamGeometryContext sgc            = null;
            var count = 0;

            bool   isSolid     = !fill.IsUndefined();
            IBrush cachedBrush = null;

            if (isSolid)
            {
                cachedBrush = GetCachedBrush(fill);
            }

            foreach (var rect in rects)
            {
                if (path == null)
                {
                    path = CreateAndAdd <Path>();
                    SetStroke(path, stroke, thickness, edgeRenderingMode, lineJoin, dashArray, 0);
                    if (isSolid)
                    {
                        path.Fill = cachedBrush;
                    }

                    streamGeometry = new StreamGeometry();
                    sgc            = streamGeometry.Open();
                    sgc.SetFillRule(FillRule.NonZero);
                }

                var a = rect.Width / 2.0;
                var b = rect.Height / 2.0;

                var x0 = rect.Center.X - a;
                var x1 = rect.Center.X - a * ratio;
                var x2 = rect.Center.X;
                var x3 = rect.Center.X + a * ratio;
                var x4 = rect.Center.X + a;

                var y0 = rect.Center.Y - b;
                var y1 = rect.Center.Y - b * ratio;
                var y2 = rect.Center.Y;
                var y3 = rect.Center.Y + b * ratio;
                var y4 = rect.Center.Y + b;

                sgc.BeginFigure(new Point(x2, y0), isSolid);
                sgc.CubicBezierTo(new Point(x3, y0), new Point(x4, y1), new Point(x4, y2));
                sgc.CubicBezierTo(new Point(x4, y3), new Point(x3, y4), new Point(x2, y4));
                sgc.CubicBezierTo(new Point(x1, y4), new Point(x0, y3), new Point(x0, y2));
                sgc.CubicBezierTo(new Point(x0, y1), new Point(x1, y0), new Point(x2, y0));
                sgc.EndFigure(true);

                count++;

                // Must limit the number of figures, otherwise drawing errors...
                if (count > MaxFiguresPerGeometry)
                {
                    sgc.Dispose();
                    path.Data = streamGeometry;
                    path      = null;
                    count     = 0;
                }
            }

            if (path != null)
            {
                sgc.Dispose();
                path.Data = streamGeometry;
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Draws a collection of polygons, where all polygons have the same stroke and fill.
        /// This performs better than calling DrawPolygon multiple times.
        /// </summary>
        /// <param name="polygons">The polygons.</param>
        /// <param name="fill">The fill color. If set to <c>OxyColors.Undefined</c>, the polygons will not be filled.</param>
        /// <param name="stroke">The stroke color. If set to <c>OxyColors.Undefined</c>, the polygons will not be stroked.</param>
        /// <param name="thickness">The stroke thickness (in device independent units, 1/96 inch).</param>
        /// <param name="dashArray">The dash array (in device independent units, 1/96 inch).</param>
        /// <param name="lineJoin">The line join type.</param>
        /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param>
        public void DrawPolygons(
            IList <IList <ScreenPoint> > polygons,
            OxyColor fill,
            OxyColor stroke,
            double thickness,
            double[] dashArray,
            LineJoin lineJoin,
            bool aliased)
        {
            var                   usg            = UseStreamGeometry;
            Path                  path           = null;
            StreamGeometry        streamGeometry = null;
            StreamGeometryContext sgc            = null;
            PathGeometry          pathGeometry   = null;
            var                   count          = 0;

            foreach (var polygon in polygons)
            {
                if (path == null)
                {
                    path = CreateAndAdd <Path>();
                    SetStroke(path, stroke, thickness, lineJoin, dashArray, 0, aliased);
                    if (!fill.IsUndefined())
                    {
                        path.Fill = GetCachedBrush(fill);
                    }

                    if (usg)
                    {
                        streamGeometry = new StreamGeometry();
                        sgc            = streamGeometry.Open();
                        sgc.SetFillRule(FillRule.NonZero);
                    }
                    else
                    {
                        pathGeometry = new PathGeometry {
                            FillRule = FillRule.NonZero
                        };
                    }
                }

                PathFigure figure = null;
                var        first  = true;
                foreach (var p in polygon)
                {
                    var point = aliased ? ToPixelAlignedPoint(p) : ToPoint(p);
                    if (first)
                    {
                        if (usg)
                        {
                            sgc.BeginFigure(point, !fill.IsUndefined());
                        }
                        else
                        {
                            figure = new PathFigure
                            {
                                StartPoint = point,
                                IsFilled   = !fill.IsUndefined(),
                                IsClosed   = true
                            };
                            pathGeometry.Figures.Add(figure);
                        }

                        first = false;
                    }
                    else
                    {
                        if (usg)
                        {
                            sgc.LineTo(point);
                        }
                        else
                        {
                            figure.Segments.Add(new LineSegment {
                                Point = point
                            });
                        }
                    }
                }

                count++;

                // Must limit the number of figures, otherwise drawing errors...
                if (count > MaxFiguresPerGeometry)
                {
                    if (usg)
                    {
                        sgc.Dispose();
                        path.Data = streamGeometry;
                    }
                    else
                    {
                        path.Data = pathGeometry;
                    }

                    path  = null;
                    count = 0;
                }
            }

            if (path != null)
            {
                if (usg)
                {
                    sgc.Dispose();
                    path.Data = streamGeometry;
                }
                else
                {
                    path.Data = pathGeometry;
                }
            }
        }