/* Interface for NSGeometry routines for GNUStep * Copyright (C) 1995 Free Software Foundation, Inc. * * Written by: Adam Fedor * Date: 1995,199 * * This file is part of the GNUstep Base Library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02111 USA. */ #ifndef __NSGeometry_h_GNUSTEP_BASE_INCLUDE #define __NSGeometry_h_GNUSTEP_BASE_INCLUDE #import "../GNUstepBase/GSVersionMacros.h" #import #import "NSString.h" #if defined(__cplusplus) extern "C" { #endif /**** Type, Constant, and Macro Definitions **********************************/ #ifndef MAX #define MAX(a,b) \ ({__typeof__(a) _MAX_a = (a); __typeof__(b) _MAX_b = (b); \ _MAX_a > _MAX_b ? _MAX_a : _MAX_b; }) #define GS_DEFINED_MAX #endif #ifndef MIN #define MIN(a,b) \ ({__typeof__(a) _MIN_a = (a); __typeof__(b) _MIN_b = (b); \ _MIN_a < _MIN_b ? _MIN_a : _MIN_b; }) #define GS_DEFINED_MIN #endif /** { CGFloat x; CGFloat y; }

Represents a 2-d cartesian position.

*/ typedef struct _NSPoint NSPoint; struct _NSPoint { CGFloat x; CGFloat y; }; #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) /** Array of NSPoint structs. */ typedef NSPoint *NSPointArray; /** Pointer to NSPoint struct. */ typedef NSPoint *NSPointPointer; #endif /** { CGFloat width; CGFloat height; }

Floating point rectangle size.

*/ typedef struct _NSSize NSSize; struct _NSSize { CGFloat width; CGFloat height; }; #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) /** Array of NSSize structs. */ typedef NSSize *NSSizeArray; /** Pointer to NSSize struct. */ typedef NSSize *NSSizePointer; #endif /** { NSPoint origin; NSSize size; }

Rectangle.

*/ typedef struct _NSRect NSRect; struct _NSRect { NSPoint origin; NSSize size; }; #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) /** Array of NSRect structs. */ typedef NSRect *NSRectArray; /** Pointer to NSRect struct. */ typedef NSRect *NSRectPointer; #endif enum { NSMinXEdge = 0, NSMinYEdge = 1, NSMaxXEdge = 2, NSMaxYEdge = 3 }; /** Sides of a rectangle. { NSMinXEdge, NSMinYEdge, NSMaxXEdge, NSMaxYEdge } */ typedef NSUInteger NSRectEdge; /** { CGFloat top; CGFloat left; CGFloat bottom; CGFloat right; }

A description of the distance between the edges of two rectangles.

