Exemple #1
0
        private A.Point GetTextOrigin(ShapeStyle style, ref Rect2 rect, ref A.Size size)
        {
            double ox, oy;

            switch (style.TextStyle.TextHAlignment)
            {
                case TextHAlignment.Left:
                    ox = rect.X;
                    break;
                case TextHAlignment.Right:
                    ox = rect.Right - size.Width;
                    break;
                case TextHAlignment.Center:
                default:
                    ox = (rect.Left + rect.Width / 2.0) - (size.Width / 2.0);
                    break;
            }

            switch (style.TextStyle.TextVAlignment)
            {
                case TextVAlignment.Top:
                    oy = rect.Y;
                    break;
                case TextVAlignment.Bottom:
                    oy = rect.Bottom - size.Height;
                    break;
                case TextVAlignment.Center:
                default:
                    oy = (rect.Bottom - rect.Height / 2f) - (size.Height / 2f);
                    break;
            }

            return new A.Point(ox, oy);
        }
Exemple #2
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="rect"></param>
 /// <returns></returns>
 public bool IntersectsWith(Rect2 rect)
 {
     return (rect.Left <= Right)
         && (rect.Right >= Left)
         && (rect.Top <= Bottom)
         && (rect.Bottom >= Top);
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="point"></param>
        /// <param name="rect"></param>
        /// <param name="selected"></param>
        /// <param name="threshold"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static bool HitTestPoint(XPoint point, Rect2 rect, ISet<BaseShape> selected, double threshold, double dx, double dy)
        {
            if (ShapeBounds.GetPointBounds(point, threshold, dx, dy).IntersectsWith(rect))
            {
                if (selected != null)
                {
                    selected.Add(point);
                }
                else
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ellipse"></param>
        /// <param name="rect"></param>
        /// <param name="selected"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static bool HitTestEllipse(XEllipse ellipse, Rect2 rect, ISet<BaseShape> selected, double dx, double dy)
        {
            if (ShapeBounds.GetEllipseBounds(ellipse, dx, dy).IntersectsWith(rect))
            {
                if (selected != null)
                {
                    selected.Add(ellipse);
                    return false;
                }
                else
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="line"></param>
        /// <param name="rect"></param>
        /// <param name="selected"></param>
        /// <param name="threshold"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static bool HitTestLine(XLine line, Rect2 rect, ISet<BaseShape> selected, double threshold, double dx, double dy)
        {
            if (ShapeBounds.GetPointBounds(line.Start, threshold, dx, dy).IntersectsWith(rect)
                || ShapeBounds.GetPointBounds(line.End, threshold, dx, dy).IntersectsWith(rect)
                || MathHelpers.LineIntersectsWithRect(rect, new Point2(line.Start.X, line.Start.Y), new Point2(line.End.X, line.End.Y)))
            {
                if (selected != null)
                {
                    selected.Add(line);
                    return false;
                }
                else
                {
                    return true;
                }
            }

            return false;
        }
Exemple #6
0
        private void DrawGridInternal(AM.DrawingContext dc, AM.Pen stroke, ref Rect2 rect, double offsetX, double offsetY, double cellWidth, double cellHeight, bool isStroked)
        {
            double ox = rect.X;
            double oy = rect.Y;
            double sx = ox + offsetX;
            double sy = oy + offsetY;
            double ex = ox + rect.Width;
            double ey = oy + rect.Height;

            for (double x = sx; x < ex; x += cellWidth)
            {
                var p0 = new A.Point(
                    _scaleToPage(x),
                    _scaleToPage(oy));
                var p1 = new A.Point(
                    _scaleToPage(x),
                    _scaleToPage(ey));
                DrawLineInternal(dc, stroke, isStroked, ref p0, ref p1);
            }

            for (double y = sy; y < ey; y += cellHeight)
            {
                var p0 = new A.Point(
                    _scaleToPage(ox),
                    _scaleToPage(y));
                var p1 = new A.Point(
                    _scaleToPage(ex),
                    _scaleToPage(y));
                DrawLineInternal(dc, stroke, isStroked, ref p0, ref p1);
            }
        }
Exemple #7
0
        private static void DrawEllipseInternal(AM.DrawingContext dc, AM.IBrush brush, AM.Pen pen, bool isStroked, bool isFilled, ref Rect2 rect)
        {
            if (!isFilled && !isStroked)
                return;

            var r = new A.Rect(rect.X, rect.Y, rect.Width, rect.Height);
            var g = new AM.EllipseGeometry(r);

            dc.DrawGeometry(
                isFilled ? brush : null,
                isStroked ? pen : null,
                g);
        }
Exemple #8
0
        private static void DrawRectangleInternal(AM.DrawingContext dc, AM.IBrush brush, AM.Pen pen, bool isStroked, bool isFilled, ref Rect2 rect)
        {
            if (!isStroked && !isFilled)
                return;

            var r = new A.Rect(rect.X, rect.Y, rect.Width, rect.Height);

            if (isFilled)
            {
                dc.FillRectangle(brush, r);
            }

            if (isStroked)
            {
                dc.DrawRectangle(pen, r);
            }
        }
Exemple #9
0
        private static A.Point DrawLineArrowInternal(AM.DrawingContext dc, AM.Pen pen, AM.IBrush brush, float x, float y, double angle, ArrowStyle style)
        {
            A.Point pt = default(A.Point);
            var rt = APAZ.MatrixHelper.Rotation(angle, new A.Vector(x, y));
            double rx = style.RadiusX;
            double ry = style.RadiusY;
            double sx = 2.0 * rx;
            double sy = 2.0 * ry;

            switch (style.ArrowType)
            {
                default:
                case ArrowType.None:
                    {
                        pt = new A.Point(x, y);
                    }
                    break;
                case ArrowType.Rectangle:
                    {
                        pt = APAZ.MatrixHelper.TransformPoint(rt, new A.Point(x - (float)sx, y));
                        var rect = new Rect2(x - sx, y - ry, sx, sy);
                        using (var d = dc.PushPreTransform(rt))
                        {
                            DrawRectangleInternal(dc, brush, pen, style.IsStroked, style.IsFilled, ref rect);
                        }
                    }
                    break;
                case ArrowType.Ellipse:
                    {
                        pt = APAZ.MatrixHelper.TransformPoint(rt, new A.Point(x - (float)sx, y));
                        using (var d = dc.PushPreTransform(rt))
                        {
                            var rect = new Rect2(x - sx, y - ry, sx, sy);
                            DrawEllipseInternal(dc, brush, pen, style.IsStroked, style.IsFilled, ref rect);
                        }
                    }
                    break;
                case ArrowType.Arrow:
                    {
                        var pts = new A.Point[]
                        {
                            new A.Point(x, y),
                            new A.Point(x - (float)sx, y + (float)sy),
                            new A.Point(x, y),
                            new A.Point(x - (float)sx, y - (float)sy),
                            new A.Point(x, y)
                        };
                        pt = APAZ.MatrixHelper.TransformPoint(rt, pts[0]);
                        var p11 = APAZ.MatrixHelper.TransformPoint(rt, pts[1]);
                        var p21 = APAZ.MatrixHelper.TransformPoint(rt, pts[2]);
                        var p12 = APAZ.MatrixHelper.TransformPoint(rt, pts[3]);
                        var p22 = APAZ.MatrixHelper.TransformPoint(rt, pts[4]);
                        DrawLineInternal(dc, pen, style.IsStroked, ref p11, ref p21);
                        DrawLineInternal(dc, pen, style.IsStroked, ref p12, ref p22);
                    }
                    break;
            }

            return pt;
        }
Exemple #10
0
        /// <summary>
        /// Calculate ellipse line segment intersection points.
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="p1">The line segment start point.</param>
        /// <param name="p2">The line segment end point.</param>
        /// <param name="onlySegment">Include only line segment solutions.</param>
        /// <returns>The ellipse line segment intersection point list.</returns>
        public static IList <Point2> FindEllipseSegmentIntersections(Rect2 rect, Point2 p1, Point2 p2, bool onlySegment)
        {
            if ((rect.Width == 0) || (rect.Height == 0) || ((p1.X == p2.X) && (p1.Y == p2.Y)))
            {
                return new Point2[] { }
            }
            ;

            if (rect.Width < 0)
            {
                rect.X = rect.Right;

                rect.Width = -rect.Width;
            }

            if (rect.Height < 0)
            {
                rect.Y      = rect.Bottom;
                rect.Height = -rect.Height;
            }

            double cx = rect.Left + rect.Width / 2.0;
            double cy = rect.Top + rect.Height / 2.0;

            rect.X -= cx;
            rect.Y -= cy;

            p1.X -= cx;
            p1.Y -= cy;
            p2.X -= cx;
            p2.Y -= cy;

            double a = rect.Width / 2.0;
            double b = rect.Height / 2.0;

            double A = (p2.X - p1.X) * (p2.X - p1.X) / a / a + (p2.Y - p1.Y) * (p2.Y - p1.Y) / b / b;
            double B = 2 * p1.X * (p2.X - p1.X) / a / a + 2 * p1.Y * (p2.Y - p1.Y) / b / b;
            double C = p1.X * p1.X / a / a + p1.Y * p1.Y / b / b - 1;

            var solutions = new List <double>();

            double discriminant = B * B - 4 * A * C;

            if (discriminant == 0)
            {
                solutions.Add(-B / 2 / A);
            }
            else if (discriminant > 0)
            {
                solutions.Add((-B + Sqrt(discriminant)) / 2 / A);
                solutions.Add((-B - Sqrt(discriminant)) / 2 / A);
            }

            var points = new List <Point2>();

            foreach (var t in solutions)
            {
                if (!onlySegment || ((t >= 0f) && (t <= 1f)))
                {
                    double x = p1.X + (p2.X - p1.X) * t + cx;
                    double y = p1.Y + (p2.Y - p1.Y) * t + cy;
                    points.Add(Point2.Create(x, y));
                }
            }

            return(points);
        }
Exemple #11
0
        /// <summary>
        /// Check if line intersects with rectangle using Liang-Barsky line clipping algorithm.
        /// </summary>
        /// <param name="rect">The rectangle shape.</param>
        /// <param name="p0">The line start point.</param>
        /// <param name="p1">The line end point.</param>
        /// <returns>True if line intersects with rectangle.</returns>
        public static bool LineIntersectsWithRect(Rect2 rect, Point2 p0, Point2 p1)
        {
            double left   = rect.Left;
            double right  = rect.Right;
            double bottom = rect.Bottom;
            double top    = rect.Top;
            double x0     = p0.X;
            double y0     = p0.Y;
            double x1     = p1.X;
            double y1     = p1.Y;

            double t0 = 0.0;
            double t1 = 1.0;
            double dx = x1 - x0;
            double dy = y1 - y0;
            double p = 0.0, q = 0.0, r;

            for (int edge = 0; edge < 4; edge++)
            {
                if (edge == 0)
                {
                    p = -dx;
                    q = -(left - x0);
                }
                if (edge == 1)
                {
                    p = dx;
                    q = (right - x0);
                }
                if (edge == 2)
                {
                    p = dy;
                    q = (bottom - y0);
                }
                if (edge == 3)
                {
                    p = -dy;
                    q = -(top - y0);
                }

                r = q / p;

                if (p == 0.0 && q < 0.0)
                {
                    return(false);
                }

                if (p < 0.0)
                {
                    if (r > t1)
                    {
                        return(false);
                    }
                    else if (r > t0)
                    {
                        t0 = r;
                    }
                }
                else if (p > 0.0)
                {
                    if (r < t0)
                    {
                        return(false);
                    }
                    else if (r < t1)
                    {
                        t1 = r;
                    }
                }
            }

            // Calculate clipped line position.
            // x0clip = x0 + t0 * dx;
            // y0clip = y0 + t0 * dy;
            // x1clip = x0 + t1 * dx;
            // y1clip = y0 + t1 * dy;

            return(true);
        }
Exemple #12
0
        private static void DrawEllipseInternal(Graphics gfx, Brush brush, Pen pen, bool isStroked, bool isFilled, ref Rect2 rect)
        {
            if (isFilled)
            {
                gfx.FillEllipse(
                    brush,
                    (float)rect.X,
                    (float)rect.Y,
                    (float)rect.Width,
                    (float)rect.Height);
            }

            if (isStroked)
            {
                gfx.DrawEllipse(
                    pen,
                    (float)rect.X,
                    (float)rect.Y,
                    (float)rect.Width,
                    (float)rect.Height);
            }
        }
Exemple #13
0
        private static PointF DrawLineArrowInternal(Graphics gfx, Pen pen, Brush brush, float x, float y, float angle, ArrowStyle style)
        {
            PointF pt;
            var rt = new Matrix();
            rt.RotateAt(angle, new PointF(x, y));
            double rx = style.RadiusX;
            double ry = style.RadiusY;
            double sx = 2.0 * rx;
            double sy = 2.0 * ry;

            switch (style.ArrowType)
            {
                default:
                case ArrowType.None:
                    {
                        pt = new PointF(x, y);
                    }
                    break;
                case ArrowType.Rectangle:
                    {
                        var pts = new PointF[] { new PointF(x - (float)sx, y) };
                        rt.TransformPoints(pts);
                        pt = pts[0];
                        var rect = new Rect2(x - sx, y - ry, sx, sy);
                        var gs = gfx.Save();
                        gfx.MultiplyTransform(rt);
                        DrawRectangleInternal(gfx, brush, pen, style.IsStroked, style.IsFilled, ref rect);
                        gfx.Restore(gs);
                    }
                    break;
                case ArrowType.Ellipse:
                    {
                        var pts = new PointF[] { new PointF(x - (float)sx, y) };
                        rt.TransformPoints(pts);
                        pt = pts[0];
                        var gs = gfx.Save();
                        gfx.MultiplyTransform(rt);
                        var rect = new Rect2(x - sx, y - ry, sx, sy);
                        DrawEllipseInternal(gfx, brush, pen, style.IsStroked, style.IsFilled, ref rect);
                        gfx.Restore(gs);
                    }
                    break;
                case ArrowType.Arrow:
                    {
                        var pts = new PointF[]
                        {
                            new PointF(x, y),
                            new PointF(x - (float)sx, y + (float)sy),
                            new PointF(x, y),
                            new PointF(x - (float)sx, y - (float)sy),
                            new PointF(x, y)
                        };
                        rt.TransformPoints(pts);
                        pt = pts[0];
                        var p11 = pts[1];
                        var p21 = pts[2];
                        var p12 = pts[3];
                        var p22 = pts[4];
                        DrawLineInternal(gfx, pen, style.IsStroked, ref p11, ref p21);
                        DrawLineInternal(gfx, pen, style.IsStroked, ref p12, ref p22);
                    }
                    break;
            }

            return pt;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="arc"></param>
        /// <param name="rect"></param>
        /// <param name="selected"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static bool HitTestArc(XArc arc, Rect2 rect, ISet<BaseShape> selected, double dx, double dy)
        {
            if (ShapeBounds.GetArcBounds(arc, dx, dy).IntersectsWith(rect))
            {
                if (selected != null)
                {
                    selected.Add(arc);
                    return false;
                }
                else
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="text"></param>
        /// <param name="rect"></param>
        /// <param name="selected"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static bool HitTestText(XText text, Rect2 rect, ISet<BaseShape> selected, double dx, double dy)
        {
            if (ShapeBounds.GetTextBounds(text, dx, dy).IntersectsWith(rect))
            {
                if (selected != null)
                {
                    selected.Add(text);
                    return false;
                }
                else
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// Hit test rectangle if intersects with any of the shape bounds.
        /// </summary>
        /// <param name="shapes"></param>
        /// <param name="rect"></param>
        /// <param name="threshold"></param>
        /// <returns></returns>
        public static ImmutableHashSet<BaseShape> HitTest(IEnumerable<BaseShape> shapes, Rect2 rect, double threshold)
        {
            var selected = ImmutableHashSet.CreateBuilder<BaseShape>();

            var selection = new Vector2[]
            {
                new Vector2(rect.X, rect.Y),
                new Vector2(rect.X + rect.Width, rect.Y),
                new Vector2(rect.X + rect.Width, rect.Y + rect.Height),
                new Vector2(rect.X, rect.Y + rect.Height)
            };

            HitTest(shapes.Reverse(), rect, selection, selected, threshold, 0, 0);

            return selected.ToImmutableHashSet();
        }
        /// <summary>
        /// Hit test rectangle if intersects with any of the shape bounds.
        /// </summary>
        /// <param name="shapes"></param>
        /// <param name="rect"></param>
        /// <param name="selection"></param>
        /// <param name="selected"></param>
        /// <param name="threshold"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static bool HitTest(IEnumerable<BaseShape> shapes, Rect2 rect, Vector2[] selection, ISet<BaseShape> selected, double threshold, double dx, double dy)
        {
            foreach (var shape in shapes)
            {
                var result = HitTest(shape, rect, selection, selected, threshold, dx, dy);
                if (result == true)
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// Hit test rectangle if intersects with any of the shape bounds.
        /// </summary>
        /// <param name="shape"></param>
        /// <param name="rect"></param>
        /// <param name="selection"></param>
        /// <param name="selected"></param>
        /// <param name="threshold"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static bool HitTest(BaseShape shape, Rect2 rect, Vector2[] selection, ISet<BaseShape> selected, double threshold, double dx, double dy)
        {
            if (shape is XPoint)
            {
                return HitTestPoint(shape as XPoint, rect, selected, threshold, dx, dy);
            }
            else if (shape is XLine)
            {
                return HitTestLine(shape as XLine, rect, selected, threshold, dx, dy);
            }
            else if (shape is XEllipse)
            {
                return HitTestEllipse(shape as XEllipse, rect, selected, dx, dy);
            }
            else if (shape is XRectangle)
            {
                return HitTestRectangle(shape as XRectangle, rect, selected, dx, dy);
            }
            else if (shape is XArc)
            {
                return HitTestArc(shape as XArc, rect, selected, dx, dy);
            }
            else if (shape is XCubicBezier)
            {
                return HitTestCubicBezier(shape as XCubicBezier, selection, selected, dx, dy);
            }
            else if (shape is XQuadraticBezier)
            {
                return HitTestQadraticBezier(shape as XQuadraticBezier, selection, selected, dx, dy);
            }
            else if (shape is XText)
            {
                return HitTestText(shape as XText, rect, selected, dx, dy);
            }
            else if (shape is XImage)
            {
                return HitTestImage(shape as XImage, rect, selected, dx, dy);
            }
            else if (shape is XPath)
            {
                return HitTestPath(shape as XPath, selection, selected, dx, dy);
            }
            else if (shape is XGroup)
            {
                return HitTestGroup(shape as XGroup, rect, selection, selected, threshold, dx, dy);
            }

            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="group"></param>
        /// <param name="rect"></param>
        /// <param name="selection"></param>
        /// <param name="selected"></param>
        /// <param name="threshold"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static bool HitTestGroup(XGroup group, Rect2 rect, Vector2[] selection, ISet<BaseShape> selected, double threshold, double dx, double dy)
        {
            if (HitTest(group.Shapes.Reverse(), rect, selection, null, threshold, dx, dy) == true)
            {
                if (selected != null)
                {
                    selected.Add(group);
                    return false;
                }
                else
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="image"></param>
        /// <param name="rect"></param>
        /// <param name="selected"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <returns></returns>
        public static bool HitTestImage(XImage image, Rect2 rect, ISet<BaseShape> selected, double dx, double dy)
        {
            if (ShapeBounds.GetImageBounds(image, dx, dy).IntersectsWith(rect))
            {
                if (selected != null)
                {
                    selected.Add(image);
                    return false;
                }
                else
                {
                    return true;
                }
            }

            return false;
        }
Exemple #21
0
 private void DrawBackgroundInternal(SKCanvas canvas, ArgbColor color, Rect2 rect)
 {
     using (SKPaint brush = ToSKPaintBrush(color))
     {
         SKRect srect = SKRect.Create(
             _scaleToPage(rect.X),
             _scaleToPage(rect.Y),
             _scaleToPage(rect.Width),
             _scaleToPage(rect.Height));
         canvas.DrawRect(srect, brush);
     }
 }
Exemple #22
0
 /// <summary>
 /// Creates a new <see cref="Rect2"/> instance.
 /// </summary>
 /// <param name="tl"></param>
 /// <param name="br"></param>
 /// <param name="dx"></param>
 /// <param name="dy"></param>
 /// <returns></returns>
 public static Rect2 Create(XPoint tl, XPoint br, double dx = 0.0, double dy = 0.0)
 {
     return(Rect2.Create(tl.X, tl.Y, br.X, br.Y, dx, dy));
 }