Beispiel #1
0
        public static APath ToAPath(this Geometry geometry, Context context)
        {
            APath path = new APath();

            float density = context.Resources.DisplayMetrics.Density;

            if (geometry is LineGeometry)
            {
                LineGeometry lineGeometry = geometry as LineGeometry;

                path.MoveTo(
                    density * (float)lineGeometry.StartPoint.X,
                    density * (float)lineGeometry.StartPoint.Y);

                path.LineTo(
                    density * (float)lineGeometry.EndPoint.X,
                    density * (float)lineGeometry.EndPoint.Y);
            }
            else if (geometry is RectangleGeometry)
            {
                FormsRectangle rect = (geometry as RectangleGeometry).Rect;

                path.AddRect(
                    density * (float)rect.Left,
                    density * (float)rect.Top,
                    density * (float)rect.Right,
                    density * (float)rect.Bottom,
                    APath.Direction.Cw);
            }
            else if (geometry is EllipseGeometry)
            {
                EllipseGeometry ellipseGeometry = geometry as EllipseGeometry;

                path.AddOval(new RectF(
                                 density * (float)(ellipseGeometry.Center.X - ellipseGeometry.RadiusX),
                                 density * (float)(ellipseGeometry.Center.Y - ellipseGeometry.RadiusY),
                                 density * (float)(ellipseGeometry.Center.X + ellipseGeometry.RadiusX),
                                 density * (float)(ellipseGeometry.Center.Y + ellipseGeometry.RadiusY)),
                             APath.Direction.Cw);
            }
            else if (geometry is GeometryGroup)
            {
                GeometryGroup geometryGroup = geometry as GeometryGroup;

                path.SetFillType(geometryGroup.FillRule == FillRule.Nonzero ? APath.FillType.Winding : APath.FillType.EvenOdd);

                foreach (Geometry child in geometryGroup.Children)
                {
                    APath childPath = child.ToAPath(context);
                    path.AddPath(childPath);
                }
            }
            else if (geometry is PathGeometry)
            {
                PathGeometry pathGeometry = geometry as PathGeometry;

                path.SetFillType(pathGeometry.FillRule == FillRule.Nonzero ? APath.FillType.Winding : APath.FillType.EvenOdd);

                foreach (PathFigure pathFigure in pathGeometry.Figures)
                {
                    path.MoveTo(
                        density * (float)pathFigure.StartPoint.X,
                        density * (float)pathFigure.StartPoint.Y);

                    Point lastPoint = pathFigure.StartPoint;

                    foreach (PathSegment pathSegment in pathFigure.Segments)
                    {
                        // LineSegment
                        if (pathSegment is LineSegment)
                        {
                            LineSegment lineSegment = pathSegment as LineSegment;

                            path.LineTo(
                                density * (float)lineSegment.Point.X,
                                density * (float)lineSegment.Point.Y);
                            lastPoint = lineSegment.Point;
                        }
                        // PolylineSegment
                        else if (pathSegment is PolyLineSegment)
                        {
                            PolyLineSegment polylineSegment = pathSegment as PolyLineSegment;
                            PointCollection points          = polylineSegment.Points;

                            for (int i = 0; i < points.Count; i++)
                            {
                                path.LineTo(
                                    density * (float)points[i].X,
                                    density * (float)points[i].Y);
                            }
                            lastPoint = points[points.Count - 1];
                        }
                        // BezierSegment
                        else if (pathSegment is BezierSegment)
                        {
                            BezierSegment bezierSegment = pathSegment as BezierSegment;

                            path.CubicTo(
                                density * (float)bezierSegment.Point1.X, density * (float)bezierSegment.Point1.Y,
                                density * (float)bezierSegment.Point2.X, density * (float)bezierSegment.Point2.Y,
                                density * (float)bezierSegment.Point3.X, density * (float)bezierSegment.Point3.Y);

                            lastPoint = bezierSegment.Point3;
                        }
                        // PolyBezierSegment
                        else if (pathSegment is PolyBezierSegment)
                        {
                            PolyBezierSegment polyBezierSegment = pathSegment as PolyBezierSegment;
                            PointCollection   points            = polyBezierSegment.Points;

                            if (points.Count >= 3)
                            {
                                for (int i = 0; i < points.Count; i += 3)
                                {
                                    path.CubicTo(
                                        density * (float)points[i + 0].X, density * (float)points[i + 0].Y,
                                        density * (float)points[i + 1].X, density * (float)points[i + 1].Y,
                                        density * (float)points[i + 2].X, density * (float)points[i + 2].Y);
                                }
                            }

                            lastPoint = points[points.Count - 1];
                        }
                        // QuadraticBezierSegment
                        else if (pathSegment is QuadraticBezierSegment)
                        {
                            QuadraticBezierSegment bezierSegment = pathSegment as QuadraticBezierSegment;

                            path.QuadTo(
                                density * (float)bezierSegment.Point1.X, density * (float)bezierSegment.Point1.Y,
                                density * (float)bezierSegment.Point2.X, density * (float)bezierSegment.Point2.Y);

                            lastPoint = bezierSegment.Point2;
                        }
                        // PolyQuadraticBezierSegment
                        else if (pathSegment is PolyQuadraticBezierSegment)
                        {
                            PolyQuadraticBezierSegment polyBezierSegment = pathSegment as PolyQuadraticBezierSegment;
                            PointCollection            points            = polyBezierSegment.Points;

                            if (points.Count >= 2)
                            {
                                for (int i = 0; i < points.Count; i += 2)
                                {
                                    path.QuadTo(
                                        density * (float)points[i + 0].X, density * (float)points[i + 0].Y,
                                        density * (float)points[i + 1].X, density * (float)points[i + 1].Y);
                                }
                            }

                            lastPoint = points[points.Count - 1];
                        }
                        // ArcSegment
                        else if (pathSegment is ArcSegment)
                        {
                            ArcSegment arcSegment = pathSegment as ArcSegment;

                            List <Point> points = new List <Point>();

                            GeometryHelper.FlattenArc(
                                points,
                                lastPoint,
                                arcSegment.Point,
                                arcSegment.Size.Width,
                                arcSegment.Size.Height,
                                arcSegment.RotationAngle,
                                arcSegment.IsLargeArc,
                                arcSegment.SweepDirection == SweepDirection.CounterClockwise,
                                1);

                            for (int i = 0; i < points.Count; i++)
                            {
                                path.LineTo(
                                    density * (float)points[i].X,
                                    density * (float)points[i].Y);
                            }

                            if (points.Count > 0)
                            {
                                lastPoint = points[points.Count - 1];
                            }
                        }
                    }

                    if (pathFigure.IsClosed)
                    {
                        path.Close();
                    }
                }
            }

            return(path);
        }
