0

I am ultimately trying to get per-character font metrics from a line of text.

Using CTFramesetter I've converted a swift String into lines by following this post (and converting from Obj-C to Swift.

The simplified code below gives me the error Cannot convert value of type 'UnsafeRawPointer?' to expected argument type 'CTLine' (error on theLine)

    let lines : CFArray = CTFrameGetLines(ctFrame)

    var ascent : CGFloat
    var descent : CGFloat
    var leading : CGFloat

    var theLine = CFArrayGetValueAtIndex(lines, 0)
    let lineWidth = CTLineGetTypographicBounds(theLine, &ascent, &descent, &leading) // ERROR HERE
    print("lineWidth \(lineWidth), ascent \(ascent), descent \(descent)")

I'm new to Swift but I've tried many things all to no avail. How can I fix it?

isherwood
  • 58,414
  • 16
  • 114
  • 157
Danny
  • 2,482
  • 3
  • 34
  • 48

1 Answers1

0

You're just dealing with type-conversions from Core Foundation (which has very sloppy types) to Swift (which has pretty strict types).

Define lines this way and things will be much simpler:

let lines = CTFrameGetLines(ctFrame) as! [CTLine]

The rest of the code (with some minor fixes) would then be:

var ascent : CGFloat = 0
var descent : CGFloat = 0
var leading : CGFloat = 0

if let theLine = lines.first {
    let lineWidth = CTLineGetTypographicBounds(theLine, &ascent, &descent, &leading)
    print("lineWidth \(lineWidth), ascent \(ascent), descent \(descent)")
}

CTFrameGetLines is known to return [CTLine], so as! is pretty safe here, but if it makes you nervous, you can use an as? cast like:

let lines = CTFrameGetLines(ctFrame) as? [CTLine] ?? []
Rob Napier
  • 286,113
  • 34
  • 456
  • 610