我目前已将NSLayoutManager与UITextView架构中的其他类一起子类化,以便实现我自己的字处理器,如UITextView。我正在尝试在字形范围下布局下划线(实现像超链接这样的东西)时遇到问题。为了布局下划线,我在NSLayoutManager中覆盖了以下方法。
- (void)drawUnderlineForGlyphRange:(NSRange)glyphRange underlineType (NSUnderlineStyle)underlineVal baselineOffset:(CGFloat)baselineOffset lineFragmentRect:(CGRect)lineRect lineFragmentGlyphRange:(NSRange)lineGlyphRange containerOrigin:(CGPoint)containerOrigin
在上面的方法中,我通过字形范围计算从下划线的原点到下划线末尾的点的下划线距离。查看以下方法:
- (void)getStartLocation:(CGFloat * _Nonnull )startLocation andEndLocation:(CGFloat * _Nonnull)endLocation ofGlyphsInRange:(NSRange)glyphRange {
NSRange characterRange = [self characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
(*startLocation) = [self locationForGlyphAtIndex:glyphRange.location].x;
CGGlyph glyphs[self.numberOfGlyphs];
NSUInteger numGlyphs = [self getGlyphsInRange:glyphRange glyphs:&glyphs[0] properties:NULL characterIndexes:NULL bidiLevels:NULL];
CTFontRef ctfont = [self getCTFontForGlyphsInRange:glyphRange];
double advances = CTFontGetAdvancesForGlyphs(ctfont, kCTFontOrientationDefault, &glyphs[0], NULL, numGlyphs);
(*endLocation) = (*startLocation) + (CGFloat)advances;}
正如你所看到的,我得到了startLocation,然后通过对glyphRange中每个字形的进展求和得到了endLocation。这种计算似乎运行得相当好,但它似乎导致某些字符序列的透支或欠拉线。最近我注意到CTFontGetAdvancesForGlyphs不考虑字体字距。任何人都可以帮我这个代码吗?如何将字体字距有效地融入我的计算中?我已经尝试在给定位置查询我的NSTextStorage中的NSKernAttribute,但我一直收到nil值。我已经尝试了获取attributeAtIndex并尝试枚举范围内的属性。
我也知道NSAttributedString有下划线选项但我想自己绘制下划线有各种原因,比如支持自定义样式,颜色等等。