/// <summary> /// /// </summary> public override void Remove() { if (_line12 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_line12); _line12 = null; } if (_line32 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_line32); _line32 = null; } if (_helperPoint1 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_helperPoint1); _helperPoint1 = null; } if (_helperPoint2 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_helperPoint2); _helperPoint2 = null; } if (_helperPoint3 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_helperPoint3); _helperPoint3 = null; } _style = null; }
/// <summary> /// /// </summary> public override void ToStateTwo() { _style = _editor.Project.Options.HelperStyle; _line12 = XLine.Create(0, 0, _style, null); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_line12); _helperPoint2 = XPoint.Create(0, 0, _editor.Project.Options.PointShape); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_helperPoint2); }
/// <summary> /// /// </summary> /// <param name="x"></param> /// <param name="y"></param> public override void LeftDown(double x, double y) { double sx = _editor.Project.Options.SnapToGrid ? Editor.Snap(x, _editor.Project.Options.SnapX) : x; double sy = _editor.Project.Options.SnapToGrid ? Editor.Snap(y, _editor.Project.Options.SnapY) : y; switch (_currentState) { case State.None: { _shape = XLine.Create( sx, sy, _editor.Project.CurrentStyleLibrary.CurrentStyle, _editor.Project.Options.PointShape, _editor.Project.Options.DefaultIsStroked); if (_editor.Project.Options.TryToConnect) { var result = TryToConnectStart(_shape as XLine, sx, sy); if (!result) { _editor.TryToSplitLine(x, y, _shape.Start); } } _editor.Project.CurrentContainer.WorkingLayer.Shapes = _editor.Project.CurrentContainer.WorkingLayer.Shapes.Add(_shape); _editor.Project.CurrentContainer.WorkingLayer.Invalidate(); ToStateOne(); Move(_shape); _editor.Project.CurrentContainer.HelperLayer.Invalidate(); _currentState = State.One; _editor.CancelAvailable = true; } break; case State.One: { var line = _shape as XLine; if (line != null) { line.End.X = sx; line.End.Y = sy; if (_editor.Project.Options.TryToConnect) { var result = TryToConnectEnd(_shape as XLine, sx, sy); if (!result) { _editor.TryToSplitLine(x, y, _shape.End); } } _editor.Project.CurrentContainer.WorkingLayer.Shapes = _editor.Project.CurrentContainer.WorkingLayer.Shapes.Remove(_shape); Remove(); Finalize(_shape); _editor.AddWithHistory(_shape); _currentState = State.None; _editor.CancelAvailable = false; } } break; } }
/// <summary> /// /// </summary> public override void ToStateThree() { _line43 = XLine.Create(0, 0, _style, null); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_line43); _line23 = XLine.Create(0, 0, _style, null); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_line23); _helperPoint3 = XPoint.Create(0, 0, _editor.Project.Options.PointShape); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_helperPoint3); }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="p"></param> /// <param name="treshold"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static bool HitTestLine(XLine line, Vector2 p, double treshold, double dx, double dy) { var a = new Vector2(line.Start.X + dx, line.Start.Y + dy); var b = new Vector2(line.End.X + dx, line.End.Y + dy); var nearest = MathHelpers.NearestPointOnLine(a, b, p); double distance = MathHelpers.Distance(p.X, p.Y, nearest.X, nearest.Y); return(distance < treshold); }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public bool TryToConnectEnd(XLine line, double x, double y) { var result = ShapeBounds.HitTest(_editor.Project.CurrentContainer, new Vector2(x, y), _editor.Project.Options.HitTreshold); if (result != null && result is XPoint) { line.End = result as XPoint; return(true); } return(false); }
/// <summary> /// /// </summary> /// <param name="pss"></param> /// <returns></returns> public static BaseShape CrossPointShape(ShapeStyle pss) { var g = XGroup.Create("PointShape"); var builder = g.Shapes.ToBuilder(); builder.Add(XLine.Create(-4, 0, 4, 0, pss, null)); builder.Add(XLine.Create(0, -4, 0, 4, pss, null)); g.Shapes = builder.ToImmutable(); return(g); }
/// <summary> /// Creates a new instance of the XLine class. /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="isStroked"></param> /// <returns></returns> public XLine Line(XPoint start, XPoint end, bool isStroked = true) { var line = XLine.Create( start, end, Context.Editor.Project.CurrentStyleLibrary.CurrentStyle, Context.Editor.Project.Options.PointShape, isStroked); Context.Editor.AddWithHistory(line); return(line); }
/// <summary> /// /// </summary> public override void Remove() { if (_ellipse != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_ellipse); _ellipse = null; } if (_startLine != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_startLine); _startLine = null; } if (_endLine != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_endLine); _endLine = null; } if (_p1HelperPoint != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_p1HelperPoint); _p1HelperPoint = null; } if (_p2HelperPoint != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_p2HelperPoint); _p2HelperPoint = null; } if (_centerHelperPoint != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_centerHelperPoint); _centerHelperPoint = null; } if (_startHelperPoint != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_startHelperPoint); _startHelperPoint = null; } if (_endHelperPoint != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_endHelperPoint); _endHelperPoint = null; } _style = null; }
/// <summary> /// /// </summary> public override void ToStateThree() { if (_ellipse != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_ellipse); _ellipse = null; } _endLine = XLine.Create(0, 0, _style, null); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_endLine); _endHelperPoint = XPoint.Create(0, 0, _editor.Project.Options.PointShape); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_endHelperPoint); }
/// <summary> /// Creates a new instance of the XLine class. /// </summary> /// <param name="x1"></param> /// <param name="y1"></param> /// <param name="x2"></param> /// <param name="y2"></param> /// <param name="isStroked"></param> /// <returns></returns> public XLine Line( double x1 = 30, double y1 = 30, double x2 = 60, double y2 = 30, bool isStroked = true) { var line = XLine.Create( x1, y1, x2, y2, Context.Editor.Project.CurrentStyleLibrary.CurrentStyle, Context.Editor.Project.Options.PointShape, isStroked); Context.Editor.AddWithHistory(line); return(line); }
/// <summary> /// /// </summary> public override void ToStateTwo() { if (_p1HelperPoint != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_p1HelperPoint); _p1HelperPoint = null; } if (_p2HelperPoint != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_p2HelperPoint); _p2HelperPoint = null; } _startLine = XLine.Create(0, 0, _style, null); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_startLine); _startHelperPoint = XPoint.Create(0, 0, _editor.Project.Options.PointShape); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_startHelperPoint); }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="y1"></param> /// <param name="y2"></param> public static void SetMaxLengthVertical(XLine line, ref double y1, ref double y2) { var ls = line.Style.LineStyle; bool shortenStart = ls.FixedLength.StartTrigger.Flags != ShapeStateFlags.Default && line.Start.State.Flags.HasFlag(ls.FixedLength.StartTrigger.Flags) && ls.FixedLength.Flags.HasFlag(LineFixedLengthFlags.Start); bool shortenEnd = ls.FixedLength.EndTrigger.Flags != ShapeStateFlags.Default && line.End.State.Flags.HasFlag(ls.FixedLength.EndTrigger.Flags) && ls.FixedLength.Flags.HasFlag(LineFixedLengthFlags.End); if (shortenStart && !shortenEnd) { if (y2 > y1) { y1 = y2 - ls.FixedLength.Length; } else { y1 = y2 + ls.FixedLength.Length; } } if (!shortenStart && shortenEnd) { if (y2 > y1) { y2 = y1 + ls.FixedLength.Length; } else { y2 = y1 - ls.FixedLength.Length; } } if (shortenStart && shortenEnd) { // TODO: Implement shorten start and end case. } }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="x1"></param> /// <param name="x2"></param> public static void SetMaxLengthHorizontal(XLine line, ref double x1, ref double x2) { var ls = line.Style.LineStyle; bool shortenStart = ls.FixedLength.StartTrigger.Flags != ShapeStateFlags.Default && line.Start.State.Flags.HasFlag(ls.FixedLength.StartTrigger.Flags) && ls.FixedLength.Flags.HasFlag(LineFixedLengthFlags.Start); bool shortenEnd = ls.FixedLength.EndTrigger.Flags != ShapeStateFlags.Default && line.End.State.Flags.HasFlag(ls.FixedLength.EndTrigger.Flags) && ls.FixedLength.Flags.HasFlag(LineFixedLengthFlags.End); if (shortenStart && !shortenEnd) { if (x2 > x1) { x1 = x2 - ls.FixedLength.Length; } else { x1 = x2 + ls.FixedLength.Length; } } if (!shortenStart && shortenEnd) { if (x2 > x1) { x2 = x1 + ls.FixedLength.Length; } else { x2 = x1 - ls.FixedLength.Length; } } if (shortenStart && shortenEnd) { // TODO: Implement shorten start and end case. } }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="x1"></param> /// <param name="y1"></param> /// <param name="x2"></param> /// <param name="y2"></param> public static void SetMaxLengthAll( XLine line, ref double x1, ref double y1, ref double x2, ref double y2) { var ls = line.Style.LineStyle; bool shortenStart = ls.FixedLength.StartTrigger.Flags != ShapeStateFlags.Default && line.Start.State.Flags.HasFlag(ls.FixedLength.StartTrigger.Flags) && ls.FixedLength.Flags.HasFlag(LineFixedLengthFlags.Start); bool shortenEnd = ls.FixedLength.EndTrigger.Flags != ShapeStateFlags.Default && line.End.State.Flags.HasFlag(ls.FixedLength.EndTrigger.Flags) && ls.FixedLength.Flags.HasFlag(LineFixedLengthFlags.End); if (shortenStart && !shortenEnd) { double dx = x1 - x2; double dy = y1 - y2; double distance = Math.Sqrt(dx * dx + dy * dy); x1 = x2 - (x2 - x1) / distance * ls.FixedLength.Length; y1 = y2 - (y2 - y1) / distance * ls.FixedLength.Length; } if (!shortenStart && shortenEnd) { double dx = x2 - x1; double dy = y2 - y1; double distance = Math.Sqrt(dx * dx + dy * dy); x2 = x1 - (x1 - x2) / distance * ls.FixedLength.Length; y2 = y1 - (y1 - y2) / distance * ls.FixedLength.Length; } if (shortenStart && shortenEnd) { // TODO: Implement shorten start and end case. } }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="x1"></param> /// <param name="y1"></param> /// <param name="x2"></param> /// <param name="y2"></param> public static void SetMaxLength( XLine line, ref double x1, ref double y1, ref double x2, ref double y2) { var ls = line.Style.LineStyle; if (ls.FixedLength.Flags == LineFixedLengthFlags.Disabled) { return; } if (ls.FixedLength.Flags.HasFlag(LineFixedLengthFlags.All)) { SetMaxLengthAll(line, ref x1, ref y1, ref x2, ref y2); } else { if (ls.FixedLength.Flags.HasFlag(LineFixedLengthFlags.Vertical)) { bool isVertical = Math.Round(x1, 1) == Math.Round(x2, 1); if (isVertical) { SetMaxLengthVertical(line, ref y1, ref y2); } } if (ls.FixedLength.Flags.HasFlag(LineFixedLengthFlags.Horizontal)) { bool isHorizontal = Math.Round(y1, 1) == Math.Round(y2, 1); if (isHorizontal) { SetMaxLengthHorizontal(line, ref x1, ref x2); } } } }
public void Draw(object ds, XLine line, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { // TODO: Finish draw line implementation. var _ds = ds as CanvasDrawingSession; double thicknessLine = line.Style.Thickness / _state.Zoom; double thicknessStartArrow = line.Style.StartArrowStyle.Thickness / _state.Zoom; double thicknessEndArrow = line.Style.EndArrowStyle.Thickness / _state.Zoom; var fillLine = ToColor(line.Style.Fill); var strokeLine = ToColor(line.Style.Stroke); var fillStartArrow = ToColor(line.Style.StartArrowStyle.Fill); var strokeStartArrow = ToColor(line.Style.StartArrowStyle.Stroke); var fillEndArrow = ToColor(line.Style.EndArrowStyle.Fill); var strokeEndArrow = ToColor(line.Style.EndArrowStyle.Stroke); var ssLine = CreateStrokeStyle(line.Style); var ssStartArrow = CreateStrokeStyle(line.Style.StartArrowStyle); var ssEndArrow = CreateStrokeStyle(line.Style.EndArrowStyle); double _x1 = line.Start.X + dx; double _y1 = line.Start.Y + dy; double _x2 = line.End.X + dx; double _y2 = line.End.Y + dy; XLine.SetMaxLength(line, ref _x1, ref _y1, ref _x2, ref _y2); float x1 = (float)_x1; float y1 = (float)_y1; float x2 = (float)_x2; float y2 = (float)_y2; var sas = line.Style.StartArrowStyle; var eas = line.Style.EndArrowStyle; float a1 = (float)Math.Atan2(y1 - y2, x1 - x2); float a2 = (float)Math.Atan2(y2 - y1, x2 - x1); var t1 = N.Matrix3x2.CreateRotation(a1, new N.Vector2(x1, y1)); var t2 = N.Matrix3x2.CreateRotation(a2, new N.Vector2(x2, y2)); N.Vector2 pt1; N.Vector2 pt2; double radiusX1 = sas.RadiusX; double radiusY1 = sas.RadiusY; double sizeX1 = 2.0 * radiusX1; double sizeY1 = 2.0 * radiusY1; switch (sas.ArrowType) { default: case ArrowType.None: { pt1 = new N.Vector2(x1, y1); } break; case ArrowType.Rectangle: { pt1 = N.Vector2.Transform(new N.Vector2(x1 - (float)sizeX1, y1), t1); var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); var old = _ds.Transform; _ds.Transform = t1; DrawRectangleInternal(_ds, fillStartArrow, strokeStartArrow, ssStartArrow, sas.IsStroked, sas.IsFilled, ref rect, thicknessStartArrow); _ds.Transform = old; } break; case ArrowType.Ellipse: { pt1 = N.Vector2.Transform(new N.Vector2(x1 - (float)sizeX1, y1), t1); var old = _ds.Transform; _ds.Transform = t1; var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); DrawEllipseInternal(_ds, fillStartArrow, strokeStartArrow, ssStartArrow, sas.IsStroked, sas.IsFilled, ref rect, thicknessStartArrow); _ds.Transform = old; } break; case ArrowType.Arrow: { pt1 = N.Vector2.Transform(new N.Vector2(x1, y1), t1); var p11 = N.Vector2.Transform(new N.Vector2(x1 - (float)sizeX1, y1 + (float)sizeY1), t1); var p21 = N.Vector2.Transform(new N.Vector2(x1, y1), t1); var p12 = N.Vector2.Transform(new N.Vector2(x1 - (float)sizeX1, y1 - (float)sizeY1), t1); var p22 = N.Vector2.Transform(new N.Vector2(x1, y1), t1); DrawLineInternal(_ds, strokeStartArrow, ssStartArrow, sas.IsStroked, ref p11, ref p21, thicknessStartArrow); DrawLineInternal(_ds, strokeStartArrow, ssStartArrow, sas.IsStroked, ref p12, ref p22, thicknessStartArrow); } break; } double radiusX2 = eas.RadiusX; double radiusY2 = eas.RadiusY; double sizeX2 = 2.0 * radiusX2; double sizeY2 = 2.0 * radiusY2; switch (eas.ArrowType) { default: case ArrowType.None: { pt2 = new N.Vector2(x2, y2); } break; case ArrowType.Rectangle: { pt2 = N.Vector2.Transform(new N.Vector2(x2 - (float)sizeX2, y2), t2); var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); var old = _ds.Transform; _ds.Transform = t1; DrawRectangleInternal(_ds, fillEndArrow, strokeEndArrow, ssEndArrow, eas.IsStroked, eas.IsFilled, ref rect, thicknessEndArrow); _ds.Transform = old; } break; case ArrowType.Ellipse: { pt2 = N.Vector2.Transform(new N.Vector2(x2 - (float)sizeX2, y2), t2); var old = _ds.Transform; _ds.Transform = t1; var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); DrawEllipseInternal(_ds, fillEndArrow, strokeEndArrow, ssEndArrow, eas.IsStroked, eas.IsFilled, ref rect, thicknessEndArrow); _ds.Transform = old; } break; case ArrowType.Arrow: { pt2 = N.Vector2.Transform(new N.Vector2(x2, y2), t2); var p11 = N.Vector2.Transform(new N.Vector2(x2 - (float)sizeX2, y2 + (float)sizeY2), t2); var p21 = N.Vector2.Transform(new N.Vector2(x2, y2), t2); var p12 = N.Vector2.Transform(new N.Vector2(x2 - (float)sizeX2, y2 - (float)sizeY2), t2); var p22 = N.Vector2.Transform(new N.Vector2(x2, y2), t2); DrawLineInternal(_ds, strokeEndArrow, ssEndArrow, eas.IsStroked, ref p11, ref p21, thicknessEndArrow); DrawLineInternal(_ds, strokeEndArrow, ssEndArrow, eas.IsStroked, ref p12, ref p22, thicknessEndArrow); } break; } DrawLineInternal(_ds, strokeLine, ssLine, line.IsStroked, ref pt1, ref pt2, thicknessLine); ssEndArrow.Dispose(); ssStartArrow.Dispose(); ssLine.Dispose(); }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public bool TryToConnectStart(XLine line, double x, double y) { var result = ShapeBounds.HitTest(_editor.Project.CurrentContainer, new Vector2(x, y), _editor.Project.Options.HitTreshold); if (result != null && result is XPoint) { line.Start = result as XPoint; return true; } return false; }
private void ToStateTwoQBezier() { _style = _editor.Project.Options.HelperStyle; _qbezierLine12 = XLine.Create(0, 0, _style, null); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_qbezierLine12); _qbezierLine32 = XLine.Create(0, 0, _style, null); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_qbezierLine32); _qbezierHelperPoint2 = XPoint.Create(0, 0, _editor.Project.Options.PointShape); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_qbezierHelperPoint2); }
/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="line"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XLine line, double dx, double dy, ImmutableArray <ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; Brush fillLine = ToSolidBrush(line.Style.Fill); Pen strokeLine = ToPen(line.Style, _scaleToPage); Brush fillStartArrow = ToSolidBrush(line.Style.StartArrowStyle.Fill); Pen strokeStartArrow = ToPen(line.Style.StartArrowStyle, _scaleToPage); Brush fillEndArrow = ToSolidBrush(line.Style.EndArrowStyle.Fill); Pen strokeEndArrow = ToPen(line.Style.EndArrowStyle, _scaleToPage); double _x1 = line.Start.X + dx; double _y1 = line.Start.Y + dy; double _x2 = line.End.X + dx; double _y2 = line.End.Y + dy; XLine.SetMaxLength(line, ref _x1, ref _y1, ref _x2, ref _y2); float x1 = _scaleToPage(_x1); float y1 = _scaleToPage(_y1); float x2 = _scaleToPage(_x2); float y2 = _scaleToPage(_y2); var sas = line.Style.StartArrowStyle; var eas = line.Style.EndArrowStyle; float a1 = (float)(Math.Atan2(y1 - y2, x1 - x2) * 180.0 / Math.PI); float a2 = (float)(Math.Atan2(y2 - y1, x2 - x1) * 180.0 / Math.PI); var t1 = new Matrix(); var c1 = new PointF(x1, y1); t1.RotateAt(a1, c1); var t2 = new Matrix(); var c2 = new PointF(x2, y2); t2.RotateAt(a2, c2); PointF pt1; PointF pt2; double radiusX1 = sas.RadiusX; double radiusY1 = sas.RadiusY; double sizeX1 = 2.0 * radiusX1; double sizeY1 = 2.0 * radiusY1; switch (sas.ArrowType) { default: case ArrowType.None: { pt1 = new PointF(x1, y1); } break; case ArrowType.Rectangle: { var pts = new PointF[] { new PointF(x1 - (float)sizeX1, y1) }; t1.TransformPoints(pts); pt1 = pts[0]; var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); var gs = _gfx.Save(); _gfx.MultiplyTransform(t1); DrawRectangleInternal(_gfx, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect); _gfx.Restore(gs); } break; case ArrowType.Ellipse: { var pts = new PointF[] { new PointF(x1 - (float)sizeX1, y1) }; t1.TransformPoints(pts); pt1 = pts[0]; var gs = _gfx.Save(); _gfx.MultiplyTransform(t1); var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); DrawEllipseInternal(_gfx, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect); _gfx.Restore(gs); } break; case ArrowType.Arrow: { var pts = new PointF[] { new PointF(x1, y1), new PointF(x1 - (float)sizeX1, y1 + (float)sizeY1), new PointF(x1, y1), new PointF(x1 - (float)sizeX1, y1 - (float)sizeY1), new PointF(x1, y1) }; t1.TransformPoints(pts); pt1 = pts[0]; var p11 = pts[1]; var p21 = pts[2]; var p12 = pts[3]; var p22 = pts[4]; DrawLineInternal(_gfx, strokeStartArrow, sas.IsStroked, ref p11, ref p21); DrawLineInternal(_gfx, strokeStartArrow, sas.IsStroked, ref p12, ref p22); } break; } double radiusX2 = eas.RadiusX; double radiusY2 = eas.RadiusY; double sizeX2 = 2.0 * radiusX2; double sizeY2 = 2.0 * radiusY2; switch (eas.ArrowType) { default: case ArrowType.None: { pt2 = new PointF(x2, y2); } break; case ArrowType.Rectangle: { var pts = new PointF[] { new PointF(x2 - (float)sizeX2, y2) }; t2.TransformPoints(pts); pt2 = pts[0]; var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); var gs = _gfx.Save(); _gfx.MultiplyTransform(t2); DrawRectangleInternal(_gfx, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect); _gfx.Restore(gs); } break; case ArrowType.Ellipse: { var pts = new PointF[] { new PointF(x2 - (float)sizeX2, y2) }; t2.TransformPoints(pts); pt2 = pts[0]; var gs = _gfx.Save(); _gfx.MultiplyTransform(t2); var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); DrawEllipseInternal(_gfx, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect); _gfx.Restore(gs); } break; case ArrowType.Arrow: { var pts = new PointF[] { new PointF(x2, y2), new PointF(x2 - (float)sizeX2, y2 + (float)sizeY2), new PointF(x2, y2), new PointF(x2 - (float)sizeX2, y2 - (float)sizeY2), new PointF(x2, y2) }; t2.TransformPoints(pts); pt2 = pts[0]; var p11 = pts[1]; var p21 = pts[2]; var p12 = pts[3]; var p22 = pts[4]; DrawLineInternal(_gfx, strokeEndArrow, eas.IsStroked, ref p11, ref p21); DrawLineInternal(_gfx, strokeEndArrow, eas.IsStroked, ref p12, ref p22); } break; } _gfx.DrawLine(strokeLine, pt1, pt2); fillLine.Dispose(); strokeLine.Dispose(); fillStartArrow.Dispose(); strokeStartArrow.Dispose(); fillEndArrow.Dispose(); strokeEndArrow.Dispose(); }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="x1"></param> /// <param name="x2"></param> public static void SetMaxLengthHorizontal(XLine line, ref double x1, ref double x2) { var ls = line.Style.LineStyle; bool shortenStart = ls.MaxLengthStartState != ShapeState.Default && line.Start.State.HasFlag(ls.MaxLengthStartState) && ls.MaxLengthFlags.HasFlag(MaxLengthFlags.Start); bool shortenEnd = ls.MaxLengthEndState != ShapeState.Default && line.End.State.HasFlag(ls.MaxLengthEndState) && ls.MaxLengthFlags.HasFlag(MaxLengthFlags.End); if (shortenStart && !shortenEnd) { if (x2 > x1) x1 = x2 - ls.MaxLength; else x1 = x2 + ls.MaxLength; } if (!shortenStart && shortenEnd) { if (x2 > x1) x2 = x1 + ls.MaxLength; else x2 = x1 - ls.MaxLength; } if (shortenStart && shortenEnd) { // TODO: Implement shorten start and end case. } }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="line"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XLine line, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as IDrawingContext; Brush fillLine = ToSolidBrush(line.Style.Fill); Pen strokeLine = ToPen(line.Style, _scaleToPage); Brush fillStartArrow = ToSolidBrush(line.Style.StartArrowStyle.Fill); Pen strokeStartArrow = ToPen(line.Style.StartArrowStyle, _scaleToPage); Brush fillEndArrow = ToSolidBrush(line.Style.EndArrowStyle.Fill); Pen strokeEndArrow = ToPen(line.Style.EndArrowStyle, _scaleToPage); double _x1 = line.Start.X + dx; double _y1 = line.Start.Y + dy; double _x2 = line.End.X + dx; double _y2 = line.End.Y + dy; XLine.SetMaxLength(line, ref _x1, ref _y1, ref _x2, ref _y2); float x1 = _scaleToPage(_x1); float y1 = _scaleToPage(_y1); float x2 = _scaleToPage(_x2); float y2 = _scaleToPage(_y2); var sas = line.Style.StartArrowStyle; var eas = line.Style.EndArrowStyle; double a1 = Math.Atan2(y1 - y2, x1 - x2); double a2 = Math.Atan2(y2 - y1, x2 - x1); var t1 = MatrixHelper.Rotation(a1, new Vector(x1, y1)); var t2 = MatrixHelper.Rotation(a2, new Vector(x2, y2)); Point pt1 = default(Point); Point pt2 = default(Point); double radiusX1 = sas.RadiusX; double radiusY1 = sas.RadiusY; double sizeX1 = 2.0 * radiusX1; double sizeY1 = 2.0 * radiusY1; switch (sas.ArrowType) { default: case ArrowType.None: { pt1 = new Point(x1, y1); } break; case ArrowType.Rectangle: { pt1 = MatrixHelper.TransformPoint(t1, new Point(x1 - (float)sizeX1, y1)); var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); var d = _dc.PushTransform(t1); DrawRectangleInternal(_dc, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect); d.Dispose(); } break; case ArrowType.Ellipse: { pt1 = MatrixHelper.TransformPoint(t1, new Point(x1 - (float)sizeX1, y1)); var d = _dc.PushTransform(t1); var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); DrawEllipseInternal(_dc, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect); d.Dispose(); } break; case ArrowType.Arrow: { var pts = new Point[] { new Point(x1, y1), new Point(x1 - (float)sizeX1, y1 + (float)sizeY1), new Point(x1, y1), new Point(x1 - (float)sizeX1, y1 - (float)sizeY1), new Point(x1, y1) }; pt1 = MatrixHelper.TransformPoint(t1, pts[0]); var p11 = MatrixHelper.TransformPoint(t1, pts[1]); var p21 = MatrixHelper.TransformPoint(t1, pts[2]); var p12 = MatrixHelper.TransformPoint(t1, pts[3]); var p22 = MatrixHelper.TransformPoint(t1, pts[4]); DrawLineInternal(_dc, strokeStartArrow, sas.IsStroked, ref p11, ref p21); DrawLineInternal(_dc, strokeStartArrow, sas.IsStroked, ref p12, ref p22); } break; } double radiusX2 = eas.RadiusX; double radiusY2 = eas.RadiusY; double sizeX2 = 2.0 * radiusX2; double sizeY2 = 2.0 * radiusY2; switch (eas.ArrowType) { default: case ArrowType.None: { pt2 = new Point(x2, y2); } break; case ArrowType.Rectangle: { pt2 = MatrixHelper.TransformPoint(t2, new Point(x2 - (float)sizeX2, y2)); var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); var d = _dc.PushTransform(t2); DrawRectangleInternal(_dc, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect); d.Dispose(); } break; case ArrowType.Ellipse: { pt2 = MatrixHelper.TransformPoint(t2, new Point(x2 - (float)sizeX2, y2)); var d = _dc.PushTransform(t2); var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); DrawEllipseInternal(_dc, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect); d.Dispose(); } break; case ArrowType.Arrow: { var pts = new Point[] { new Point(x2, y2), new Point(x2 - (float)sizeX2, y2 + (float)sizeY2), new Point(x2, y2), new Point(x2 - (float)sizeX2, y2 - (float)sizeY2), new Point(x2, y2) }; pt2 = MatrixHelper.TransformPoint(t2, pts[0]); var p11 = MatrixHelper.TransformPoint(t2, pts[1]); var p21 = MatrixHelper.TransformPoint(t2, pts[2]); var p12 = MatrixHelper.TransformPoint(t2, pts[3]); var p22 = MatrixHelper.TransformPoint(t2, pts[4]); DrawLineInternal(_dc, strokeEndArrow, eas.IsStroked, ref p11, ref p21); DrawLineInternal(_dc, strokeEndArrow, eas.IsStroked, ref p12, ref p22); } break; } _dc.DrawLine(strokeLine, pt1, pt2); // TODO: fillLine.Dispose(); // TODO: strokeLine.Dispose(); // TODO: fillStartArrow.Dispose(); // TODO: strokeStartArrow.Dispose(); // TODO: fillEndArrow.Dispose(); // TODO: strokeEndArrow.Dispose(); }
/// <summary> /// /// </summary> /// <param name="dc"></param> /// <param name="line"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object dc, XLine line, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _dc = dc as DrawingContext; var style = line.Style; if (style == null) return; double zoom = _state.Zoom; double thicknessLine = style.Thickness / zoom; double halfLine = thicknessLine / 2.0; double thicknessStartArrow = style.StartArrowStyle.Thickness / zoom; double halfStartArrow = thicknessStartArrow / 2.0; double thicknessEndArrow = style.EndArrowStyle.Thickness / zoom; double halfEndArrow = thicknessEndArrow / 2.0; // line style Tuple<Brush, Pen> lineCache = null; Brush fillLine; Pen strokeLine; if (_enableStyleCache && _styleCache.TryGetValue(style, out lineCache)) { fillLine = lineCache.Item1; strokeLine = lineCache.Item2; } else { fillLine = CreateBrush(style.Fill); strokeLine = CreatePen(style, thicknessLine); if (_enableStyleCache) _styleCache.Add(style, Tuple.Create(fillLine, strokeLine)); } // start arrow style Tuple<Brush, Pen> startArrowCache = null; Brush fillStartArrow; Pen strokeStartArrow; if (_enableArrowStyleCache && _arrowStyleCache.TryGetValue(style.StartArrowStyle, out startArrowCache)) { fillStartArrow = startArrowCache.Item1; strokeStartArrow = startArrowCache.Item2; } else { fillStartArrow = CreateBrush(style.StartArrowStyle.Fill); strokeStartArrow = CreatePen(style.StartArrowStyle, thicknessStartArrow); if (_enableArrowStyleCache) _arrowStyleCache.Add(style.StartArrowStyle, Tuple.Create(fillStartArrow, strokeStartArrow)); } // end arrow style Tuple<Brush, Pen> endArrowCache = null; Brush fillEndArrow; Pen strokeEndArrow; if (_enableArrowStyleCache && _arrowStyleCache.TryGetValue(style.EndArrowStyle, out endArrowCache)) { fillEndArrow = endArrowCache.Item1; strokeEndArrow = endArrowCache.Item2; } else { fillEndArrow = CreateBrush(style.EndArrowStyle.Fill); strokeEndArrow = CreatePen(style.EndArrowStyle, thicknessEndArrow); if (_enableArrowStyleCache) _arrowStyleCache.Add(style.EndArrowStyle, Tuple.Create(fillEndArrow, strokeEndArrow)); } // line max length double x1 = line.Start.X + dx; double y1 = line.Start.Y + dy; double x2 = line.End.X + dx; double y2 = line.End.Y + dy; XLine.SetMaxLength(line, ref x1, ref y1, ref x2, ref y2); // arrow transforms var sas = style.StartArrowStyle; var eas = style.EndArrowStyle; double a1 = Math.Atan2(y1 - y2, x1 - x2) * 180.0 / Math.PI; double a2 = Math.Atan2(y2 - y1, x2 - x1) * 180.0 / Math.PI; bool doRectTransform1 = a1 % 90.0 != 0.0; bool doRectTransform2 = a2 % 90.0 != 0.0; var t1 = new RotateTransform(a1, x1, y1); var t2 = new RotateTransform(a2, x2, y2); Point pt1; Point pt2; // draw start arrow double radiusX1 = sas.RadiusX; double radiusY1 = sas.RadiusY; double sizeX1 = 2.0 * radiusX1; double sizeY1 = 2.0 * radiusY1; switch (sas.ArrowType) { default: case ArrowType.None: { pt1 = new Point(x1, y1); } break; case ArrowType.Rectangle: { pt1 = t1.Transform(new Point(x1 - sizeX1, y1)); var rect = new Rect(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); if (doRectTransform1) { _dc.PushTransform(t1); DrawRectangleInternal(_dc, halfStartArrow, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect); _dc.Pop(); } else { var bounds = t1.TransformBounds(rect); DrawRectangleInternal(_dc, halfStartArrow, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref bounds); } } break; case ArrowType.Ellipse: { pt1 = t1.Transform(new Point(x1 - sizeX1, y1)); _dc.PushTransform(t1); var c = new Point(x1 - radiusX1, y1); DrawEllipseInternal(_dc, halfStartArrow, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref c, radiusX1, radiusY1); _dc.Pop(); } break; case ArrowType.Arrow: { pt1 = t1.Transform(new Point(x1, y1)); var p11 = t1.Transform(new Point(x1 - sizeX1, y1 + sizeY1)); var p21 = t1.Transform(new Point(x1, y1)); var p12 = t1.Transform(new Point(x1 - sizeX1, y1 - sizeY1)); var p22 = t1.Transform(new Point(x1, y1)); DrawLineInternal(_dc, halfStartArrow, strokeStartArrow, sas.IsStroked, ref p11, ref p21); DrawLineInternal(_dc, halfStartArrow, strokeStartArrow, sas.IsStroked, ref p12, ref p22); } break; } // draw end arrow double radiusX2 = eas.RadiusX; double radiusY2 = eas.RadiusY; double sizeX2 = 2.0 * radiusX2; double sizeY2 = 2.0 * radiusY2; switch (eas.ArrowType) { default: case ArrowType.None: { pt2 = new Point(x2, y2); } break; case ArrowType.Rectangle: { pt2 = t2.Transform(new Point(x2 - sizeX2, y2)); var rect = new Rect(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); if (doRectTransform2) { _dc.PushTransform(t2); DrawRectangleInternal(_dc, halfEndArrow, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect); _dc.Pop(); } else { var bounds = t2.TransformBounds(rect); DrawRectangleInternal(_dc, halfEndArrow, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref bounds); } } break; case ArrowType.Ellipse: { pt2 = t2.Transform(new Point(x2 - sizeX2, y2)); _dc.PushTransform(t2); var c = new Point(x2 - radiusX2, y2); DrawEllipseInternal(_dc, halfEndArrow, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref c, radiusX2, radiusY2); _dc.Pop(); } break; case ArrowType.Arrow: { pt2 = t2.Transform(new Point(x2, y2)); var p11 = t2.Transform(new Point(x2 - sizeX2, y2 + sizeY2)); var p21 = t2.Transform(new Point(x2, y2)); var p12 = t2.Transform(new Point(x2 - sizeX2, y2 - sizeY2)); var p22 = t2.Transform(new Point(x2, y2)); DrawLineInternal(_dc, halfEndArrow, strokeEndArrow, eas.IsStroked, ref p11, ref p21); DrawLineInternal(_dc, halfEndArrow, strokeEndArrow, eas.IsStroked, ref p12, ref p22); } break; } // draw line using points from arrow transforms DrawLineInternal(_dc, halfLine, strokeLine, line.IsStroked, ref pt1, ref pt2); }
private void RemoveQBezierHelpers() { if (_qbezierLine12 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_qbezierLine12); _qbezierLine12 = null; } if (_qbezierLine32 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_qbezierLine32); _qbezierLine32 = null; } if (_qbezierHelperPoint1 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_qbezierHelperPoint1); _qbezierHelperPoint1 = null; } if (_qbezierHelperPoint2 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_qbezierHelperPoint2); _qbezierHelperPoint2 = null; } if (_qbezierHelperPoint3 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_qbezierHelperPoint3); _qbezierHelperPoint3 = null; } _style = null; }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="p"></param> /// <param name="treshold"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static bool HitTestLine(XLine line, Vector2 p, double treshold, double dx, double dy) { var a = new Vector2(line.Start.X + dx, line.Start.Y + dy); var b = new Vector2(line.End.X + dx, line.End.Y + dy); var nearest = MathHelpers.NearestPointOnLine(a, b, p); double distance = MathHelpers.Distance(p.X, p.Y, nearest.X, nearest.Y); return distance < treshold; }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="x1"></param> /// <param name="y1"></param> /// <param name="x2"></param> /// <param name="y2"></param> public static void SetMaxLength( XLine line, ref double x1, ref double y1, ref double x2, ref double y2) { var ls = line.Style.LineStyle; if (ls.MaxLengthFlags == MaxLengthFlags.Disabled) return; if (ls.MaxLengthFlags.HasFlag(MaxLengthFlags.All)) { SetMaxLengthAll(line, ref x1, ref y1, ref x2, ref y2); } else { if (ls.MaxLengthFlags.HasFlag(MaxLengthFlags.Vertical)) { bool isVertical = Math.Round(x1, 1) == Math.Round(x2, 1); if (isVertical) { SetMaxLengthVertical(line, ref y1, ref y2); } } if (ls.MaxLengthFlags.HasFlag(MaxLengthFlags.Horizontal)) { bool isHorizontal = Math.Round(y1, 1) == Math.Round(y2, 1); if (isHorizontal) { SetMaxLengthHorizontal(line, ref x1, ref x2); } } } }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="x1"></param> /// <param name="y1"></param> /// <param name="x2"></param> /// <param name="y2"></param> public static void SetMaxLengthAll( XLine line, ref double x1, ref double y1, ref double x2, ref double y2) { var ls = line.Style.LineStyle; bool shortenStart = ls.MaxLengthStartState != ShapeState.Default && line.Start.State.HasFlag(ls.MaxLengthStartState) && ls.MaxLengthFlags.HasFlag(MaxLengthFlags.Start); bool shortenEnd = ls.MaxLengthEndState != ShapeState.Default && line.End.State.HasFlag(ls.MaxLengthEndState) && ls.MaxLengthFlags.HasFlag(MaxLengthFlags.End); if (shortenStart && !shortenEnd) { double dx = x1 - x2; double dy = y1 - y2; double distance = Math.Sqrt(dx * dx + dy * dy); x1 = x2 - (x2 - x1) / distance * ls.MaxLength; y1 = y2 - (y2 - y1) / distance * ls.MaxLength; } if (!shortenStart && shortenEnd) { double dx = x2 - x1; double dy = y2 - y1; double distance = Math.Sqrt(dx * dx + dy * dy); x2 = x1 - (x1 - x2) / distance * ls.MaxLength; y2 = y1 - (y1 - y2) / distance * ls.MaxLength; } if (shortenStart && shortenEnd) { // TODO: Implement shorten start and end case. } }
/// <summary> /// /// </summary> public override void Remove() { if (_line12 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_line12); _line12 = null; } if (_line43 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_line43); _line43 = null; } if (_line23 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_line23); _line23 = null; } if (_helperPoint1 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_helperPoint1); _helperPoint1 = null; } if (_helperPoint2 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_helperPoint2); _helperPoint2 = null; } if (_helperPoint3 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_helperPoint3); _helperPoint3 = null; } if (_helperPoint4 != null) { _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Remove(_helperPoint4); _helperPoint4 = null; } _style = null; }
/// <summary> /// /// </summary> /// <param name="line"></param> /// <param name="y1"></param> /// <param name="y2"></param> public static void SetMaxLengthVertical(XLine line, ref double y1, ref double y2) { var ls = line.Style.LineStyle; bool shortenStart = ls.MaxLengthStartState != ShapeState.Default && line.Start.State.HasFlag(ls.MaxLengthStartState) && ls.MaxLengthFlags.HasFlag(MaxLengthFlags.Start); bool shortenEnd = ls.MaxLengthEndState != ShapeState.Default && line.End.State.HasFlag(ls.MaxLengthEndState) && ls.MaxLengthFlags.HasFlag(MaxLengthFlags.End); if (shortenStart && !shortenEnd) { if (y2 > y1) y1 = y2 - ls.MaxLength; else y1 = y2 + ls.MaxLength; } if (!shortenStart && shortenEnd) { if (y2 > y1) y2 = y1 + ls.MaxLength; else y2 = y1 - ls.MaxLength; } if (shortenStart && shortenEnd) { // TODO: Implement shorten start and end case. } }
private void ToStateThreeBezier() { _bezierLine43 = XLine.Create(0, 0, _style, null); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_bezierLine43); _bezierLine23 = XLine.Create(0, 0, _style, null); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_bezierLine23); _bezierHelperPoint3 = XPoint.Create(0, 0, _editor.Project.Options.PointShape); _editor.Project.CurrentContainer.HelperLayer.Shapes = _editor.Project.CurrentContainer.HelperLayer.Shapes.Add(_bezierHelperPoint3); }
/// <summary> /// /// </summary> /// <param name="gfx"></param> /// <param name="line"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="db"></param> /// <param name="r"></param> public void Draw(object gfx, XLine line, double dx, double dy, ImmutableArray<ShapeProperty> db, Record r) { var _gfx = gfx as Graphics; Brush fillLine = ToSolidBrush(line.Style.Fill); Pen strokeLine = ToPen(line.Style, _scaleToPage); Brush fillStartArrow = ToSolidBrush(line.Style.StartArrowStyle.Fill); Pen strokeStartArrow = ToPen(line.Style.StartArrowStyle, _scaleToPage); Brush fillEndArrow = ToSolidBrush(line.Style.EndArrowStyle.Fill); Pen strokeEndArrow = ToPen(line.Style.EndArrowStyle, _scaleToPage); double _x1 = line.Start.X + dx; double _y1 = line.Start.Y + dy; double _x2 = line.End.X + dx; double _y2 = line.End.Y + dy; XLine.SetMaxLength(line, ref _x1, ref _y1, ref _x2, ref _y2); float x1 = _scaleToPage(_x1); float y1 = _scaleToPage(_y1); float x2 = _scaleToPage(_x2); float y2 = _scaleToPage(_y2); var sas = line.Style.StartArrowStyle; var eas = line.Style.EndArrowStyle; float a1 = (float)(Math.Atan2(y1 - y2, x1 - x2) * 180.0 / Math.PI); float a2 = (float)(Math.Atan2(y2 - y1, x2 - x1) * 180.0 / Math.PI); var t1 = new Matrix(); var c1 = new PointF(x1, y1); t1.RotateAt(a1, c1); var t2 = new Matrix(); var c2 = new PointF(x2, y2); t2.RotateAt(a2, c2); PointF pt1; PointF pt2; double radiusX1 = sas.RadiusX; double radiusY1 = sas.RadiusY; double sizeX1 = 2.0 * radiusX1; double sizeY1 = 2.0 * radiusY1; switch (sas.ArrowType) { default: case ArrowType.None: { pt1 = new PointF(x1, y1); } break; case ArrowType.Rectangle: { var pts = new PointF[] { new PointF(x1 - (float)sizeX1, y1) }; t1.TransformPoints(pts); pt1 = pts[0]; var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); var gs = _gfx.Save(); _gfx.MultiplyTransform(t1); DrawRectangleInternal(_gfx, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect); _gfx.Restore(gs); } break; case ArrowType.Ellipse: { var pts = new PointF[] { new PointF(x1 - (float)sizeX1, y1) }; t1.TransformPoints(pts); pt1 = pts[0]; var gs = _gfx.Save(); _gfx.MultiplyTransform(t1); var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1); DrawEllipseInternal(_gfx, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect); _gfx.Restore(gs); } break; case ArrowType.Arrow: { var pts = new PointF[] { new PointF(x1, y1), new PointF(x1 - (float)sizeX1, y1 + (float)sizeY1), new PointF(x1, y1), new PointF(x1 - (float)sizeX1, y1 - (float)sizeY1), new PointF(x1, y1) }; t1.TransformPoints(pts); pt1 = pts[0]; var p11 = pts[1]; var p21 = pts[2]; var p12 = pts[3]; var p22 = pts[4]; DrawLineInternal(_gfx, strokeStartArrow, sas.IsStroked, ref p11, ref p21); DrawLineInternal(_gfx, strokeStartArrow, sas.IsStroked, ref p12, ref p22); } break; } double radiusX2 = eas.RadiusX; double radiusY2 = eas.RadiusY; double sizeX2 = 2.0 * radiusX2; double sizeY2 = 2.0 * radiusY2; switch (eas.ArrowType) { default: case ArrowType.None: { pt2 = new PointF(x2, y2); } break; case ArrowType.Rectangle: { var pts = new PointF[] { new PointF(x2 - (float)sizeX2, y2) }; t2.TransformPoints(pts); pt2 = pts[0]; var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); var gs = _gfx.Save(); _gfx.MultiplyTransform(t2); DrawRectangleInternal(_gfx, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect); _gfx.Restore(gs); } break; case ArrowType.Ellipse: { var pts = new PointF[] { new PointF(x2 - (float)sizeX2, y2) }; t2.TransformPoints(pts); pt2 = pts[0]; var gs = _gfx.Save(); _gfx.MultiplyTransform(t2); var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2); DrawEllipseInternal(_gfx, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect); _gfx.Restore(gs); } break; case ArrowType.Arrow: { var pts = new PointF[] { new PointF(x2, y2), new PointF(x2 - (float)sizeX2, y2 + (float)sizeY2), new PointF(x2, y2), new PointF(x2 - (float)sizeX2, y2 - (float)sizeY2), new PointF(x2, y2) }; t2.TransformPoints(pts); pt2 = pts[0]; var p11 = pts[1]; var p21 = pts[2]; var p12 = pts[3]; var p22 = pts[4]; DrawLineInternal(_gfx, strokeEndArrow, eas.IsStroked, ref p11, ref p21); DrawLineInternal(_gfx, strokeEndArrow, eas.IsStroked, ref p12, ref p22); } break; } _gfx.DrawLine(strokeLine, pt1, pt2); fillLine.Dispose(); strokeLine.Dispose(); fillStartArrow.Dispose(); strokeStartArrow.Dispose(); fillEndArrow.Dispose(); strokeEndArrow.Dispose(); }