namespace AIStudio.Tools.PowerPoint; /// /// Where a placeholder sits on the slide, in English Metric Units (EMU). /// /// The distance of the left edge from the left edge of the slide. /// The distance of the top edge from the top edge of the slide. /// The width. /// The height. internal readonly record struct SlotBounds(long X, long Y, long Width, long Height) { public long Right => this.X + this.Width; public long Bottom => this.Y + this.Height; public long CenterX => this.X + this.Width / 2; public long CenterY => this.Y + this.Height / 2; public double Area => (double)this.Width * this.Height; /// /// Whether the two areas share a part of their horizontal extent. /// public bool OverlapsHorizontally(SlotBounds other) => this.X < other.Right && other.X < this.Right; /// /// The area both share; 0 when they do not overlap. /// public double IntersectionArea(SlotBounds other) { var width = Math.Min(this.Right, other.Right) - Math.Max(this.X, other.X); var height = Math.Min(this.Bottom, other.Bottom) - Math.Max(this.Y, other.Y); return width > 0 && height > 0 ? (double)width * height : 0; } /// /// Whether the other area lies within this one, give or take the given tolerance on each edge. /// public bool Contains(SlotBounds other, long horizontalTolerance, long verticalTolerance) => other.X >= this.X - horizontalTolerance && other.Right <= this.Right + horizontalTolerance && other.Y >= this.Y - verticalTolerance && other.Bottom <= this.Bottom + verticalTolerance; /// /// Whether both areas are the same, give or take the given tolerance on each edge. /// public bool IsCloseTo(SlotBounds other, long horizontalTolerance, long verticalTolerance) => Math.Abs(this.X - other.X) <= horizontalTolerance && Math.Abs(this.Width - other.Width) <= horizontalTolerance && Math.Abs(this.Y - other.Y) <= verticalTolerance && Math.Abs(this.Height - other.Height) <= verticalTolerance; }