void AddPolyQuad(PathF path, PolyQuadraticBezierSegment polyQuadraticBezierSegment) { var points = polyQuadraticBezierSegment.Points; if (points.Count >= 2) { for (int i = 0; i < polyQuadraticBezierSegment.Points.Count; i += 2) { if (i + 1 > polyQuadraticBezierSegment.Points.Count - 1) { break; } var pt1 = new PointF((float)(points[i].X), (float)(points[i].Y)); var pt2 = new PointF((float)(points[i + 1].X), (float)(points[i + 1].Y)); path.QuadTo(pt1, pt2); } } }
/// <include file="../../../docs/Microsoft.Maui.Controls.Shapes/GeometryHelper.xml" path="//Member[@MemberName='FlattenGeometry'][1]/Docs" /> public static void FlattenGeometry(PathGeometry pathGeoDst, Geometry geoSrc, double tolerance, Matrix matxPrevious) { Matrix matx = matxPrevious; if (geoSrc is GeometryGroup) { foreach (Geometry geoChild in (geoSrc as GeometryGroup).Children) { FlattenGeometry(pathGeoDst, geoChild, tolerance, matx); } } else if (geoSrc is LineGeometry) { LineGeometry lineGeoSrc = geoSrc as LineGeometry; PathFigure figDst = new PathFigure(); PolyLineSegment segDst = new PolyLineSegment(); figDst.StartPoint = matx.Transform(lineGeoSrc.StartPoint); segDst.Points.Add(matx.Transform(lineGeoSrc.EndPoint)); figDst.Segments.Add(segDst); pathGeoDst.Figures.Add(figDst); } else if (geoSrc is RectangleGeometry) { RectangleGeometry rectGeoSrc = geoSrc as RectangleGeometry; PathFigure figDst = new PathFigure(); PolyLineSegment segDst = new PolyLineSegment(); figDst.StartPoint = matx.Transform(new Point(rectGeoSrc.Rect.Left, rectGeoSrc.Rect.Top)); segDst.Points.Add(matx.Transform(new Point(rectGeoSrc.Rect.Right, rectGeoSrc.Rect.Top))); segDst.Points.Add(matx.Transform(new Point(rectGeoSrc.Rect.Right, rectGeoSrc.Rect.Bottom))); segDst.Points.Add(matx.Transform(new Point(rectGeoSrc.Rect.Left, rectGeoSrc.Rect.Bottom))); segDst.Points.Add(matx.Transform(new Point(rectGeoSrc.Rect.Left, rectGeoSrc.Rect.Top))); figDst.IsClosed = true; figDst.Segments.Add(segDst); pathGeoDst.Figures.Add(figDst); } else if (geoSrc is EllipseGeometry) { EllipseGeometry elipGeoSrc = geoSrc as EllipseGeometry; PathFigure figDst = new PathFigure(); PolyLineSegment segDst = new PolyLineSegment(); int max = (int)(4 * (elipGeoSrc.RadiusX + elipGeoSrc.RadiusY) / tolerance); for (int i = 0; i < max; i++) { double x = elipGeoSrc.Center.X + elipGeoSrc.RadiusX * Math.Sin(i * 2 * Math.PI / max); double y = elipGeoSrc.Center.Y - elipGeoSrc.RadiusY * Math.Cos(i * 2 * Math.PI / max); Point pt = matx.Transform(new Point(x, y)); if (i == 0) { figDst.StartPoint = pt; } else { segDst.Points.Add(pt); } } figDst.IsClosed = true; figDst.Segments.Add(segDst); pathGeoDst.Figures.Add(figDst); } else if (geoSrc is PathGeometry) { PathGeometry pathGeoSrc = geoSrc as PathGeometry; pathGeoDst.FillRule = pathGeoSrc.FillRule; foreach (PathFigure figSrc in pathGeoSrc.Figures) { PathFigure figDst = new PathFigure { IsFilled = figSrc.IsFilled, IsClosed = figSrc.IsClosed, StartPoint = matx.Transform(figSrc.StartPoint) }; Point ptLast = figDst.StartPoint; foreach (PathSegment segSrc in figSrc.Segments) { PolyLineSegment segDst = new PolyLineSegment(); if (segSrc is LineSegment) { LineSegment lineSegSrc = segSrc as LineSegment; ptLast = matx.Transform(lineSegSrc.Point); segDst.Points.Add(ptLast); } else if (segSrc is PolyLineSegment) { PolyLineSegment polySegSrc = segSrc as PolyLineSegment; foreach (Point pt in polySegSrc.Points) { ptLast = matx.Transform(pt); segDst.Points.Add(ptLast); } } else if (segSrc is BezierSegment) { BezierSegment bezSeg = segSrc as BezierSegment; Point pt0 = ptLast; Point pt1 = matx.Transform(bezSeg.Point1); Point pt2 = matx.Transform(bezSeg.Point2); Point pt3 = matx.Transform(bezSeg.Point3); Points.Clear(); FlattenCubicBezier(Points, pt0, pt1, pt2, pt3, tolerance); for (int i = 1; i < Points.Count; i++) { segDst.Points.Add(Points[i]); } ptLast = Points[Points.Count - 1]; } else if (segSrc is PolyBezierSegment) { PolyBezierSegment polyBezSeg = segSrc as PolyBezierSegment; for (int bez = 0; bez < polyBezSeg.Points.Count; bez += 3) { if (bez + 2 > polyBezSeg.Points.Count - 1) { break; } Point pt0 = ptLast; Point pt1 = matx.Transform(polyBezSeg.Points[bez]); Point pt2 = matx.Transform(polyBezSeg.Points[bez + 1]); Point pt3 = matx.Transform(polyBezSeg.Points[bez + 2]); Points.Clear(); FlattenCubicBezier(Points, pt0, pt1, pt2, pt3, tolerance); for (int i = 1; i < Points.Count; i++) { segDst.Points.Add(Points[i]); } ptLast = Points[Points.Count - 1]; } } else if (segSrc is QuadraticBezierSegment) { QuadraticBezierSegment quadBezSeg = segSrc as QuadraticBezierSegment; Point pt0 = ptLast; Point pt1 = matx.Transform(quadBezSeg.Point1); Point pt2 = matx.Transform(quadBezSeg.Point2); Points.Clear(); FlattenQuadraticBezier(Points, pt0, pt1, pt2, tolerance); for (int i = 1; i < Points.Count; i++) { segDst.Points.Add(Points[i]); } ptLast = Points[Points.Count - 1]; } else if (segSrc is PolyQuadraticBezierSegment) { PolyQuadraticBezierSegment polyQuadBezSeg = segSrc as PolyQuadraticBezierSegment; for (int bez = 0; bez < polyQuadBezSeg.Points.Count; bez += 2) { if (bez + 1 > polyQuadBezSeg.Points.Count - 1) { break; } Point pt0 = ptLast; Point pt1 = matx.Transform(polyQuadBezSeg.Points[bez]); Point pt2 = matx.Transform(polyQuadBezSeg.Points[bez + 1]); Points.Clear(); FlattenQuadraticBezier(Points, pt0, pt1, pt2, tolerance); for (int i = 1; i < Points.Count; i++) { segDst.Points.Add(Points[i]); } ptLast = Points[Points.Count - 1]; } } else if (segSrc is ArcSegment) { ArcSegment arcSeg = segSrc as ArcSegment; Points.Clear(); FlattenArc( Points, ptLast, arcSeg.Point, arcSeg.Size.Width, arcSeg.Size.Height, arcSeg.RotationAngle, arcSeg.IsLargeArc, arcSeg.SweepDirection == SweepDirection.CounterClockwise, tolerance); // Set ptLast while transferring points for (int i = 1; i < Points.Count; i++) { segDst.Points.Add(ptLast = Points[i]); } } figDst.Segments.Add(segDst); } pathGeoDst.Figures.Add(figDst); } } }