Reputation: 788
I'd like to create a rounded rect similar to the one around the labels (while editing) in AddressBook. I am trying to use a bezierPath with a rounded rect and then stroking it to do this. But, the end result doesn't have very smooth edges.
Address Book label
Address Book label zoomed in pixie
My label
My label zoomed in pixie
It looks like the curves in the addressbook version are more aggressively mixed towards the background white color. In Pixie, the pixel I have my cursor on has a sRGB value of (0.98, 0.98, 0.98), wheras in my version it is (0.86, 0.86, 0.86) resulting in a bit of jagged edge. My code to draw the rect is
override func drawWithFrame(cellFrame: NSRect, inView controlView: NSView) {
if let context = NSGraphicsContext.currentContext() {
context.saveGraphicsState()
let borderColor = NSColor.init(SRGBRed: 0.75, green: 0.75, blue: 0.75, alpha: 1)
let outline = NSBezierPath.init(roundedRect: cellFrame, xRadius: 4, yRadius: 4)
outline.lineWidth = 4
borderColor.setStroke()
outline.stroke()
drawInteriorWithFrame(cellFrame, inView: controlView)
context.restoreGraphicsState()
}
}
I have tried playing around with different compositing types, line widths and xy radiuses for the round rect - without much success. I would appreciate some guidance on this. Thanks
Upvotes: 0
Views: 879
Reputation: 788
I believe this article here explains the issue. When we stroke a rect, Coregraphics draws the outline along the middle of the edge of the rectangle we provide. If the rect is 1 pixel wide, then half the stroke line will lie outside the rectangle, while the other half will lie on the inside. As we can't draw half a pixel, Coregraphics mixes the two colors (on the inside and outside) to draw the line. So, to draw a single pixel line, we need to modify the outline rect
CGRect rectFor1PxStroke(CGRect rect)
{
return CGRectMake(rect.origin.x + 0.5, rect.origin.y + 0.5, rect.size.width - 1, rect.size.height - 1);
}
A couple of other options are also provided in the referenced article. But, with my initial testing, the above solution seems to work fine - along with setting the linewidth = 1 and x-y radiuses of the curve to 2
Upvotes: 2