- - (void) drawAnnotationElement:(unsigned) indx maxElement:(unsigned) max inRect:(NSRect) aRect atEdge:(DKOGridEdge) edge
- {
- //<indx> is the ordinal item to draw, starting from 0. The actual drawn element factors in the offset and increment. <edge> specifies which edge(s) the annotation // should be drawn at. It will be left or right. For vertical annotation left == top, right == bottom.
- if( edge == 0 )
- return; // nothing to do
- NSString* str = [self annotationStringForElement:indx
- maxElement:max];
- NSAttributedString* std = [[NSAttributedString alloc] initWithString:str attributes:[self textAttributes]];
- NSRect bbox, ir;
- // get the bounding box for the string
- bbox.size = [std size];
- ir = [mGridRef borderRect];
- // swap the box width/height if rotated
- if([self isRotated])
- {
- float temp = bbox.size.width;
- bbox.size.width = bbox.size.height;
- bbox.size.height = temp;
- }
- // position the box
- float textOffset = [mGridRef borderAllowance] + mOffset;
- float sd = [mGridRef spanLength];
- if([self orientationIsVertical])
- {
- if( edge == kDKOLeftEdge )
- bbox.origin.x = NSMinX( ir ) - bbox.size.width -
- textOffset;
- else
- bbox.origin.x = NSMaxX( ir ) + textOffset;
- bbox.origin.y = ( NSMinY( ir ) + ( sd * indx )) - (bbox.size.height * 0.5);
- if([self placement] == kDKOPlaceAnnotationBetweenGrid )
- bbox.origin.y += sd * 0.5;
- // don't draw if beyond end of interior
- if( bbox.origin.y > NSMaxY( ir ))
- return;
- }
- else
- {
- if( edge == kDKOLeftEdge )
- bbox.origin.y = NSMinY( ir ) - bbox.size.height - ( textOffset * 0.7);
- else
- bbox.origin.y = NSMaxY( ir ) + ( textOffset * 0.7 );
- bbox.origin.x = ( NSMinX( ir ) + ( sd * indx )) - (bbox.size.width * 0.5);
- if([self placement] == kDKOPlaceAnnotationBetweenGrid )
- bbox.origin.x += sd * 0.5;
- if( bbox.origin.x > NSMaxX( ir ))
- return;
- }
- // draw the text in the box
- if( NSIntersectsRect( bbox, aRect ))
- {
- NSPoint origin = bbox.origin;
- [NSGraphicsContext saveGraphicsState];
- if([self isRotated])
- {
- NSAffineTransform* tfm = [NSAffineTransform transform];
- if([self orientationIsVertical])
- {
- origin.x = NSMaxX( bbox );
- [tfm translateXBy:origin.x yBy:origin.y];
- [tfm rotateByDegrees:90];
- [tfm translateXBy:-origin.x yBy:-origin.y];
- }
- else
- {
- origin.y = NSMaxY( bbox );
- [tfm translateXBy:origin.x yBy:origin.y];
- [tfm rotateByDegrees:-90];
- [tfm translateXBy:-origin.x yBy:-origin.y];
- }
- [tfm concat];
- }
- [std drawAtPoint:origin];
- [NSGraphicsContext restoreGraphicsState];
- }
- }
NSAffineTransform *transform = [NSAffineTransform transform];
[transform translateXBy:0.5f * [image width] yBy:0.5f * [image height]];
[transform rotateByDegrees:45.0f];
[transform translateXBy:-0.5f * [image width] yBy:-0.5f * [image height]];
[NSGraphicsContext saveGraphicsState];
[transform concat];
[image compositeToPoint:NSMakePoint(0.0f, 0.0f) operation:NSCompositeSourceOver];
[NSGraphicsContext restoreGraphicsState];
这个工程非常不错。我变化一下,下面的任何人都感兴趣。
NSAffineTransform *transform = [NSAffineTransform transform];
[transform translateXBy:0.5f * [image width] yBy:0.5f * [image height]];
[transform rotateByDegrees:45.0f];
[transform translateXBy:-0.5f * [image width] yBy:-0.5f * [image height]];
[NSGraphicsContext saveGraphicsState];
[transform concat];
//[image compositeToPoint:NSMakePoint(0.0f, 0.0f) operation:NSCompositeSourceOver];
[image drawAtPoint:NSMakePoint(0.0f, 0.0f) fromRect:[self bounds] operation:NSCompositeSourceOver fraction:1];
[NSGraphicsContext restoreGraphicsState];
- #import <Cocoa/Cocoa.h>
- @interface UFOView : NSView {
- float angle;
- NSBezierPath *path;
- }
- @end
- //helper - gives center of rectangle
- static NSPoint MidRect(NSRect rect) { return NSMakePoint(NSMidX(rect), NSMidY(rect)); }
- @implementation UFOView
- - (void)awakeFromNib {
- path = [[NSBezierPath bezierPath] retain]; //cache to save recreating
- [path moveToPoint:NSMakePoint(-22, -30)];
- [path lineToPoint:NSMakePoint(-2, 30)];
- [path lineToPoint:NSMakePoint(28, -30)];
- [path lineToPoint:NSMakePoint(-35, 8)];
- [path lineToPoint:NSMakePoint(35, 8)];
- [path closePath];
- [NSTimer scheduledTimerWithTimeInterval:1.0/24 target:self selector:@selector(singleStep:) userInfo:nil repeats:YES];
- }
- - (void)dealloc {
- [path release];
- [super dealloc];
- }
- - (void)singleStep:(NSTimer *)timer {
- angle += 5.0;
- [self setNeedsDisplay:YES];
- }
- - (void)drawRect:(NSRect)rect { // unless you specify opaque it clears the view for you
- NSPoint pathCenter = MidRect([path bounds]); // could cache this too...
- NSPoint viewCenter = MidRect([self bounds]);
- NSAffineTransform *transform = [NSAffineTransform transform]; // it will autorelease
- [transform translateXBy:viewCenter.x yBy:viewCenter.y];
- [transform rotateByDegrees:angle];
- [transform translateXBy:-pathCenter.x yBy:-pathCenter.y];
- // alternatively to creating a new path is to [transform concat] and just draw...
- NSBezierPath *drawPath = [transform transformBezierPath:path]; // it will autorelease
- [[NSColor lightGrayColor] setFill];
- [[NSColor blackColor] setStroke];
- [drawPath fill];
- [drawPath stroke];
- }
- @end