Я использую CoreGraphics для рисования отдельных глифов вместе с примитивами в CGContext. Следующий код работает на быстрой площадке в XCode 9.2. При запуске на площадке маленький прямоугольник с двойной буквой A должен появиться в заданных координатах на площадке liveView.
import Cocoa
import PlaygroundSupport
class MyView: NSView {
init(inFrame: CGRect) {
super.init(frame: inFrame)
}
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
// setup context properties
let context: CGContext = NSGraphicsContext.current!.cgContext
context.setStrokeColor(CGColor.black)
context.setTextDrawingMode(.fill)
context.setFillColor(CGColor(red: 0.99, green: 0.99, blue: 0.85, alpha: 1))
context.beginPath()
context.addRect(rect)
context.fillPath()
context.setFillColor(.black)
// prepare variables and constants
var font = CTFontCreateWithName("Helvetica" as CFString, 48, nil)
var glyph = CTFontGetGlyphWithName(font, "A" as CFString)
var glyph1Position = CGPoint(x: self.frame.minX, y: self.frame.maxY/2)
var glyph2Position = CGPoint(x: self.frame.minX+150, y: self.frame.maxY/2)
let text = "Hello"
var textOrigin = NSPoint(x: self.frame.minX+50, y: self.frame.maxY/2)
// draw one character
CTFontDrawGlyphs(font, &glyph, &glyph1Position, 1, context)
// *** *** when the next line is uncommented the bug appears *** ***
// text.draw(at: textOrigin)
CTFontDrawGlyphs(font, &glyph, &glyph2Position, 1, context)
}
}
var frameRect = CGRect(x: 0, y: 0, width: 200, height: 100)
PlaygroundPage.current.liveView = MyView(inFrame: frameRect)
Теперь я хочу нарисовать обычный текст в том же контексте. Однако, когда текстовая строка рисуется между рисованием двух глифов через собственный метод рисования, текущий контекст кажется испорченным, второй глиф не будет отображаться. Когда текст рисуется после того, как нарисованы оба глифа, все в порядке.
Таким образом, очевидно, что рисование текста оказывает влияние на текущий CGContext, но я не могу выяснить, что именно происходит. Я попробовал метод saveGstate () для рисования строки и восстановления после нее, но безуспешно.
Я также пытался использовать методы CoreText для создания приписанной строки с помощью CTFramesetterCreateWithAttributedString и показывать ее с помощью CTFramesetterCreateFrame, она также не работает, здесь после создания фрейм-установщика контекст перепутался.
Моя настоящая игровая площадка более сложна, там глифы не совсем исчезают, но отображаются в неправильном вертикальном положении, но основная проблема - и вопрос тот же:
Как я могу нарисовать текст в currentContext без каких-либо других изменений в контексте, выполняемых в фоновом режиме?