CTLine 或 NSAttributedString - 在没有图形上下文的情况下获取图像边界?
这可能吗?基本上,我有一堆 NSAttributedString 对象和相应的 CTLine 对象。我想在绘制矩形阶段之前获取图像边界。所以在这一点上,没有什么可借鉴的。然后,我将使用这些图像边界来准确决定我需要为绘图创建什么。
编辑:另一种尺寸测量可能效果很好。但调用具有欺骗性名称的 CTLineGetTypgraphicBounds 函数仅返回宽度。如果我传入上升和下降浮点数的地址,它们将返回为零。
编辑:给定的答案在 MacOS 中效果很好。任何人都可以在 iOS 中做到这一点吗?
Is this possible? Basically, I have a bunch of NSAttributedString objects and corresponding CTLine objects. I want to get the image bounds before the drawRect stage. So at this point, there is nothing to draw into. I will then use these image bounds to decide exactly what I need to create for drawing.
EDIT: Another measurement of the size would probably work just fine. But calling the deceptively named CTLineGetTypographicBounds function only returns the width. If I pass in addresses of ascent and descent floats, they come back as zero.
EDIT: The given answer works great in MacOS. Can anyone do it in iOS?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您正在为 iOS6+ 进行开发。您可以使用以下方法:
假设您没有在上下文中应用任何转换,但不需要上下文,这会给出与
CTLineGetImageBounds()
相同的边界。对于 iOS 5 及更低版本,您需要使用 Иван 描述的方法。CTLineGetTypgraphicBounds()
为我提供了与此函数或图像边界不同的宽度。我不知道为什么。返回的上升和下降是字体的上升和下降,而不是 CTLineRef 中显示的字符。If you are developing for iOS6+. You can use the following method:
This is gives the same bounds as
CTLineGetImageBounds()
assuming you have no transforms applied in your context, but does not require the context. For iOS 5 and below, you would need to use the method described by Иван.CTLineGetTypographicBounds()
gives me a different width than this function or image bounds. I am not sure why. And the ascent and descent returned are those of the font and not the characters displayed in theCTLineRef.
是的,可以,但没那么容易。
通常,您应该使用 CTLineGetTypgraphicBounds(),对我来说,它确实返回 上升、下降 和 前导,但是有点混乱 - 'ascent' 等于总高度(即应该是 ascent+descent),而 'descent' 始终是字体的最大下降 - 无论如何如果你有下降字符与否。
另一种方法是从行 (CTLineGetGlyphRuns) 检索 CTRun,然后获取字形数组 (CTRunGetGlyphs 或 CTRunGetGlyphsPtr ),然后使用CTFontGetBoundingRectsForGlyphs和CTFontGetAdvancesForGlyphs 构建您需要的信息。
编辑:
我刚刚找到了这个方法: NSAttributedString 的“- (NSRect)boundingRectWithSize:(NSSize)size options:(NSStringDrawingOptions)options”,这似乎完全正确 需要什么。
希望,这会有所帮助...
Yes, you can, but not so easy.
You should, generally use CTLineGetTypographicBounds() which, for me, does return ascent, descent and leading, but a bit messed up - 'ascent' equals the total height (i.e. what should be ascent + descent) and 'descent' is always the maximum descent of the font - no matter if you have descending characters or not.
Other way is to retrieve the CTRun(s) from the line (CTLineGetGlyphRuns), then get the glyphs array (CTRunGetGlyphs or CTRunGetGlyphsPtr) and then using CTFontGetBoundingRectsForGlyphs and CTFontGetAdvancesForGlyphs build up the information you need.
EDIT:
I've just found this method: "- (NSRect) boundingRectWithSize:(NSSize)size options:(NSStringDrawingOptions)options" of NSAttributedString which seems to do exactly what is needed.
Hope, this is helpful...
CTLineGetTypgraphicBounds()
返回的边界与图像边界不同。正如名称(以及 Иван 的答案)所示,ascent 等是为字体定义的,不会根据字符串而改变。例如,如果您有多行文本,如果您想找到正确的行高,则可以使用它,因为行高通常不应该取决于您使用的确切字符。另一方面,
CTLineGetImageBounds()
返回完全适合图像的边界。例如,如果您想围绕一条线绘制一个框,这就是您所需要的。CTLineGetImageBounds()
需要上下文,因为可能存在文本转换之类的事情。如果您不想担心这一点,只需使用虚拟上下文即可。例如:Bounds returned by
CTLineGetTypographicBounds()
are not the same as image bounds. As the name, (and Иван's answer) suggests, ascent etc. are defined for the font and won't change based on the string. For example, you would use it if you want to find the correct line height if you have a multiline text, as line height normally should not depend on the exact characters you use.CTLineGetImageBounds()
on the other hand, returns the bounds that exactly fit the image. For example, if you want to draw a box around a single line, this is what you need.CTLineGetImageBounds()
needs a context because there may be text transforms and things like that. If you don't want to worry about that, just use a dummy context. For example:另一种方法是使用
CTFontGetGlyphsForCharacters()
将字符串转换为字形,然后使用从第一个函数获取的字形数组调用CTFontGetBoundingRectsForGlyphs()
。后一个函数返回“字形运行的整体边界矩形”,因此不必担心必须对各个边界矩形进行处理。如果在 iOS 中成功使用这两个功能。如果您这样做,请记住字形和字符之间的映射并不总是一对一的,特别是当字符串包含非英语字符时。
Another method is to convert the string to glyphs using
CTFontGetGlyphsForCharacters()
and then callingCTFontGetBoundingRectsForGlyphs()
with the glyph array you get from the first function. The latter function returns "the overall bounding rectangle for the glyph run" so don't worry about having to do processing on the individual bounding rects. If used both these functions successfully in iOS.If you do this remember the mapping between glyphs and characters is not always one to one, especially when the string has non-English characters.