Search code examples
swiftmacoscocoaprintingnsdocument

Cocoa printing with Swift: "Any" printer setup has irregular margins/page size, any workaround?


I'm working on a graphics app for Mac OS in Swift and want to have a professional WYSIWYG layout features for printing.

I've isolated a weird behavior of the Cocoa printing system and just wondered if anyone knows of a setup step I'm missing or a workaround. The issue is that the "Any" printer has irregular, non-centered margins even when horizontal+vertical centering is requested. In particular, the left margin of my landscape letter-size docuemnt is 18pt and the right margin is 40pt - bigger than 1/2", which I feel is an unacceptable contraint, not to mention the annoyance of not being able to rely on the requested centering.

My app is NSDocument-based and I set printInfo margins to 0, centered fields to true, and orientation to .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

I am using Page Setup in this test. I have an EPSON printer that gives me the choice of regular or borderless printing, and with either option, selecting US Letter landscape, I get reasonable imageablePageBounds reported to draw into.

With the borderless page setup, I get

... imageablePageBounds: (0.0, 0.0, 792.0, 612.0)

and with 'regular' letter/landscape I get

... imageablePageBounds: (8.4000244140625, 8.399999618530273, 775.199951171875, 595.1999759674072)

The latter is setting to some driver minimum, but if you double the 8.4 point offsets and add to height and width you still get 792x612 == 11in x 8.5in

If instead I select "Any" printer in Page Setup and select US Letter, landscape, imageablePageBounds is reported (and enforced, even when printing to PDF) as: ... imageablePageBounds: (18.0, 18.0, 734.0, 576.0)

This gives 1/4" (18-pt) margins left, bottom, and top, but forces a 40-pt margin to the right (since width is only 734 - it should be 756 for a 10.5" drawing area). And indeed, if I try to draw an 10-inch image centered with 36pt margins, the right edge very annoyingly gets clipped unless I scale or shift it. It even gets clipped off with PDF output with this setup. Here's an image in the print panel that shows this clipping - the outer black line is the imageable view bounds given by the printing system, the blue line (right edge cut off) is a centered 10 x 7.5 image.

Screenshot of printing panel with issue

Does anyone know if there's a fix for this weird behavior? The ideal fix would be to get a reasonable 1/4" border as a default for anything I'm trying to print, but even if I can't get the max default width above 734pt I still want it to be centered so that I can at least work within 1/2" margins without any clipping.


Solution

  • While the original behavior does seem like a bug, it appears that setting printInfo.paperSize field may provide a partial workaround, as long as the Mac has an installed printer available.

    In addition to my other setup, if I add the line

    self.printInfo.paperSize = CGSize(width: 792.0, height: 612.0)
    

    for my US-Letter landscape document, and still use Page Setup to set printer "Any" and letter/landscape, when the print job actually runs it now shows up having selected the driver from the EPSON driver rather than leaving the buggy "Any" driver's margins - the result is nicely centered with minimal margins as desired.

    enter image description here

    I tested on a MacBook Pro with no printer set up, and this workaround did not correct the issue - it still shows up with off-center margin and clips the drawing. So the workaround requires some actual printer to be installed.

    I've filed a bug via Apple's feedback assistant, will post an update if anything more is discovered or resolved.