1//
2//  PXSelectionLayer.m
3//  Pixen-XCode
4//
5//  Created by Joe Osborn on Sun Jan 04 2004.
6//  Copyright (c) 2004 Open Sword Group. All rights reserved.
7//
8
9#import "PXSelectionLayer.h"
10#import "PXImage.h"
11#import "PXPoint.h"
12#import "KTMutableMatrix.h"
13
14@implementation PXSelectionLayer
15
16+ selectionWithSize:(NSSize)aSize
17{
18	return [[[self alloc] initWithName:@"(selection)" size:aSize] autorelease];
19}
20
21- initWithName:aName size:(NSSize)aSize
22{
23	[super initWithName:aName size:aSize];
24	return self;
25}
26
27- (void)setIsSubtracting:(BOOL)subtracting
28{
29	isSubtracting = subtracting;
30}
31
32- (void)checkWorkingPoints
33{
34	if (workingPoints == nil)
35	{
36		workingPoints = [[KTMutableMatrix matrixWithCapacity:512*512 cuboidBounds:(unsigned)([self size].width), (unsigned)([self size].height), 0, 0] retain];
37	}
38}
39
40- workingPoints
41{
42	return workingPoints;
43}
44
45- (void)addWorkingPoint:(NSPoint)aPoint
46{
47	[self checkWorkingPoints];
48	[workingPoints setObject:self atCoordinates:(unsigned)aPoint.x, (unsigned)aPoint.y];
49}
50
51- (void)removeWorkingPoint:(NSPoint)aPoint
52{
53	[self checkWorkingPoints];
54	[workingPoints setObject:nil atCoordinates:(unsigned)aPoint.x, (unsigned)aPoint.y];
55}
56
57- (BOOL)canDrawAtPoint:(NSPoint)point
58{
59	return [super canDrawAtPoint:point] && [self pointIsSelected:point];
60}
61
62- pixelAtPoint:(NSPoint)point
63{
64	return [image _pixelAtPoint:point];
65}
66
67- (BOOL)pointIsSelected:(NSPoint)point
68{
69	return (([image pixelAtPoint:point] != nil) || ([workingPoints objectAtCoordinates:(unsigned)point.x, (unsigned)point.y] == self));
70}
71
72- (NSColor *)colorAtPoint:(NSPoint)aPoint
73{
74	return [image colorAtPoint:aPoint];
75}
76
77- (void)finalize
78{
79	[workingPoints removeAllObjects];
80}
81
82- (void)transformedDrawRect:(NSRect)aRect fixBug:(BOOL)fix
83{
84	[super transformedDrawRect:NSMakeRect(aRect.origin.x-2, aRect.origin.y-2, aRect.size.width+4, aRect.size.height+4) fixBug:fix];
85	unsigned i, j;
86	NSRect rect = NSIntersectionRect(aRect, NSMakeRect(0, 0, [self size].width, [self size].height));
87	for(i = MAX(aRect.origin.x, 0); i < MIN(NSMaxX(aRect), [self size].width); i++)
88	{
89		for(j = MAX(aRect.origin.y, 0); j < MIN(NSMaxY(aRect), [self size].height); j++)
90		{
91			if([self pixelAtPoint:NSMakePoint(i, j)] != nil)
92			{
93				NSRect currentRect = NSMakeRect(i, j, 1, 1);
94				if(NSEqualRects(rect, NSZeroRect)) { rect = currentRect; }
95				rect = NSUnionRect(rect, currentRect);
96			}
97		}
98	}
99
100	for (i = MAX(rect.origin.x, 0); i < MIN(NSMaxX(aRect), [self size].width) + 1; i++)
101	{
102		for (j = MAX(rect.origin.y, 0); j < MIN(NSMaxY(rect), [self size].height) + 1; j++)
103		{
104			if (![self canDrawAtPoint:NSMakePoint(i,j)]) { continue; }
105			if (![self canDrawAtPoint:NSMakePoint(i-1, j)])
106			{
107				[self drawBezierFromPoint:NSMakePoint(i, j) toPoint:NSMakePoint(i, j + 1) color:[NSColor blackColor]];
108			}
109			if (![self canDrawAtPoint:NSMakePoint(i+1, j)])
110			{
111				[self drawBezierFromPoint:NSMakePoint(i + 1, j) toPoint:NSMakePoint(i + 1, j + 1) color:[NSColor blackColor]];
112			}
113			if (![self canDrawAtPoint:NSMakePoint(i, j-1)])
114			{
115				[self drawBezierFromPoint:NSMakePoint(i, j) toPoint:NSMakePoint(i + 1, j) color:[NSColor blackColor]];
116			}
117			if (![self canDrawAtPoint:NSMakePoint(i, j+1)])
118			{
119				[self drawBezierFromPoint:NSMakePoint(i, j + 1) toPoint:NSMakePoint(i + 1, j + 1) color:[NSColor blackColor]];
120			}
121		}
122	}
123
124	if (isSubtracting)
125	{
126		for(i = MAX(rect.origin.x - 1, 0); i < (MIN(NSMaxX(rect), [self size].width-2) + 2); i++)
127		{
128			for(j = MAX(rect.origin.y - 1, 0); j < (MIN(NSMaxY(rect), [self size].height-2) + 2); j++)
129			{
130				if (![workingPoints objectAtCoordinates:i, j]) { continue; }
131				if (![workingPoints objectAtCoordinates:i-1, j])
132				{
133					[self drawBezierFromPoint:NSMakePoint(i, j) toPoint:NSMakePoint(i, j + 1) color:[NSColor redColor]];
134				}
135				if (![workingPoints objectAtCoordinates:i+1,j])
136				{
137					[self drawBezierFromPoint:NSMakePoint(i + 1, j) toPoint:NSMakePoint(i + 1, j + 1) color:[NSColor redColor]];
138				}
139				if (![workingPoints objectAtCoordinates:i,j-1])
140				{
141					[self drawBezierFromPoint:NSMakePoint(i, j) toPoint:NSMakePoint(i + 1, j) color:[NSColor redColor]];
142				}
143				if (![workingPoints objectAtCoordinates:i,j+1])
144				{
145					[self drawBezierFromPoint:NSMakePoint(i, j + 1) toPoint:NSMakePoint(i + 1, j + 1) color:[NSColor redColor]];
146				}
147			}
148		}
149	}
150}
151
152- (void)drawBezierFromPoint:(NSPoint)fromPoint toPoint:(NSPoint)toPoint color:color
153{
154	id path = [[[NSBezierPath alloc] init] autorelease];
155	[path setLineWidth:.1];
156	const float pattern[] = { 0.5, 0.5 };
157	[path moveToPoint:fromPoint];
158	[path lineToPoint:toPoint];
159	[[NSColor colorWithCalibratedWhite:1 alpha:1] set];
160	[path setLineDash:pattern count:1 phase:0];
161	[path stroke];
162	[color set];
163	[path setLineDash:pattern count:1 phase:.5];
164	[path stroke];
165}
166
167@end