예제 #1
0
        /// <summary>
        /// Sets the contents of the region to the specified path.
        /// </summary>
        /// <param name="region">The region to set the path into.</param>
        /// <param name="path">The path object.</param>
        /// <param name="usePathBounds">Whether to set the region's new bounds to the bounds of the path itself.</param>
        internal static bool SetPath(this SKRegion region, SKPath path, bool usePathBounds)
        {
            if (usePathBounds && path.GetBounds(out SKRect bounds))
            {
                using SKRegion clip = new SKRegion();

                clip.SetRect(SKRectI.Ceiling(bounds));
                return(region.SetPath(path, clip));
            }
            else
            {
                return(region.SetPath(path));
            }
        }
예제 #2
0
        /// <summary>
        /// Combines the region with a given path, specifying the operation used to combine.
        /// </summary>
        /// <param name="region">The region to perform the operation on.</param>
        /// <param name="path">The path to perform the operation with.</param>
        /// <param name="operation">The type of operation to perform.</param>
        /// <returns></returns>
        internal static bool CombineWithPath(this SKRegion region, SKPath path, SKRegionOperation operation)
        {
            using SKRegion pathRegion = new SKRegion();

            pathRegion.SetPath(path, usePathBounds: true);
            return(region.Op(pathRegion, operation));
        }
예제 #3
0
 internal static bool Op(this SKRegion region, SKPath path, SKRegionOperation operation)
 {
     using (SKRegion pathRegion = new SKRegion())
     {
         pathRegion.SetPath(path, true);
         return(region.Op(pathRegion, operation));
     }
 }
예제 #4
0
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            // Retrieve canvas state.
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            // Clear any drawing from previous draw call.
            canvas.Clear();

            int radius = 10;

            // Create circular path
            using (SKPath circlePath = new SKPath())
            {
                circlePath.AddCircle(0, 0, radius);

                // Create circular region
                using (SKRegion circleRegion = new SKRegion())
                {
                    // Defines a region that is 20 x 20 pixel units.
                    circleRegion.SetRect(new SKRectI(-radius, -radius, radius, radius));
                    circleRegion.SetPath(circlePath);

                    // Set transform to move it to center and scale up
                    canvas.Translate(info.Width / 2, info.Height / 2);
                    // This scales the region to be proportional to our arbitrary units.
                    canvas.Scale(Math.Min(info.Width / 2, info.Height / 2) / radius);

                    // Fill region
                    using (SKPaint fillPaint = new SKPaint())
                    {
                        fillPaint.Style = SKPaintStyle.Fill;
                        fillPaint.Color = SKColors.Orange;

                        // The circle appears pixelated because our
                        // defined region defines the pixel count.
                        canvas.DrawRegion(circleRegion, fillPaint);
                    }
                    // Fill paint is properly disposed of.

                    // Stroke path for comparison
                    using (SKPaint strokePaint = new SKPaint())
                    {
                        strokePaint.Style       = SKPaintStyle.Stroke;
                        strokePaint.Color       = SKColors.Blue;
                        strokePaint.StrokeWidth = 0.1f;

                        // The drawn path is not pixelated as it
                        // is not bounded by a region.
                        canvas.DrawPath(circlePath, strokePaint);
                    }
                    // Stoke paint is properly disposed of.
                }
                // Circle region is properly disposed of.
            }
            // Circle path is properly disposed of.
        }
예제 #5
0
 public void ClipRegion(SKRegion region, SKPath path,
                        SKRegionOperation regionOperation = SKRegionOperation.Intersect)
 {
     using (SKRegion region1 = new SKRegion())
     {
         region1.SetPath(path);
         region.Op(region1, regionOperation);
     }
 }
예제 #6
0
        public void SetPathWithoutClipDoesNotCreateEmptyRegion()
        {
            using var path = new SKPath();
            path.AddRect(SKRect.Create(10, 20, 30, 40));

            using var region = new SKRegion();
            var isNonEmpty = region.SetPath(path);

            Assert.True(isNonEmpty);
            Assert.Equal(SKRectI.Truncate(path.Bounds), region.Bounds);
        }
예제 #7
0
        public void SetPathWithEmptyClipDoesCreatesEmptyRegion()
        {
            var path = new SKPath();

            path.AddRect(SKRect.Create(10, 20, 30, 40));

            var region     = new SKRegion();
            var isNonEmpty = region.SetPath(path, new SKRegion());

            Assert.IsFalse(isNonEmpty);
            Assert.AreEqual(SKRectI.Empty, region.Bounds);
        }
예제 #8
0
        /// <summary>
        /// Checks whether the region intersects the given path.
        /// </summary>
        /// <param name="region">The region to check collision with.</param>
        /// <param name="rect">The rectangle to check for intersection.</param>
        internal static bool IntersectsPath(this SKRegion region, SKPath path)
        {
            if (region.Bounds.IsEmpty)
            {
                return(false);
            }

            using SKRegion pathRegion = new SKRegion();

            pathRegion.SetPath(path, region);
            return(region.Intersects(pathRegion));
        }
