Hello, What is the correct way to draw a pixel aligned bezier path for HiDPI display modes ? I've got the following code to draw a rounded rectangle in both standard 1440x900 and HiDPI 720x450 resolutions, though it seems overly complex. Is there a simpler solution, perhaps an api method ? I have to rerun the code for it to take account of a display resolution change, how do I fix this ?
Thanks. Steven Lion, Xcode 4.1, Garbage collection on. -------------------------------------------------- #import <Cocoa/Cocoa.h> @interface TestView : NSView { NSBezierPath *thePath; } - (NSAffineTransform *)transformationToDrawBezierPath:(NSBezierPath *)path alignedInView:(NSView *)view centredAtX:(CGFloat)x y:(CGFloat)y alignPathWidth:(BOOL)alignPathWidth; @end -------------------------------------------------- #import "TestView.h" @implementation TestView - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { NSRect bounds = NSMakeRect(100.0, 100.0, 60.0, 60.0); thePath = [NSBezierPath bezierPathWithRoundedRect:bounds xRadius:6.0 yRadius:6.0]; [thePath setLineWidth:0.0]; } return self; } - (BOOL)isFlipped { return YES; } - (void)drawRect:(NSRect)dirtyRect { NSAffineTransform* transform = [self transformationToDrawBezierPath:thePath alignedInView:self centredAtX:123.0 y:84.0 alignPathWidth:YES]; [transform concat]; [[NSColor blueColor] set]; [thePath stroke]; [transform invert]; [transform concat]; } - (NSAffineTransform *)transformationToDrawBezierPath:(NSBezierPath *)path alignedInView:(NSView *)view centredAtX:(CGFloat)x y:(CGFloat)y alignPathWidth:(BOOL)alignPathWidth; { CGFloat onePixelWidth = [self convertSizeFromBacking:NSMakeSize(1.0, 1.0)].width; CGFloat halfPixelWidth = onePixelWidth * 0.5; NSInteger lineWidthPixelCount = MAX(1, (NSInteger) round([path lineWidth] / onePixelWidth)); BOOL isLineWidthEven = lineWidthPixelCount %2 == 0; NSRect pathBounds = [path bounds]; NSRect alignedBounds = [self centerScanRect:pathBounds]; NSRect insideBounds; NSPoint pathCentrePoint = NSMakePoint(NSMidX(pathBounds), NSMidY(pathBounds)); //Note : used centerScanRect to align the target point as, convertPointToBacking, //only modified the y coordinate (followed by convertPointFromBacking). NSRect target = [self centerScanRect:NSMakeRect(x, y, 1.0, 1.0)]; if (isLineWidthEven) { //Place an even line width path between pixels insideBounds = alignedBounds; } else { //Inset an odd line width path on the centre of pixels insideBounds = NSInsetRect(alignedBounds, halfPixelWidth, halfPixelWidth); } if (alignPathWidth) { [path setLineWidth:lineWidthPixelCount * onePixelWidth]; } CGFloat xScale = insideBounds.size.width / pathBounds.size.width; CGFloat yScale = insideBounds.size.height / pathBounds.size.height; CGFloat xScaleInverse = 1.0 / xScale; CGFloat yScaleInverse = 1.0 / yScale; NSAffineTransform* transform = [NSAffineTransform transform]; //Scale about the path centre [transform translateXBy:pathCentrePoint.x yBy:pathCentrePoint.y]; [transform scaleXBy:xScale yBy:yScale]; //Position the path [transform translateXBy:-pathCentrePoint.x + ((target.origin.x - pathCentrePoint.x) * xScaleInverse) yBy:-pathCentrePoint.y + ((target.origin.y - pathCentrePoint.y) * yScaleInverse)]; return transform; } @end _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com