func layoutManager()

in Sources/TwitterTextEditor/LayoutManager.swift [202:261]


    func layoutManager(_ layoutManager: NSLayoutManager,
                       shouldGenerateGlyphs glyphs: UnsafePointer<CGGlyph>,
                       properties props: UnsafePointer<NSLayoutManager.GlyphProperty>,
                       characterIndexes charIndexes: UnsafePointer<Int>,
                       font aFont: UIFont,
                       forGlyphRange glyphRange: NSRange) -> Int
    {
        guard let textStorage = layoutManager.textStorage else {
            return 0
        }

        let unsafeBufferGlyphs = UnsafeBufferGlyphs(glyphs: glyphs,
                                                    properties: props,
                                                    characterIndexes: charIndexes,
                                                    count: glyphRange.length)

        var sortedInsertions = [MutableGlyphs.Insertion]()
        for index in 0..<unsafeBufferGlyphs.count {
            let characterIndex = unsafeBufferGlyphs.characterIndexes[index]
            let attributes = textStorage.attributes(at: characterIndex, effectiveRange: nil)

            // We can't derive two glyphs from a character that has `NSTextAttachment`.
            // For safely, check if there is no `.attachment` attribute.
            if attributes[.suffixedAttachment] is TextAttributes.SuffixedAttachment,
               attributes[.attachment] == nil
            {
                let insertion = MutableGlyphs.Insertion(index: index + 1,
                                                        glyph: CGGlyph(0),
                                                        property: .controlCharacter,
                                                        characterIndex: characterIndex)
                sortedInsertions.append(insertion)
            }
        }

        if sortedInsertions.isEmpty {
            return 0
        }

        var mutableGlyphs = MutableGlyphs(unsafeBufferGlyphs: unsafeBufferGlyphs)
        var offset = 0
        for insertion in sortedInsertions {
            mutableGlyphs.insert(insertion, offset: offset)
            offset += 1
        }

        let cacheableGlyphs = CacheableGlyphs(mutableGlyphs: mutableGlyphs)

        let mutatedLength = cacheableGlyphs.glyphs.count
        let mutatedGlyphRange = NSRange(location: glyphRange.location, length: mutatedLength)
        assert(glyphRange.length + offset == mutatedGlyphRange.length)

        glyphsCache.append(cacheableGlyphs)
        layoutManager.setGlyphs(cacheableGlyphs.glyphs.baseAddress!,
                                properties: cacheableGlyphs.properties.baseAddress!,
                                characterIndexes: cacheableGlyphs.characterIndexes.baseAddress!,
                                font: aFont,
                                forGlyphRange: mutatedGlyphRange)

        return mutatedGlyphRange.length
    }