我正在尝试使用Core Text函数绘制文本,并希望行间距与使用NSTextView时尽可能接近。
以这个字体为例:
NSFont *font = [NSFont fontWithName:@"Times New Roman" size:96.0];
如果我在NSTextView中使用这种字体,它的行高为111.0。
NSLayoutManager *lm = [[NSLayoutManager alloc] init];
NSLog(@"%f", [lm defaultLineHeightForFont:font]); // this is 111.0
现在,如果我使用Core Text进行相同的操作,结果为110.4(假设您可以通过将上升、下降和行间距相加来计算行高)。
CTFontRef cFont = CTFontCreateWithName(CFSTR("Times New Roman"), 96.0, NULL);
NSLog(@"%f", CTFontGetDescent(cFont) + CTFontGetAscent(cFont) +
CTFontGetLeading(cFont)); // this is 110.390625
这个值非常接近111.0,但对于某些字体来说,差异会更大。例如,在Helvetica字体中,NSLayoutManager给出了115.0而CTFont ascent + descent + leading = 96.0。显然,对于Helvetica字体,我将无法使用ascent + descent + leading来计算行间距。
因此,我想使用CTFrame和CTFramesetter来布置几行,并从中获取行高。但那也会给出不同的值。
CTFontRef cFont = CTFontCreateWithName(CFSTR("Times New Roman"), 96.0, NULL);
NSDictionary *attrs = [NSDictionary dictionaryWithObject:(id)cFont forKey:(id)kCTFontAttributeName];
NSAttributedString *threeLines = [[NSAttributedString alloc] initWithString:@"abcdefg\nabcdefg\nabcdefg" attributes:attrs];
CTFramesetterRef threeLineFramesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)threeLines);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0.0, 0.0, 600.0, 600.0));
CTFrameRef threeLineFrame = CTFramesetterCreateFrame(threeLineFramesetter, CFRangeMake(0, 0), path, NULL);
CGPoint lineOrigins[3];
CTFrameGetLineOrigins(threeLineFrame, CFRangeMake(0, 0), lineOrigins);
NSLog(@"space between line 1 and 2: %f", lineOrigins[0].y - lineOrigins[1].y); // result: 119.278125
NSLog(@"space between line 2 and 3: %f", lineOrigins[1].y - lineOrigins[2].y); // result: 113.625000
因此,行间距现在与我在NSTextView中使用的111.0更加不同,而且不是每一行都相等。似乎换行符会添加一些额外的空间(即使paragraphSpacingBefore
的默认值为0.0)。
我现在正在解决这个问题,通过NSLayoutManager获取行高,然后逐个绘制每个CTLine,但我想知道是否有更好的方法来解决这个问题。