Я пытаюсь показать невидимые символы, как новый символ линии в моем подклассе NSTextView. Обычный подход, такой как переопределение метода drawGlyph для NSLayoutManager, является плохой идеей, потому что он слишком медленный и не работает должным образом с многопользовательской компоновкой.NSLayoutManager скрывает новые символы линии, независимо от того, что я делаю
Что я пытаюсь сделать, это переопределить метод setGlyph для NSLayoutManager, чтобы он заменил невидимый «\ n» глиф с «¶» глифом и «» на «∙».
И он работает на «" глифах пространства, но не влияет на новые символы линии.
public override func setGlyphs(_ glyphs: UnsafePointer<CGGlyph>, properties props: UnsafePointer<NSGlyphProperty>, characterIndexes charIndexes: UnsafePointer<Int>, font aFont: Font, forGlyphRange glyphRange: NSRange) {
var substring = (self.currentTextStorage.string as NSString).substring(with: glyphRange)
// replace invisible characters with visible
if PreferencesManager.shared.shouldShowInvisibles == true {
substring = substring.replacingOccurrences(of: " ", with: "\u{00B7}")
substring = substring.replacingOccurrences(of: "\n", with: "u{00B6}")
}
// create a CFString
let stringRef = substring as CFString
let count = CFStringGetLength(stringRef)
// convert processed string to the C-pointer
let cfRange = CFRangeMake(0, count)
let fontRef = CTFontCreateWithName(aFont.fontName as CFString?, aFont.pointSize, nil)
let characters = UnsafeMutablePointer<UniChar>.allocate(capacity: MemoryLayout<UniChar>.size * count)
CFStringGetCharacters(stringRef, cfRange, characters)
// get glyphs for the pointer of characters
let glyphsRef = UnsafeMutablePointer<CGGlyph>.allocate(capacity: MemoryLayout<CGGlyph>.size * count)
CTFontGetGlyphsForCharacters(fontRef, characters, glyphsRef, count)
// set those glyphs
super.setGlyphs(glyphsRef, properties:props, characterIndexes: charIndexes, font: aFont, forGlyphRange: glyphRange)
}
Тогда я придумал идею: он выглядит как NSTypesetter отмечает новые диапазоны линии полукокса, как те, что не должно обрабатывать вообще. Поэтому я подклассифицировал NSTypesetter и переопределил метод:
override func setNotShownAttribute(_ flag: Bool, forGlyphRange glyphRange: NSRange) {
let theFlag = PreferencesManager.shared.shouldShowInvisibles == true ? false : true
super.setNotShownAttribute(theFlag, forGlyphRange: glyphRange)
}
Но это не работает. NSLayoutManager все равно не будет генерировать глиф для нового символа линии, независимо от того, какой глиф я создаю.
Что я делаю неправильно?
Кажется этот код находится в Swift3, как мы можем преобразовать его в Swift 2.3? Я заметил, что «MemoryLayout» недоступен в Swift 2.3. –