给予Framesetter正确的行间距调整(Giving Framesetter the corre

2019-06-23 11:10发布

几个职位已经注意到获得一个精确的高度了CTFramesetterSuggestFrameSizeWithConstraints的,在这里,困难(framesetter后) ,@克里斯DeSalvo给出什么样子的最终解决方法:使用正确的线间距调整添加段落样式设置。

DeSalvo得到他的“龙头”从其lineHeight是去除UIFont的伸和下伸。 我不知道怎么会比较CTFontGetLeading

我曾与这样创造的字:

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是 - 伸+伸

这里有一些其他UIFont值:

  • 21.000 UIFont的lineHeight是
  • 15.232 UIFont的上升段(从基线的y坐标)
  • -3.408 UIFont的伸(从基线的y坐标)
  • 08.368 UIFont的X字高

这里是CTFont值肯Thomases询问:

  • 11.568001 CTFontGetCapHeight
  • 08.368 CTFontGetXHeight
  • -15.216001,-7.696001,38.352001,24.928001 CTFontGetBoundingBox
  • 15.232 CTFontGetAscent
  • 03.408 CTFontGetDescent(类REF表示“经缩放的字体下降度量根据字体参考的点大小和矩阵缩放?” - 这显然意味着它是Y的绝对值从基线坐标)

我注意到,UIFont以前有一个属性专门为“龙头”,但它已被弃用,我们建议使用lineHeight代替。 所以UIFont认为领导是21和CTFontRef 0.448相同的字体? 有些不对劲。

疑问三:

  1. 是“龙头”真的是什么意思kCTParagraphStyleSpecifierLineSpacingAdjustment?
  2. 如果是这样,该方法/公式我应该用得到它?
  3. 如果不是这样,我应该怎么用的行间距的调整?

Answer 1:

我也碰到了这一点,这里是一个真正的项目工作的代码:

// 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;
}


Answer 2:

答案在3个问题我上面有:

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

答案1和2的工作:在你的属性串的paragraphStyle属性指定一家领先的值将启用Core文本framesetter 准确计算其高度。

有两点需要说明:

  1. 如果试图以增量计算的高度,每次一个字符串,包含初始换行符每串,framesetter将考虑换行代表整条生产线,而不仅仅是领先。 如果你想串联字符串的高度,你必须是串联馈送到framesetter。 当然,你可以跟踪的增量高度差,但有没有办法避免framesetter重新计算前面的字符串尺寸。
  2. CATextLayer忽略间距调整(及其它属性)。 如果每个字符串精确高度框架是一个问题,你必须直接画到CALayer的。

而且还有一个神秘:这是怎么回事用UIFont的弃用领先? 领导和lineHeight是两种截然不同的东西。



文章来源: Giving Framesetter the correct line spacing adjustment