Day 17: Custom drawing (5) : NSGraphicsContext
Yesterday (or to be honest, earlier today), I gave a quick introduction to NSBezierPath’s -addCllip: and I said I’d give an example of how to do an inner stroke. By default, NSBezierPath only does a stroke on the center. It’s important to note that the points in your path located between the pixels, not on the pixels. As a consequence, a 1px stroke can’t be drawn exactly but rather a 2px softer stroke will be drawn. Many times this is undesirable and the way to fix this is using -addCllip:.
Before I give the snippet, I should explain a bit about NSGraphicsContext. This is where many state-altering actions are stored. For example -[NSColor setColor] stores its current color on the NSGraphicsContext and so do many other operations such as NSAffineTransform (which I’m sure will be talked about later) and our -addClip:. An NSGraphicsContext behaves like a stack where +saveGraphicsState: is the push and +restoreGraphicsState: is the pop. The correct procedure for any temporary state-altering is first to push a new context, do your drawing and then pull the context. A push and pull should always balance out. If not, your application will look completely distorted; often resulting in a window with an empty tooblar and an empty window or something similar. The lesson here is to be careful with exceptions. One last thing to note is that when you push a new context with +saveGraphicsState: you’ll create a new context with all the attributes of the previous context (color, clipping path etc).
Today’s post is already longer than I had planned - and so is yesterday’s. I’ll be saving the actual snippet for tomorrow. Mind you, I do have 365 days to fill…