libs-base/Source/NSGeometry.m

384 lines
11 KiB
Mathematica
Raw Permalink Normal View History

/** NSGeometry.m - geometry functions
* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
*
* Written by: Adam Fedor <fedor@boulder.colorado.edu>
* Date: Mar 1995
*
* 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 Library 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 Library 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.
<title>NSGeometry class reference</title>
$Date$ $Revision$
*/
/*
* Define IN_NSGEOMETRY_M so that the Foundation/NSGeometry.h header can
* provide non-inline versions of the function implementations for us.
*/
#define IN_NSGEOMETRY_M
/**** Included Headers *******************************************************/
#include "config.h"
#include <math.h>
#include "GNUstepBase/preface.h"
#include "Foundation/NSString.h"
#include "Foundation/NSGeometry.h"
#include "Foundation/NSScanner.h"
#include "Foundation/NSNotification.h"
extern BOOL GSMacOSXCompatibleGeometry(void); // Compatibility mode
static Class NSStringClass = 0;
static Class NSScannerClass = 0;
static SEL scanFloatSel;
static SEL scanStringSel;
static SEL scannerSel;
static BOOL (*scanFloatImp)(NSScanner*, SEL, float*);
static BOOL (*scanStringImp)(NSScanner*, SEL, NSString*, NSString**);
static id (*scannerImp)(Class, SEL, NSString*);
static inline void
setupCache(void)
{
if (NSStringClass == 0)
{
NSStringClass = [NSString class];
NSScannerClass = [NSScanner class];
scanFloatSel = @selector(scanFloat:);
scanStringSel = @selector(scanString:intoString:);
scannerSel = @selector(scannerWithString:);
scanFloatImp = (BOOL (*)(NSScanner*, SEL, float*))
[NSScannerClass instanceMethodForSelector: scanFloatSel];
scanStringImp = (BOOL (*)(NSScanner*, SEL, NSString*, NSString**))
[NSScannerClass instanceMethodForSelector: scanStringSel];
scannerImp = (id (*)(Class, SEL, NSString*))
[NSScannerClass methodForSelector: scannerSel];
}
}
/**** Function Implementations ***********************************************/
/* Most of these are implemented in the header file as inline functkions */
NSRect
NSIntegralRect(NSRect aRect)
{
NSRect rect;
if (NSIsEmptyRect(aRect))
return NSMakeRect(0, 0, 0, 0);
rect.origin.x = floor(NSMinX(aRect));
rect.origin.y = floor(NSMinY(aRect));
rect.size.width = ceil(NSMaxX(aRect)) - rect.origin.x;
rect.size.height = ceil(NSMaxY(aRect)) - rect.origin.y;
return rect;
}
void
NSDivideRect(NSRect aRect,
NSRect *slice,
NSRect *remainder,
float amount,
NSRectEdge edge)
{
static NSRect sRect;
static NSRect rRect;
if (!slice)
slice = &sRect;
if (!remainder)
remainder = &rRect;
if (NSIsEmptyRect(aRect))
{
*slice = NSMakeRect(0,0,0,0);
*remainder = NSMakeRect(0,0,0,0);
return;
}
switch (edge)
{
case NSMinXEdge:
if (amount > aRect.size.width)
{
*slice = aRect;
*remainder = NSMakeRect(NSMaxX(aRect),
aRect.origin.y,
0,
aRect.size.height);
}
else
{
*slice = NSMakeRect(aRect.origin.x,
aRect.origin.y,
amount,
aRect.size.height);
*remainder = NSMakeRect(NSMaxX(*slice),
aRect.origin.y,
NSMaxX(aRect) - NSMaxX(*slice),
aRect.size.height);
}
break;
case NSMinYEdge:
if (amount > aRect.size.height)
{
*slice = aRect;
*remainder = NSMakeRect(aRect.origin.x,
NSMaxY(aRect),
aRect.size.width, 0);
}
else
{
*slice = NSMakeRect(aRect.origin.x,
aRect.origin.y,
aRect.size.width,
amount);
*remainder = NSMakeRect(aRect.origin.x,
NSMaxY(*slice),
aRect.size.width,
NSMaxY(aRect) - NSMaxY(*slice));
}
break;
case (NSMaxXEdge):
if (amount > aRect.size.width)
{
*slice = aRect;
*remainder = NSMakeRect(aRect.origin.x,
aRect.origin.y,
0,
aRect.size.height);
}
else
{
*slice = NSMakeRect(NSMaxX(aRect) - amount,
aRect.origin.y,
amount,
aRect.size.height);
*remainder = NSMakeRect(aRect.origin.x,
aRect.origin.y,
NSMinX(*slice) - aRect.origin.x,
aRect.size.height);
}
break;
case NSMaxYEdge:
if (amount > aRect.size.height)
{
*slice = aRect;
*remainder = NSMakeRect(aRect.origin.x,
aRect.origin.y,
aRect.size.width,
0);
}
else
{
*slice = NSMakeRect(aRect.origin.x,
NSMaxY(aRect) - amount,
aRect.size.width,
amount);
*remainder = NSMakeRect(aRect.origin.x,
aRect.origin.y,
aRect.size.width,
NSMinY(*slice) - aRect.origin.y);
}
break;
default:
break;
}
return;
}
/** Get a String Representation... **/
/* NOTE: Spaces around '=' so that old OpenStep implementations can
read our strings (Both GNUstep and Mac OS X can read these as well). */
NSString*
NSStringFromPoint(NSPoint aPoint)
{
setupCache();
if (GSMacOSXCompatibleGeometry() == YES)
return [NSStringClass stringWithFormat:
@"{%g, %g}", aPoint.x, aPoint.y];
else
return [NSStringClass stringWithFormat:
@"{x = %g; y = %g}", aPoint.x, aPoint.y];
}
NSString*
NSStringFromRect(NSRect aRect)
{
setupCache();
if (GSMacOSXCompatibleGeometry() == YES)
return [NSStringClass stringWithFormat:
@"{{%g, %g}, {%g, %g}}",
aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height];
else
return [NSStringClass stringWithFormat:
@"{x = %g; y = %g; width = %g; height = %g}",
aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height];
}
NSString*
NSStringFromSize(NSSize aSize)
{
setupCache();
if (GSMacOSXCompatibleGeometry() == YES)
return [NSStringClass stringWithFormat:
@"{%g, %g}", aSize.width, aSize.height];
else
return [NSStringClass stringWithFormat:
@"{width = %g; height = %g}", aSize.width, aSize.height];
}
NSPoint
NSPointFromString(NSString* string)
{
NSScanner *scanner;
NSPoint point;
setupCache();
scanner = (*scannerImp)(NSScannerClass, scannerSel, string);
if ((*scanStringImp)(scanner, scanStringSel, @"{", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"x", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"=", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &point.x)
&& (*scanStringImp)(scanner, scanStringSel, @";", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"y", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"=", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &point.y)
&& (*scanStringImp)(scanner, scanStringSel, @"}", NULL))
{
return point;
}
else
{
[scanner setScanLocation: 0];
if ((*scanStringImp)(scanner, scanStringSel, @"{", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &point.x)
&& (*scanStringImp)(scanner, scanStringSel, @",", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &point.y)
&& (*scanStringImp)(scanner, scanStringSel, @"}", NULL))
{
return point;
}
else
{
return NSMakePoint(0, 0);
}
}
}
NSSize
NSSizeFromString(NSString* string)
{
NSScanner *scanner;
NSSize size;
setupCache();
scanner = (*scannerImp)(NSScannerClass, scannerSel, string);
if ((*scanStringImp)(scanner, scanStringSel, @"{", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"width", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"=", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &size.width)
&& (*scanStringImp)(scanner, scanStringSel, @";", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"height", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"=", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &size.height)
&& (*scanStringImp)(scanner, scanStringSel, @"}", NULL))
{
return size;
}
else
{
[scanner setScanLocation: 0];
if ((*scanStringImp)(scanner, scanStringSel, @"{", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &size.width)
&& (*scanStringImp)(scanner, scanStringSel, @",", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &size.height)
&& (*scanStringImp)(scanner, scanStringSel, @"}", NULL))
{
return size;
}
else
{
return NSMakeSize(0, 0);
}
}
}
NSRect
NSRectFromString(NSString* string)
{
NSScanner *scanner;
NSRect rect;
setupCache();
scanner = (*scannerImp)(NSScannerClass, scannerSel, string);
if ((*scanStringImp)(scanner, scanStringSel, @"{", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"x", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"=", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &rect.origin.x)
&& (*scanStringImp)(scanner, scanStringSel, @";", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"y", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"=", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &rect.origin.y)
&& (*scanStringImp)(scanner, scanStringSel, @";", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"width", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"=", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &rect.size.width)
&& (*scanStringImp)(scanner, scanStringSel, @";", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"height", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"=", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &rect.size.height)
&& (*scanStringImp)(scanner, scanStringSel, @"}", NULL))
{
return rect;
}
else
{
[scanner setScanLocation: 0];
if ((*scanStringImp)(scanner, scanStringSel, @"{", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"{", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &rect.origin.x)
&& (*scanStringImp)(scanner, scanStringSel, @",", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &rect.origin.y)
&& (*scanStringImp)(scanner, scanStringSel, @"}", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @",", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"{", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &rect.size.width)
&& (*scanStringImp)(scanner, scanStringSel, @",", NULL)
&& (*scanFloatImp)(scanner, scanFloatSel, &rect.size.height)
&& (*scanStringImp)(scanner, scanStringSel, @"}", NULL)
&& (*scanStringImp)(scanner, scanStringSel, @"}", NULL))
{
return rect;
}
else
{
return NSMakeRect(0, 0, 0, 0);
}
}
}