如何获得 CFAttributedString 的 *real* 高度
How to get *real* height of CFAttributedString
我用 Futura-Bold 字体和大小 100px 创建了一个简单的 CFAttributedString
:
let font = NSFont(name: "Futura-Bold", size: 100.0)!
当我在 CGContext
(使用 CTFramesetterCreateFrame
)上呈现该字符串时,我得到以下图像:
现在的问题是如何得到这段文字的真实高度?正如您在上面的示例中看到的,我们正在查看 85px。
当查询 font
对象的各种属性时,我得到以下值:
font.pointSize // 100.0
font.ascender // 103.90
font.descender // -25.99
font.capHeight // 75.40
font.leading // 2.99
font.boundingRectForFont // (-22.7, -34.3994140625, 168.6, 144.29931640625)
有谁知道如何计算渲染字符串的实际像素大小?
一种可以为您提供所需价值的解决方案是使用 NSString boundingRect(with:options:attributes:)
方法。通过传递正确的选项,您可以获得所需的结果:
let font = NSFont(name: "Futura-Bold", size: 100)!
let text: NSString = "Hello World!"
let rect = text.boundingRect(with: NSSize(width: 0, height: 0), options: [ .usesDeviceMetrics ], attributes: [ .font: font ], context: nil)
print("Height of \"\(text)\" is \(rect.height)")
输出:
Height of "Hello World!" is 85.1
这也适用于 NSAttributedString
。
let font = NSFont(name: "Futura-Bold", size: 100)!
let attrStr = NSAttributedString(string: "Hello World!", attributes: [ .font: font ])
let rect2 = attrStr.boundingRect(with: NSSize(width: 0, height: 0), options: [ .usesDeviceMetrics ])
print("Height of \"\(attrStr)\" is \(rect2.height)")
输出:
Height of "Hello World!{
NSFont = "\"Futura-Bold 100.00 pt. P [] (0x7ff6eae563b0) fobj=0x7ff6eaf1ea50, spc=34.00\"";
}" is 85.1
如果需要,您可以将 CFAttributedString
转换为 NSAttributedString
。
let attrStr: CFAttributedString = ... // some CFAttributedString
let rect2 = (attrStr as NSAttributedString).boundingRect(with: NSSize(width: 0, height: 0), options: [ .usesDeviceMetrics ])
除了 rmaddys 的出色回答之外,我自己找到了另一种解决方案,它也给出了预期的结果。诀窍是使用 CTLineGetImageBounds.
let font = NSFont(name: "Futura-Bold", size: 100.0)!
let text = NSAttributedString(string: "Hello World!", attributes: [.font:font])
let line = CTLineCreateWithAttributedString(text)
print(CTLineGetImageBounds(line, textContext))
其中 textContext
是您呈现文本的 CGContext。根据 Apple 文档:
This is required because the context could have settings in it that
would cause changes in the image bounds.
以上代码给出以下结果:
(7.9, -2.1, 664.2, 85.1)
^^^^
我用 Futura-Bold 字体和大小 100px 创建了一个简单的 CFAttributedString
:
let font = NSFont(name: "Futura-Bold", size: 100.0)!
当我在 CGContext
(使用 CTFramesetterCreateFrame
)上呈现该字符串时,我得到以下图像:
现在的问题是如何得到这段文字的真实高度?正如您在上面的示例中看到的,我们正在查看 85px。
当查询 font
对象的各种属性时,我得到以下值:
font.pointSize // 100.0
font.ascender // 103.90
font.descender // -25.99
font.capHeight // 75.40
font.leading // 2.99
font.boundingRectForFont // (-22.7, -34.3994140625, 168.6, 144.29931640625)
有谁知道如何计算渲染字符串的实际像素大小?
一种可以为您提供所需价值的解决方案是使用 NSString boundingRect(with:options:attributes:)
方法。通过传递正确的选项,您可以获得所需的结果:
let font = NSFont(name: "Futura-Bold", size: 100)!
let text: NSString = "Hello World!"
let rect = text.boundingRect(with: NSSize(width: 0, height: 0), options: [ .usesDeviceMetrics ], attributes: [ .font: font ], context: nil)
print("Height of \"\(text)\" is \(rect.height)")
输出:
Height of "Hello World!" is 85.1
这也适用于 NSAttributedString
。
let font = NSFont(name: "Futura-Bold", size: 100)!
let attrStr = NSAttributedString(string: "Hello World!", attributes: [ .font: font ])
let rect2 = attrStr.boundingRect(with: NSSize(width: 0, height: 0), options: [ .usesDeviceMetrics ])
print("Height of \"\(attrStr)\" is \(rect2.height)")
输出:
Height of "Hello World!{
NSFont = "\"Futura-Bold 100.00 pt. P [] (0x7ff6eae563b0) fobj=0x7ff6eaf1ea50, spc=34.00\"";
}" is 85.1
如果需要,您可以将 CFAttributedString
转换为 NSAttributedString
。
let attrStr: CFAttributedString = ... // some CFAttributedString
let rect2 = (attrStr as NSAttributedString).boundingRect(with: NSSize(width: 0, height: 0), options: [ .usesDeviceMetrics ])
除了 rmaddys 的出色回答之外,我自己找到了另一种解决方案,它也给出了预期的结果。诀窍是使用 CTLineGetImageBounds.
let font = NSFont(name: "Futura-Bold", size: 100.0)!
let text = NSAttributedString(string: "Hello World!", attributes: [.font:font])
let line = CTLineCreateWithAttributedString(text)
print(CTLineGetImageBounds(line, textContext))
其中 textContext
是您呈现文本的 CGContext。根据 Apple 文档:
This is required because the context could have settings in it that would cause changes in the image bounds.
以上代码给出以下结果:
(7.9, -2.1, 664.2, 85.1)
^^^^