mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-30 13:50:37 +00:00
Corrected some bugs. Opimized the concret subclass to use a GSIArray.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@8731 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e26d81b3d4
commit
ffdddc1887
1 changed files with 99 additions and 134 deletions
|
@ -51,88 +51,7 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@class GSBezierPath;
|
||||||
@interface PathElement : NSObject <NSCopying>
|
|
||||||
{
|
|
||||||
@public
|
|
||||||
NSPoint points[3];
|
|
||||||
NSBezierPathElement type;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (PathElement *)closePathElement;
|
|
||||||
+ (PathElement *)movePathElement:(NSPoint)aPoint;
|
|
||||||
+ (PathElement *)linePathElement:(NSPoint)aPoint;
|
|
||||||
+ (PathElement *)curvePathElement:(NSPoint)aPoint
|
|
||||||
controlPoint1:(NSPoint)controlPoint1
|
|
||||||
controlPoint2:(NSPoint)controlPoint2;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@interface GSBezierPath : NSBezierPath
|
|
||||||
{
|
|
||||||
NSMutableArray *pathElements;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)calculateDraftPolygon: (int*)pc withPoints: (NSPoint*)draftPolygon;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@implementation PathElement
|
|
||||||
|
|
||||||
+ (PathElement *)closePathElement
|
|
||||||
{
|
|
||||||
PathElement *elem = [self alloc];
|
|
||||||
|
|
||||||
elem->type = NSClosePathBezierPathElement;
|
|
||||||
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (PathElement *)movePathElement:(NSPoint)aPoint
|
|
||||||
{
|
|
||||||
PathElement *elem = [self alloc];
|
|
||||||
|
|
||||||
elem->type = NSMoveToBezierPathElement;
|
|
||||||
elem->points[0] = aPoint;
|
|
||||||
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (PathElement *)linePathElement:(NSPoint)aPoint
|
|
||||||
{
|
|
||||||
PathElement *elem = [self alloc];
|
|
||||||
|
|
||||||
elem->type = NSLineToBezierPathElement;
|
|
||||||
elem->points[0] = aPoint;
|
|
||||||
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (PathElement *)curvePathElement:(NSPoint)aPoint
|
|
||||||
controlPoint1:(NSPoint)controlPoint1
|
|
||||||
controlPoint2:(NSPoint)controlPoint2
|
|
||||||
{
|
|
||||||
PathElement *elm = [self alloc];
|
|
||||||
|
|
||||||
elm->type = NSCurveToBezierPathElement;
|
|
||||||
elm->points[0] = controlPoint1;
|
|
||||||
elm->points[1] = controlPoint2;
|
|
||||||
elm->points[2] = aPoint;
|
|
||||||
|
|
||||||
return elm;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)copyWithZone:(NSZone *)zone
|
|
||||||
{
|
|
||||||
PathElement *element = (PathElement *)NSCopyObject (self, 0, zone);
|
|
||||||
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@implementation NSBezierPath
|
@implementation NSBezierPath
|
||||||
|
|
||||||
|
@ -599,7 +518,6 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
- (NSBezierPath *)bezierPathByFlatteningPath
|
- (NSBezierPath *)bezierPathByFlatteningPath
|
||||||
{
|
{
|
||||||
NSBezierPath *path = [isa bezierPath];
|
NSBezierPath *path = [isa bezierPath];
|
||||||
NSBezierPath *path2;
|
|
||||||
NSBezierPathElement type;
|
NSBezierPathElement type;
|
||||||
NSPoint pts[3];
|
NSPoint pts[3];
|
||||||
NSPoint coeff[4];
|
NSPoint coeff[4];
|
||||||
|
@ -608,7 +526,7 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
BOOL first = YES;
|
BOOL first = YES;
|
||||||
|
|
||||||
count = [self elementCount];
|
count = [self elementCount];
|
||||||
for(i = count - 1; i >= 0; i--)
|
for(i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
type = [self elementAtIndex: i associatedPoints: pts];
|
type = [self elementAtIndex: i associatedPoints: pts];
|
||||||
switch(type)
|
switch(type)
|
||||||
|
@ -628,13 +546,11 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NSCurveToBezierPathElement:
|
case NSCurveToBezierPathElement:
|
||||||
path2 = [isa bezierPath];
|
|
||||||
coeff[0] = p;
|
coeff[0] = p;
|
||||||
coeff[1] = pts[0];
|
coeff[1] = pts[0];
|
||||||
coeff[2] = pts[1];
|
coeff[2] = pts[1];
|
||||||
coeff[3] = pts[2];
|
coeff[3] = pts[2];
|
||||||
flatten(coeff, [self flatness], path2);
|
flatten(coeff, [self flatness], path);
|
||||||
[path appendBezierPath: path2];
|
|
||||||
p = pts[2];
|
p = pts[2];
|
||||||
if (first)
|
if (first)
|
||||||
{
|
{
|
||||||
|
@ -1337,23 +1253,53 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _PathElement
|
||||||
|
{
|
||||||
|
NSBezierPathElement type;
|
||||||
|
NSPoint points[3];
|
||||||
|
} PathElement;
|
||||||
|
|
||||||
|
//#define GSUNION_TYPES GSUNION_OBJ
|
||||||
|
#define GSI_ARRAY_TYPES 0
|
||||||
|
#define GSI_ARRAY_EXTRA PathElement
|
||||||
|
|
||||||
|
#define GSI_ARRAY_NO_RETAIN
|
||||||
|
#define GSI_ARRAY_NO_RELEASE
|
||||||
|
|
||||||
|
#ifdef GSIArray
|
||||||
|
#undef GSIArray
|
||||||
|
#endif
|
||||||
|
#include <base/GSIArray.h>
|
||||||
|
|
||||||
|
@interface GSBezierPath : NSBezierPath
|
||||||
|
{
|
||||||
|
GSIArray pathElements;
|
||||||
|
BOOL flat;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)calculateDraftPolygon: (int*)pc withPoints: (NSPoint*)draftPolygon;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation GSBezierPath
|
@implementation GSBezierPath
|
||||||
|
|
||||||
- (id)init
|
- (id)init
|
||||||
{
|
{
|
||||||
|
NSZone *zone;
|
||||||
|
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if(self)
|
zone = GSObjCZone(self);
|
||||||
{
|
pathElements = NSZoneMalloc(zone, sizeof(GSIArray_t));
|
||||||
pathElements = [[NSMutableArray alloc] initWithCapacity: 1];
|
GSIArrayInitWithZoneAndCapacity(pathElements, zone, 8);
|
||||||
}
|
flat = YES;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
RELEASE(pathElements);
|
GSIArrayEmpty(pathElements);
|
||||||
|
NSZoneFree(GSObjCZone(self), pathElements);
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1362,17 +1308,21 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
//
|
//
|
||||||
- (void)moveToPoint:(NSPoint)aPoint
|
- (void)moveToPoint:(NSPoint)aPoint
|
||||||
{
|
{
|
||||||
PathElement *elm = [PathElement movePathElement: aPoint];
|
PathElement elem;
|
||||||
|
|
||||||
[pathElements addObject: elm];
|
elem.type = NSMoveToBezierPathElement;
|
||||||
|
elem.points[0] = aPoint;
|
||||||
|
GSIArrayAddItem(pathElements, (GSIArrayItem)elem);
|
||||||
INVALIDATE_CACHE();
|
INVALIDATE_CACHE();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)lineToPoint:(NSPoint)aPoint
|
- (void)lineToPoint:(NSPoint)aPoint
|
||||||
{
|
{
|
||||||
PathElement *elm = [PathElement linePathElement: aPoint];
|
PathElement elem;
|
||||||
|
|
||||||
[pathElements addObject: elm];
|
elem.type = NSLineToBezierPathElement;
|
||||||
|
elem.points[0] = aPoint;
|
||||||
|
GSIArrayAddItem(pathElements, (GSIArrayItem)elem);
|
||||||
INVALIDATE_CACHE();
|
INVALIDATE_CACHE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1380,25 +1330,30 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
controlPoint1:(NSPoint)controlPoint1
|
controlPoint1:(NSPoint)controlPoint1
|
||||||
controlPoint2:(NSPoint)controlPoint2
|
controlPoint2:(NSPoint)controlPoint2
|
||||||
{
|
{
|
||||||
PathElement *elm = [PathElement curvePathElement: aPoint
|
PathElement elem;
|
||||||
controlPoint1: controlPoint1
|
|
||||||
controlPoint2: controlPoint2];
|
elem.type = NSCurveToBezierPathElement;
|
||||||
|
elem.points[0] = controlPoint1;
|
||||||
|
elem.points[1] = controlPoint2;
|
||||||
|
elem.points[2] = aPoint;
|
||||||
|
GSIArrayAddItem(pathElements, (GSIArrayItem)elem);
|
||||||
|
flat = NO;
|
||||||
|
|
||||||
[pathElements addObject: elm];
|
|
||||||
INVALIDATE_CACHE();
|
INVALIDATE_CACHE();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)closePath
|
- (void)closePath
|
||||||
{
|
{
|
||||||
PathElement *elm = [PathElement closePathElement];
|
PathElement elem;
|
||||||
|
|
||||||
[pathElements addObject: elm];
|
elem.type = NSClosePathBezierPathElement;
|
||||||
|
GSIArrayAddItem(pathElements, (GSIArrayItem)elem);
|
||||||
INVALIDATE_CACHE();
|
INVALIDATE_CACHE();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)removeAllPoints
|
- (void)removeAllPoints
|
||||||
{
|
{
|
||||||
[pathElements removeAllObjects];
|
GSIArrayRemoveAllItems(pathElements);
|
||||||
INVALIDATE_CACHE();
|
INVALIDATE_CACHE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1407,27 +1362,26 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
//
|
//
|
||||||
- (int)elementCount
|
- (int)elementCount
|
||||||
{
|
{
|
||||||
return [pathElements count];
|
return GSIArrayCount(pathElements);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSBezierPathElement)elementAtIndex:(int)index
|
- (NSBezierPathElement)elementAtIndex:(int)index
|
||||||
associatedPoints:(NSPoint *)points
|
associatedPoints:(NSPoint *)points
|
||||||
{
|
{
|
||||||
PathElement *elm = [pathElements objectAtIndex: index];
|
PathElement elm = GSIArrayItemAtIndex(pathElements, index).ext;
|
||||||
NSBezierPathElement type = elm->type;
|
NSBezierPathElement type = elm.type;
|
||||||
NSPoint *p = elm->points;
|
|
||||||
|
|
||||||
if(points != NULL)
|
if (points != NULL)
|
||||||
{
|
{
|
||||||
if(type == NSMoveToBezierPathElement || type == NSLineToBezierPathElement)
|
if(type == NSMoveToBezierPathElement || type == NSLineToBezierPathElement)
|
||||||
{
|
{
|
||||||
points[0] = p[0];
|
points[0] = elm.points[0];
|
||||||
}
|
}
|
||||||
else if(type == NSCurveToBezierPathElement)
|
else if(type == NSCurveToBezierPathElement)
|
||||||
{
|
{
|
||||||
points[0] = p[0];
|
points[0] = elm.points[0];
|
||||||
points[1] = p[1];
|
points[1] = elm.points[1];
|
||||||
points[2] = p[2];
|
points[2] = elm.points[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1436,19 +1390,19 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
|
|
||||||
- (void)setAssociatedPoints:(NSPoint *)points atIndex:(int)index
|
- (void)setAssociatedPoints:(NSPoint *)points atIndex:(int)index
|
||||||
{
|
{
|
||||||
PathElement *elm = [pathElements objectAtIndex: index];
|
PathElement elm = GSIArrayItemAtIndex(pathElements, index).ext;
|
||||||
NSBezierPathElement type = elm->type;
|
NSBezierPathElement type = elm.type;
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case NSMoveToBezierPathElement:
|
case NSMoveToBezierPathElement:
|
||||||
case NSLineToBezierPathElement:
|
case NSLineToBezierPathElement:
|
||||||
elm->points[0] = points[0];
|
elm.points[0] = points[0];
|
||||||
break;
|
break;
|
||||||
case NSCurveToBezierPathElement:
|
case NSCurveToBezierPathElement:
|
||||||
elm->points[0] = points[0];
|
elm.points[0] = points[0];
|
||||||
elm->points[1] = points[1];
|
elm.points[1] = points[1];
|
||||||
elm->points[2] = points[2];
|
elm.points[2] = points[2];
|
||||||
break;
|
break;
|
||||||
case NSClosePathBezierPathElement:
|
case NSClosePathBezierPathElement:
|
||||||
break;
|
break;
|
||||||
|
@ -1456,9 +1410,21 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GSIArraySetItemAtIndex(pathElements, (GSIArrayItem)elm, index);
|
||||||
INVALIDATE_CACHE();
|
INVALIDATE_CACHE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Path modifications.
|
||||||
|
//
|
||||||
|
- (NSBezierPath *)bezierPathByFlatteningPath
|
||||||
|
{
|
||||||
|
if (flat)
|
||||||
|
return self;
|
||||||
|
|
||||||
|
return [super bezierPathByFlatteningPath];
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// NSCopying Protocol
|
// NSCopying Protocol
|
||||||
//
|
//
|
||||||
|
@ -1466,7 +1432,7 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
{
|
{
|
||||||
GSBezierPath *path = [super copyWithZone: zone];
|
GSBezierPath *path = [super copyWithZone: zone];
|
||||||
|
|
||||||
path->pathElements = [pathElements copy];
|
path->pathElements = GSIArrayCopyWithZone(pathElements, zone);
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
@ -1536,22 +1502,20 @@ static Class NSBezierPath_concrete_class = nil;
|
||||||
// FIXME: This does not handle multiple segments!
|
// FIXME: This does not handle multiple segments!
|
||||||
- (void)calculateDraftPolygon: (int*)pc withPoints: (NSPoint*)draftPolygon
|
- (void)calculateDraftPolygon: (int*)pc withPoints: (NSPoint*)draftPolygon
|
||||||
{
|
{
|
||||||
PathElement *elm;
|
|
||||||
NSBezierPathElement bpt;
|
NSBezierPathElement bpt;
|
||||||
NSPoint p, *pts;
|
NSPoint p, pts[3];
|
||||||
double x, y, t, k = 0.25;
|
double x, y, t, k = 0.25;
|
||||||
int i;
|
int i;
|
||||||
int pcount;
|
int pcount;
|
||||||
|
int count = [self elementCount];
|
||||||
|
|
||||||
if(![pathElements count])
|
if(!count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pcount = 0;
|
pcount = 0;
|
||||||
for(i = 0; i < [pathElements count]; i++)
|
for(i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
elm = [pathElements objectAtIndex: i];
|
bpt = [self elementAtIndex: i associatedPoints: pts];
|
||||||
bpt = elm->type;
|
|
||||||
pts = elm->points;
|
|
||||||
|
|
||||||
if(bpt == NSMoveToBezierPathElement || bpt == NSLineToBezierPathElement)
|
if(bpt == NSMoveToBezierPathElement || bpt == NSLineToBezierPathElement)
|
||||||
{
|
{
|
||||||
|
@ -1637,8 +1601,9 @@ static void flatten(NSPoint coeff[], float flatness, NSBezierPath *path)
|
||||||
x1_0 = coeff[1].x - coeff[0].x;
|
x1_0 = coeff[1].x - coeff[0].x;
|
||||||
y1_0 = coeff[1].y - coeff[0].y;
|
y1_0 = coeff[1].y - coeff[0].y;
|
||||||
z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0;
|
z3_0_dot = x3_0 * x3_0 + y3_0 * y3_0;
|
||||||
|
|
||||||
if (z3_0_dot < 0.001)
|
if (z3_0_dot < 0.001)
|
||||||
flat = YES;
|
flat = YES;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
max_perp_sq = flatness * flatness * z3_0_dot;
|
max_perp_sq = flatness * flatness * z3_0_dot;
|
||||||
|
@ -1681,14 +1646,14 @@ static void flatten(NSPoint coeff[], float flatness, NSBezierPath *path)
|
||||||
bleft[1].y = (coeff[0].y + coeff[1].y) / 2;
|
bleft[1].y = (coeff[0].y + coeff[1].y) / 2;
|
||||||
bleft[2].x = (coeff[0].x + 2*coeff[1].x + coeff[2].x) / 4;
|
bleft[2].x = (coeff[0].x + 2*coeff[1].x + coeff[2].x) / 4;
|
||||||
bleft[2].y = (coeff[0].y + 2*coeff[1].y + coeff[2].y) / 4;
|
bleft[2].y = (coeff[0].y + 2*coeff[1].y + coeff[2].y) / 4;
|
||||||
bleft[3].x = (coeff[0].x + 3*(coeff[1].x + coeff[2].x) + coeff[3].x) / 6;
|
bleft[3].x = (coeff[0].x + 3*(coeff[1].x + coeff[2].x) + coeff[3].x) / 8;
|
||||||
bleft[3].y = (coeff[0].y + 3*(coeff[1].y + coeff[2].y) + coeff[3].y) / 6;
|
bleft[3].y = (coeff[0].y + 3*(coeff[1].y + coeff[2].y) + coeff[3].y) / 8;
|
||||||
bright[0].x = bleft[3].x;
|
bright[0].x = bleft[3].x;
|
||||||
bright[0].y = bleft[3].y;
|
bright[0].y = bleft[3].y;
|
||||||
bright[1].x = (coeff[3].x + 2*coeff[2].x + coeff[1].x) / 4;
|
bright[1].x = (coeff[3].x + 2*coeff[2].x + coeff[1].x) / 4;
|
||||||
bright[1].y = (coeff[3].y + 2*coeff[2].y + coeff[1].y) / 4;
|
bright[1].y = (coeff[3].y + 2*coeff[2].y + coeff[1].y) / 4;
|
||||||
bright[2].x = (coeff[2].x + coeff[1].x) / 2;
|
bright[2].x = (coeff[3].x + coeff[2].x) / 2;
|
||||||
bright[2].y = (coeff[2].y + coeff[1].y) / 2;
|
bright[2].y = (coeff[3].y + coeff[2].y) / 2;
|
||||||
bright[3] = coeff[3];
|
bright[3] = coeff[3];
|
||||||
|
|
||||||
flatten(bleft, flatness, path);
|
flatten(bleft, flatness, path);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue