如何获得CFAttributedString

时间:2017-10-09 20:26:01

标签: swift core-graphics core-image core-text

我使用Futura-Bold字体创建一个简单的CFAttributedString,大小为100px:

let font = NSFont(name: "Futura-Bold", size: 100.0)!

当我在CGContextCTFramesetterCreateFrame)上呈现该字符串时,我得到以下图片:

enter image description here

现在的问题是如何获得此文本的真实高度?正如您在上面的示例中所看到的,我们正在查看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)

有谁知道计算渲染字符串的实际像素大小?

2 个答案:

答案 0 :(得分:3)

为您提供所需价值的一种解决方案是使用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)")

输出:

  

" Hello World!"是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)")

输出:

  

" Hello World的高度!{
      NSFont =" \" Futura-Bold 100.00 pt。 P [](0x7ff6eae563b0)fobj = 0x7ff6eaf1ea50,spc = 34.00 \"&#34 ;;
  }"是85.1

如果需要,您可以将CFAttributedString投射到NSAttributedString

let attrStr: CFAttributedString = ... // some CFAttributedString
let rect2 = (attrStr as NSAttributedString).boundingRect(with: NSSize(width: 0, height: 0), options: [ .usesDeviceMetrics ])

答案 1 :(得分:1)

除了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文档:

  

这是必需的,因为上下文中可能有设置   会导致图像边界发生变化。

上面的代码给出了以下结果:

(7.9, -2.1, 664.2, 85.1)
                   ^^^^