import Foundation public struct Extent: Hashable { public var left: T, top: T, right: T, bottom: T public init(left: T, top: T, right: T, bottom: T) { self.left = left self.top = top self.right = right self.bottom = bottom } @inline(__always) public var topLeft: Point { .init(left, top) } @inline(__always) public var topRight: Point { .init(right, top) } @inline(__always) public var bottomLeft: Point { .init(left, bottom) } @inline(__always) public var bottomRight: Point { .init(right, bottom) } @inline(__always) public static func == (lhs: Self, rhs: Self) -> Bool { lhs.left == rhs.left && lhs.right == rhs.right && lhs.top == rhs.top && lhs.bottom == rhs.bottom } } public extension Extent where T: Comparable { var size: Size { .init( right > left ? right - left : left - right, bottom > top ? bottom - top : top - bottom) } } public extension Extent where T: SIMDScalar { init(from: SIMD2, to: SIMD2) { self.left = from.x self.top = from.y self.right = to.x self.bottom = to.y } @inline(__always) static func + (lhs: Self, rhs: SIMD2) -> Self { .init( left: lhs.left + rhs.x, top: lhs.top + rhs.y, right: lhs.right + rhs.x, bottom: lhs.bottom + rhs.y) } } public extension Extent where T: AdditiveArithmetic { init(_ rect: Rect) { self.left = rect.x self.top = rect.y self.right = rect.x + rect.w self.bottom = rect.y + rect.h } } public extension Extent where T: Numeric { @inline(__always) static func * (lhs: Self, rhs: Size) -> Self { .init( left: lhs.left * rhs.w, top: lhs.top * rhs.w, right: lhs.right * rhs.h, bottom: lhs.bottom * rhs.h) } } public extension Extent where T: BinaryInteger { init(_ other: Extent) { self.left = T(other.left) self.top = T(other.top) self.right = T(other.right) self.bottom = T(other.bottom) } init(_ other: Extent) { self.left = T(other.left) self.top = T(other.top) self.right = T(other.right) self.bottom = T(other.bottom) } } public extension Extent where T: FloatingPoint { init(_ other: Extent) { self.left = T(other.left) self.top = T(other.top) self.right = T(other.right) self.bottom = T(other.bottom) } @inline(__always) static func / (lhs: Self, rhs: T) -> Self { .init( left: lhs.left / rhs, top: lhs.top / rhs, right: lhs.right / rhs, bottom: lhs.bottom / rhs) } } public extension Extent where T: BinaryFloatingPoint { init(_ other: Extent) { self.left = T(other.left) self.top = T(other.top) self.right = T(other.right) self.bottom = T(other.bottom) } } @inlinable public func floor(_ extent: Extent) -> Extent { .init( left: floor(extent.left), top: floor(extent.top), right: floor(extent.right), bottom: floor(extent.bottom)) }