static void FillContexForCurve(StreamGeometryContext context,Curve c) { foreach(ICurve seg in c.Segments) { var bezSeg = seg as CubicBezierSegment; if(bezSeg != null) { context.BezierTo(Common.WpfPoint(bezSeg.B(1)), Common.WpfPoint(bezSeg.B(2)),Common.WpfPoint(bezSeg.B(3)),true,false); } else { var ls = seg as LineSegment; if(ls != null) context.LineTo(Common.WpfPoint(ls.End),true,false); else { var ellipse = seg as Ellipse; if(ellipse != null) { // context.LineTo(Common.WpfPoint(ellipse.End),true,false); double sweepAngle = EllipseSweepAngle(ellipse); bool largeArc = Math.Abs(sweepAngle) >= Math.PI; Rectangle box = ellipse.FullBox(); context.ArcTo(Common.WpfPoint(ellipse.End), new Size(box.Width / 2,box.Height / 2), sweepAngle, largeArc, sweepAngle < 0 ? SweepDirection.Counterclockwise : SweepDirection.Clockwise, true,true); } else throw new NotImplementedException(); } } } }
/// <summary> /// Parse a PathFigureCollection string /// </summary> internal void ParseToGeometryContext( StreamGeometryContext context, string pathString, int startIndex) { // [BreakingChange] Dev10 Bug #453199 // We really should throw an ArgumentNullException here for context and pathString. // From original code // This is only used in call to Double.Parse _formatProvider = System.Globalization.CultureInfo.InvariantCulture; _context = context; _pathString = pathString; _pathLength = pathString.Length; _curIndex = startIndex; _secondLastPoint = new Point(0, 0); _lastPoint = new Point(0, 0); _lastStart = new Point(0, 0); _figureStarted = false; bool first = true; char last_cmd = ' '; while (ReadToken()) // Empty path is allowed in XAML { char cmd = _token; if (first) { if ((cmd != 'M') && (cmd != 'm')) // Path starts with M|m { ThrowBadToken(); } first = false; } switch (cmd) { case 'm': case 'M': // XAML allows multiple points after M/m _lastPoint = ReadPoint(cmd, ! AllowComma); context.BeginFigure(_lastPoint, IsFilled, ! IsClosed); _figureStarted = true; _lastStart = _lastPoint; last_cmd = 'M'; while (IsNumber(AllowComma)) { _lastPoint = ReadPoint(cmd, ! AllowComma); context.LineTo(_lastPoint, IsStroked, ! IsSmoothJoin); last_cmd = 'L'; } break; case 'l': case 'L': case 'h': case 'H': case 'v': case 'V': EnsureFigure(); do { switch (cmd) { case 'l': _lastPoint = ReadPoint(cmd, ! AllowComma); break; case 'L': _lastPoint = ReadPoint(cmd, ! AllowComma); break; case 'h': _lastPoint.X += ReadNumber(! AllowComma); break; case 'H': _lastPoint.X = ReadNumber(! AllowComma); break; case 'v': _lastPoint.Y += ReadNumber(! AllowComma); break; case 'V': _lastPoint.Y = ReadNumber(! AllowComma); break; } context.LineTo(_lastPoint, IsStroked, ! IsSmoothJoin); } while (IsNumber(AllowComma)); last_cmd = 'L'; break; case 'c': case 'C': // cubic Bezier case 's': case 'S': // smooth cublic Bezier EnsureFigure(); do { Point p; if ((cmd == 's') || (cmd == 'S')) { if (last_cmd == 'C') { p = Reflect(); } else { p = _lastPoint; } _secondLastPoint = ReadPoint(cmd, ! AllowComma); } else { p = ReadPoint(cmd, ! AllowComma); _secondLastPoint = ReadPoint(cmd, AllowComma); } _lastPoint = ReadPoint(cmd, AllowComma); context.BezierTo(p, _secondLastPoint, _lastPoint, IsStroked, ! IsSmoothJoin); last_cmd = 'C'; } while (IsNumber(AllowComma)); break; case 'q': case 'Q': // quadratic Bezier case 't': case 'T': // smooth quadratic Bezier EnsureFigure(); do { if ((cmd == 't') || (cmd == 'T')) { if (last_cmd == 'Q') { _secondLastPoint = Reflect(); } else { _secondLastPoint = _lastPoint; } _lastPoint = ReadPoint(cmd, ! AllowComma); } else { _secondLastPoint = ReadPoint(cmd, ! AllowComma); _lastPoint = ReadPoint(cmd, AllowComma); } context.QuadraticBezierTo(_secondLastPoint, _lastPoint, IsStroked, ! IsSmoothJoin); last_cmd = 'Q'; } while (IsNumber(AllowComma)); break; case 'a': case 'A': EnsureFigure(); do { // A 3,4 5, 0, 0, 6,7 double w = ReadNumber(! AllowComma); double h = ReadNumber(AllowComma); double rotation = ReadNumber(AllowComma); bool large = ReadBool(); bool sweep = ReadBool(); _lastPoint = ReadPoint(cmd, AllowComma); context.ArcTo( _lastPoint, new Size(w, h), rotation, large, #if PBTCOMPILER sweep, #else sweep ? SweepDirection.Clockwise : SweepDirection.Counterclockwise, #endif IsStroked, ! IsSmoothJoin ); } while (IsNumber(AllowComma)); last_cmd = 'A'; break; case 'z': case 'Z': EnsureFigure(); context.SetClosedState(IsClosed); _figureStarted = false; last_cmd = 'Z'; _lastPoint = _lastStart; // Set reference point to be first point of current figure break; default: ThrowBadToken(); break; } } }
/// <summary> /// The actual method for drawing the arrow. /// </summary> /// <param name="StreamGeometryContext">Describes a geometry using drawing commands.</param> protected override void DrawArrowGeometry(StreamGeometryContext StreamGeometryContext) { var theta = Math.Atan2(Y1 - Y2, X1 - X2); var sint = Math.Sin(theta); var cost = Math.Cos(theta); var ArrowOrigin = new Point(X1, Y1); var OriginControlPoint = new Point(X1CP, Y1CP); var ArrowTarget = new Point(X2, Y2); var TargetControlPoint = new Point(Y2CP, Y2CP); var pt3 = new Point(X2 + (HeadWidth * cost - HeadHeight * sint), Y2 + (HeadWidth * sint + HeadHeight * cost)); var pt4 = new Point(X2 + (HeadWidth * cost + HeadHeight * sint), Y2 - (HeadHeight * cost - HeadWidth * sint)); StreamGeometryContext.BeginFigure(ArrowOrigin, isFilled: false, isClosed: false); StreamGeometryContext.BezierTo(OriginControlPoint, TargetControlPoint, ArrowTarget, true, true); //StreamGeometryContext.LineTo (pt3, isStroked: true, isSmoothJoin: true); //StreamGeometryContext.LineTo (ArrowTarget, isStroked: true, isSmoothJoin: true); //StreamGeometryContext.LineTo (pt4, isStroked: true, isSmoothJoin: true); }
static internal void FillContextForICurve(StreamGeometryContext context,ICurve iCurve) { context.BeginFigure(Common.WpfPoint(iCurve.Start),false,false); var c = iCurve as Curve; if(c != null) FillContexForCurve(context,c); else { var cubicBezierSeg = iCurve as CubicBezierSegment; if(cubicBezierSeg != null) context.BezierTo(Common.WpfPoint(cubicBezierSeg.B(1)),Common.WpfPoint(cubicBezierSeg.B(2)), Common.WpfPoint(cubicBezierSeg.B(3)),true,false); else { var ls = iCurve as LineSegment; if(ls != null) context.LineTo(Common.WpfPoint(ls.End),true,false); else { var rr = iCurve as RoundedRect; if(rr != null) FillContexForCurve(context,rr.Curve); else { var poly = iCurve as Polyline; if (poly != null) FillContexForPolyline(context, poly); else { var ellipse = iCurve as Ellipse; if (ellipse != null) { // context.LineTo(Common.WpfPoint(ellipse.End),true,false); double sweepAngle = EllipseSweepAngle(ellipse); bool largeArc = Math.Abs(sweepAngle) >= Math.PI; Rectangle box = ellipse.FullBox(); context.ArcTo(Common.WpfPoint(ellipse.End), new Size(box.Width/2, box.Height/2), sweepAngle, largeArc, sweepAngle < 0 ? SweepDirection.Counterclockwise : SweepDirection.Clockwise, true, true); } else { throw new NotImplementedException(); } } } } } } }
/// <summary> /// SerializeData - Serialize the contents of this Segment to the provided context. /// </summary> internal override void SerializeData(StreamGeometryContext ctx) { ctx.BezierTo(Point1, Point2, Point3, IsStroked, IsSmoothJoin); }
public static void DrawFigure(StreamGeometryContext ctx, PathFigure figure) { ctx.BeginFigure(figure.StartPoint, figure.IsFilled, figure.IsClosed); foreach (var segment in figure.Segments) { var lineSegment = segment as WpfLineSegment; if (lineSegment != null) { ctx.LineTo(lineSegment.Point, lineSegment.IsStroked, lineSegment.IsSmoothJoin); continue; } var bezierSegment = segment as BezierSegment; if (bezierSegment != null) { ctx.BezierTo(bezierSegment.Point1, bezierSegment.Point2, bezierSegment.Point3, bezierSegment.IsStroked, bezierSegment.IsSmoothJoin); continue; } var quadraticSegment = segment as QuadraticBezierSegment; if (quadraticSegment != null) { ctx.QuadraticBezierTo(quadraticSegment.Point1, quadraticSegment.Point2, quadraticSegment.IsStroked, quadraticSegment.IsSmoothJoin); continue; } var polyLineSegment = segment as PolyLineSegment; if (polyLineSegment != null) { ctx.PolyLineTo(polyLineSegment.Points, polyLineSegment.IsStroked, polyLineSegment.IsSmoothJoin); continue; } var polyBezierSegment = segment as PolyBezierSegment; if (polyBezierSegment != null) { ctx.PolyBezierTo(polyBezierSegment.Points, polyBezierSegment.IsStroked, polyBezierSegment.IsSmoothJoin); continue; } var polyQuadraticSegment = segment as PolyQuadraticBezierSegment; if (polyQuadraticSegment != null) { ctx.PolyQuadraticBezierTo(polyQuadraticSegment.Points, polyQuadraticSegment.IsStroked, polyQuadraticSegment.IsSmoothJoin); continue; } var arcSegment = segment as ArcSegment; if (arcSegment != null) { ctx.ArcTo(arcSegment.Point, arcSegment.Size, arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection, arcSegment.IsStroked, arcSegment.IsSmoothJoin); continue; } } }
private void InternalDrawArrowGeometry(StreamGeometryContext context) { Point pt1, pt2, pt3, pt4; if (ConnectionArrowType == ConnectionArrowType.Normal) { var theta = Math.Atan2(Y1 - Y2, X1 - X2); var sint = Math.Sin(theta); var cost = Math.Cos(theta); switch (ViewType) { case 0: // прямая в центр pt1 = new Point(X1, Y1); pt2 = new Point(X2, Y2); pt3 = new Point( X2 + (HeadWidth * cost - HeadHeight * sint), Y2 + (HeadWidth * sint + HeadHeight * cost)); pt4 = new Point( X2 + (HeadWidth * cost + HeadHeight * sint), Y2 - (HeadHeight * cost - HeadWidth * sint)); context.BeginFigure(pt1, true, false); context.LineTo(pt2, true, true); context.LineTo(pt3, true, true); context.LineTo(pt2, true, true); context.LineTo(pt4, true, true); break; case 1: // безье (слабое) в центр pt1 = new Point(X1, Y1); pt2 = new Point(X2, Y2); var ptTemp1 = new Point( X1 - (X1 - X2) / 2, Y1 - (Y1 - Y2) / 3); var ptTemp2 = new Point( X1 - (X1 - X2) / 4 * 3, Y1 - (Y1 - Y2) / 3 * 2); pt3 = new Point( X2 + (HeadWidth * cost - HeadHeight * sint), Y2 + (HeadWidth * sint + HeadHeight * cost)); pt4 = new Point( X2 + (HeadWidth * cost + HeadHeight * sint), Y2 - (HeadHeight * cost - HeadWidth * sint)); context.BeginFigure(pt1, true, false); context.BezierTo(ptTemp1, ptTemp2, pt2, true, true); context.LineTo(pt3, true, true); context.LineTo(pt2, true, true); context.LineTo(pt4, true, true); break; case 2: // к ближайшему краю var startPoint = GetBoundPoint(false); X1 = startPoint.X; Y1 = startPoint.Y; var endPoint = GetBoundPoint(true); X2 = endPoint.X; Y2 = endPoint.Y; pt3 = new Point( X2 + (HeadWidth * cost - HeadHeight * sint), Y2 + (HeadWidth * sint + HeadHeight * cost)); pt4 = new Point( X2 + (HeadWidth * cost + HeadHeight * sint), Y2 - (HeadHeight * cost - HeadWidth * sint)); context.BeginFigure(startPoint, true, false); context.LineTo(endPoint, true, false); context.LineTo(pt3, true, true); context.LineTo(endPoint, true, true); context.LineTo(pt4, true, true); break; } } else if (ConnectionArrowType == ConnectionArrowType.Loopback) { pt1 = new Point(FromItem.Position.X - 5, FromItem.Position.Y + 83); pt2 = new Point(pt1.X + 10, pt1.Y - 10); pt3 = new Point(pt2.X - 4, pt2.Y + 9); pt4 = new Point(pt2.X - 6, pt2.Y + 16); context.BeginFigure(pt1, true, false); context.ArcTo(pt2, new Size(6, 6), 125, true, SweepDirection.Clockwise, true, true); context.ArcTo(pt1, new Size(6, 6), 125, true, SweepDirection.Clockwise, true, true); context.LineTo(pt3, true, true); context.LineTo(pt1, true, true); context.LineTo(pt4, true, true); } else { pt1 = new Point(X1 + 20, Y1 - 25); pt2 = new Point(pt1.X + 10, pt1.Y - 10); pt3 = new Point(pt2.X - 6, pt2.Y + 2); pt4 = new Point(pt2.X - 2, pt2.Y + 6); context.BeginFigure(pt1, true, false); context.LineTo(pt2, true, true); context.LineTo(pt3, true, true); context.LineTo(pt2, true, true); context.LineTo(pt4, true, true); } }
internal void FillContextForICurve(StreamGeometryContext context, ICurve iCurve) { if (iCurve == null) return; context.BeginFigure(CommonX.WpfPoint(iCurve.Start), false, false); var c = iCurve as Curve; if (c != null) FillContexForCurve(context, c); else { var cubicBezierSeg = iCurve as CubicBezierSegment; if (cubicBezierSeg != null) context.BezierTo(CommonX.WpfPoint(cubicBezierSeg.B(1)), CommonX.WpfPoint(cubicBezierSeg.B(2)), CommonX.WpfPoint(cubicBezierSeg.B(3)), true, false); else { var ls = iCurve as LineSegment; if (ls != null) context.LineTo(CommonX.WpfPoint(ls.End), true, false); else { var rr = iCurve as RoundedRect; if (rr != null) FillContexForCurve(context, rr.Curve); else { var poly = iCurve as Polyline; FillContexForPolyline(context, poly); } } } } }