1// 2// PXEllipseTool.m 3// Pixen-XCode 4// 5// Created by Ian Henderson on Wed Mar 10 2004. 6// Copyright (c) 2004 Open Sword Group. All rights reserved. 7// 8 9#import "PXCanvasController.h" 10#import "PXCanvas.h" 11#import "PXEllipseTool.h" 12#import "PXEllipseToolPropertiesView.h" 13 14 15@implementation PXEllipseTool 16 17- (NSString *)name 18{ 19 return NSLocalizedString(@"ELLIPSE_NAME", @"Ellipse Tool"); 20} 21 22- actionName 23{ 24 return NSLocalizedString(@"ELLIPSE_ACTION", @"Drawing Ellipse"); 25} 26 27- init 28{ 29 [super init]; 30 propertiesView = [[PXEllipseToolPropertiesView alloc] init]; 31 return self; 32} 33 34- (void)mouseDownAt:(NSPoint)aPoint fromCanvasController:controller 35{ 36 //origin = aPoint; 37 [super mouseDownAt:aPoint fromCanvasController:controller]; 38} 39 40- (void)drawPointsAddingToArray:(NSMutableArray *)points ifTracking:(BOOL)tracking withX:(int)x y:(int)y cx:(int)cx cy:(int)cy evenWidth:(BOOL)evenWidth evenHeight:(BOOL)evenHeight borderWidth:(int)borderWidth inCanvas:canvas goingHorizontally:(BOOL)horiz 41{ 42 int cWidth; 43 for (cWidth = 0; cWidth < borderWidth; cWidth++) { 44 int dx = x; 45 int dy = y; 46 if (horiz) { 47 dx -= cWidth; 48 } else { 49 dy -= cWidth; 50 } 51 int cxp; 52 int cxn; 53 int cyp; 54 int cyn; 55 cxp = cx-evenWidth; 56 cxn = cx; 57 cyp = cy-evenHeight; 58 cyn = cy; 59 NSPoint p1 = NSMakePoint(cxp+dx, cyp+dy); 60 NSPoint p2 = NSMakePoint(cxp+dx, cyn-dy); 61 NSPoint p3 = NSMakePoint(cxn-dx, cyp+dy); 62 NSPoint p4 = NSMakePoint(cxn-dx, cyn-dy); 63 if (tracking) { 64 [points addObject:NSStringFromPoint(p1)]; 65 [points addObject:NSStringFromPoint(p2)]; 66 [points addObject:NSStringFromPoint(p3)]; 67 [points addObject:NSStringFromPoint(p4)]; 68 } 69 [self drawPixelAtPoint:p1 inCanvas:canvas]; 70 [self drawPixelAtPoint:p2 inCanvas:canvas]; 71 [self drawPixelAtPoint:p3 inCanvas:canvas]; 72 [self drawPixelAtPoint:p4 inCanvas:canvas]; 73 } 74} 75 76- (NSArray *)plotEllipseInscribedInRect:(NSRect)bound withLineWidth:(int)borderWidth trackingPoints:(BOOL)tracking inCanvas:canvas 77{ 78 NSMutableArray *points = [NSMutableArray array]; 79 int xRadius = bound.size.width/2, yRadius = bound.size.height/2; 80 if (xRadius < 1) { 81 xRadius = 1; 82 } 83 if (yRadius < 1) { 84 yRadius = 1; 85 } 86 int cx = bound.origin.x + xRadius, cy = bound.origin.y + yRadius; 87 int twoASquared = 2 * xRadius * xRadius; 88 int twoBSquared = 2 * yRadius * yRadius; 89 int x = xRadius; 90 int y = 0; 91 int xChange = yRadius * yRadius * (1 - 2*xRadius); 92 int yChange = xRadius * xRadius; 93 int error = 0; 94 int stoppingX = twoBSquared * xRadius; 95 int stoppingY = 0; 96 BOOL evenWidth = ((float)xRadius == bound.size.width / 2.0f); 97 BOOL evenHeight = ((float)yRadius == bound.size.height / 2.0f); 98 while (stoppingX >= stoppingY) { 99 [self drawPointsAddingToArray:points ifTracking:tracking withX:x y:y cx:cx cy:cy evenWidth:evenWidth evenHeight:evenHeight borderWidth:borderWidth inCanvas:canvas goingHorizontally:YES]; 100 y++; 101 stoppingY += twoASquared; 102 error += yChange; 103 yChange += twoASquared; 104 if ((2*error + xChange) > 0) { 105 x--; 106 stoppingX -= twoBSquared; 107 error += xChange; 108 xChange += twoBSquared; 109 } 110 } 111 112 x = 0; 113 y = yRadius; 114 xChange = yRadius * yRadius; 115 yChange = xRadius * xRadius * (1 - 2*yRadius); 116 error = 0; 117 stoppingX = 0; 118 stoppingY = twoASquared * yRadius; 119 120 while (stoppingX <= stoppingY) { 121 [self drawPointsAddingToArray:points ifTracking:tracking withX:x y:y cx:cx cy:cy evenWidth:evenWidth evenHeight:evenHeight borderWidth:borderWidth inCanvas:canvas goingHorizontally:NO]; 122 x++; 123 stoppingX += twoBSquared; 124 error += xChange; 125 xChange += twoBSquared; 126 if ((2*error + yChange) > 0) { 127 y--; 128 stoppingY -= twoASquared; 129 error += yChange; 130 yChange += twoASquared; 131 } 132 } 133 return points; 134} 135 136- (void)drawPixelAtPoint:(NSPoint)aPoint withColor:(NSColor *)specialColor inCanvas:aCanvas //should probably be put into PXPencilTool 137{ 138 [self drawWithOldColor:[aCanvas 139colorAtPoint:aPoint] newColor:specialColor atPoint:aPoint inLayer:[aCanvas activeLayer] ofCanvas:aCanvas]; 140} 141 142- (void)plotFilledEllipseInscribedInRect:(NSRect)bound withLineWidth:(int)borderWidth withFillColor:(NSColor *)fillColor inCanvas:canvas 143{ 144 NSArray *points = [self plotEllipseInscribedInRect:(NSRect)bound withLineWidth:borderWidth trackingPoints:YES inCanvas:canvas]; 145 NSEnumerator *pointEnumerator = [points objectEnumerator]; 146 id start, end; 147 NSPoint startPoint, endPoint; 148 NSColor *prevColor = [[[self color] retain] autorelease]; 149 [self setColor:fillColor]; 150 while ((start = [pointEnumerator nextObject]) && (end = [pointEnumerator nextObject])) { 151 startPoint = NSPointFromString(start); 152 endPoint = NSPointFromString(end); 153 while ([points containsObject:NSStringFromPoint(startPoint)]) { 154 startPoint.y--; 155 } 156 startPoint.y++; 157 while ([points containsObject:NSStringFromPoint(endPoint)]) { 158 endPoint.y++; 159 } 160 if (startPoint.y > endPoint.y) { 161 [self drawLineFrom:startPoint to:endPoint inCanvas:canvas]; 162 } 163 } 164 [self setColor:prevColor]; 165} 166 167- (void)plotUnfilledEllipseInscribedInRect:(NSRect)bound withLineWidth:(int)borderWidth inCanvas:canvas 168{ 169 [self plotEllipseInscribedInRect:(NSRect)bound withLineWidth:borderWidth trackingPoints:NO inCanvas:canvas]; 170} 171 172- (NSRect)getEllipseBoundFromdrawFromPoint:(NSPoint)origin toPoint:(NSPoint)aPoint 173{ 174 NSPoint start = origin; 175 NSPoint end = aPoint; 176 if (aPoint.x < start.x) 177 { 178 start.x = aPoint.x + 1; 179 end.x = origin.x + 1; 180 } 181 if (aPoint.y < start.y) 182 { 183 start.y = aPoint.y + 1; 184 end.y = origin.y + 1; 185 } 186 return NSMakeRect(start.x, start.y, end.x - start.x, end.y - start.y); 187} 188 189- (void)finalDrawFromPoint:(NSPoint)origin toPoint:(NSPoint)aPoint inCanvas:canvas 190{ 191 NSRect ellipseBound = [self getEllipseBoundFromdrawFromPoint:(NSPoint)origin toPoint:aPoint]; 192 if ([propertiesView shouldFill]) { 193 [self plotFilledEllipseInscribedInRect:ellipseBound withLineWidth:[propertiesView borderWidth] withFillColor:([propertiesView shouldUseMainColorForFill]) ? [self color] : [propertiesView fillColor] inCanvas:canvas]; 194 } else { 195 [self plotUnfilledEllipseInscribedInRect:ellipseBound withLineWidth:[propertiesView borderWidth] inCanvas:canvas]; 196 } 197} 198- (void)drawFromPoint:(NSPoint)origin toPoint:(NSPoint)finalPoint inCanvas:canvas 199{ 200 NSRect ellipseBound = [self getEllipseBoundFromdrawFromPoint:(NSPoint)origin toPoint:finalPoint]; 201 [self plotUnfilledEllipseInscribedInRect:ellipseBound withLineWidth:[propertiesView borderWidth] inCanvas:canvas]; 202} 203@end 204