我有一个NSView,它使用CALayers创建内容,并希望生成向量格式的pdf输出。首先,这是可能的,其次,苹果在文档中引用的逻辑坐标系是什么?最后,您应该如何绘制CALayers默认背景和边框属性?如果使用这些属性,则它们不会绘制到上下文中,如果绘制边框,则会重复属性设置。对于何时应该或不应该使用这些属性,或者在创建向量输出(例如pdf文档)时是否应该使用CALayers,这有点让人困惑。
视图有以下几个层:
视图层( sublayers
的矢量绘图的
下面列出了NSView类和CALayer子类。
视图层和绘图层被绘制在正确的位置,但是所有的绘图层子视图都绘制在错误的位置和错误的大小。
我假设这是因为绘图层有一个应用于is的转换,下面的绘图没有考虑到这一点。这就是问题所在吗?如果这是解决方案,我将如何将图层转换应用到CGContext,以使事情处于正确的位置?
class DrawingView: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
guard let context = NSGraphicsContext.current?.cgContext else {
return
}
// In theory should generate vector graphics
self.layer?.draw(in: context)
//Or
// Generates bitmap image
//self.layer?.render(in: context)
}
}
class DrawingLayer: CALayer {
override func draw(in ctx: CGContext) {
drawBorder(in: ctx)
if let subs = self.sublayers {
for sub in subs {
sub.draw(in: ctx)
}
}
}
func drawBorder(in ctx: CGContext){
let rect = self.frame
if let background = self.backgroundColor {
ctx.setFillColor(background)
ctx.fill(rect)
}
if let borders = self.borderColor {
ctx.setStrokeColor(borders)
ctx.setLineWidth(self.borderWidth)
ctx.stroke(rect)
}
}
}发布于 2020-06-09 22:39:04
以下是我的解决方案--使用不同的函数绘制PDF文件。我仍然不知道为什么系统在绘制到pdf和屏幕时的行为不一致。
编辑:-部分问题似乎是,我使用图层框架来计算绘图()函数中的大小/位置,但是当一个层被转换时,它的帧会改变大小和形状,以适应原来的旋转矩形!所以提示-保存你原来的矩形在其他地方,然后你的图纸不会突然变得奇怪,当你应用旋转或使用边界!!
EDIT2:-因此呈现(in:)工作,“有点”-一些3D转换被忽略,比如CATransform3DMakeTranslation()。幸运的是,旋转转换似乎可以工作,所以只需确保设置正确的原点,以避免需要转换。
当绘制pdf时,NSView的dirtyRect:)函数由CALayers way ( in:)函数调用,因此您似乎必须自己在层次结构上一直调用它们,记住要翻译每个子层的坐标系统--如果它们是在本地坐标系中绘制的话。请注意,这并不能保证pdf中的向量输出--似乎有些东西像文本被呈现为位图。如果有人对事情的行为和原因有解释,请解释。
无论如何,我只是回到使用CALayer.render( In :)函数,它会导致整个层层次结构被呈现--并且仍然使用一些向量和一些位映射元素!
class DrawingView: NSView {
var drawingLayer: DrawingLayer? {
return self.layer?.sublayers?[0] as? DrawingLayer
}
override func draw(_ dirtyRect: NSRect) {
//super.draw(dirtyRect)
guard let context = NSGraphicsContext.current?.cgContext else {
return
}
// In theory should generate vector graphics
self.drawingLayer?.drawPdf(in: context)
//Or
// Generates bitmap image
//self.layer?.render(in: context)
}
}
class DrawingLayer: CALayer {
var fillColor: CGColor?
var lineColor: CGColor?
var lineWidth: CGFloat = 0.5
var scale: CGFloat = 1.0
// No need for this since we don't need to call draw for each sublayer
// that gets done for us!
override func draw(in ctx: CGContext) {
print("drawing DrawingLayer \(name ?? "")")
// if let subs = self.sublayers {
// for sub in subs {
// sub.draw(in: ctx)
// }
// }
}
func drawPdf(in ctx: CGContext) {
ctx.saveGState()
ctx.translateBy(x: self.frame.minX, y: self.frame.minY)
if let subs = self.sublayers {
for sub in subs {
(sub as! NormalLayer).drawPdf(in: ctx)
}
}
ctx.restoreGState()
}
}
class NormalLayer: CALayer {
var fillColor: CGColor?
var lineColor: CGColor?
var lineWidth: CGFloat = 0.5
var scale: CGFloat = 1.0
override func draw(in ctx: CGContext) {
drawBorder(in: ctx)
}
func drawBorder(in ctx: CGContext){
let bds = self.bounds
let rect = CGRect(x: bds.minX*scale, y: bds.minY*scale, width: bds.width*scale, height: bds.height*scale)
print("drawing NormalLayer \(name ?? "") \(rect)")
if let background = self.fillColor {
ctx.setFillColor(background)
ctx.fill(rect)
}
if let borders = self.lineColor {
ctx.setStrokeColor(borders)
ctx.setLineWidth(self.lineWidth)
ctx.stroke(rect)
}
}
func drawPdf(in ctx: CGContext) {
ctx.saveGState()
ctx.translateBy(x: self.frame.minX, y: self.frame.minY)
drawBorder(in: ctx)
ctx.restoreGState()
}
}https://stackoverflow.com/questions/62273702
复制相似问题