*/ #if OS_API_VERSION(MAC_OS_X_VERSION_10_7, GS_API_LATEST) typedef struct NSEdgeInsets { CGFloat top; CGFloat left; CGFloat bottom; CGFloat right; } NSEdgeInsets; #endif /** Point at 0,0 */ static const NSPoint NSZeroPoint __attribute__((unused)) = {0.0,0.0}; /** Zero-size rectangle at 0,0 */ static const NSRect NSZeroRect __attribute__((unused)) = {{0.0,0.0},{0.0,0.0}}; /** Zero size */ static const NSSize NSZeroSize __attribute__((unused)) = {0.0,0.0}; #if OS_API_VERSION(MAC_OS_X_VERSION_10_7, GS_API_LATEST) /** Zero edge insets **/ static const NSEdgeInsets NSEdgeInsetsZero __attribute__((unused)) = {0.0,0.0,0.0,0.0}; #endif /**** Function Prototypes ****************************************************/ /* * All but the most complex functions are declared static inline in this * header file so that they are maximally efficient. In order to provide * true functions (for code modules that don't have this header) this * header is included in NSGeometry.m where the functions are no longer * declared inline. */ #ifdef IN_NSGEOMETRY_M #define GS_GEOM_SCOPE extern #define GS_GEOM_ATTR #else #define GS_GEOM_SCOPE static inline #define GS_GEOM_ATTR __attribute__((unused)) #endif /** Create Basic Structures... **/ GS_GEOM_SCOPE NSPoint NSMakePoint(CGFloat x, CGFloat y) GS_GEOM_ATTR; /** Returns an NSPoint having x-coordinate X and y-coordinate Y. */ GS_GEOM_SCOPE NSPoint NSMakePoint(CGFloat x, CGFloat y) { NSPoint point; point.x = x; point.y = y; return point; } GS_GEOM_SCOPE NSSize NSMakeSize(CGFloat w, CGFloat h) GS_GEOM_ATTR; /** Returns an NSSize having width w and height h. */ GS_GEOM_SCOPE NSSize NSMakeSize(CGFloat w, CGFloat h) { NSSize size; size.width = w; size.height = h; return size; } 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) { NSRect rect; rect.origin.x = x; rect.origin.y = y; rect.size.width = w; rect.size.height = h; return rect; } /** Constructs NSEdgeInsets. **/ #if OS_API_VERSION(MAC_OS_X_VERSION_10_7, GS_API_LATEST) GS_GEOM_SCOPE NSEdgeInsets NSEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) GS_GEOM_ATTR; GS_GEOM_SCOPE NSEdgeInsets NSEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) { NSEdgeInsets edgeInsets; edgeInsets.top = top; edgeInsets.left = left; edgeInsets.bottom = bottom; edgeInsets.right = right; return edgeInsets; } #if OS_API_VERSION(MAC_OS_X_VERSION_10_10, GS_API_LATEST) /** Compares two edge insets for equality. **/ GS_EXPORT BOOL NSEdgeInsetsEqual(NSEdgeInsets e1, NSEdgeInsets e2); #endif #endif /** Get a Rectangle's Coordinates... **/ GS_GEOM_SCOPE CGFloat NSMaxX(NSRect aRect) GS_GEOM_ATTR; /** Returns the greatest x-coordinate value still inside aRect. */ GS_GEOM_SCOPE CGFloat NSMaxX(NSRect aRect) { return aRect.origin.x + aRect.size.width; } GS_GEOM_SCOPE CGFloat NSMaxY(NSRect aRect) GS_GEOM_ATTR; /** Returns the greatest y-coordinate value still inside aRect. */ GS_GEOM_SCOPE CGFloat NSMaxY(NSRect aRect) { return aRect.origin.y + aRect.size.height; } GS_GEOM_SCOPE CGFloat NSMidX(NSRect aRect) GS_GEOM_ATTR; /** Returns the x-coordinate of aRect's middle point. */ GS_GEOM_SCOPE CGFloat NSMidX(NSRect aRect) { return aRect.origin.x + (aRect.size.width / 2.0); } GS_GEOM_SCOPE CGFloat NSMidY(NSRect aRect) GS_GEOM_ATTR; /** Returns the y-coordinate of aRect's middle point. */ GS_GEOM_SCOPE CGFloat NSMidY(NSRect aRect) { return aRect.origin.y + (aRect.size.height / 2.0); } GS_GEOM_SCOPE CGFloat NSMinX(NSRect aRect) GS_GEOM_ATTR; /** Returns the least x-coordinate value still inside aRect. */ GS_GEOM_SCOPE CGFloat NSMinX(NSRect aRect) { return aRect.origin.x; } GS_GEOM_SCOPE CGFloat NSMinY(NSRect aRect) GS_GEOM_ATTR; /** Returns the least y-coordinate value still inside aRect. */ GS_GEOM_SCOPE CGFloat NSMinY(NSRect aRect) { return aRect.origin.y; } GS_GEOM_SCOPE CGFloat NSWidth(NSRect aRect) GS_GEOM_ATTR; /** Returns aRect's width. */ GS_GEOM_SCOPE CGFloat NSWidth(NSRect aRect) { return aRect.size.width; } GS_GEOM_SCOPE CGFloat NSHeight(NSRect aRect) GS_GEOM_ATTR; /** Returns aRect's height. */ GS_GEOM_SCOPE CGFloat NSHeight(NSRect aRect) { return aRect.size.height; } GS_GEOM_SCOPE BOOL NSIsEmptyRect(NSRect aRect) GS_GEOM_ATTR; /** Returns 'YES' iff the area of aRect is zero (i.e., iff either * of aRect's width or height is negative or zero). */ GS_GEOM_SCOPE BOOL NSIsEmptyRect(NSRect aRect) { return ((NSWidth(aRect) > 0) && (NSHeight(aRect) > 0)) ? NO : YES; } /** Modify a Copy of a Rectangle... **/ GS_GEOM_SCOPE NSRect NSOffsetRect(NSRect aRect, CGFloat dx, CGFloat dy) GS_GEOM_ATTR; /** Returns the rectangle obtained by translating aRect * horizontally by dx and vertically by dy. */ GS_GEOM_SCOPE NSRect NSOffsetRect(NSRect aRect, CGFloat dx, CGFloat dy) { NSRect rect = aRect; rect.origin.x += dx; rect.origin.y += dy; return rect; } GS_GEOM_SCOPE NSRect NSInsetRect(NSRect aRect, CGFloat dX, CGFloat dY) GS_GEOM_ATTR; /** Returns the rectangle obtained by moving each of aRect's * horizontal sides inward by dy and each of aRect's vertical * sides inward by dx.
* NB. For MacOS-X compatability, this is permitted to return * a rectanglew with nagative width or height, strange as that seems. */ GS_GEOM_SCOPE NSRect NSInsetRect(NSRect aRect, CGFloat dX, CGFloat dY) { NSRect rect; rect = NSOffsetRect(aRect, dX, dY); rect.size.width -= (2 * dX); rect.size.height -= (2 * dY); return rect; } /** Divides aRect into two rectangles (namely slice and remainder) by * "cutting" aRect---parallel to, and a distance amount from the given edge * of aRect. You may pass 0 in as either of slice or * remainder to avoid obtaining either of the created rectangles. */ GS_EXPORT void NSDivideRect(NSRect aRect, NSRect *slice, NSRect *remainder, CGFloat amount, NSRectEdge edge); /** Returns a rectangle obtained by expanding aRect minimally * so that all four of its defining components are integers. */ GS_EXPORT NSRect NSIntegralRect(NSRect aRect); /** Compute a Third Rectangle from Two Rectangles... **/ GS_GEOM_SCOPE NSRect NSUnionRect(NSRect aRect, NSRect bRect) GS_GEOM_ATTR; /** Returns the smallest rectangle which contains both aRect * and bRect (modulo a set of measure zero). If either of aRect * or bRect is an empty rectangle, then the other rectangle is * returned. If both are empty, then the empty rectangle is returned. */ GS_GEOM_SCOPE NSRect NSUnionRect(NSRect aRect, NSRect bRect) { NSRect rect; if (NSIsEmptyRect(aRect) && NSIsEmptyRect(bRect)) return NSMakeRect(0.0,0.0,0.0,0.0); else if (NSIsEmptyRect(aRect)) return bRect; else if (NSIsEmptyRect(bRect)) return aRect; rect = NSMakeRect(MIN(NSMinX(aRect), NSMinX(bRect)), MIN(NSMinY(aRect), NSMinY(bRect)), 0.0, 0.0); rect = NSMakeRect(NSMinX(rect), NSMinY(rect), MAX(NSMaxX(aRect), NSMaxX(bRect)) - NSMinX(rect), MAX(NSMaxY(aRect), NSMaxY(bRect)) - NSMinY(rect)); return rect; } GS_GEOM_SCOPE NSRect NSIntersectionRect(NSRect aRect, NSRect bRect) GS_GEOM_ATTR; /** Returns the largest rectangle which lies in both aRect and * bRect. If aRect and bRect have empty intersection (or, rather, * intersection of measure zero, since this includes having their * intersection be only a point or a line), then the empty * rectangle is returned. */ GS_GEOM_SCOPE NSRect NSIntersectionRect (NSRect aRect, NSRect bRect) { if (NSMaxX(aRect) <= NSMinX(bRect) || NSMaxX(bRect) <= NSMinX(aRect) || NSMaxY(aRect) <= NSMinY(bRect) || NSMaxY(bRect) <= NSMinY(aRect)) { return NSMakeRect(0.0, 0.0, 0.0, 0.0); } else { NSRect rect; if (NSMinX(aRect) <= NSMinX(bRect)) rect.origin.x = bRect.origin.x; else rect.origin.x = aRect.origin.x; if (NSMinY(aRect) <= NSMinY(bRect)) rect.origin.y = bRect.origin.y; else rect.origin.y = aRect.origin.y; if (NSMaxX(aRect) >= NSMaxX(bRect)) rect.size.width = NSMaxX(bRect) - rect.origin.x; else rect.size.width = NSMaxX(aRect) - rect.origin.x; if (NSMaxY(aRect) >= NSMaxY(bRect)) rect.size.height = NSMaxY(bRect) - rect.origin.y; else rect.size.height = NSMaxY(aRect) - rect.origin.y; return rect; } } /** Test geometric relationships... **/ /** Returns 'YES' iff aRect's and bRect's origin and size are the same. */ GS_EXPORT BOOL NSEqualRects(NSRect aRect, NSRect bRect) GS_GEOM_ATTR; /** Returns 'YES' iff aSize's and bSize's width and height are the same. */ GS_EXPORT BOOL NSEqualSizes(NSSize aSize, NSSize bSize) GS_GEOM_ATTR; /** Returns 'YES' iff aPoint's and bPoint's x- and y-coordinates * are the same. */ GS_EXPORT BOOL NSEqualPoints(NSPoint aPoint, NSPoint bPoint) GS_GEOM_ATTR; GS_GEOM_SCOPE BOOL NSMouseInRect(NSPoint aPoint, NSRect aRect, BOOL flipped) GS_GEOM_ATTR; /** Returns 'YES' iff aPoint is inside aRect. */ GS_GEOM_SCOPE BOOL NSMouseInRect(NSPoint aPoint, NSRect aRect, BOOL flipped) { if (flipped) { return ((aPoint.x >= NSMinX(aRect)) && (aPoint.y >= NSMinY(aRect)) && (aPoint.x < NSMaxX(aRect)) && (aPoint.y < NSMaxY(aRect))) ? YES : NO; } else { return ((aPoint.x >= NSMinX(aRect)) && (aPoint.y > NSMinY(aRect)) && (aPoint.x < NSMaxX(aRect)) && (aPoint.y <= NSMaxY(aRect))) ? YES : NO; } } GS_GEOM_SCOPE BOOL NSPointInRect(NSPoint aPoint, NSRect aRect) GS_GEOM_ATTR; /** Just like 'NSMouseInRect(aPoint, aRect, YES)'. */ GS_GEOM_SCOPE BOOL NSPointInRect(NSPoint aPoint, NSRect aRect) { return NSMouseInRect(aPoint, aRect, YES); } GS_GEOM_SCOPE BOOL NSContainsRect(NSRect aRect, NSRect bRect) GS_GEOM_ATTR; /** Returns 'YES' iff aRect totally encloses bRect. NOTE: For * this to be the case, aRect cannot be empty, nor can any side * of bRect go beyond any side of aRect. Note that this behavior * is different than the original OpenStep behavior, where the sides * of bRect could not touch aRect. */ GS_GEOM_SCOPE BOOL NSContainsRect(NSRect aRect, NSRect bRect) { return (!NSIsEmptyRect(bRect) && (NSMinX(aRect) <= NSMinX(bRect)) && (NSMinY(aRect) <= NSMinY(bRect)) && (NSMaxX(aRect) >= NSMaxX(bRect)) && (NSMaxY(aRect) >= NSMaxY(bRect))) ? YES : NO; } #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) GS_GEOM_SCOPE BOOL NSIntersectsRect(NSRect aRect, NSRect bRect) GS_GEOM_ATTR; /** Returns YES if aRect and bRect have non-zero intersection area (intersecting at a line or a point doesn't count). */ GS_GEOM_SCOPE BOOL NSIntersectsRect(NSRect aRect, NSRect bRect) { /* Note that intersecting at a line or a point doesn't count */ return (NSMaxX(aRect) <= NSMinX(bRect) || NSMaxX(bRect) <= NSMinX(aRect) || NSMaxY(aRect) <= NSMinY(bRect) || NSMaxY(bRect) <= NSMinY(aRect) || NSIsEmptyRect(aRect) || NSIsEmptyRect(bRect)) ? NO : YES; } #endif /** Get a String Representation... **/ #ifdef __OBJC__ /** Returns an NSString of the form "{x=X; y=Y}", where * X and Y are the x- and y-coordinates of aPoint, respectively. */ GS_EXPORT NSString * NSStringFromPoint(NSPoint aPoint); /** Returns an NSString of the form "{x=X; y=Y; width=W; height=H}", * where X, Y, W, and H are the x-coordinate, y-coordinate, * width, and height of aRect, respectively. */ GS_EXPORT NSString * NSStringFromRect(NSRect aRect); /** Returns an NSString of the form "{width=W; height=H}", where * W and H are the width and height of aSize, respectively. */ GS_EXPORT NSString * NSStringFromSize(NSSize aSize); /** Parses point from string of form "{x=a; y=b}". (0,0) returned if parsing fails. */ GS_EXPORT NSPoint NSPointFromString(NSString* string); /** Parses size from string of form "{width=a; height=b}". Size of 0,0 returned if parsing fails. */ GS_EXPORT NSSize NSSizeFromString(NSString* string); /** Parses point from string of form "{x=a; y=b; width=c; height=d}". Rectangle of 0 size at origin returned if parsing fails. */ GS_EXPORT NSRect NSRectFromString(NSString* string); #endif /* __OBJC__ */ #ifdef GS_DEFINED_MAX #undef GS_DEFINED_MAX #undef MAX #endif #ifdef GS_DEFINED_MIN #undef GS_DEFINED_MIN #undef MIN #endif #if defined(__cplusplus) } #endif #endif /* __NSGeometry_h_GNUSTEP_BASE_INCLUDE */