Search code examples
iosuilabelcore-text

coretext custom font vertical draw display not corret


When I use coretext, I find that the fonts created with systemfontofsize: and fontWithName: size: have different effects in the vertical direction. I don't know if this is normal.Thanks for any help.

systemfontofsize image:

systemfontofsize

fontWithName: size: image:

fontWithName: size:

label code here:

@interface TestUILabel: UIView

@end

@implementation TestUILabel

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
//    UIFont *font = [UIFont systemFontOfSize:16];
    UIFont *font =  [UIFont fontWithName:@"PingFangSC-Regular" size:16];
    NSAttributedString *attributeStr = [[NSMutableAttributedString alloc] initWithString:@"hello world"
                                                                              attributes:@{NSFontAttributeName: font,
                                                                                           NSForegroundColorAttributeName: UIColor.blackColor,
                                                                                           NSVerticalGlyphFormAttributeName: @(YES)
                                                                                         }];
    
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributeStr);
    CFRange rangeAll = CFRangeMake(0,attributeStr.length);
    CFRange fitRange = CFRangeMake(0, 0);
    CGSize s = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, rangeAll, nil, rect.size, &fitRange);
    CGContextTranslateCTM(context, 0, rect.size.height);
    CGContextScaleCTM(context, 1, -1);
    CGRect frameRect =CGRectMake((rect.size.width-s.height)/2.0, (rect.size.height-s.width)/2.0, s.height, s.width);
    CGPathRef framePath = CGPathCreateWithRect(frameRect, nil);
    NSDictionary *dic = @{(id)kCTFrameProgressionAttributeName:@(kCTFrameProgressionLeftToRight)};
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, rangeAll, framePath, (__bridge CFDictionaryRef)dic);
    CTFrameDraw(frame, context);
}

@end

Solution

  • Apple specifies that setting NSVerticalGlyphFormAttributeName to anything besides horizontal is undefined on iOS. Maybe this is just some side-effect of that.

    In iOS, horizontal text is always used and specifying a different value is undefined.

    https://developer.apple.com/documentation/uikit/nsverticalglyphformattributename