// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System; using System.Buffers; using System.Numerics; using SixLabors.ImageSharp.Memory; using SixLabors.Primitives; using SixLabors.Shapes; namespace SixLabors.ImageSharp.Drawing { /// /// A mapping between a and a region. /// internal class ShapeRegion : Region { private readonly MemoryManager memoryManager; /// /// Initializes a new instance of the class. /// /// The shape. public ShapeRegion(MemoryManager memoryManager, IPath shape) { this.memoryManager = memoryManager; this.Shape = shape.AsClosedPath(); int left = (int)MathF.Floor(shape.Bounds.Left); int top = (int)MathF.Floor(shape.Bounds.Top); int right = (int)MathF.Ceiling(shape.Bounds.Right); int bottom = (int)MathF.Ceiling(shape.Bounds.Bottom); this.Bounds = Rectangle.FromLTRB(left, top, right, bottom); } /// /// Gets the fillable shape /// public IPath Shape { get; } /// public override int MaxIntersections => this.Shape.MaxIntersections; /// public override Rectangle Bounds { get; } /// public override int Scan(float y, float[] buffer, int offset) { var start = new PointF(this.Bounds.Left - 1, y); var end = new PointF(this.Bounds.Right + 1, y); using (var innerBuffer = this.memoryManager.Allocate(buffer.Length)) { PointF[] array = innerBuffer.Array; int count = this.Shape.FindIntersections(start, end, array, 0); for (int i = 0; i < count; i++) { buffer[i + offset] = array[i].X; } return count; } } } }