What is difference between lineFragmentRect and lineFragmentUsedRect in TextKit?

Recently, I've started to learn deep TextKit APIs and concepts, such as typeface, typesetter, Text Layout and so on.

I found APIs named lineFragmentRect and lineFragmentUsedRect, however I can't understand these conceptual difference. (These values are bit of different.)

Cloud you tell me them if you know something about it?

Accepted Reply

After few hours later, I cloud solve this question by myself.

These are difference that my screenshots claim:

・lineFragmentRect

・lineFragmentUsedRect

Please look at the right edge of red borders. These maxX and width are not equal. Assuming from this behavior, I understand that lineFragmentRect is rect for proposing line fragment in glyph layout process, and lineFragmentUsedRect is actual rect that the glyphs are filled, considering word wrap and hyphen factor.

・Code I used for investigation.

    func addLineFragmentBorder(of text: String) {

        let range = (textView.text as NSString).range(of: text)

        let glyphRange = textView.layoutManager.glyphRange(forCharacterRange: range, actualCharacterRange: nil)

        // You can try the difference by changing `lineFragmentUsedRect` to `lineFragmentRect`.
        let lineRect = textView.layoutManager.lineFragmentUsedRect(forGlyphAt: glyphRange.location, effectiveRange: nil)



        let borderLayer = CALayer()

        borderLayer.frame = .init(x: lineRect.minX, y: lineRect.minY + textView.textContainerInset.top, width: lineRect.width, height: lineRect.height)

        borderLayer.borderColor = UIColor.red.cgColor

        borderLayer.borderWidth = 2

        borderLayer.backgroundColor = UIColor.clear.cgColor



        textView.layer.addSublayer(borderLayer)

    }

Replies

After few hours later, I cloud solve this question by myself.

These are difference that my screenshots claim:

・lineFragmentRect

・lineFragmentUsedRect

Please look at the right edge of red borders. These maxX and width are not equal. Assuming from this behavior, I understand that lineFragmentRect is rect for proposing line fragment in glyph layout process, and lineFragmentUsedRect is actual rect that the glyphs are filled, considering word wrap and hyphen factor.

・Code I used for investigation.

    func addLineFragmentBorder(of text: String) {

        let range = (textView.text as NSString).range(of: text)

        let glyphRange = textView.layoutManager.glyphRange(forCharacterRange: range, actualCharacterRange: nil)

        // You can try the difference by changing `lineFragmentUsedRect` to `lineFragmentRect`.
        let lineRect = textView.layoutManager.lineFragmentUsedRect(forGlyphAt: glyphRange.location, effectiveRange: nil)



        let borderLayer = CALayer()

        borderLayer.frame = .init(x: lineRect.minX, y: lineRect.minY + textView.textContainerInset.top, width: lineRect.width, height: lineRect.height)

        borderLayer.borderColor = UIColor.red.cgColor

        borderLayer.borderWidth = 2

        borderLayer.backgroundColor = UIColor.clear.cgColor



        textView.layer.addSublayer(borderLayer)

    }

PS: I've updated my understanding. lineFragmentRect is rect that a layoutManager proposes lineFragment which the width as big as possible considering exclusionPaths. lineFragmentUsedRect is rect that the glyphs actually use.