예제 #9
0
        //Default resolution makes 10 points per line segment
        private bool IsInside(SKPath pInput, SKPath pBoundary)
        {
            var input    = new SKRegion();
            var boundary = new SKRegion();

            input.SetRect(ToIntRect(pInput.Bounds));
            boundary.SetRect(ToIntRect(pBoundary.Bounds));
            input.SetPath(pInput);
            boundary.SetPath(pBoundary);

            var contained = boundary.Contains(input);

            return(contained);
        }
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            int radius = 10;

            // Create circular path
            using (SKPath circlePath = new SKPath())
            {
                circlePath.AddCircle(0, 0, radius);

                // Create circular region
                using (SKRegion circleRegion = new SKRegion())
                {
                    circleRegion.SetRect(new SKRectI(-radius, -radius, radius, radius));
                    circleRegion.SetPath(circlePath);

                    // Set transform to move it to center and scale up
                    canvas.Translate(info.Width / 2, info.Height / 2);
                    canvas.Scale(Math.Min(info.Width / 2, info.Height / 2) / radius);

                    // Fill region
                    using (SKPaint fillPaint = new SKPaint())
                    {
                        fillPaint.Style = SKPaintStyle.Fill;
                        fillPaint.Color = SKColors.Orange;

                        canvas.DrawRegion(circleRegion, fillPaint);
                    }

                    // Stroke path for comparison
                    using (SKPaint strokePaint = new SKPaint())
                    {
                        strokePaint.Style       = SKPaintStyle.Stroke;
                        strokePaint.Color       = SKColors.Blue;
                        strokePaint.StrokeWidth = 0.1f;

                        canvas.DrawPath(circlePath, strokePaint);
                    }
                }
            }
        }
예제 #11
0
        public void SetPathWithClipDoesCreatesCorrectRegion()
        {
            var clipRect = new SKRectI(25, 25, 50, 50);
            var clip     = new SKRegion();

            clip.SetRect(clipRect);

            var rect = new SKRectI(10, 20, 30, 40);
            var path = new SKPath();

            path.AddRect(rect);

            var region     = new SKRegion();
            var isNonEmpty = region.SetPath(path, clip);

            Assert.IsTrue(isNonEmpty);
            Assert.AreEqual(SKRectI.Intersect(clipRect, rect), region.Bounds);
        }
예제 #12
0
        void DisplayClipOp(SKCanvas canvas, SKRect rect, SKRegionOperation regionOp)
        {
            float textSize = textPaint.TextSize;

            canvas.DrawText(regionOp.ToString(), rect.MidX, rect.Top + textSize, textPaint);
            rect.Top += textSize;

            float radius  = 0.9f * Math.Min(rect.Width / 3, rect.Height / 2);
            float xCenter = rect.MidX;
            float yCenter = rect.MidY;

            SKRectI recti = new SKRectI((int)rect.Left, (int)rect.Top,
                                        (int)rect.Right, (int)rect.Bottom);

            using (SKRegion wholeRectRegion = new SKRegion())
            {
                wholeRectRegion.SetRect(recti);

                using (SKRegion region1 = new SKRegion(wholeRectRegion))
                    using (SKRegion region2 = new SKRegion(wholeRectRegion))
                    {
                        using (SKPath path1 = new SKPath())
                        {
                            path1.AddCircle(xCenter - radius / 2, yCenter, radius);
                            region1.SetPath(path1);
                        }

                        using (SKPath path2 = new SKPath())
                        {
                            path2.AddCircle(xCenter + radius / 2, yCenter, radius);
                            region2.SetPath(path2);
                        }

                        region1.Op(region2, regionOp);

                        canvas.Save();
                        canvas.ClipRegion(region1);
                        canvas.DrawPaint(fillPaint);
                        canvas.Restore();
                    }
            }
        }
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            float xCenter = info.Width / 2;
            float yCenter = info.Height / 2;
            float radius  = 0.24f * Math.Min(info.Width, info.Height);

            using (SKRegion wholeScreenRegion = new SKRegion())
            {
                wholeScreenRegion.SetRect(new SKRectI(0, 0, info.Width, info.Height));

                using (SKRegion leftRegion = new SKRegion(wholeScreenRegion))
                    using (SKRegion rightRegion = new SKRegion(wholeScreenRegion))
                        using (SKRegion topRegion = new SKRegion(wholeScreenRegion))
                            using (SKRegion bottomRegion = new SKRegion(wholeScreenRegion))
                            {
                                using (SKPath circlePath = new SKPath())
                                {
                                    // Make basic circle path
                                    circlePath.AddCircle(xCenter, yCenter, radius);

                                    // Left leaf
                                    circlePath.Transform(SKMatrix.MakeTranslation(-radius, 0));
                                    leftRegion.SetPath(circlePath);

                                    // Right leaf
                                    circlePath.Transform(SKMatrix.MakeTranslation(2 * radius, 0));
                                    rightRegion.SetPath(circlePath);

                                    // Make union of right with left
                                    leftRegion.Op(rightRegion, SKRegionOperation.Union);

                                    // Top leaf
                                    circlePath.Transform(SKMatrix.MakeTranslation(-radius, -radius));
                                    topRegion.SetPath(circlePath);

                                    // Combine with bottom leaf
                                    circlePath.Transform(SKMatrix.MakeTranslation(0, 2 * radius));
                                    bottomRegion.SetPath(circlePath);

                                    // Make union of top with bottom
                                    bottomRegion.Op(topRegion, SKRegionOperation.Union);

                                    // Exclusive-OR left and right with top and bottom
                                    leftRegion.Op(bottomRegion, SKRegionOperation.XOR);

                                    // Set that as clip region
                                    canvas.ClipRegion(leftRegion);

                                    // Set transform for drawing lines from center
                                    canvas.Translate(xCenter, yCenter);

                                    // Draw 360 lines
                                    for (double angle = 0; angle < 360; angle++)
                                    {
                                        float x = 2 * radius * (float)Math.Cos(Math.PI * angle / 180);
                                        float y = 2 * radius * (float)Math.Sin(Math.PI * angle / 180);

                                        using (SKPaint strokePaint = new SKPaint())
                                        {
                                            strokePaint.Color       = SKColors.Green;
                                            strokePaint.StrokeWidth = 2;

                                            canvas.DrawLine(0, 0, x, y, strokePaint);
                                        }
                                    }
                                }
                            }
            }
        }