Question

According to the documentation, it is possible to enable font smoothing inside CATextLayer:

Text can only be drawn using sub-pixel antialiasing when it is composited into an existing opaque background at the same time that it's rasterized.

Here is how I understand this sentence:

@implementation CATextLayerWithFontSmoothing
-(id)init {
    self=[super init];
    if (self) {
    CALayer * whiteBackground = [CALayer layer];
    CATextLayer * blackText = [CATextLayer layer];

    [whiteBackground setBounds:NSMakeRect(0, 0, 300, 300)];
    [blackText setBounds:NSMakeRect(0, 0, 300, 300)];

    [whiteBackground setBackgroundColor:[NSColor whiteColor].CGColor];
    [blackText setForegroundColor:[NSColor blackColor].CGColor];
    [blackText setString:@"CATextLayer"];

    [blackText setShouldRasterize:YES];

    [self addSublayer:whiteBackground];
    [self addSublayer: blackText];

    }
    return self;

which doesn't work. Text is not drawn using subpixel anti-aliasing.

Was it helpful?

Solution

The method described here works:

Case 2: If you're using a CATextLayer directly, you'll need to subclass CATextLayer and do something like the following in your drawing code:

- (void)drawInContext:(CGContextRef)ctx
{
CGContextSetRGBFillColor (ctx, r, g, b, a);
CGContextFillRect (ctx, [self bounds]);
CGContextSetShouldSmoothFonts (ctx, true);
[super drawInContext:ctx];
}

Here is a comparison of smoothed vs non-smoothed:

text on a regular CATextLayer

text with sub-pixel-aa

800% zoom of both layers

PS: Don't look at this answer on a CRT.

OTHER TIPS

May be late. But I see that this question has a perfect solution, as Steve's answer, and nacho4d's comment:

How to get text in a CATextLayer to be clear

The way I understand this documentation, it says that CATextLayer always disables sub-pixel antialiasing. The sentence you quoted is just given as an explanation for this, not as instructions on how to enable it – it's followed by:

Setting the opacity property of the layer to YES does not change the rendering mode.

...which implies that even if you use an opaque background for the layer, this won't change the fact that CATextLayer doesn't use sub-pixel-aa.

If you came searching for an issue where CATextLayer is rendering slightly blurry text in OSX, after much wall head banging, I got the sharp clear text by doing:

text_layer.contentsScale = self.window!.backingScaleFactor
text_layer.zPosition = 0

(I also set the views background layer contentsScale to be the same).

Accepted answer do not work for my.

I found working solution on Ignacio Nieto blog

textLayer.contentsScale = UIScreen.mainScreen().scale

the most common case is to have clear sharp visible fonts, so in Objective-C it would look like...

CATextLayer *text = [CATextLayer layer];
text.allowsEdgeAntialiasing = NO;
text.allowsFontSubpixelQuantization = YES;
// the following is a CGFloat, so can even be scaled down, to make it pixelish
text.contentsScale = [UIScreen mainScreen].scale;
text.frame = CGRectInset(self.frame, 0, 5);
text.foregroundColor = UIColor.orangeColor.CGColor;
text.fontSize = 36.0;
text.font = (__bridge CFTypeRef _Nullable)([UIFont fontWithName:@"HelveticaNeue-UltraLight" size:text.fontSize]);
[self.layer addSublayer:text];

text.fontSize is ignored when setting .font property but before setting the font with bridging it can be used to store the fonts size when creating the font

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top