diff --git a/ChangeLog b/ChangeLog index 6557b728d..12ba74620 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2024-11-18 Matvii Jarosh + + * Source/NSGeometry.m: added NSIntegralRectWithOptions function. + * Header/Foundation/NSGeometry.h: Fixed incompatible NSRectEdge, + added enum NSAlignmentOptions, added NSRectFromCGRect, + NSRectToCGRect, NSPointFromCGPoint, NSPointToCGPoint, + NSSizeFromCGSize and NSSizeToCGSizea functions. + * MISSING: + 2024-11-14 Richard Frith-Macdonald * Source/NSBundle.m: Restructure a bit to expose resource lookup diff --git a/Headers/Foundation/NSGeometry.h b/Headers/Foundation/NSGeometry.h index 491f60bf8..2689adf15 100644 --- a/Headers/Foundation/NSGeometry.h +++ b/Headers/Foundation/NSGeometry.h @@ -97,13 +97,13 @@ typedef NSRect *NSRectArray; typedef NSRect *NSRectPointer; #endif -enum +typedef enum { NSMinXEdge = 0, NSMinYEdge = 1, NSMaxXEdge = 2, NSMaxYEdge = 3 -}; +} NSRectEdge; /** Sides of a rectangle. { @@ -113,8 +113,72 @@ enum NSMaxYEdge } - */ -typedef NSUInteger NSRectEdge; +

NSRectEdge

*/ +// typedef NSUInteger NSRectEdge; +/** A value representing the alignment process + +{ + NSAlignMinXInward, + NSAlignMinYInward, + NSAlignMaxXInward, + NSAlignMaxYInward, + NSAlignWidthInward, + NSAlignHeightInward, + NSAlignMinXOutward, + NSAlignMinYOutward, + NSAlignMaxXOutward, + NSAlignMaxYOutward, + NSAlignWidthOutward, + NSAlignHeightOutward, + NSAlignMinXNearest, + NSAlignMinYNearest, + NSAlignMaxXNearest, + NSAlignMaxYNearest, + NSAlignWidthNearest, + NSAlignHeightNearest, + NSAlignRectFlipped, + NSAlignAllEdgesInward, + NSAlignAllEdgesOutward, + NSAlignAllEdgesNearest +} + +

NSAlignmentOptions

