public PointF TransformPoint(Point p) { #if __UNIFIED__ return(control.TransformPoint(p.ToNS()).ToEto()); #else return(control.TransformPoint(p.ToSDPointF()).ToEto()); #endif }
// // Helper function to generate shadow // private void GenerateShapeShadow(CGContext context, UIBezierPath shapeObject, nfloat xOffset, nfloat yOffset, nfloat blurValue, CGBlendMode blendingMode, UIColor shadowColor, nfloat borderWidth, int borderPosition, nfloat iWidth, nfloat iHeight) { CGPoint basePoint; CGPoint offsetPoint; CGSize calculatedShadowOffset; nfloat calculatedShadowBlur; CGPoint constPointZero; constPointZero = new CGPoint(0, 0); basePoint = baseTransform.TransformPoint(context.PointToDeviceSpace(constPointZero)); offsetPoint = baseTransform.TransformPoint(context.PointToDeviceSpace(new CGPoint(xOffset, yOffset))); calculatedShadowOffset = new CGSize(offsetPoint.X - basePoint.X, offsetPoint.Y - basePoint.Y); if (blurValue == 0) { calculatedShadowBlur = 0; } else { calculatedShadowBlur = Hypot(calculatedShadowOffset.Width, calculatedShadowOffset.Height) / blurValue; } context.SetShadow(calculatedShadowOffset, calculatedShadowBlur, shadowColor.CGColor); context.SetBlendMode(blendingMode); context.BeginTransparencyLayer(null); UIColor.Black.SetFill(); shapeObject.Fill(); if (borderWidth > 0) { if (borderPosition == 0) { context.SaveState(); shapeObject.LineWidth = borderWidth; UIColor.Black.SetStroke(); shapeObject.Stroke(); context.RestoreState(); } if (borderPosition == 1) { context.BeginPath(); context.AddPath(shapeObject.CGPath); context.EOClip(); } if (borderPosition == 2) { context.BeginPath(); context.AddPath(shapeObject.CGPath); context.AddRect(RectangleFExtensions.Inset(shapeObject.Bounds, iWidth, iHeight)); context.EOClip(); } } context.EndTransparencyLayer(); }
public void TransformPoints(PointF[] pts) { if (pts == null) { throw new ArgumentNullException("pts"); } for (int i = 0; i < pts.Length; i++) { pts [i] = transform.TransformPoint(pts [i].ToCGPoint()).ToPointF(); } }
public void TransformPoints(PointF[] pts) { if (pts == null) { throw new ArgumentNullException("pts"); } for (int i = 0; i < pts.Length; i++) { var point = transform.TransformPoint(new CGPoint(pts [i].X, pts [i].Y)); pts [i] = new PointF((float)point.X, (float)point.Y); } }
public void TransformPoint() { var transform = new CGAffineTransform(1, 2, 3, 4, 5, 6); var point = transform.TransformPoint(new CGPoint(4, 5)); Assert.AreEqual((nfloat)24, point.X, "X"); Assert.AreEqual((nfloat)34, point.Y, "Y"); }
private static PointF RotateCGPointAroundCenter(PointF point, PointF center, float angle) { CGAffineTransform translation = CGAffineTransform.MakeTranslation(center.X, center.Y); CGAffineTransform rotation = CGAffineTransform.MakeRotation(angle); var inverted = CGAffineTransform.CGAffineTransformInvert(translation); CGAffineTransform transformGroup = inverted * rotation * translation; return(transformGroup.TransformPoint(point)); }
public void TransformPoint(object backend, ref double x, ref double y) { GetContext(backend); CGContext gp = NSGraphicsContext.CurrentContext.GraphicsPort; CGAffineTransform t = gp.GetCTM(); PointF p = t.TransformPoint(new PointF((float)x, (float)y)); x = p.X; y = p.Y; }
public void TransformPoints(object backend, Point[] points) { GetContext(backend); CGContext gp = NSGraphicsContext.CurrentContext.GraphicsPort; CGAffineTransform t = gp.GetCTM(); PointF p; for (int i = 0; i < points.Length; ++i) { p = t.TransformPoint(new PointF((float)points[i].X, (float)points[i].Y)); points[i].X = p.X; points[i].Y = p.Y; } }
public void TransformDistance(object backend, ref double dx, ref double dy) { GetContext(backend); CGContext gp = NSGraphicsContext.CurrentContext.GraphicsPort; CGAffineTransform t = gp.GetCTM(); // remove translational elements from CTM t.x0 = 0; t.y0 = 0; PointF p = t.TransformPoint(new PointF((float)dx, (float)dy)); dx = p.X; dy = p.Y; }
public void TransformDistances(object backend, Distance[] vectors) { GetContext(backend); CGContext gp = NSGraphicsContext.CurrentContext.GraphicsPort; CGAffineTransform t = gp.GetCTM(); t.x0 = 0; t.y0 = 0; PointF p; for (int i = 0; i < vectors.Length; ++i) { p = t.TransformPoint(new PointF((float)vectors[i].Dx, (float)vectors[i].Dy)); vectors[i].Dx = p.X; vectors[i].Dy = p.Y; } }
public PointF TransformPoint(Point p) { return(Platform.Conversions.ToEto(control.TransformPoint(p.ToSDPointF()))); }
public static CGPoint Apply (this CGPoint point, CGAffineTransform transform) { return transform.TransformPoint (point); }
public static PathData ToCGPath(this Geometry geometry) { PathData pathData = new PathData { Data = new CGPath() }; CGAffineTransform transform = CGAffineTransform.MakeIdentity(); if (geometry is LineGeometry) { LineGeometry lineGeometry = geometry as LineGeometry; pathData.Data.MoveToPoint(transform, lineGeometry.StartPoint.ToPointF()); pathData.Data.AddLineToPoint(transform, lineGeometry.EndPoint.ToPointF()); } else if (geometry is RectangleGeometry) { Rect rect = (geometry as RectangleGeometry).Rect; pathData.Data.AddRect(transform, new CGRect(rect.X, rect.Y, rect.Width, rect.Height)); } else if (geometry is EllipseGeometry) { EllipseGeometry ellipseGeometry = geometry as EllipseGeometry; CGRect rect = new CGRect( ellipseGeometry.Center.X - ellipseGeometry.RadiusX, ellipseGeometry.Center.Y - ellipseGeometry.RadiusY, ellipseGeometry.RadiusX * 2, ellipseGeometry.RadiusY * 2); pathData.Data.AddEllipseInRect(transform, rect); } else if (geometry is GeometryGroup) { GeometryGroup geometryGroup = geometry as GeometryGroup; pathData.IsNonzeroFillRule = geometryGroup.FillRule == FillRule.Nonzero; foreach (Geometry child in geometryGroup.Children) { PathData pathChild = child.ToCGPath(); pathData.Data.AddPath(pathChild.Data); } } else if (geometry is PathGeometry) { PathGeometry pathGeometry = geometry as PathGeometry; pathData.IsNonzeroFillRule = pathGeometry.FillRule == FillRule.Nonzero; foreach (PathFigure pathFigure in pathGeometry.Figures) { pathData.Data.MoveToPoint(transform, pathFigure.StartPoint.ToPointF()); Point lastPoint = pathFigure.StartPoint; foreach (PathSegment pathSegment in pathFigure.Segments) { // LineSegment if (pathSegment is LineSegment) { LineSegment lineSegment = pathSegment as LineSegment; pathData.Data.AddLineToPoint(transform, lineSegment.Point.ToPointF()); 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++) { pathData.Data.AddLineToPoint(transform, points[i].ToPointF()); } lastPoint = points[points.Count - 1]; } // BezierSegment if (pathSegment is BezierSegment) { BezierSegment bezierSegment = pathSegment as BezierSegment; pathData.Data.AddCurveToPoint( transform, bezierSegment.Point1.ToPointF(), bezierSegment.Point2.ToPointF(), bezierSegment.Point3.ToPointF()); 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) { pathData.Data.AddCurveToPoint( transform, points[i].ToPointF(), points[i + 1].ToPointF(), points[i + 2].ToPointF()); } lastPoint = points[points.Count - 1]; } // QuadraticBezierSegment if (pathSegment is QuadraticBezierSegment) { QuadraticBezierSegment bezierSegment = pathSegment as QuadraticBezierSegment; pathData.Data.AddQuadCurveToPoint( transform, new nfloat(bezierSegment.Point1.X), new nfloat(bezierSegment.Point1.Y), new nfloat(bezierSegment.Point2.X), new nfloat(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) { pathData.Data.AddQuadCurveToPoint( transform, new nfloat(points[i + 0].X), new nfloat(points[i + 0].Y), new nfloat(points[i + 1].X), new nfloat(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); CGPoint[] cgpoints = new CGPoint[points.Count]; for (int i = 0; i < points.Count; i++) { cgpoints[i] = transform.TransformPoint(points[i].ToPointF()); } pathData.Data.AddLines(cgpoints); lastPoint = points[points.Count - 1]; } } if (pathFigure.IsClosed) { pathData.Data.CloseSubpath(); } } } return(pathData); }
public static CGPoint Apply(this CGPoint point, CGAffineTransform transform) { return(transform.TransformPoint(point)); }
internal void NativeDrawString(string s, Font font, Color brush, RectangleF layoutRectangle, StringFormat stringFormat) { if (font == null) { throw new ArgumentNullException("font"); } if (s == null || s.Length == 0) { return; } var attributedString = buildAttributedString(s, font, brush); // Work out the geometry RectangleF insetBounds = layoutRectangle; bool layoutAvailable = true; if (insetBounds.Size == SizeF.Empty) { insetBounds.Size = new SizeF(8388608, 8388608); layoutAvailable = false; } PointF textPosition = new PointF(insetBounds.X, insetBounds.Y); float boundsWidth = insetBounds.Width; // Calculate the lines int start = 0; int length = (int)attributedString.Length; var typesetter = new CTTypesetter(attributedString); float baselineOffset = 0; // First we need to calculate the offset for Vertical Alignment if we // are using anything but Top if (layoutAvailable && stringFormat.LineAlignment != StringAlignment.Near) { while (start < length) { int count = (int)typesetter.SuggestLineBreak(start, boundsWidth); var line = typesetter.GetLine(new NSRange(start, count)); // Create and initialize some values from the bounds. nfloat ascent; nfloat descent; nfloat leading; line.GetTypographicBounds(out ascent, out descent, out leading); baselineOffset += (float)Math.Ceiling(ascent + descent + leading + 1); // +1 matches best to CTFramesetter's behavior line.Dispose(); start += count; } } start = 0; while (start < length && textPosition.Y < insetBounds.Bottom) { // Now we ask the typesetter to break off a line for us. // This also will take into account line feeds embedded in the text. // Example: "This is text \n with a line feed embedded inside it" int count = (int)typesetter.SuggestLineBreak(start, boundsWidth); var line = typesetter.GetLine(new NSRange(start, count)); // Create and initialize some values from the bounds. nfloat ascent; nfloat descent; nfloat leading; double lineWidth = line.GetTypographicBounds(out ascent, out descent, out leading); if (!layoutAvailable) { insetBounds.Width = (float)lineWidth; insetBounds.Height = (float)(ascent + descent + leading); } // Calculate the string format if need be var penFlushness = 0.0f; if (stringFormat.Alignment == StringAlignment.Far) { penFlushness = (float)line.GetPenOffsetForFlush(1.0f, insetBounds.Width); } else if (stringFormat.Alignment == StringAlignment.Center) { penFlushness = (float)line.GetPenOffsetForFlush(0.5f, insetBounds.Width); } // initialize our Text Matrix or we could get trash in here var textMatrix = new CGAffineTransform( 1, 0, 0, -1, 0, ascent); if (stringFormat.LineAlignment == StringAlignment.Near) { textMatrix.Translate(penFlushness + textPosition.X, textPosition.Y); //insetBounds.Height - textPosition.Y -(float)Math.Floor(ascent - 1)); } if (stringFormat.LineAlignment == StringAlignment.Center) { textMatrix.Translate(penFlushness + textPosition.X, textPosition.Y + ((insetBounds.Height / 2) - (baselineOffset / 2))); // -(float)Math.Floor(ascent) } if (stringFormat.LineAlignment == StringAlignment.Far) { textMatrix.Translate(penFlushness + textPosition.X, textPosition.Y + ((insetBounds.Height) - (baselineOffset))); } var glyphRuns = line.GetGlyphRuns(); for (int glyphRunIndex = 0; glyphRunIndex < glyphRuns.Length; glyphRunIndex++) { var glyphRun = glyphRuns [glyphRunIndex]; var glyphs = glyphRun.GetGlyphs(); var glyphPositions = glyphRun.GetPositions(); //var textMatrix = glyphRun.TextMatrix; // Create and initialize some values from the bounds. float glyphAscent; float glyphDescent; float glyphLeading; var elementPoints = new PointF [3]; for (int glyphIndex = 0; glyphIndex < glyphs.Length; glyphIndex++) { if (glyphIndex > 0) { textMatrix.x0 += glyphPositions [glyphIndex].X - glyphPositions[glyphIndex - 1].X; textMatrix.y0 += glyphPositions [glyphIndex].Y - glyphPositions[glyphIndex - 1].Y; } var glyphPath = font.nativeFont.GetPathForGlyph(glyphs [glyphIndex]); // glyphPath = null if it is a white space character if (glyphPath != null) { glyphPath.Apply( delegate(CGPathElement pathElement) { elementPoints[0] = textMatrix.TransformPoint(pathElement.Point1).ToPointF(); elementPoints[1] = textMatrix.TransformPoint(pathElement.Point2).ToPointF(); elementPoints[2] = textMatrix.TransformPoint(pathElement.Point3).ToPointF(); //Console.WriteLine ("Applying {0} - {1}, {2}, {3}", pathElement.Type, elementPoints[0], elementPoints[1], elementPoints[2]); // now add position offsets switch (pathElement.Type) { case CGPathElementType.MoveToPoint: start_new_fig = true; Append(elementPoints[0].X, elementPoints[0].Y, PathPointType.Line, true); break; case CGPathElementType.AddLineToPoint: var lastPoint = points[points.Count - 1]; AppendPoint(lastPoint, PathPointType.Line, false); AppendPoint(elementPoints[0], PathPointType.Line, false); break; case CGPathElementType.AddCurveToPoint: case CGPathElementType.AddQuadCurveToPoint: // This is the only thing I can think of right now for the fonts that // I have tested. See the description of the quadraticToCubic method for // more information // Get the last point var pt1 = points[points.Count - 1]; var pt2 = PointF.Empty; var pt3 = PointF.Empty; var pt4 = elementPoints[1]; GeomUtilities.QuadraticToCubic(pt1, elementPoints[0], elementPoints[1], out pt2, out pt3); Append(pt1.X, pt1.Y, PathPointType.Line, true); AppendBezier(pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y); break; case CGPathElementType.CloseSubpath: CloseFigure(); break; } } ); } } } // Move the index beyond the line break. start += count; textPosition.Y += (float)Math.Ceiling(ascent + descent + leading + 1); // +1 matches best to CTFramesetter's behavior line.Dispose(); } }
internal void NativeDrawString(string s, Font font, Color brush, RectangleF layoutRectangle, StringFormat stringFormat) { if (font == null) throw new ArgumentNullException ("font"); if (s == null || s.Length == 0) return; var attributedString = buildAttributedString(s, font, brush); // Work out the geometry RectangleF insetBounds = layoutRectangle; bool layoutAvailable = true; if (insetBounds.Size == SizeF.Empty) { insetBounds.Size = new SizeF (8388608, 8388608); layoutAvailable = false; } PointF textPosition = new PointF(insetBounds.X, insetBounds.Y); float boundsWidth = insetBounds.Width; // Calculate the lines int start = 0; int length = (int)attributedString.Length; var typesetter = new CTTypesetter(attributedString); float baselineOffset = 0; // First we need to calculate the offset for Vertical Alignment if we // are using anything but Top if (layoutAvailable && stringFormat.LineAlignment != StringAlignment.Near) { while (start < length) { int count = (int)typesetter.SuggestLineBreak (start, boundsWidth); var line = typesetter.GetLine (new NSRange(start, count)); // Create and initialize some values from the bounds. nfloat ascent; nfloat descent; nfloat leading; line.GetTypographicBounds (out ascent, out descent, out leading); baselineOffset += (float)Math.Ceiling (ascent + descent + leading + 1); // +1 matches best to CTFramesetter's behavior line.Dispose (); start += count; } } start = 0; while (start < length && textPosition.Y < insetBounds.Bottom) { // Now we ask the typesetter to break off a line for us. // This also will take into account line feeds embedded in the text. // Example: "This is text \n with a line feed embedded inside it" int count = (int)typesetter.SuggestLineBreak(start, boundsWidth); var line = typesetter.GetLine(new NSRange(start, count)); // Create and initialize some values from the bounds. nfloat ascent; nfloat descent; nfloat leading; double lineWidth = line.GetTypographicBounds(out ascent, out descent, out leading); if (!layoutAvailable) { insetBounds.Width = (float)lineWidth; insetBounds.Height = (float)(ascent + descent + leading); } // Calculate the string format if need be var penFlushness = 0.0f; if (stringFormat.Alignment == StringAlignment.Far) penFlushness = (float)line.GetPenOffsetForFlush(1.0f, insetBounds.Width); else if (stringFormat.Alignment == StringAlignment.Center) penFlushness = (float)line.GetPenOffsetForFlush(0.5f, insetBounds.Width); // initialize our Text Matrix or we could get trash in here var textMatrix = new CGAffineTransform ( 1, 0, 0, -1, 0, ascent); if (stringFormat.LineAlignment == StringAlignment.Near) textMatrix.Translate (penFlushness + textPosition.X, textPosition.Y); //insetBounds.Height - textPosition.Y -(float)Math.Floor(ascent - 1)); if (stringFormat.LineAlignment == StringAlignment.Center) textMatrix.Translate (penFlushness + textPosition.X, textPosition.Y + ((insetBounds.Height / 2) - (baselineOffset / 2)) ); // -(float)Math.Floor(ascent) if (stringFormat.LineAlignment == StringAlignment.Far) textMatrix.Translate(penFlushness + textPosition.X, textPosition.Y + ((insetBounds.Height) - (baselineOffset))); var glyphRuns = line.GetGlyphRuns (); for (int glyphRunIndex = 0; glyphRunIndex < glyphRuns.Length; glyphRunIndex++) { var glyphRun = glyphRuns [glyphRunIndex]; var glyphs = glyphRun.GetGlyphs (); var glyphPositions = glyphRun.GetPositions (); //var textMatrix = glyphRun.TextMatrix; // Create and initialize some values from the bounds. float glyphAscent; float glyphDescent; float glyphLeading; var elementPoints = new PointF [3]; for (int glyphIndex = 0; glyphIndex < glyphs.Length; glyphIndex++) { if (glyphIndex > 0) { textMatrix.x0 += glyphPositions [glyphIndex].X - glyphPositions[glyphIndex - 1].X; textMatrix.y0 += glyphPositions [glyphIndex].Y - glyphPositions[glyphIndex - 1].Y; } var glyphPath = font.nativeFont.GetPathForGlyph (glyphs [glyphIndex]); // glyphPath = null if it is a white space character if (glyphPath != null) { glyphPath.Apply ( delegate (CGPathElement pathElement) { elementPoints[0] = textMatrix.TransformPoint(pathElement.Point1).ToPointF (); elementPoints[1] = textMatrix.TransformPoint(pathElement.Point2).ToPointF (); elementPoints[2] = textMatrix.TransformPoint(pathElement.Point3).ToPointF (); //Console.WriteLine ("Applying {0} - {1}, {2}, {3}", pathElement.Type, elementPoints[0], elementPoints[1], elementPoints[2]); // now add position offsets switch(pathElement.Type) { case CGPathElementType.MoveToPoint: start_new_fig = true; Append(elementPoints[0].X, elementPoints[0].Y,PathPointType.Line,true); break; case CGPathElementType.AddLineToPoint: var lastPoint = points[points.Count - 1]; AppendPoint(lastPoint, PathPointType.Line, false); AppendPoint(elementPoints[0], PathPointType.Line, false); break; case CGPathElementType.AddCurveToPoint: case CGPathElementType.AddQuadCurveToPoint: // This is the only thing I can think of right now for the fonts that // I have tested. See the description of the quadraticToCubic method for // more information // Get the last point var pt1 = points[points.Count - 1]; var pt2 = PointF.Empty; var pt3 = PointF.Empty; var pt4 = elementPoints[1]; GeomUtilities.QuadraticToCubic(pt1, elementPoints[0], elementPoints[1], out pt2, out pt3); Append (pt1.X, pt1.Y, PathPointType.Line, true); AppendBezier (pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y); break; case CGPathElementType.CloseSubpath: CloseFigure(); break; } } ); } } } // Move the index beyond the line break. start += count; textPosition.Y += (float)Math.Ceiling(ascent + descent + leading + 1); // +1 matches best to CTFramesetter's behavior line.Dispose(); } }
public object ConvertToNative(Geometry geometry) { // Create the CGPathPlus CGPathPlus cgPath = new CGPathPlus(); // TODO: Has a Dispose. What are the implications? // Obtain the native transform to apply to the geometry CGAffineTransform transform = new CGAffineTransform(); if (geometry.Transform == null) { transform = CGAffineTransform.MakeIdentity(); } else { transform = (CGAffineTransform)geometry.Transform.GetNativeObject(); } // Determine what type of Geometry we're dealing with if (geometry is LineGeometry) { LineGeometry lineGeometry = geometry as LineGeometry; cgPath.MoveToPoint(transform, ConvertPoint(lineGeometry.StartPoint)); cgPath.AddLineToPoint(transform, ConvertPoint(lineGeometry.EndPoint)); } else if (geometry is RectangleGeometry) { Rect rect = (geometry as RectangleGeometry).Rect; cgPath.AddRect(transform, new CGRect(rect.X, rect.Y, rect.Width, rect.Height)); } else if (geometry is EllipseGeometry) { EllipseGeometry ellipseGeometry = geometry as EllipseGeometry; CGRect rect = new CGRect(ellipseGeometry.Center.X - ellipseGeometry.RadiusX, ellipseGeometry.Center.Y - ellipseGeometry.RadiusY, ellipseGeometry.RadiusX * 2, ellipseGeometry.RadiusY * 2); cgPath.AddEllipseInRect(transform, rect); } else if (geometry is GeometryGroup) { GeometryGroup geometryGroup = geometry as GeometryGroup; cgPath.IsNonzeroFill = geometryGroup.FillRule == FillRule.Nonzero; // make a little method? foreach (Geometry child in geometryGroup.Children) { CGPath pathChild = ConvertToNative(child) as CGPath; cgPath.AddPath(pathChild); // Should there be a transform here as the first argument???? } } else if (geometry is PathGeometry) { PathGeometry pathGeometry = geometry as PathGeometry; cgPath.IsNonzeroFill = pathGeometry.FillRule == FillRule.Nonzero; foreach (PathFigure pathFigure in pathGeometry.Figures) { cgPath.MoveToPoint(transform, ConvertPoint(pathFigure.StartPoint)); Point lastPoint = pathFigure.StartPoint; foreach (PathSegment pathSegment in pathFigure.Segments) { // LineSegment if (pathSegment is LineSegment) { LineSegment lineSegment = pathSegment as LineSegment; cgPath.AddLineToPoint(transform, ConvertPoint(lineSegment.Point)); lastPoint = lineSegment.Point; } // PolyLineSegment else if (pathSegment is PolyLineSegment) { PolyLineSegment polylineSegment = pathSegment as PolyLineSegment; PointCollection points = polylineSegment.Points; // TODO: Or AddLines for (int i = 0; i < points.Count; i++) { cgPath.AddLineToPoint(transform, ConvertPoint(points[i])); } lastPoint = points[points.Count - 1]; } // BezierSegment if (pathSegment is BezierSegment) { BezierSegment bezierSegment = pathSegment as BezierSegment; cgPath.AddCurveToPoint(transform, ConvertPoint(bezierSegment.Point1), ConvertPoint(bezierSegment.Point2), ConvertPoint(bezierSegment.Point3)); 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) { cgPath.AddCurveToPoint(transform, ConvertPoint(points[i]), ConvertPoint(points[i + 1]), ConvertPoint(points[i + 2])); } lastPoint = points[points.Count - 1]; } // QuadraticBezierSegment if (pathSegment is QuadraticBezierSegment) { QuadraticBezierSegment bezierSegment = pathSegment as QuadraticBezierSegment; cgPath.AddQuadCurveToPoint(transform, new nfloat(bezierSegment.Point1.X), new nfloat(bezierSegment.Point1.Y), new nfloat(bezierSegment.Point2.X), new nfloat(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) { cgPath.AddQuadCurveToPoint(transform, new nfloat(points[i + 0].X), new nfloat(points[i + 0].Y), new nfloat(points[i + 1].X), new nfloat(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); CGPoint[] cgpoints = new CGPoint[points.Count]; for (int i = 0; i < points.Count; i++) { cgpoints[i] = transform.TransformPoint(ConvertPoint(points[i])); } cgPath.AddLines(cgpoints); lastPoint = points[points.Count - 1]; } } if (pathFigure.IsClosed) { cgPath.CloseSubpath(); } } } return(cgPath); }
public PointF TransformPoint(Point p) { return(control.TransformPoint(p.ToNS()).ToEto()); }