给框架设定器正确的行间距调整

几个post已经注意到了从CTFramesetterSuggestFrameSizeWithConstraints得到一个确切的高度,在这里, (framesetter post) ,@Chris DeSalvo给出了看起来像权威性的修复:添加一个段落风格设置与正确的行距调整。

DeSalvo通过从其lineHeight移除UIFont的上行和下行来获得他的“领导”。 我想知道如何比较CTFontGetLeading

我使用像这样创build的字体:

 CTFontRef fontr = CTFontCreateWithName((CFStringRef)@"Helvetica Neue", 16.0f, NULL); UIFont *font = [UIFont fontWithName:@"Helvetica Neue" size:16.0f]; 

价值是非常不同的:

  • 0.448 CTFontGetLeading
  • 2.360 DeSalvo的公式:UIFont lineHeight – ascender + descender

以下是一些其他UIFont值:

  • 21.000 UIFont的lineHeight
  • 15.232 UIFont的上升(从基线起的Y坐标)
  • -3.408 UIFont的下行(从基线起的Y坐标)
  • 08.368 UIFont的xHeight

以下是Ken Thomases询问的CTFont值:

  • 11.568001 CTFontGetCapHeight
  • 08.368 CTFontGetXHeight
  • -15.216001,-7.696001,38.352001,24.928001 CTFontGetBoundingBox
  • 15.232 CTFontGetAscent
  • 03.408 CTFontGetDescent(class ref是指“根据字体大小和字体引用matrix缩放的缩放字体下降度量” – 这显然意味着它是从基线的Y坐标的绝对值?)

我注意到,UIFont以前有一个专门用于“领先”的属性,但是它已被弃用,我们build议使用lineHeight 。 所以UIFont认为相同的字体是21和CTFontRef.448? 有什么不对的

三个问题:

  1. kCTParagraphStyleSpecifierLineSpacingAdjustment的意思是“领先”吗?
  2. 如果是这样,我应该使用哪种方法/公式来得到它?
  3. 如果不是,我应该使用什么行间距调整?

以上三个问题的答案:

  1. 是的,“领先”真的是什么意思kCTParagraphStyleSpecifierLineSpacingAdjustment。 无论如何,它按预期工作。
  2. 使用CTFontGetLeading(fontRef)来获取字体的正常前导,或者插入你select的任何值(作为CGFloat)。
  3. N / A。

答案1和2工作:在属性string的paragraphStyle属性中指定前导值将使Core-Text framesetter 精确地计算其高度。

有两个警告:

  1. 如果您尝试逐渐计算高度,则一次一个string,每个string包含一个初始换行符,framesetter将认为该换行符表示整行,而不仅仅是前导。 如果您想要连接string的高度,则必须将该连接馈送到framesetter。 当然,您可以跟踪增量高度差异,但是无法避免让搭架人员重新计算较早的string尺寸。
  2. CATextLayer忽略间距调整(和其他属性)。 如果根据确切的string高度进行构图是个问题,则必须直接绘制CALayer。

还有一个谜团:UIFont弃用的领先地位正在发生什么? 领导和lineHeight是两个截然不同的东西。

我也碰到过这个,这是在一个真正的项目中工作的代码:

 // When you create an attributed string the default paragraph style has a leading // of 0.0. Create a paragraph style that will set the line adjustment equal to // the leading value of the font. This logic will ensure that the measured // height for a given paragraph of attributed text will be accurate wrt the font. - (void) applyParagraphAttributes:(CFMutableAttributedStringRef)mAttributedString { CGFloat leading = CTFontGetLeading(self.plainTextFont); CTParagraphStyleSetting paragraphSettings[1] = { kCTParagraphStyleSpecifierLineSpacingAdjustment, sizeof (CGFloat), &leading }; CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(paragraphSettings, 1); CFRange textRange = CFRangeMake(0, [self length]); CFStringRef keys[] = { kCTParagraphStyleAttributeName }; CFTypeRef values[] = { paragraphStyle }; CFDictionaryRef attrValues = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&keys, (const void**)&values, sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); BOOL clearOtherAttributes = FALSE; CFAttributedStringSetAttributes(mAttributedString, textRange, attrValues, (Boolean)clearOtherAttributes); CFRelease(attrValues); CFRelease(paragraphStyle); self.stringRange = textRange; return; } 
    Interesting Posts