*/ +#if OS_API_VERSION(MAC_OS_X_VERSION_10_7, GS_API_LATEST) +typedef enum +{ + NSAlignMinXInward = 1ULL << 0, + NSAlignMinYInward = 1ULL << 1, + NSAlignMaxXInward = 1ULL << 2, + NSAlignMaxYInward = 1ULL << 3, + NSAlignWidthInward = 1ULL << 4, + NSAlignHeightInward = 1ULL << 5, + NSAlignMinXOutward = 1ULL << 8, + NSAlignMinYOutward = 1ULL << 9, + NSAlignMaxXOutward = 1ULL << 10, + NSAlignMaxYOutward = 1ULL << 11, + NSAlignWidthOutward = 1ULL << 12, + NSAlignHeightOutward = 1ULL << 13, + NSAlignMinXNearest = 1ULL << 16, + NSAlignMinYNearest = 1ULL << 17, + NSAlignMaxXNearest = 1ULL << 18, + NSAlignMaxYNearest = 1ULL << 19, + NSAlignWidthNearest = 1ULL << 20, + NSAlignHeightNearest = 1ULL << 21, + NSAlignRectFlipped = 1ULL << 63, + NSAlignAllEdgesInward = NSAlignMinXInward + | NSAlignMaxXInward + | NSAlignMinYInward + | NSAlignMaxYInward, + NSAlignAllEdgesOutward = NSAlignMinXOutward + | NSAlignMaxXOutward + | NSAlignMinYOutward + | NSAlignMaxYOutward, + NSAlignAllEdgesNearest = NSAlignMinXNearest + | NSAlignMaxXNearest + | NSAlignMinYNearest + | NSAlignMaxYNearest +} NSAlignmentOptions; +#endif /** { @@ -195,7 +259,7 @@ NSMakeSize(CGFloat w, CGFloat h) GS_GEOM_SCOPE NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) GS_GEOM_ATTR; - + /** Returns an NSRect having point of origin (x, y) and size {w, h}. */ GS_GEOM_SCOPE NSRect NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) @@ -209,6 +273,68 @@ NSMakeRect(CGFloat x, CGFloat y, CGFloat w, CGFloat h) return rect; } +#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GS_API_LATEST) +GS_GEOM_SCOPE NSRect +NSRectFromCGRect(CGRect rect) GS_GEOM_ATTR; + +/** Return an NSRect from CGRect. **/ +GS_GEOM_SCOPE NSRect +NSRectFromCGRect(CGRect rect) +{ + return (NSRect)rect; +} + +GS_GEOM_SCOPE CGRect +NSRectToCGRect(NSRect rect) GS_GEOM_ATTR; + +/** Return an CGRect from NSRect. **/ +GS_GEOM_SCOPE CGRect +NSRectToCGRect(NSRect rect) +{ + return (CGRect)rect; +} + +GS_GEOM_SCOPE NSPoint +NSPointFromCGPoint(CGPoint point) GS_GEOM_ATTR; + +/** Return an NSPoint from CGPoint **/ +GS_GEOM_SCOPE NSPoint +NSPointFromCGPoint(CGPoint point) +{ + return (NSPoint)point; +} + +GS_GEOM_SCOPE CGPoint +NSPointToCGPoint(NSPoint point) GS_GEOM_ATTR; + +/** Return an CGPoint from NSPoint **/ +GS_GEOM_SCOPE CGPoint +NSPointToCGPoint(NSPoint point) +{ + return (CGPoint)point; +} + +GS_GEOM_SCOPE NSSize +NSSizeFromCGSize(CGSize size) GS_GEOM_ATTR; + +/** Return an NSSize from CGSize **/ +GS_GEOM_SCOPE NSSize +NSSizeFromCGSize(CGSize size) +{ + return (NSSize)size; +} + +GS_GEOM_SCOPE CGSize +NSSizeToCGSize(NSSize size) GS_GEOM_ATTR; + +/** Return an CGSize from NSSize **/ +GS_GEOM_SCOPE CGSize +NSSizeToCGSize(NSSize size) +{ + return (CGSize)size; +} +#endif + /** Constructs NSEdgeInsets. **/ #if OS_API_VERSION(MAC_OS_X_VERSION_10_7, GS_API_LATEST) GS_GEOM_SCOPE NSEdgeInsets @@ -382,6 +508,12 @@ NSDivideRect(NSRect aRect, GS_EXPORT NSRect NSIntegralRect(NSRect aRect); +/** Returns a rectangle obtained by expanding aRect minimally + * so that all four of its defining components are integers, + * using the specified alignment options to control rounding behavior. */ +GS_EXPORT NSRect +NSIntegralRectWithOptions(NSRect aRect, NSAlignmentOptions options); + /** Compute a Third Rectangle from Two Rectangles... **/ GS_GEOM_SCOPE NSRect diff --git a/MISSING b/MISSING index ae27d0b1a..cb5f906b0 100644 --- a/MISSING +++ b/MISSING @@ -221,19 +221,8 @@ NSGeometry: - incompatible NSRectEdge - NSAlignmentOptions - @class NSString - NSRectFromCGRect() - NSRectToCGRect() - NSPointFromCGPoint() - NSPointToCGPoint() - NSSizeFromCGSize() - NSSizeToCGSize() - NSIntegralRectWithOptions() - @interface NSValue (NSValueGeometryExtensions) @interface NSCoder (NSGeometryCoding) @interface NSCoder (NSGeometryKeyedCoding) diff --git a/Source/NSGeometry.m b/Source/NSGeometry.m index a3d15538f..4466dc203 100644 --- a/Source/NSGeometry.m +++ b/Source/NSGeometry.m @@ -100,6 +100,50 @@ NSIntegralRect(NSRect aRect) return rect; } +NSRect +NSIntegralRectWithOptions(NSRect aRect, NSAlignmentOptions options) +{ + NSRect rect; + CGFloat maxX, maxY; + + if (NSIsEmptyRect(aRect)) + return NSMakeRect(0, 0, 0, 0); + + if (options & NSAlignMinXInward) + rect.origin.x = ceil(NSMinX(aRect)); + else if (options & NSAlignMinXOutward) + rect.origin.x = floor(NSMinX(aRect)); + else + rect.origin.x = round(NSMinX(aRect)); + + if (options & NSAlignMinYInward) + rect.origin.y = ceil(NSMinY(aRect)); + else if (options & NSAlignMinYOutward) + rect.origin.y = floor(NSMinY(aRect)); + else + rect.origin.y = round(NSMinY(aRect)); + + if (options & NSAlignMaxXInward) + maxX = floor(NSMaxX(aRect)); + else if (options & NSAlignMaxXOutward) + maxX = ceil(NSMaxX(aRect)); + else + maxX = round(NSMaxX(aRect)); + + if (options & NSAlignMaxYInward) + maxY = floor(NSMaxY(aRect)); + else if (options & NSAlignMaxYOutward) + maxY = ceil(NSMaxY(aRect)); + else + maxY = round(NSMaxY(aRect)); + + rect.size.width = maxX - rect.origin.x; + rect.size.height = maxY - rect.origin.y; + + return rect; +} + + void NSDivideRect(NSRect aRect, NSRect *slice, @@ -508,4 +552,3 @@ NSEdgeInsetsEqual(NSEdgeInsets e1, NSEdgeInsets e2) && almostEqual(e1.right, e2.right) ); } -