This is SNUserPath.m in view mode; [Download] [Up]
#import "Risk.h"
RCSID ("$Id: SNUserPath.m,v 1.2 1997/12/15 07:44:18 nygard Exp $");
#import "SNUserPath.h"
#import <Foundation/NSObjCRuntime.h>
#import <AppKit/dpsOpenStep.h>
#import "NSObjectExtensions.h"
#import "SNUserPathOperation.h"
#import "SNUserPathWraps.h"
//======================================================================
// An SNUserPath provides an interface for creating user paths and
// using them for drawing or hit detection. The bounding box
// calculations are incomplete, but work with straight lines.
//
// The MiscKit provides a more complete implementation. Under Rhapsody
// this will probably move towards using the NSBezierPath path.
//
// Note that this means curved paths could be easily supported to
// provide better looking maps, but RiskUtil.app would need to be
// able to support them.
//======================================================================
#define SNUserPath_VERSION 1
@implementation SNUserPath
+ (void) initialize
{
if (self == [SNUserPath class])
{
[self setVersion:SNUserPath_VERSION];
}
}
//----------------------------------------------------------------------
- init
{
if ([super init] == nil)
return nil;
operations = [[NSMutableArray array] retain];
pathGenerated = NO;
cached = NO;
operators = NULL;
operatorCount = 0;
operands = NULL;
operandCount = 0;
return self;
}
//----------------------------------------------------------------------
- (void) dealloc
{
SNRelease (operations);
if (operators != NULL)
free (operators);
if (operands != NULL)
free (operands);
[super dealloc];
}
//----------------------------------------------------------------------
// Encodes operations, not the generated user path data structures
- (void) encodeWithCoder:(NSCoder *)aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObject:operations];
//[aCoder encodeValueOfObjCType:@encode (BOOL) at:&pathGenerated];
}
//----------------------------------------------------------------------
- initWithCoder:(NSCoder *)aDecoder
{
[super initWithCoder:aDecoder];
operations = [[aDecoder decodeObject] retain];
pathGenerated = NO;
cached = NO;
operators = NULL;
operatorCount = 0;
operands = NULL;
operandCount = 0;
return self;
}
//----------------------------------------------------------------------
- (void) addOperation:(SNUserPathOperation *)newOperation
{
NSAssert (pathGenerated == NO, @"The user path has already been generated.");
[operations addObject:newOperation];
}
//----------------------------------------------------------------------
// Also creates bounding box
- (void) createPathWithCache:(BOOL)flag
{
NSEnumerator *enumerator;
SNUserPathOperation *operation;
DPSUserPathOp *nextOperator;
float *nextOperand;
NSPoint lowerLeft, upperRight;
NSPoint ll, ur;
NSAssert (pathGenerated == NO, @"The user path has already been generated.");
lowerLeft = NSMakePoint (10000, 10000);
upperRight = NSMakePoint (-10000, -10000);
enumerator = [operations objectEnumerator];
while (operation = [enumerator nextObject])
{
ll = [operation lowerLeft];
ur = [operation upperRight];
//NSLog (@"** lowerLeft: (%f,%f), point: (%f,%f)", lowerLeft.x, lowerLeft.y, ll.x, ll.y);
lowerLeft.x = MIN (ll.x, lowerLeft.x);
lowerLeft.y = MIN (ll.y, lowerLeft.y);
//NSLog (@"** new lowerLeft: (%f,%f)", lowerLeft.x, lowerLeft.y);
upperRight.x = MAX (ur.x, upperRight.x);
upperRight.y = MAX (ur.y, upperRight.y);
}
//NSLog (@"snup bbox: lowerLeft (%f,%f), upperRight (%f,%f)", lowerLeft.x, lowerLeft.y, upperRight.x, upperRight.y);
[operations insertObject:[SNUserPathOperation setbbox:lowerLeft:upperRight] atIndex:0];
if (flag == YES)
{
cached = YES;
[operations insertObject:[SNUserPathOperation ucache] atIndex:0];
}
operatorCount = [operations count];
enumerator = [operations objectEnumerator];
operandCount = 0;
while (operation = [enumerator nextObject])
{
operandCount += [operation operandCount];
}
// Mallocing...
operators = (DPSUserPathOp *) malloc (operatorCount * sizeof (float));
NSAssert (operators != NULL, @"Could not malloc() operators.");
operands = (float *) malloc (operandCount * sizeof (float));
NSAssert (operands != NULL, @"Could not malloc() operands.");
nextOperator = operators;
nextOperand = operands;
enumerator = [operations objectEnumerator];
while (operation = [enumerator nextObject])
{
*nextOperator++ = [operation operator];
[operation operands:nextOperand];
nextOperand += [operation operandCount];
}
pathGenerated = YES;
if (cached == YES)
{
// Remove it to make sure it's not archived (which might result
// in duplicate ucache operators.)
[operations removeObjectAtIndex:0];
}
// Get rid of the bounding box for the same reason.
[operations removeObjectAtIndex:0];
}
//----------------------------------------------------------------------
- (BOOL) isPathGenerated
{
return pathGenerated;
}
//----------------------------------------------------------------------
- (DPSUserPathOp *) operators
{
NSAssert (pathGenerated == YES, @"The user path has not been generated.");
return operators + ((cached == YES) ? 2 : 1); // Skip over bbox
}
//----------------------------------------------------------------------
- (int) operatorCount
{
NSAssert (pathGenerated == YES, @"The user path has not been generated.");
return operatorCount - ((cached == YES) ? 2 : 1); // Skip bbox
}
//----------------------------------------------------------------------
- (float *) operands
{
NSAssert (pathGenerated == YES, @"The user path has not been generated.");
return operands + 4; // Skip bbox
}
//----------------------------------------------------------------------
- (int) operandCount
{
NSAssert (pathGenerated == YES, @"The user path has not been generated.");
return operandCount - 4; // Skip bbox
}
//----------------------------------------------------------------------
- (float *) bbox
{
return operands;
}
//----------------------------------------------------------------------
- (NSRect) bounds
{
return NSMakeRect (operands[0], operands[1], operands[2] - operands[0], operands[3] - operands[1]);
}
//----------------------------------------------------------------------
- (void) getUserPath:(DPSUserPathOp **)operatorPtr:(int *)operatorCountPtr:(float **)operandPtr:(int *)operandCountPtr
:(float **)bboxPtr
{
NSAssert (pathGenerated == YES, @"The user path has not been generated.");
*operatorPtr = operators + ((cached == YES) ? 2 : 1);
*operatorCountPtr = operatorCount - ((cached == YES) ? 2 : 1);
*operandPtr = operands + 4;
*operandCountPtr = operandCount - 4;
*bboxPtr = operands;
}
//----------------------------------------------------------------------
- (void) getFullUserPath:(DPSUserPathOp **)operatorPtr:(int *)operatorCountPtr:(float **)operandPtr:(int *)operandCountPtr
{
NSAssert (pathGenerated == YES, @"The user path has not been generated.");
*operatorPtr = operators;
*operatorCountPtr = operatorCount;
*operandPtr = operands;
*operandCountPtr = operandCount;
}
//----------------------------------------------------------------------
- (void) fill
{
SNUserPathDraw (operators, operatorCount, operands, operandCount, dps_ufill);
}
//----------------------------------------------------------------------
- (void) evenOddFill
{
SNUserPathDraw (operators, operatorCount, operands, operandCount, dps_ueofill);
}
//----------------------------------------------------------------------
- (void) stroke
{
SNUserPathDraw (operators, operatorCount, operands, operandCount, dps_ustroke);
}
//----------------------------------------------------------------------
- (BOOL) inFill:(NSPoint)aPoint
{
int r = 0;
SNUserPathWasHitFill (aPoint.x, aPoint.y, operators, operatorCount, operands, operandCount, &r);
return r == 1;
}
//----------------------------------------------------------------------
- (BOOL) inEvenOddFill:(NSPoint)aPoint
{
int r = 0;
SNUserPathWasHitEvenOddFill (aPoint.x, aPoint.y, operators, operatorCount, operands, operandCount, &r);
return r == 1;
}
//----------------------------------------------------------------------
- (BOOL) inStroke:(NSPoint)aPoint
{
int r = 0;
SNUserPathWasHitStroke (aPoint.x, aPoint.y, operators, operatorCount, operands, operandCount, &r);
return r == 1;
}
//----------------------------------------------------------------------
- (NSString *) description
{
return [NSString stringWithFormat:@"<SNUserPath: pathGenerated = %@, operations = %@>",
(pathGenerated == YES) ? @"Yes" : @"No", operations];
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.