/// <summary> /// /// </summary> /// <param name="pg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static XPathGeometry ToXPathGeometry(this PathGeometry pg, double dx, double dy) { var geometry = XPathGeometry.Create( ImmutableArray.Create <XPathFigure>(), pg.FillRule == FillRule.EvenOdd ? XFillRule.EvenOdd : XFillRule.Nonzero); var context = new XPathGeometryContext(geometry); foreach (var pf in pg.Figures) { context.BeginFigure( XPoint.Create(pf.StartPoint.X + dx, pf.StartPoint.Y + dy), pf.IsFilled, pf.IsClosed); foreach (var segment in pf.Segments) { if (segment is ArcSegment) { var arcSegment = segment as ArcSegment; context.ArcTo( XPoint.Create(arcSegment.Point.X + dx, arcSegment.Point.Y + dy), XPathSize.Create(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == SweepDirection.Clockwise ? XSweepDirection.Clockwise : XSweepDirection.Counterclockwise, arcSegment.IsStroked, arcSegment.IsSmoothJoin); } else if (segment is BezierSegment) { var cubicBezierSegment = segment as BezierSegment; context.CubicBezierTo( XPoint.Create(cubicBezierSegment.Point1.X + dx, cubicBezierSegment.Point1.Y + dy), XPoint.Create(cubicBezierSegment.Point2.X + dx, cubicBezierSegment.Point2.Y + dy), XPoint.Create(cubicBezierSegment.Point3.X + dx, cubicBezierSegment.Point3.Y + dy), cubicBezierSegment.IsStroked, cubicBezierSegment.IsSmoothJoin); } else if (segment is LineSegment) { var lineSegment = segment as LineSegment; context.LineTo( XPoint.Create(lineSegment.Point.X + dx, lineSegment.Point.Y + dy), lineSegment.IsStroked, lineSegment.IsSmoothJoin); } else if (segment is PolyBezierSegment) { var polyCubicBezierSegment = segment as PolyBezierSegment; context.PolyCubicBezierTo( ToXPoints(polyCubicBezierSegment.Points, dx, dy), polyCubicBezierSegment.IsStroked, polyCubicBezierSegment.IsSmoothJoin); } else if (segment is PolyLineSegment) { var polyLineSegment = segment as PolyLineSegment; context.PolyLineTo( ToXPoints(polyLineSegment.Points, dx, dy), polyLineSegment.IsStroked, polyLineSegment.IsSmoothJoin); } else if (segment is PolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as PolyQuadraticBezierSegment; context.PolyQuadraticBezierTo( ToXPoints(polyQuadraticSegment.Points, dx, dy), polyQuadraticSegment.IsStroked, polyQuadraticSegment.IsSmoothJoin); } else if (segment is QuadraticBezierSegment) { var quadraticBezierSegment = segment as QuadraticBezierSegment; context.QuadraticBezierTo( XPoint.Create(quadraticBezierSegment.Point1.X + dx, quadraticBezierSegment.Point1.Y + dy), XPoint.Create(quadraticBezierSegment.Point2.X + dx, quadraticBezierSegment.Point2.Y + dy), quadraticBezierSegment.IsStroked, quadraticBezierSegment.IsSmoothJoin); } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } } return(geometry); }
/// <inheritdoc/> public override void LeftDown(double x, double y) { base.LeftDown(x, y); double sx = _editor.Project.Options.SnapToGrid ? ProjectEditor.Snap(x, _editor.Project.Options.SnapX) : x; double sy = _editor.Project.Options.SnapToGrid ? ProjectEditor.Snap(y, _editor.Project.Options.SnapY) : y; switch (_currentState) { case ToolState.None: { _arc.Start = _editor.TryToGetConnectionPoint(sx, sy) ?? XPoint.Create(sx, sy, _editor.Project.Options.PointShape); if (!_toolPath._isInitialized) { _toolPath.InitializeWorkingPath(_arc.Start); } else { _arc.Start = _toolPath.GetLastPathPoint(); } _arc.End = XPoint.Create(sx, sy, _editor.Project.Options.PointShape); _toolPath._context.ArcTo( _arc.End, XPathSize.Create( Abs(_arc.Start.X - _arc.End.X), Abs(_arc.Start.Y - _arc.End.Y)), _defaultRotationAngle, _defaultIsLargeArc, _defaultSweepDirection, _editor.Project.Options.DefaultIsStroked, _editor.Project.Options.DefaultIsSmoothJoin); _editor.Project.CurrentContainer.WorkingLayer.Invalidate(); ToStateOne(); Move(null); _currentState = ToolState.One; _editor.CancelAvailable = true; } break; case ToolState.One: { _arc.End.X = sx; _arc.End.Y = sy; if (_editor.Project.Options.TryToConnect) { var end = _editor.TryToGetConnectionPoint(sx, sy); if (end != null) { _arc.End = end; } } _arc.Start = _arc.End; _arc.End = XPoint.Create(sx, sy, _editor.Project.Options.PointShape); _toolPath._context.ArcTo( _arc.End, XPathSize.Create( Abs(_arc.Start.X - _arc.End.X), Abs(_arc.Start.Y - _arc.End.Y)), _defaultRotationAngle, _defaultIsLargeArc, _defaultSweepDirection, _editor.Project.Options.DefaultIsStroked, _editor.Project.Options.DefaultIsSmoothJoin); _editor.Project.CurrentContainer.WorkingLayer.Invalidate(); Move(null); _currentState = ToolState.One; } break; } }
/// <summary> /// /// </summary> /// <param name="pg"></param> /// <returns></returns> public static XPathGeometry ToXPathGeometry(this PathGeometry pg) { var xpg = XPathGeometry.Create( new List <XPathFigure>(), pg.FillRule == FillRule.EvenOdd ? XFillRule.EvenOdd : XFillRule.Nonzero); foreach (var pf in pg.Figures) { xpg.BeginFigure( XPoint.Create(pf.StartPoint.X, pf.StartPoint.Y), pf.IsFilled, pf.IsClosed); foreach (var segment in pf.Segments) { if (segment is ArcSegment) { var arcSegment = segment as ArcSegment; xpg.ArcTo( XPoint.Create(arcSegment.Point.X, arcSegment.Point.Y), XPathSize.Create(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == SweepDirection.Clockwise ? XSweepDirection.Clockwise : XSweepDirection.Counterclockwise, arcSegment.IsStroked, arcSegment.IsSmoothJoin); } else if (segment is BezierSegment) { var bezierSegment = segment as BezierSegment; xpg.BezierTo( XPoint.Create(bezierSegment.Point1.X, bezierSegment.Point1.Y), XPoint.Create(bezierSegment.Point2.X, bezierSegment.Point2.Y), XPoint.Create(bezierSegment.Point3.X, bezierSegment.Point3.Y), bezierSegment.IsStroked, bezierSegment.IsSmoothJoin); } else if (segment is LineSegment) { var lineSegment = segment as LineSegment; xpg.LineTo( XPoint.Create(lineSegment.Point.X, lineSegment.Point.Y), lineSegment.IsStroked, lineSegment.IsSmoothJoin); } else if (segment is PolyBezierSegment) { var polyBezierSegment = segment as PolyBezierSegment; xpg.PolyBezierTo( ToXPoints(polyBezierSegment.Points), polyBezierSegment.IsStroked, polyBezierSegment.IsSmoothJoin); } else if (segment is PolyLineSegment) { var polyLineSegment = segment as PolyLineSegment; xpg.PolyLineTo( ToXPoints(polyLineSegment.Points), polyLineSegment.IsStroked, polyLineSegment.IsSmoothJoin); } else if (segment is PolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as PolyQuadraticBezierSegment; xpg.PolyQuadraticBezierTo( ToXPoints(polyQuadraticSegment.Points), polyQuadraticSegment.IsStroked, polyQuadraticSegment.IsSmoothJoin); } else if (segment is QuadraticBezierSegment) { var qbezierSegment = segment as QuadraticBezierSegment; xpg.QuadraticBezierTo( XPoint.Create(qbezierSegment.Point1.X, qbezierSegment.Point1.Y), XPoint.Create(qbezierSegment.Point2.X, qbezierSegment.Point2.Y), qbezierSegment.IsStroked, qbezierSegment.IsSmoothJoin); } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } } return(xpg); }
/// <summary> /// Parse a SVG path geometry string. /// </summary> /// <param name="context">The geometry context.</param> /// <param name="pathString">The path geometry string</param> /// <param name="startIndex">The string start index.</param> public void Parse(XGeometryContext context, string pathString, int startIndex) { _context = context; _pathString = pathString; _pathLength = pathString.Length; _curIndex = startIndex; _secondLastPoint = Point2.Create(0, 0); _lastPoint = Point2.Create(0, 0); _lastStart = Point2.Create(0, 0); _figureStarted = false; bool first = true; char last_cmd = ' '; while (ReadToken()) { char cmd = _token; if (first) { if ((cmd != 'M') && (cmd != 'm')) { InvalidToken(); } first = false; } switch (cmd) { case 'm': case 'M': _lastPoint = ReadPoint(cmd, !_allowComma); _context.BeginFigure(XPoint.FromPoint2(_lastPoint), _isFilled, !_isClosed); _figureStarted = true; _lastStart = _lastPoint; last_cmd = 'M'; while (IsNumber(_allowComma)) { _lastPoint = ReadPoint(cmd, !_allowComma); _context.LineTo(XPoint.FromPoint2(_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(XPoint.FromPoint2(_lastPoint), _isStroked, !_isSmoothJoin); }while (IsNumber(_allowComma)); last_cmd = 'L'; break; case 'c': case 'C': case 's': case 'S': EnsureFigure(); do { Point2 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.CubicBezierTo( XPoint.FromPoint2(p), XPoint.FromPoint2(_secondLastPoint), XPoint.FromPoint2(_lastPoint), _isStroked, !_isSmoothJoin); last_cmd = 'C'; }while (IsNumber(_allowComma)); break; case 'q': case 'Q': case 't': case 'T': 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( XPoint.FromPoint2(_secondLastPoint), XPoint.FromPoint2(_lastPoint), _isStroked, !_isSmoothJoin); last_cmd = 'Q'; }while (IsNumber(_allowComma)); break; case 'a': case 'A': EnsureFigure(); do { double w = ReadNumber(!_allowComma); double h = ReadNumber(_allowComma); double rotation = ReadNumber(_allowComma); bool large = ReadBool(); bool sweep = ReadBool(); _lastPoint = ReadPoint(cmd, _allowComma); _context.ArcTo( XPoint.FromPoint2(_lastPoint), XPathSize.Create(w, h), rotation, large, sweep ? XSweepDirection.Clockwise : XSweepDirection.Counterclockwise, _isStroked, !_isSmoothJoin); }while (IsNumber(_allowComma)); last_cmd = 'A'; break; case 'z': case 'Z': EnsureFigure(); _context.SetClosedState(_isClosed); _figureStarted = false; last_cmd = 'Z'; _lastPoint = _lastStart; break; default: InvalidToken(); break; } } }
/// <summary> /// Initializes static designer context. /// </summary> /// <param name="renderer">The design time renderer instance.</param> /// <param name="clipboard">The design time clipboard instance.</param> /// <param name="jsonSerializer">The design time Json serializer instance.</param> /// <param name="xamlSerializer">The design time Xaml serializer instance.</param> /// <returns>The new instance of the <see cref="DesignerContext"/> class.</returns> public static void InitializeContext(ShapeRenderer renderer, ITextClipboard clipboard, ITextSerializer jsonSerializer, ITextSerializer xamlSerializer) { // Editor Editor = new ProjectEditor() { CurrentTool = Tool.Selection, CurrentPathTool = PathTool.Line, CommandManager = new DesignerCommandManager(), Renderers = new ShapeRenderer[] { renderer }, ProjectFactory = new ProjectFactory(), TextClipboard = clipboard, JsonSerializer = jsonSerializer, XamlSerializer = xamlSerializer }.Defaults(); // Recent Projects Editor.RecentProjects = Editor.RecentProjects.Add(RecentFile.Create("Test1", "Test1.project")); Editor.RecentProjects = Editor.RecentProjects.Add(RecentFile.Create("Test2", "Test2.project")); // Commands Editor.InitializeCommands(); InitializeCommands(Editor); Editor.CommandManager.RegisterCommands(); // New Project Editor.OnNew(null); // Data var db = XDatabase.Create("Db"); var fields = new string[] { "Column0", "Column1" }; var columns = ImmutableArray.CreateRange(fields.Select(c => XColumn.Create(db, c))); db.Columns = columns; var values = Enumerable.Repeat("<empty>", db.Columns.Length).Select(c => XValue.Create(c)); var record = XRecord.Create( db, db.Columns, ImmutableArray.CreateRange(values)); db.Records = db.Records.Add(record); db.CurrentRecord = record; Database = db; Data = XContext.Create(record); Record = record; // Project IProjectFactory factory = new ProjectFactory(); Project = factory.GetProject(); Template = XContainer.CreateTemplate(); Page = XContainer.CreatePage(); var layer = Page.Layers.FirstOrDefault(); layer.Shapes = layer.Shapes.Add(XLine.Create(0, 0, null, null)); Page.CurrentLayer = layer; Page.CurrentShape = layer.Shapes.FirstOrDefault(); Page.Template = Template; Document = XDocument.Create(); Layer = XLayer.Create(); Options = XOptions.Create(); // State State = ShapeState.Create(); // Style ArgbColor = ArgbColor.Create(); ArrowStyle = ArrowStyle.Create(); FontStyle = FontStyle.Create(); LineFixedLength = LineFixedLength.Create(); LineStyle = LineStyle.Create(); Style = ShapeStyle.Create("Default"); TextStyle = TextStyle.Create(); // Shapes Arc = XArc.Create(0, 0, Style, null); CubicBezier = XCubicBezier.Create(0, 0, Style, null); Ellipse = XEllipse.Create(0, 0, Style, null); Group = XGroup.Create(Constants.DefaulGroupName); Image = XImage.Create(0, 0, Style, null, "key"); Line = XLine.Create(0, 0, Style, null); Path = XPath.Create("Path", Style, null); Point = XPoint.Create(); QuadraticBezier = XQuadraticBezier.Create(0, 0, Style, null); Rectangle = XRectangle.Create(0, 0, Style, null); Text = XText.Create(0, 0, Style, null, "Text"); // Path ArcSegment = XArcSegment.Create(XPoint.Create(), XPathSize.Create(), 180, true, XSweepDirection.Clockwise, true, true); CubicBezierSegment = XCubicBezierSegment.Create(XPoint.Create(), XPoint.Create(), XPoint.Create(), true, true); LineSegment = XLineSegment.Create(XPoint.Create(), true, true); PathFigure = XPathFigure.Create(XPoint.Create(), false, true); PathGeometry = XPathGeometry.Create(ImmutableArray.Create <XPathFigure>(), XFillRule.EvenOdd); PathSize = XPathSize.Create(); PolyCubicBezierSegment = XPolyCubicBezierSegment.Create(ImmutableArray.Create <XPoint>(), true, true); PolyLineSegment = XPolyLineSegment.Create(ImmutableArray.Create <XPoint>(), true, true); PolyQuadraticBezierSegment = XPolyQuadraticBezierSegment.Create(ImmutableArray.Create <XPoint>(), true, true); QuadraticBezierSegment = XQuadraticBezierSegment.Create(XPoint.Create(), XPoint.Create(), true, true); }