/// <summary>
        /// Draws the line segments by stream geometry.
        /// </summary>
        /// <param name="points">The points.</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="thickness">The thickness.</param>
        /// <param name="edgeRenderingMode">The edge rendering mode.</param>
        /// <param name="dashArray">The dash array. Use <c>null</c> to get a solid line.</param>
        /// <param name="lineJoin">The line join.</param>
        private void DrawLineSegmentsByStreamGeometry(
            IList <ScreenPoint> points,
            OxyColor stroke,
            double thickness,
            EdgeRenderingMode edgeRenderingMode,
            double[] dashArray,
            LineJoin lineJoin)
        {
            bool aliased = edgeRenderingMode == EdgeRenderingMode.PreferSpeed;

            StreamGeometry        streamGeometry        = null;
            StreamGeometryContext streamGeometryContext = null;

            var count = 0;

            for (int i = 0; i + 1 < points.Count; i += 2)
            {
                if (streamGeometry == null)
                {
                    streamGeometry        = new StreamGeometry();
                    streamGeometryContext = streamGeometry.Open();
                }

                streamGeometryContext.BeginFigure(ToPoint(points[i], aliased), false);
                streamGeometryContext.LineTo(ToPoint(points[i + 1], aliased));

                count++;

                // Must limit the number of figures, otherwise drawing errors...
                if (count > MaxFiguresPerGeometry || dashArray != null)
                {
                    streamGeometryContext.Dispose();
                    var path = CreateAndAdd <Path>();
                    SetStroke(path, stroke, thickness, edgeRenderingMode, lineJoin, dashArray, 0);
                    path.Data      = streamGeometry;
                    streamGeometry = null;
                    count          = 0;
                }
            }

            if (streamGeometry != null)
            {
                streamGeometryContext.Dispose();
                var path = CreateAndAdd <Path>();
                SetStroke(path, stroke, thickness, edgeRenderingMode, lineJoin, null, 0);
                path.Data = streamGeometry;
            }
        }
Exemplo n.º 2
0
        public void EndRead()
        {
            var brush = Foreground?.ToSolidColorBrush() ?? _canvas.CurrentBrush;

            _context.Dispose();
            _canvas.DrawingContext.DrawGeometry(brush, new Pen(brush), _path);
        }
Exemplo n.º 3
0
        public override void Dispose()
        {
            if (_isOpen)
            {
                _context.EndFigure(false); _isOpen = false;
            }
            _context.Dispose();
            // Passing a null brush is a workaround for https://github.com/AvaloniaUI/Avalonia/issues/1419
            IBrush?brush = Foreground?.ToSolidColorBrush() ?? _canvas.CurrentBrush;
            IPen?  pen   = null;

            if (_canvas.CurrentStyle == PaintStyle.Stroke)
            {
                pen = new Pen(brush); brush = null;
            }
            _canvas.DrawingContext.DrawGeometry(brush, pen, _path);
        }
        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;
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// Close the geometry to so no more path adding is allowed and return the instance so it can be rendered.
 /// </summary>
 public StreamGeometry GetClosedGeometry()
 {
     _geometryContext.EndFigure(true);
     _geometryContext.Dispose();
     return(_geometry);
 }
        /// <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;
                }
            }
        }