I am drawing several CGPaths
in a Cocoa view in the drawRect method on an iPad. I started out drawing them straight to the UIGraphicsGetCurrentContext()
context, but performance went south when my paths got really long. Based on several other questions, I started looking into using CGLayer
s.
So what I do now is to render a path inside of the CGContextRef
I get from calling CGLayerGetContext
. Here's the basic outline of what I'm doing:
// rect comes from the drawRect: method
layer = CGLayerCreateWithContext(context, rect.size, NULL);
layerContext = CGLayerGetContext(layer);
CGContextSetLineCap(layerContext, kCGLineCapRound);
// Set the line styles
CGContextSetLineJoin(layerContext, kCGLineJoinRound);
CGContextSetLineWidth(layerContext, 1.0);
CGContextSetStrokeColorWithColor(layerContext, [UIColor blackColor].CGColor);
// Create a mutable path
path = CGPathCreateMutable();
// Move to start point
//...
for (int i = 0; i < points.count; i++) {
// compute controlPoint and anchorPoint
//...
CGPathAddQuadCurveToPoint(path,
nil,
controlPoint.x,
controlPoint.y,
anchorPoint.x,
anchorPoint.y);
}
// Stroke the path
CGContextAddPath(layerContext, path);
CGContextStrokePath(layerContext);
// Add the layer to the main context
CGContextDrawLayerAtPoint(context, CGPointZero, layer);
Now, I get good performance drawing, but my lines are extremely jagged and do not seem to be anti-aliased. I've tried adding
CGContextSetShouldAntialias(layerContext, YES);
CGContextSetAllowsAntialiasing(layerContext, YES);
CGContextSetInterpolationQuality(layerContext, kCGInterpolationHigh);
to the code above to no avail. I've even set the anti-aliasing properties on the main context
, with no change. I took screen shots of the same code results, but with the second image being the image created from drawing in the CGLayer
. As you can see, it is really jagged, despite being the same code, just drawing into a layerContext
. How can I get the lines in the CGLayer
to be smooth?
I found the reason the second image is not anti-aliased is because there was nothing to anti-alias against. The background was empty, and so anti-aliasing didn't work. If you make a big rectangle over the bounds of the view that is entirely transparent, the line will draw with anti-aliasing. However, performance is killed. Better not to go this route.