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