Skip to content

Instantly share code, notes, and snippets.

@krzyzanowskim
Last active September 14, 2024 17:20
Show Gist options
  • Save krzyzanowskim/510ecf8df259d779e22df8ad13c256c0 to your computer and use it in GitHub Desktop.
Save krzyzanowskim/510ecf8df259d779e22df8ad13c256c0 to your computer and use it in GitHub Desktop.
FB15131180 TextKit extra line frame is incorrect and does not respect layout fragment size (Regression)

Starting macOS 15/iOS 18 TextKit 2 extra line frame is more broken (height always been broken) than previously. The same code return different values when run on macOS 14/iOS 17 and macOS 15/iOS 18.

The problem is that extra line fragment (NSTextLineFragment) origin and size is incorrect. I sketch the problem with the code snippet below:

// Storage
let textContentManager = NSTextContentStorage()

// Layout
let textLayoutManager = NSTextLayoutManager()
textContentManager.addTextLayoutManager(textLayoutManager)
textContentManager.primaryTextLayoutManager = textLayoutManager

let textContainer = NSTextContainer()
textContainer.lineFragmentPadding = 0
textLayoutManager.textContainer = textContainer

textContentManager.attributedString = NSAttributedString(string: "\n", attributes: [.font: NSFont.systemFont(ofSize: 38)])
textLayoutManager.ensureLayout(for: textContentManager.documentRange)

var fragmentOffset = 0
textLayoutManager.enumerateTextLayoutFragments(from: nil) { textLayoutFragment in
    print("[\(fragmentOffset)] frame \(textLayoutFragment.layoutFragmentFrame)")
    for line in textLayoutFragment.textLineFragments.enumerated() {
        print("[\(fragmentOffset)] (\(line.offset)) \(line.element.typographicBounds)")
    }

    fragmentOffset += 1
    return true
}


// Output:
// 
// {
//    NSFont = "\".AppleSystemUIFont 38.00 pt. P [] (0x133410430) fobj=0x133410430, spc=8.16\"";
// }
// [0] frame (0.0, 0.0, 0.0, 45.0)
// [0] (0) (0.0, 0.0, 0.0, 45.0)
// [0] (1) (0.0, 14.0, 0.0, 14.0) <- this is a bug, it should be (0.0, 45.0, 0.0, 45)

for a single layout frament, we have 2 line fragments. The second line fragment is the extra line fragment. Tha line fragment origin is 14, which is not below the previous line fragment (of height 45). On top of that, I expect the height of extra line be equal to the height of the last line, otherwise the height of the extra line fragment can't be really configured

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment