Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Text a bit smaller than NSString drawInRect:?

In theory, these should be the same size, but they're not:

The text in blue is from Core Text, in black is from -[NSString drawInRect:]. Here is the code:

//Some formatting to get the correct frame
int y = MESSAGE_FRAME.origin.y + 8;

    if (month) y = y + 27;

    int height = [JHomeViewCellContentView heightOfMessage:self.entry.message];

    CGRect rect = CGRectMake(MESSAGE_FRAME.origin.x + 8, y, MESSAGE_FRAME.size.width - 16, height);


    //Draw in rect method
    UIFont *font = [UIFont fontWithName:@"Crimson" size:15.0f];

    [[UIColor colorWithWhite:0.2 alpha:1.0] setFill];

    [self.entry.message drawInRect:rect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];



    //Frame change to suit CoreText
    CGRect rect2 = CGRectMake(MESSAGE_FRAME.origin.x + 8, self.bounds.size.height - y - height, MESSAGE_FRAME.size.width - 16, height);

    //Core text method
    CTFontRef fontRef = CTFontCreateWithName((CFStringRef)@"Crimson", 15.0f, NULL);

    NSDictionary *attDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                   (__bridge_transfer id)fontRef, (NSString *)kCTFontAttributeName,
                                   (id)[[UIColor blueColor] CGColor], (NSString *)kCTForegroundColorAttributeName,
                                   nil];

    NSAttributedString *attString = [[NSAttributedString alloc] initWithString:self.entry.message attributes:attDictionary];

    //Flip the coordinate system
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);



    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, NULL, rect2);

    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge_retained CFAttributedStringRef)attString);
    CTFrameRef theFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, [attString length]), path, NULL);
    CFRelease(framesetter);
    CFRelease(path);

    CTFrameDraw(theFrame, context);
    CFRelease(theFrame);

The font is the same. I don't understand why one is being rendered differently.

like image 881
Andrew Avatar asked May 14 '12 16:05

Andrew


1 Answers

It’s because NSLayoutManager uses some unusual heuristics to cope with certain fonts.

See How does line spacing work in Core Text? (and why is it different from NSLayoutManager?) for more detail.

like image 140
al45tair Avatar answered Sep 25 '22 19:09

al45tair