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()
}