0

这可能吗?基本上,我有一堆 NSAttributedString 对象和相应的 CTLine 对象。我想在 drawRect 阶段之前获得图像边界。所以在这一点上,没有什么可以借鉴的。然后,我将使用这些图像边界来确定我需要为绘图创建什么。

编辑:尺寸的另一种测量可能会很好。但是调用具有欺骗性名称的 CTLineGetTypographicBounds 函数只返回宽度。如果我传入上升和下降浮动的地址,它们会返回为零。

编辑:给定的答案在 MacOS 中效果很好。任何人都可以在 iOS 中做到这一点吗?

4

4 回答 4

2

是的,你可以,但不是那么容易。

你应该,通常使用CTLineGetTypographicBounds(),对我来说,它确实返回ascentdescentleading,但有点混乱 - ' ascent ' 等于总高度(即应该是 ascent + descent )和 ' descent ' 总是字体的最大下降 - 无论您是否有下降字符。

另一种方法是从行(CTLineGetGlyphRuns )中检索CTRun (s) ,然后获取字形数组(CTRunGetGlyphsCTRunGetGlyphsPtr),然后使用CTFontGetBoundingRectsForGlyphsCTFontGetAdvancesForGlyphs构建您需要的信息。

编辑:我刚刚找到了这个方法:“ - (NSRect) boundingRectWithSize:(NSSize)size options:(NSStringDrawingOptions)options ” of NSAttributedString这似乎完全符合需要。

希望,这有帮助...

于 2011-11-25T12:01:51.240 回答
2

返回的CTLineGetTypographicBounds()边界与图像边界不同。顾名思义,(以及Иван的回答)暗示,上升等是为字体定义的,不会根据字符串而改变。例如,如果您想在多行文本中找到正确的行高,则可以使用它,因为行高通常不应取决于您使用的确切字符。

CTLineGetImageBounds()另一方面,返回完全适合图像的边界。例如,如果您想围绕一条线绘制一个框,这就是您所需要的。

CTLineGetImageBounds()需要一个上下文,因为可能存在文本转换之类的东西。如果您不想担心这一点,只需使用虚拟上下文即可。例如:

CTLineRef line;

// create the line...

UIGraphicsBeginImageContext(CGSizeMake(1, 1));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextPosition(context, 0, 0);
CGRect bounds = CTLineGetImageBounds(line, context);
UIGraphicsEndImageContext();

// use bounds...
于 2012-01-23T22:45:34.540 回答
2

如果你正在为 iOS6+ 开发。您可以使用以下方法:

CTLineRef line;
// Create the line...

CGRect bounds = CTLineGetBoundsWithOptions(line, kCTLineBoundsUseGlyphPathBounds);
// use bounds...

这与CTLineGetImageBounds()假设您没有在上下文中应用转换但不需要上下文相同的界限。对于 iOS 5 及更低版本,您需要使用Иван 描述的方法。

CTLineGetTypographicBounds()给我一个不同于这个函数或图像边界的宽度。我不确定为什么。并且返回的上升和下降是字体的,而不是显示在CTLineRef.

于 2013-09-05T07:33:23.560 回答
0

另一种方法是使用从第一个函数获得的字形数组将字符串转换为字形CTFontGetGlyphsForCharacters(),然后调用。CTFontGetBoundingRectsForGlyphs()后一个函数返回“字形运行的整体边界矩形”,因此不必担心必须对各个边界矩形进行处理。如果在 iOS 中成功使用这两个功能。

如果您这样做,请记住字形和字符之间的映射并不总是一对一的,尤其是当字符串包含非英文字符时。

于 2012-09-17T02:49:27.987 回答