0

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.

faulty 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?

Tritonal
  • 607
  • 4
  • 16
  • Post your code please. – Willeke Jun 01 '22 at 21:36
  • Simplified code is now there. – Tritonal Jun 02 '22 at 12:33
  • Do you set `webview.fame`, `printOperation.view?.frame` and/or the paper size somewhere? – Willeke Jun 02 '22 at 13:20
  • Yes, it happened in another function, but I've added it to the code now. – Tritonal Jun 02 '22 at 14:28
  • Do all users use the same printer and paper size? – Willeke Jun 02 '22 at 15:16
  • For now, those who experience issue, have used A4, though my app supports US Letter too. Although now that I've gathered more info, what's common for (most of) the users experiencing the issue, is that they don't have a physical printer installed. – Tritonal Jun 03 '22 at 10:01
  • Update: The issue is actually very much related to not having a printer installed. The shared `NSPrintInfo` will have much smaller `imageablePageBounds`. For some reason, page contents are also upscaled. – Tritonal Jun 04 '22 at 13:55

0 Answers0