Ejemplo n.º 1
0
        /// <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 = Matrix.Create();
            var c1 = new PointF(x1, y1);

            t1.RotateAt(a1, c1);

            var t2 = Matrix.Create();
            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:
            {
                pt1 = t1.TransformPoint(new PointF(x1 - (float)sizeX1, y1));
                var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1);
                _gfx.SaveTransform();
                _gfx.MultiplyTransform(t1);
                DrawRectangleInternal(_gfx, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect);
                _gfx.RestoreTransform();
            }
            break;

            case ArrowType.Ellipse:
            {
                pt1 = t1.TransformPoint(new PointF(x1 - (float)sizeX1, y1));
                _gfx.SaveTransform();
                _gfx.MultiplyTransform(t1);
                var rect = new Rect2(x1 - sizeX1, y1 - radiusY1, sizeX1, sizeY1);
                DrawEllipseInternal(_gfx, fillStartArrow, strokeStartArrow, sas.IsStroked, sas.IsFilled, ref rect);
                _gfx.RestoreTransform();
            }
            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)
                };
                pt1 = t1.TransformPoint(pts[0]);
                var p11 = t1.TransformPoint(pts[1]);
                var p21 = t1.TransformPoint(pts[2]);
                var p12 = t1.TransformPoint(pts[3]);
                var p22 = t1.TransformPoint(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:
            {
                pt2 = t2.TransformPoint(new PointF(x2 - (float)sizeX2, y2));
                var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2);
                _gfx.SaveTransform();
                _gfx.MultiplyTransform(t2);
                DrawRectangleInternal(_gfx, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect);
                _gfx.RestoreTransform();
            }
            break;

            case ArrowType.Ellipse:
            {
                pt2 = t2.TransformPoint(new PointF(x2 - (float)sizeX2, y2));
                _gfx.SaveTransform();
                _gfx.MultiplyTransform(t2);
                var rect = new Rect2(x2 - sizeX2, y2 - radiusY2, sizeX2, sizeY2);
                DrawEllipseInternal(_gfx, fillEndArrow, strokeEndArrow, eas.IsStroked, eas.IsFilled, ref rect);
                _gfx.RestoreTransform();
            }
            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)
                };
                pt2 = t2.TransformPoint(pts[0]);
                var p11 = t2.TransformPoint(pts[1]);
                var p21 = t2.TransformPoint(pts[2]);
                var p12 = t2.TransformPoint(pts[3]);
                var p22 = t2.TransformPoint(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();
        }
Ejemplo n.º 2
0
        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();
        }
Ejemplo n.º 3
0
        /// <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;

            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.PushPreTransform(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.PushPreTransform(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.PushPreTransform(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.PushPreTransform(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;
            }

            DrawLineInternal(_dc, strokeLine, line.IsStroked, ref pt1, ref pt2);

            // TODO: fillLine.Dispose();
            // TODO: strokeLine.Dispose();

            // TODO: fillStartArrow.Dispose();
            // TODO: strokeStartArrow.Dispose();

            // TODO: fillEndArrow.Dispose();
            // TODO: strokeEndArrow.Dispose();
        }
Ejemplo n.º 4
0
        /// <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);
        }