Ste*_*ghe 26 macos objective-c nslayoutmanager nstextview core-text
我正在尝试使用Core Text函数绘制文本,其行间距尽可能接近使用NSTextView时的行间距.
以此字体为例:
NSFont *font = [NSFont fontWithName:@"Times New Roman" size:96.0];
Run Code Online (Sandbox Code Playgroud)
如果我在NSTextView中使用它,这个字体的行高是111.0.
NSLayoutManager *lm = [[NSLayoutManager alloc] init];
NSLog(@"%f", [lm defaultLineHeightForFont:font]); // this is 111.0
Run Code Online (Sandbox Code Playgroud)
现在,如果我使用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
Run Code Online (Sandbox Code Playgroud)
这非常接近111.0,但对于某些字体,差异要大得多.例如,对于Helvetica,NSLayoutManager给出115.0而CTFont上升+下降+领先= 96.0.很明显,对于Helvetica,我无法使用上升+下降+导致计算线之间的间距.
所以我想我会使用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
Run Code Online (Sandbox Code Playgroud)
因此行间距现在与我的NSTextView中使用的111.0更加不同,并不是每条线都相等.似乎换行添加了一些额外的空间(即使默认值为paragraphSpacingBefore0.0).
我现在正在解决这个问题,通过NSLayoutManager获取行高,然后单独绘制每个CTLine,但我想知道是否有更好的方法来做到这一点.
ala*_*air 45
好的,所以我仔细研究了NSLayoutManager的内容,看来,根据我对反汇编的解读,它使用的代码归结为这样的代码:
CGFloat ascent = CTFontGetAscent(theFont);
CGFloat descent = CTFontGetDescent(theFont);
CGFloat leading = CTFontGetLeading(theFont);
if (leading < 0)
leading = 0;
leading = floor (leading + 0.5);
lineHeight = floor (ascent + 0.5) + floor (descent + 0.5) + leading;
if (leading > 0)
ascenderDelta = 0;
else
ascenderDelta = floor (0.2 * lineHeight + 0.5);
defaultLineHeight = lineHeight + ascenderDelta;
Run Code Online (Sandbox Code Playgroud)
这将为您提供上面提到的两种字体的111.0和115.0值.
我应该补充一点,根据OpenType规范,正确的方法是添加三个值(小心,如果你使用的API不能使它们都是正数,那么得到下降值的符号是正确的).
| 归档时间: |
|
| 查看次数: |
11980 次 |
| 最近记录: |