Cocoa 使用 Swift 打印:"Any" 打印机设置有不规则的 margins/page 大小,有什么解决方法吗?
Cocoa printing with Swift: "Any" printer setup has irregular margins/page size, any workaround?
我正在 Swift 中为 Mac OS 开发图形应用程序,并希望拥有专业的 WYSIWYG 打印布局功能。
我发现了 Cocoa 打印系统的一个奇怪行为,只是想知道是否有人知道我遗漏的设置步骤或解决方法。问题是 "Any" 打印机有不规则的、非居中的边距,即使在要求水平+垂直居中时也是如此。特别是,我的横向信纸大小文档的左边距是 18pt,右边距是 40pt - 大于 1/2",我觉得这是一个不可接受的矛盾,更不用说无法依赖的烦恼了要求居中。
我的应用程序是基于 NSDocument 的,我将 printInfo 边距设置为 0,将居中字段设置为 true,并将方向设置为 .landscape。
self.printInfo.topMargin = 0.0
self.printInfo.rightMargin = 0.0
self.printInfo.leftMargin = 0.0
self.printInfo.bottomMargin = 0.0
self.printInfo.isHorizontallyCentered = true
self.printInfo.isVerticallyCentered = true
self.printInfo.orientation = .landscape
let newPrintOp = NSPrintOperation(view: self.printView!, printInfo: self.printInfo)
newPrintOp.showsPrintPanel = true
return newPrintOp
我在这个测试中使用了页面设置。我有一台 EPSON 打印机,可以让我选择常规打印或无边界打印,并且无论选择哪种方式,selecting US Letter landscape,我都会得到合理的 imageablePageBounds 报告绘制。
使用无边框页面设置,我得到
... imageablePageBounds: (0.0, 0.0, 792.0, 612.0)
和 'regular' letter/landscape 我得到
... imageablePageBounds: (8.4000244140625, 8.399999618530273, 775.199951171875, 595.1999759674072)
后者设置为某些驱动程序最小值,但如果将 8.4 点偏移加倍并添加到高度和宽度,您仍然会得到 792x612 == 11in x 8.5in
如果我 select "Any" 页面设置中的打印机和 select US Letter,landscape,imageablePageBounds 被报告(并强制执行,即使打印为 PDF)为:
... imageablePageBounds: (18.0, 18.0, 734.0, 576.0)
这给出了 1/4 英寸(18 磅)的左、下和上边距,但强制向右留出 40 磅的边距(因为宽度只有 734 - 对于 10.5 英寸的绘图应该是 756区域)。事实上,如果我尝试绘制一个以 36pt 边距为中心的 10 英寸图像,除非我缩放或移动它,否则右边缘会非常恼人地被剪掉。使用此设置,它甚至会被 PDF 输出剪掉。这是打印面板中显示此剪裁的图像 - 外部黑线是打印系统给出的可成像视图边界,蓝线(右边缘被切掉)是居中的 10 x 7.5 图像。
有谁知道是否有针对这种奇怪行为的修复方法?理想的解决方法是为我尝试打印的任何内容设置一个合理的 1/4" 边框作为默认值,但即使我无法获得高于 734pt 的最大默认宽度,我仍然希望它居中,以便我至少可以在 1/2" 的边距内工作而不会出现任何裁剪。
虽然最初的行为看起来确实像是一个错误,但设置 printInfo.paperSize
字段似乎可以提供部分解决方法,只要 Mac 安装了可用的打印机即可。
除了我的其他设置之外,如果我添加行
self.printInfo.paperSize = CGSize(width: 792.0, height: 612.0)
对于我的 US-Letter 横向文档,仍然使用页面设置来设置打印机 "Any" 和 letter/landscape,当打印作业实际运行时,它现在显示已从 EPSON 中选择了驱动程序驱动程序而不是留下越野车 "Any" 驱动程序的边距 - 结果很好地居中,所需的边距最小。
我在未设置打印机的情况下在 MacBook Pro 上进行了测试,此变通方法并未解决该问题 - 它仍然显示出偏离中心的边距并剪裁了绘图。所以解决方法需要安装一些实际的打印机。
我已经通过 Apple 的反馈助手提交了一个错误,如果发现或解决了更多问题,将会 post 进行更新。
这是我的测试应用程序,它在一页上无边距打印视图,也许它有帮助:
Document.swift
override func windowControllerDidLoadNib(_ windowController: NSWindowController) {
let newPrintInfo = NSPrintInfo()
newPrintInfo.leftMargin = 0.0
newPrintInfo.bottomMargin = 0.0
newPrintInfo.rightMargin = 0.0
newPrintInfo.topMargin = 0.0
newPrintInfo.horizontalPagination = .clip
newPrintInfo.verticalPagination = .clip
self.printInfo = newPrintInfo
}
override var printInfo: NSPrintInfo {
didSet {
view.printInfoChanged(printInfo)
}
}
override func printOperation(withSettings printSettings: [NSPrintInfo.AttributeKey : Any]) throws -> NSPrintOperation {
return NSPrintOperation(view: view, printInfo: printInfo)
}
MyView.swift
func printInfoChanged(_ newPrintInfo: NSPrintInfo) {
setFrameSize(newPrintInfo.paperSize)
}
override func locationOfPrintRect(_ rect: NSRect) -> NSPoint {
return NSZeroPoint
}
override func knowsPageRange(_ range: NSRangePointer) -> Bool {
range.pointee.location = 1
range.pointee.length = 1
return true
}
override func rectForPage(_ page: Int) -> NSRect {
return bounds
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
NSColor.green.set()
NSBezierPath(rect:bounds).stroke()
NSColor.red.set()
NSBezierPath(ovalIn:bounds).stroke()
}
我正在 Swift 中为 Mac OS 开发图形应用程序,并希望拥有专业的 WYSIWYG 打印布局功能。
我发现了 Cocoa 打印系统的一个奇怪行为,只是想知道是否有人知道我遗漏的设置步骤或解决方法。问题是 "Any" 打印机有不规则的、非居中的边距,即使在要求水平+垂直居中时也是如此。特别是,我的横向信纸大小文档的左边距是 18pt,右边距是 40pt - 大于 1/2",我觉得这是一个不可接受的矛盾,更不用说无法依赖的烦恼了要求居中。
我的应用程序是基于 NSDocument 的,我将 printInfo 边距设置为 0,将居中字段设置为 true,并将方向设置为 .landscape。
self.printInfo.topMargin = 0.0
self.printInfo.rightMargin = 0.0
self.printInfo.leftMargin = 0.0
self.printInfo.bottomMargin = 0.0
self.printInfo.isHorizontallyCentered = true
self.printInfo.isVerticallyCentered = true
self.printInfo.orientation = .landscape
let newPrintOp = NSPrintOperation(view: self.printView!, printInfo: self.printInfo)
newPrintOp.showsPrintPanel = true
return newPrintOp
我在这个测试中使用了页面设置。我有一台 EPSON 打印机,可以让我选择常规打印或无边界打印,并且无论选择哪种方式,selecting US Letter landscape,我都会得到合理的 imageablePageBounds 报告绘制。
使用无边框页面设置,我得到
... imageablePageBounds: (0.0, 0.0, 792.0, 612.0)
和 'regular' letter/landscape 我得到
... imageablePageBounds: (8.4000244140625, 8.399999618530273, 775.199951171875, 595.1999759674072)
后者设置为某些驱动程序最小值,但如果将 8.4 点偏移加倍并添加到高度和宽度,您仍然会得到 792x612 == 11in x 8.5in
如果我 select "Any" 页面设置中的打印机和 select US Letter,landscape,imageablePageBounds 被报告(并强制执行,即使打印为 PDF)为:
... imageablePageBounds: (18.0, 18.0, 734.0, 576.0)
这给出了 1/4 英寸(18 磅)的左、下和上边距,但强制向右留出 40 磅的边距(因为宽度只有 734 - 对于 10.5 英寸的绘图应该是 756区域)。事实上,如果我尝试绘制一个以 36pt 边距为中心的 10 英寸图像,除非我缩放或移动它,否则右边缘会非常恼人地被剪掉。使用此设置,它甚至会被 PDF 输出剪掉。这是打印面板中显示此剪裁的图像 - 外部黑线是打印系统给出的可成像视图边界,蓝线(右边缘被切掉)是居中的 10 x 7.5 图像。
有谁知道是否有针对这种奇怪行为的修复方法?理想的解决方法是为我尝试打印的任何内容设置一个合理的 1/4" 边框作为默认值,但即使我无法获得高于 734pt 的最大默认宽度,我仍然希望它居中,以便我至少可以在 1/2" 的边距内工作而不会出现任何裁剪。
虽然最初的行为看起来确实像是一个错误,但设置 printInfo.paperSize
字段似乎可以提供部分解决方法,只要 Mac 安装了可用的打印机即可。
除了我的其他设置之外,如果我添加行
self.printInfo.paperSize = CGSize(width: 792.0, height: 612.0)
对于我的 US-Letter 横向文档,仍然使用页面设置来设置打印机 "Any" 和 letter/landscape,当打印作业实际运行时,它现在显示已从 EPSON 中选择了驱动程序驱动程序而不是留下越野车 "Any" 驱动程序的边距 - 结果很好地居中,所需的边距最小。
我在未设置打印机的情况下在 MacBook Pro 上进行了测试,此变通方法并未解决该问题 - 它仍然显示出偏离中心的边距并剪裁了绘图。所以解决方法需要安装一些实际的打印机。
我已经通过 Apple 的反馈助手提交了一个错误,如果发现或解决了更多问题,将会 post 进行更新。
这是我的测试应用程序,它在一页上无边距打印视图,也许它有帮助:
Document.swift
override func windowControllerDidLoadNib(_ windowController: NSWindowController) {
let newPrintInfo = NSPrintInfo()
newPrintInfo.leftMargin = 0.0
newPrintInfo.bottomMargin = 0.0
newPrintInfo.rightMargin = 0.0
newPrintInfo.topMargin = 0.0
newPrintInfo.horizontalPagination = .clip
newPrintInfo.verticalPagination = .clip
self.printInfo = newPrintInfo
}
override var printInfo: NSPrintInfo {
didSet {
view.printInfoChanged(printInfo)
}
}
override func printOperation(withSettings printSettings: [NSPrintInfo.AttributeKey : Any]) throws -> NSPrintOperation {
return NSPrintOperation(view: view, printInfo: printInfo)
}
MyView.swift
func printInfoChanged(_ newPrintInfo: NSPrintInfo) {
setFrameSize(newPrintInfo.paperSize)
}
override func locationOfPrintRect(_ rect: NSRect) -> NSPoint {
return NSZeroPoint
}
override func knowsPageRange(_ range: NSRangePointer) -> Bool {
range.pointee.location = 1
range.pointee.length = 1
return true
}
override func rectForPage(_ page: Int) -> NSRect {
return bounds
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
NSColor.green.set()
NSBezierPath(rect:bounds).stroke()
NSColor.red.set()
NSBezierPath(ovalIn:bounds).stroke()
}