/// <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; } }
/// <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; } } }