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
}