Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
432 views
in Technique[技术] by (71.8m points)

objective c - NSBezierPath drawing

I want to do a rounded rectangle outline on an NSImage and I figured that using NSBezierPath would be the best way. However, I ran into a problem: instead of drawing a nice curve, I get this:

enter image description here

For reasons I can't understand, NSBezierPath is drawing the rounded part with a darker color than the rest.

Here's the code I'm using (inside a drawRect: call on a custom view):

NSBezierPath* bp = [NSBezierPath bezierPathWithRoundedRect: self.bounds xRadius: 5 yRadius: 5];
[[[NSColor blackColor] colorWithAlphaComponent: 0.5] setStroke];
[bp stroke];

Any ideas?

Edit:

If I inset the path by 0.5 everything draws just fine. But why is it that I get this when I offset the path by 10 pixels (for example)?

enter image description here

If I understand correctly, it should draw a thin line as well...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Many rendering systems are derived from the PostScript drawing model. Core Graphics is one of these derivative systems. (Here are some others: PDF, SVG, the HTML Canvas 2D Context, Cairo.)

All of these systems have the idea of stroking a path with a line of some fixed width. When you stroke the path, the line straddles the path: half of the line's width is on one side of the path, and half of the line's width is on the other side. Here's a diagram that may make this clearer:

path stroke

Now, what happens when you stroke a path that lies along the boundary of your view? Half of the stroke will fall outside of your view's bounds and be clipped away - not drawn. You will only see the half of the stroke that falls inside the view's bounds.

When you use a rounded corner, that corner pulls away from the view's boundary, toward its center, so more of the stroke around the corner falls inside the view's boundary. So the stroke appears to get thicker around the rounded corner, like this:

path stroke clipped

To fix this, you need to inset your path by half the line width, so that the entire stroke falls inside your view's bounds along the entire path. The default line width is 1.0, so:

NSBezierPath* bp = [NSBezierPath bezierPathWithRoundedRect:
    NSRectInset(self.bounds, 0.5, 0.5) xRadius:5 yRadius:5];

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...