Beispiel #2
0
        public object ConvertToNative(Geometry geometry)
        {
            // TODO: Can we keep this object around and reset it?
            droidGraphics.Path path = new droidGraphics.Path();
            // TODO: Might we also save a non-transformed path and a transformed path? -- No, that fails for GeometryGroup

            // Determine what type of Geometry we're dealing with
            if (geometry is LineGeometry)
            {
                LineGeometry lineGeometry = geometry as LineGeometry;

                path.MoveTo(PixelsPerDip * (float)lineGeometry.StartPoint.X,
                            PixelsPerDip * (float)lineGeometry.StartPoint.Y);

                path.LineTo(PixelsPerDip * (float)lineGeometry.EndPoint.X,
                            PixelsPerDip * (float)lineGeometry.EndPoint.Y);
            }

            else if (geometry is RectangleGeometry)
            {
                Rect rect = (geometry as RectangleGeometry).Rect;

                path.AddRect(PixelsPerDip * (float)rect.Left,
                             PixelsPerDip * (float)rect.Top,
                             PixelsPerDip * (float)rect.Right,
                             PixelsPerDip * (float)rect.Bottom,
                             droidGraphics.Path.Direction.Cw);              // TODO: Check for compatibility!
            }

            else if (geometry is EllipseGeometry)
            {
                EllipseGeometry ellipseGeometry = geometry as EllipseGeometry;

                path.AddOval(new droidGraphics.RectF(
                                 PixelsPerDip * (float)(ellipseGeometry.Center.X - ellipseGeometry.RadiusX),
                                 PixelsPerDip * (float)(ellipseGeometry.Center.Y - ellipseGeometry.RadiusY),
                                 PixelsPerDip * (float)(ellipseGeometry.Center.X + ellipseGeometry.RadiusX),
                                 PixelsPerDip * (float)(ellipseGeometry.Center.Y + ellipseGeometry.RadiusY)),
                             droidGraphics.Path.Direction.Cw);              // TODO: Check for compatibility!
            }

            else if (geometry is GeometryGroup)
            {
                GeometryGroup geometryGroup = geometry as GeometryGroup;
                SetFillRule(path, geometryGroup.FillRule);

                foreach (Geometry child in geometryGroup.Children)
                {
                    droidGraphics.Path childPath = ConvertToNative(child) as droidGraphics.Path;
                    path.AddPath(childPath);
                }
            }

            else if (geometry is PathGeometry)
            {
                PathGeometry pathGeometry = geometry as PathGeometry;

                SetFillRule(path, pathGeometry.FillRule);

                foreach (PathFigure pathFigure in pathGeometry.Figures)
                {
                    path.MoveTo(PixelsPerDip * (float)pathFigure.StartPoint.X,
                                PixelsPerDip * (float)pathFigure.StartPoint.Y);
                    Point lastPoint = pathFigure.StartPoint;

                    foreach (PathSegment pathSegment in pathFigure.Segments)
                    {
                        // LineSegment
                        if (pathSegment is LineSegment)
                        {
                            LineSegment lineSegment = pathSegment as LineSegment;

                            path.LineTo(PixelsPerDip * (float)lineSegment.Point.X,
                                        PixelsPerDip * (float)lineSegment.Point.Y);
                            lastPoint = lineSegment.Point;
                        }

                        // PolylineSegment
                        else if (pathSegment is PolyLineSegment)
                        {
                            PolyLineSegment polylineSegment = pathSegment as PolyLineSegment;
                            PointCollection points          = polylineSegment.Points;

                            for (int i = 0; i < points.Count; i++)
                            {
                                path.LineTo(PixelsPerDip * (float)points[i].X,
                                            PixelsPerDip * (float)points[i].Y);
                            }
                            lastPoint = points[points.Count - 1];
                        }

                        // BezierSegment
                        else if (pathSegment is BezierSegment)
                        {
                            BezierSegment bezierSegment = pathSegment as BezierSegment;

                            path.CubicTo(PixelsPerDip * (float)bezierSegment.Point1.X, PixelsPerDip * (float)bezierSegment.Point1.Y,
                                         PixelsPerDip * (float)bezierSegment.Point2.X, PixelsPerDip * (float)bezierSegment.Point2.Y,
                                         PixelsPerDip * (float)bezierSegment.Point3.X, PixelsPerDip * (float)bezierSegment.Point3.Y);

                            lastPoint = bezierSegment.Point3;
                        }

                        // PolyBezierSegment
                        else if (pathSegment is PolyBezierSegment)
                        {
                            PolyBezierSegment polyBezierSegment = pathSegment as PolyBezierSegment;
                            PointCollection   points            = polyBezierSegment.Points;

                            for (int i = 0; i < points.Count; i += 3)
                            {
                                path.CubicTo(PixelsPerDip * (float)points[i + 0].X, PixelsPerDip * (float)points[i + 0].Y,
                                             PixelsPerDip * (float)points[i + 1].X, PixelsPerDip * (float)points[i + 1].Y,
                                             PixelsPerDip * (float)points[i + 2].X, PixelsPerDip * (float)points[i + 2].Y);
                            }
                            lastPoint = points[points.Count - 1];
                        }

                        // QuadraticBezierSegment
                        else if (pathSegment is QuadraticBezierSegment)
                        {
                            QuadraticBezierSegment bezierSegment = pathSegment as QuadraticBezierSegment;

                            path.QuadTo(PixelsPerDip * (float)bezierSegment.Point1.X, PixelsPerDip * (float)bezierSegment.Point1.Y,
                                        PixelsPerDip * (float)bezierSegment.Point2.X, PixelsPerDip * (float)bezierSegment.Point2.Y);

                            lastPoint = bezierSegment.Point2;
                        }

                        // PolyQuadraticBezierSegment
                        else if (pathSegment is PolyQuadraticBezierSegment)
                        {
                            PolyQuadraticBezierSegment polyBezierSegment = pathSegment as PolyQuadraticBezierSegment;
                            PointCollection            points            = polyBezierSegment.Points;

                            for (int i = 0; i < points.Count; i += 2)
                            {
                                path.QuadTo(PixelsPerDip * (float)points[i + 0].X, PixelsPerDip * (float)points[i + 0].Y,
                                            PixelsPerDip * (float)points[i + 1].X, PixelsPerDip * (float)points[i + 1].Y);
                            }
                            lastPoint = points[points.Count - 1];
                        }

                        // ArcSegment
                        else if (pathSegment is ArcSegment)
                        {
                            ArcSegment arcSegment = pathSegment as ArcSegment;

                            List <Point> points = new List <Point>();
                            Xamarin.Forms.Shapes.Shapes.FlattenArc(points,
                                                                   lastPoint,
                                                                   arcSegment.Point,
                                                                   arcSegment.Size.Width,
                                                                   arcSegment.Size.Height,
                                                                   arcSegment.RotationAngle,
                                                                   arcSegment.IsLargeArc,
                                                                   arcSegment.SweepDirection == SweepDirection.Counterclockwise,
                                                                   1);

                            for (int i = 0; i < points.Count; i++)
                            {
                                path.LineTo(PixelsPerDip * (float)points[i].X,
                                            PixelsPerDip * (float)points[i].Y);
                            }
                            lastPoint = points[points.Count - 1];
                        }
                    }

                    if (pathFigure.IsClosed)
                    {
                        path.Close();
                    }
                }
            }

            // Apply transform
            if (geometry.Transform != null)
            {
                path.Transform((droidGraphics.Matrix)geometry.Transform.GetNativeObject());
            }

            return(path);
        }