/// <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(); }