I have problem with Core Text when it's rendered to CALayer the text is blurry. I did check the position to be integral and frame height and width but still text appears blurry. The layout is simple in the IB i have standard UIView, then in the code i will create CALayer, append this layer to UIView layer and will draw text to this layer with :
drawLayer:(CALayer *)layer inContext:(CGContextRef)context{
Here is the code:
- (void)viewDidLoad {
[super viewDidLoad];
[self.view.layer setPosition:CGPointMake(lroundf(self.view.frame.size.width/2), lroundf(self.view.frame.size.height/2))];
[self.view setFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
CALayer *newLayer = [[CALayer alloc] initWithLayer:self.view.layer];
newLayer.frame =CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
newLayer.delegate=self;
[self.view.layer setPosition:CGPointMake(lroundf(self.view.frame.size.width/2), lroundf(self.view.frame.size.height/2))];
[self.view.layer addSublayer:newLayer];
[newLayer setNeedsDisplay];
}
-(void) drawLayer:(CALayer *)layer inContext:(CGContextRef)currentContext{
NSLog(@"drawLayer Layer position x %f pos y %f", layer.position.x,layer.position.y);
NSLog(@"drawLayer Layer origin x %f y %f", layer.bounds.origin.x,layer.bounds.origin.y);
NSLog(@"drawLayer Layer bounds width %f height %f", layer.bounds.size.width,layer.bounds.size.height);
layer.contentsScale=[[UIScreen mainScreen]scale];
CTFontRef fontRef =
CTFontCreateWithName((CFStringRef)@"Didot", 36, NULL);
NSDictionary *attrDictionary = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge id)fontRef, (NSString *)kCTFontAttributeName, (id)[[UIColor blackColor] CGColor], (NSString *)(kCTForegroundColorAttributeName), nil];
CFRelease(fontRef);
// Flip the coordinate system
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);
CGContextTranslateCTM(currentContext, 0, layer.bounds.size.height);
CGContextScaleCTM(currentContext, 1.0, -1.0);
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);
NSAttributedString *timeMarker = [[NSAttributedString alloc] initWithString:@"Hello blurry text !!!" attributes:attrDictionary] ;
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)timeMarker);
CGContextSetTextPosition(currentContext, 0, 50);
CTLineDraw(line, currentContext);
CFRelease(line);
}
Here is the View bounds:
DrawRect[14767:15435976] View bounds <UIView: 0x7fe153d22980; frame = (0 0; 375 667); autoresize = W+H; autoresizesSubviews = NO; layer = <CALayer: 0x7fe153d21c40>>
Below is NSLOG:
2014-11-25 20:18:10.159 DrawRect[15103:15454664] viewDidLoad View Position x 187.500000 pos y 333.500000
2014-11-25 20:18:10.159 DrawRect[15103:15454664] viewDidLoad View bounds width 375.000000 heights 667.000000
2014-11-25 20:18:10.159 DrawRect[15103:15454664] viewDidLoad View bounds origin x 0.000000 x 0.000000
2014-11-25 20:18:10.159 DrawRect[15103:15454664] viewDidLoad View frame size width 375.000000 height 667.000000
2014-11-25 20:18:10.159 DrawRect[15103:15454664] viewDidLoad View frame origin width 0.000000 height 0.000000
2014-11-25 20:18:10.160 DrawRect[15103:15454664] View Layer frame size width 375.000000 height 667.000000
2014-11-25 20:18:10.160 DrawRect[15103:15454664] View Layer origin width 0.000000 height 0.000000
2014-11-25 20:18:10.165 DrawRect[15103:15454664] drawLayer Layer position x 188.000000 pos y 334.000000
2014-11-25 20:18:10.165 DrawRect[15103:15454664] drawLayer Layer origin x 0.000000 y 0.000000
2014-11-25 20:18:10.165 DrawRect[15103:15454664] drawLayer Layer bounds width 375.000000 height 667.000000
2014-11-25 20:18:10.166 DrawRect[15103:15454664] drawLayer after CTM Layer position x 188.000000 pos y 334.000000
2014-11-25 20:18:10.166 DrawRect[15103:15454664] drawLayer after CTM Layer origin x 0.000000 y 0.000000
2014-11-25 20:18:10.174 DrawRect[15103:15454664] drawLayer after CTM Layer bounds width 375.000000 height 667.000000
The clue was printing CALayer object (po 0x7fec22927c40) in the debugger.
CABackingStore buffer had same values as layer bounds [375 853], but based on the scale definition CAlayer should draw twice in the buffer.
Infer was that second draw was skipped. My layer.contentsScale was in the method:
drawLayer:(CALayer *)layer inContext:(CGContextRef)currentContext
When layer.contentsScale was moved to the viewDidLoad method problem was fixed.
CALayer *newLayer = [[CALayer alloc] initWithLayer:self.view.layer];
newLayer.frame =CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
newLayer.delegate=self;
newLayer.contentsScale=2;
CABackingStore buffer from [375 853] become [750 1706].
The text was crisp even with non integral super view position.
viewDidLoad View Position x 187.500000 pos y 333.500000