Andrew
Andrew

Reputation: 16051

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.

Upvotes: 10

Views: 1704

Answers (1)

al45tair
al45tair

Reputation: 4433

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.

Upvotes: 4

Related Questions