I have some problems with CATextLayer that may be due to me, but I did not find any help on this topic. I'm on OS X (on iOS it should be the same).
I create CATextLayer layers with a zoom factor> 1 and I get blurry text. I think the layer is rasterized before applying the scale. Is this expected behavior? I hope this is not the case because it just doesn’t make sense ... CAShapeLayer is rasterized after the transformation matrix is applied, why should the CATextLayer be different?
If I do something wrong ... what is it?
CATextLayer *layer = [CATextLayer layer]; layer.string = @"I like what I am doing"; layer.font = (__bridge CFTypeRef)[NSFont systemFontOfSize:24]; layer.fontSize = 24; layer.anchorPoint = CGPointZero; layer.frame = CGRectMake(0, 0, 400, 100); layer.foregroundColor = [NSColor blackColor].CGColor; layer.transform = CATransform3DMakeScale(2., 2., 1.); layer.shouldRasterize = NO; [self.layer addSublayer:layer];
The solution I'm currently using is to set the contentsScale property of the layer to a scale factor. The problem is that this solution does not scale: if the scale factor for any of the parent layers changes, then the contentsScale must also be updated. I have to write code to traverse the layer tree to update the contentsScale properties of all CATextLayers ... not quite what I would like to do.
Another solution, which is not really a solution, is to convert text to form and use CAShapeLayer. But then I see no reason to have CATextLayers.
Can a custom subclass of CALayer help solve this problem?
EDIT: even a CAGradientLayer can display its contents, such as CAShapeLayer, after which its transformation matrix is applied. Can someone explain how this is possible?
EDIT 2: I assume that the paths and gradients are displayed as OpenGL display lists, so they are rasterized by the actual size on the screen by OpenGL itself. Texts are rasterized by Core Animation, so they are bitmaps for OpenGL.
I think for now I will move on with the contentScale solution. Perhaps in the future I will convert texts to forms. To get the best results with a little work, this is the code I'm using now:
[CATransaction setDisableActions:YES]; CGFloat contentsScale = ceilf(scaleOfParentLayer);