I am using WKWebView
to export data from my macOS app. I'm using CSS and page-break-after: always;
to create pagination.
This works fine on most systems, but on some Macs, resulting WKWebView
contents are scaled up about 5% — from 507px
to 536px
. This causes my CSS-driven pagination to run over page boundaries, resulting in orphaned pages.
I'm creating the web view programmatically, so the user can't have scaled it by mistake. NSPrintInfo
is also forced to use specific margins, and if those don't fit the .imageablePageBounds
, the difference is taken into account. (This part is not in this sample code, though.)
func makeWebview(html:String) {
webview = WKWebView()
webview?.loadHTMLString(html, baseURL: nil)
}
func exportToPDF (url: NSURL) {
let printInfo = NSPrintInfo.shared
printInfo.dictionary().addEntries(from: [
NSPrintInfo.AttributeKey.jobDisposition: NSPrintInfo.JobDisposition.save,
NSPrintInfo.AttributeKey.jobSavingURL: url
])
// Set margins
printInfo.topMargin = 12.5
printInfo.leftMargin = 12.5
printInfo.rightMargin = 12.5
printInfo.bottomMargin = 12.5
var offset = CGSize(width: 0, height: 0)
let referenceMargin = 12.5
let imageableOrigin = CGSize(width: printInfo.imageablePageBounds.origin.x, height: printInfo.imageablePageBounds.origin.y)
if (imageableOrigin.width - referenceMargin > 0) {
offset.width = imageableOrigin.width - referenceMargin
}
if (imageableOrigin.height - referenceMargin > 0) {
offset.height = imageableOrigin.height - referenceMargin
}
printInfo.topMargin = printInfo.topMargin - offset.height;
printInfo.leftMargin = printInfo.topMargin - offset.width;
let printOperation = webview?.printOperation(with: printInfo)
printOperation?.showsPrintPanel = false
printOperation?.showsProgressPanel = true
printOperation.view.frame = NSMakeRect(0,0, printInfo.paperSize.width, printInfo.paperSize.height)
printOperation?.runModal(for: self.window, delegate: self, didRun: #selector(printOperationDidRun), contextInfo: nil)
}
My CSS also uses cm
and pt
sizes, which makes this issue even weirder. Again, this only happens on select systems, so I can't reproduce it myself.
body {
width: calc(21cm - 88pt); /* Accounts for printer margins */
font-size: 12pt;
}
For some users, the results are very off, including previously set margins.
The faulty scaling must happen inside the web view, because as the pages flow over, page breaks still happen after correct elements. I know that WKWebView
will scale contents to fit, causing the page to shrink, if content width exceeds printable width, but I haven't seen the opposite.
I'm wondering if there is a system-wide setting for web view contents scale, which could affect WKWebView
?
Any hints or ideas are welcome.
Update: The issue happens when the user has no printers installed on their system. For some reason, NSPrintInfo
has much smaller imageablePageBounds
without a physical printer, and print operation also then scales up the contents.
This thread revolves around the same issue, with no apparent workaround:
Cocoa printing with Swift: "Any" printer setup has irregular margins/page size, any workaround?