提问人:Peter Nowell 提问时间:9/17/2023 最后编辑:Peter Nowell 更新时间:9/18/2023 访问量:74
如何在CGContext中绘制正确的垂直文本?
How to draw proper vertical text in a CGContext?
问:
我需要使用垂直布局方向(即垂直的“书写方向”)绘制一个到一个。仅仅旋转水平排版的文本行是不够的,因为这不会激活垂直 OpenType 功能,也不会考虑字形应该在哪些脚本中是直立的(例如:中文)。NSAttributedString
CGContext
这已经可以通过 NSTextView
实现。通过设置 NSLayoutManager.TextLayoutOrientation
值,或者通过 UI 在视图内单击鼠标右键,可以是水平或垂直的布局方向。但我需要将文本绘制到 Core Graphics PDF 上下文中,而不是视图中。NSTextView
我在 CoreText 中没有看到任何关于垂直排版的信息,但我猜 TextKit 能够做到这一点。TextKit 的 NSTextContainer 似乎可以被子类化为使用垂直方向,这似乎是难题的重要组成部分。我目前正在这样做:
class VerticalTextContainer: NSTextContainer {
override var layoutOrientation: NSLayoutManager.TextLayoutOrientation { .vertical }
}
我是 TextKit 的新手,找不到很多人们将其与 CGContext 而不是视图一起使用的示例,因此我确定我的设置不正确。这是我的 TextKit 设置:
let attrString = NSAttributedString(
string: "Hello 你好!"
)
/// The text box; the shape/frame to fill with the text.
let textContainer: NSTextContainer = VerticalTextContainer(size: NSSize(width: 300, height: 300) )
/// The part that handles laying out text elements, generating text layout fragments.
let textLayoutManager: NSTextLayoutManager = {
var layoutManager = NSTextLayoutManager()
layoutManager.textContainer = textContainer
return layoutManager
}()
/// The part that stores the attributed string and connects to the layout manager.
let textContentStorage: NSTextContentStorage = {
var storage = NSTextContentStorage()
storage.attributedString = attrString
storage.addTextLayoutManager( textLayoutManager )
return storage
}()
然后,在我的 CGContext 中,我尝试了这个——但什么也没出现:
// inside a new 300x300 CGContext:
// prep:
cgContext.scaleBy(x: 1, y: -1)
cgContext.translateBy(x: 0, y: size.height * -1)
cgContext.textMatrix = .identity
cgContext.setFillColor( .black )
// try drawing the TextKit line fragments
textLayoutManager.enumerateTextLayoutFragments(
from: textLayoutManager.documentRange.location,
options: .ensuresLayout
) { textLayoutFragment in
textLayoutFragment.draw(at: CGPoint(x: 100, y: 100), in: cgContext)
return true
}
我尝试了许多变体,包括传递给枚举方法的参数,遍历每个参数并绘制每个参数,然后执行.似乎没有任何效果。我什至不确定是否正在创建布局片段。nil
from:
textLayoutFragment.textLineFragments
textLayoutManager.ensureLayout(for: textLayoutFragment.rangeInElement)
任何帮助将不胜感激!
答: 暂无答案
评论
render(in:)
NSTextView
NSTextView