예제 #1
0
        /// <summary>
        /// create the path points
        /// </summary>
        /// <param name="stroke">the stroke</param>
        /// <returns>the path points</returns>
        public static SKPoint[] CreatePathPoints(XInkStroke stroke)
        {
            if (stroke == null)
            {
                throw new ArgumentNullException(nameof(stroke));
            }

            var inkPoints = stroke.GetInkPoints().ToArray();

            if (inkPoints.Length < 2)
            {
                return(null);
            }
            var pointCount = inkPoints.Length * 2 + 2;

            var allPoints = new SKPoint[pointCount];

            double angle = 0.0;

            for (var i = 0; i < inkPoints.Length; i++)
            {
                var point1 = inkPoints[i];

                if (i < inkPoints.Length - 1)
                {
                    var point2 = inkPoints[i + 1];

                    var x = point2.Position.X - point1.Position.X;
                    var y = point2.Position.Y - point1.Position.Y;

                    angle = Math.Atan2(y, x) - Math.PI / 2;
                }

                var h = stroke.DrawingAttributes.Size * 0.5;

                if (!stroke.DrawingAttributes.IgnorePressure)
                {
                    h *= point1.Pressure;
                }

                var leftX  = point1.Position.X + (Math.Cos(angle) * h);
                var leftY  = point1.Position.Y + (Math.Sin(angle) * h);
                var rightX = point1.Position.X - (Math.Cos(angle) * h);
                var rightY = point1.Position.Y - (Math.Sin(angle) * h);

                allPoints[i + 1] = new Point(leftX, leftY).ToSKPoint();

                allPoints[pointCount - i - 1] = new Point(rightX, rightY).ToSKPoint();
            }

            allPoints[0] = GetModifiedFirstPoint(stroke, inkPoints).ToSKPoint();

            allPoints[inkPoints.Length + 1] = GetModifiedLastPoint(stroke, inkPoints).ToSKPoint();

            return(allPoints);
        }
예제 #2
0
        /// <summary>
        /// create a path for the stroke
        /// </summary>
        /// <param name="stroke">the stroke</param>
        /// <returns>a new path</returns>
        public static SKPath CreatePath(this XInkStroke stroke)
        {
            if (stroke == null)
            {
                throw new ArgumentNullException(nameof(stroke));
            }

            var path = new SKPath();

            var inkPoints = stroke.GetInkPoints();

            var points = from point in inkPoints
                         let x                 = (float)point.Position.X
                                         let y = (float)point.Position.Y
                                                 select new SKPoint(x, y);

            var count = points.Count();

            //path.AddPoly(points.ToArray(), false);

            if (count > 1)
            {
                var firstPoints  = new Point[count - 1];
                var secondPoints = new Point[count - 1];

                var controlPoints = (from item in inkPoints
                                     select item.Position).ToArray();
                BezierSpline.GetCurveControlPoints(controlPoints, out firstPoints, out secondPoints);

                path.MoveTo(controlPoints.First().ToSKPoint());

                for (var i = 1; i < count; i++)
                {
                    path.CubicTo(firstPoints[i - 1].ToSKPoint(), secondPoints[i - 1].ToSKPoint(), points.ElementAt(i));
                }
            }

            return(path);
        }
예제 #3
0
        /// <summary>
        /// Convert a Xamarin Ink Stroke to a UWP InkStroke
        /// </summary>
        /// <param name="xInkStroke">a Xamarin Ink Stroke</param>
        /// <returns>a UWP Ink Stroke</returns>
        public static InkStroke ToInkStroke(this XInkStroke xInkStroke)
        {
            if (xInkStroke == null)
            {
                throw new ArgumentNullException(nameof(xInkStroke));
            }

            var builder = new InkStrokeBuilder();

            var inkPoints = from item in xInkStroke.GetInkPoints()
                            select new InkPoint(new Point(item.Position.X, item.Position.Y), item.Pressure);

            if (!inkPoints.Any())
            {
                return(null);
            }

            var stroke = builder.CreateStrokeFromInkPoints(inkPoints, Matrix3x2.Identity);

            stroke.DrawingAttributes = xInkStroke.DrawingAttributes.ToInkDrawingAttributes();

            return(stroke);
        }
예제 #4
0
        /// <summary>
        /// Draw an ink stroke
        /// </summary>
        /// <param name="canvas">the canvas</param>
        /// <param name="stroke">the stroke</param>
        /// <param name="useCache">true to use cached data</param>
        public static void Draw(this SKCanvas canvas, XInkStroke stroke, bool useCache)
        {
            _ = canvas ?? throw new ArgumentNullException(nameof(canvas));
            _ = stroke ?? throw new ArgumentNullException(nameof(stroke));

            var inkPoints = stroke.GetInkPoints();

            if (useCache)
            {
                if (inkPoints.Count == 1)
                {
                    if (stroke.Paint == null)
                    {
                        var paintResult = stroke.CreatePaint(SKPaintStyle.Fill);

                        stroke.Paint = paintResult.Item1;

                        stroke.Resources = paintResult.Item2;
                    }

                    canvas.DrawCircle(
                        stroke.GetInkPoints()[0].Position.ToSKPoint(),
                        stroke.DrawingAttributes.Size / 4.0f,
                        stroke.Paint);
                }
                else
                {
                    stroke.Path ??= stroke.DrawingAttributes.IgnorePressure
                        ? stroke.CreatePath()
                        : stroke.CreateVariableThicknessPath();

                    if (stroke.Paint == null)
                    {
                        var paintResult = stroke.CreatePaint();
                        stroke.Resources = paintResult.Item2;
                        stroke.Paint     = paintResult.Item1;
                    }

                    if (stroke.Path != null)
                    {
                        canvas.DrawPath(stroke.Path, stroke.Paint);
                    }
                }
            }
            else
            {
                if (inkPoints.Count == 1)
                {
                    var paintResult = stroke.CreatePaint(SKPaintStyle.Fill);

                    using (var paint = paintResult.Item1)
                    {
                        paint.IsStroke = false;

                        var radius = stroke.DrawingAttributes.Size / 4.0f;

                        //System.Diagnostics.Debug.WriteLine($"Drawing dot radius {radius}");
                        canvas.DrawCircle(
                            inkPoints[0].Position.ToSKPoint(),
                            radius,
                            paint);
                    }

                    if (paintResult.Item2 != null)
                    {
                        foreach (var item in paintResult.Item2)
                        {
                            item.Dispose();
                        }
                    }
                }
                else
                {
                    using var path = stroke.DrawingAttributes.IgnorePressure ? stroke.CreatePath() : stroke.CreateVariableThicknessPath();
                    if (path == null)
                    {
                        return;
                    }

                    var paintResult = stroke.CreatePaint();

                    using (var paint = paintResult.Item1)
                    {
                        canvas.DrawPath(path, paint);
                    }

                    if (paintResult.Item2 != null)
                    {
                        foreach (var item in paintResult.Item2)
                        {
                            item.Dispose();
                        }
                    }
                }
            }
        }