强制NSLayoutManager绘制具有不同字体

时间:2016-10-06 07:21:49

标签: objective-c swift cocoa cocoa-touch nslayoutmanager

我正在尝试强制NSLayoutManager在某个范围内绘制具有不同属性的字形,但它仍然使用在NSTextStorage对象中设置的属性。

我试图用不同的字体创建NSGlyph并将其替换为NSTypesetter的字形存储中的NSGlyph。但它的用途 - 布局管理器仍然使用字体和文本存储属性字符串中指定的颜色绘制该字形。

public override func drawGlyphs(forGlyphRange glyphsToShow: NSRange, at origin: NSPoint) {
    // now set glyphs for invisible characters
    if PreferencesManager.shared.shouldShowInvisibles == true {
        var spaceRanges = [NSRange]()
        let charRange = self.characterRange(forGlyphRange: glyphsToShow, actualGlyphRange: nil)
        var substring = (self.currentTextStorage.string as NSString).substring(with: charRange)

        let spacesExpression = try? NSRegularExpression(pattern: "[ ]", options: NSRegularExpression.Options.useUnicodeWordBoundaries)
        let substringRange = NSRange(location: 0, length: substring.characters.count)
        if let matches = spacesExpression?.matches(in: substring, options: .withoutAnchoringBounds, range: substringRange) {
            for match in matches {
                spaceRanges.append(NSRange(location: charRange.location + match.range.location, length: 1))
            }
        }

        for spaceRange in spaceRanges {
            let invisibleFont = Font(name: "Gill Sans", size: 11) ?? Font.systemFont(ofSize: 11)

            // get any glyph to test the approach
            var glyph = invisibleFont.glyph(withName: "paragraph")

            // replce the glyphs
            self.typesetter.substituteGlyphs(in: spaceRange, withGlyphs: &glyph)

        }
    }
    // BUT LAYOUT MANAGER IGNORES THE FONT OF THE GLYPH I CREATED
    super.drawGlyphs(forGlyphRange: glyphsToShow, at: origin)
}

如何强制布局管理器在某个范围内忽略这些属性,并使用我需要的字体和颜色绘制我创建的字形?我需要这个,因为我正在以最有效的方式绘制隐形字符。

1 个答案:

答案 0 :(得分:1)

您在这里直接修改排字机,但是当您致电super时,它会重新完成所有工作。您可能会覆盖getGlyphs(in:glyphs:properties:characterIndexes:bidiLevels:),调用super,然后交换所需的任何字形。或者,您可以在致电setGlyphs(...)之前致电super

有关使用弃用方法尝试执行的操作的示例,请参阅Display hidden characters in NSTextView。我相当确定replaceGlyphAtIndexsetGlyphs取代。