[Bug/Critical] Printer quality and media type settings ignored when printing target — lp path missing PMPrintSettings ticket #201
Notifications
Due Date
No due date set.
Blocks
#202 [Feature/Backend] AirPrint queue detection and Stage 2 unmanaged-colour warning
gronod/iccery-v2-mac
Reference: gronod/iccery-v2-mac#201
Reference in New Issue
Block a user
Summary
When printing profiling targets via the
lpCLI (the current spooling path inPrintSessionViewModel.swift/CupsService.printTarget), printer drivers such as the Epson raster filter ignore the media type and print quality selections. The printed target falls back to plain paper and normal quality, which corrupts the profiling data.Root Cause Analysis
Following investigation of the macOS printing pipeline (
PrintPanelService,CupsParsers,LpArgs), the defect originates at the driver boundary:NSPrintPanelproperties into standard CUPS string options (e.g.,EPIJ_Qual=3) and passes them tolp -o. However,lpon macOS only creates an IPP job with string attributes; it does not generate the nativecom.apple.print.PrintSettingsticket (a serialized CoreFoundation plist containing vendor PDE state).PMPrintSettingsdictionary to configure hardware parameters (ink density, media type, quality, ColorSync bypass). Becauselpomits this ticket, the driver ignores the CUPS string options and applies defaults (plain paper, standard quality, standard color management).LpArgs.build(lines 59–105), captured CUPS options silently override explicit Stage 2 selections. If a user sets "Glossy" in the Preferences panel then changes the Stage 2 inline dropdown to "Matte",LpArgsprioritizes the capturedEPIJ_Medikey and ignores the inline change.What was checked and dismissed
-ovalues with spaces were incorrectly split by shell tokenization was dismissed.ProcessManager.runCapturedpassesargvdirectly toProcesswithout shell evaluation, so space-containing arguments are safely preserved.AP_ColorMatchingMode=AP_ApplicationColorMatchingis correctly passed, but without the print ticket its effectiveness relies entirely on the driver parsing basic IPP attributes.Proposed Fix (Deterministic)
Replace the
lpspooler with a headlessNSPrintOperationinCupsService(bringing forward the Quartz rendering architecture from #16).lpspooling with Quartz/NSPrintOperationCupsServicethat avoidslp.CGImageSource(disable interpolation and antialiasing, respecting 1:1 points-to-pixels based on DPI, perdocs/14-iccery-cpu-targetprint.md).NSViewsubclass implementingknowsPageRangeandrectForPage, ensuringisFlippedreturnstruefor correct coordinate mapping.NSPrintInfowith captured settingsPMPrintSettings(or its serializedData/NSDictionary) natively in memory when the user clicks "Use Settings" inNSPrintPanel, instead of flattening viaPMPrintSettingsToOptions(which loses opaque PDE binary data).NSPrintInfo, bind it to the queue, and restore the savedPMPrintSettingsdictionary.NSPrintInfo.printSettingsbefore spooling.NSPrintOperationwith the configuredNSPrintInfoand targetNSView.showsPrintPanel = falseandshowsProgressPanel = true(or custom UI) to execute on the Main Actor.lpoptionsmappingCupsParserslogic manually mapping driver bypass keys (CNIJIntent2,EPIJ_CMat) can be phased out, as the nativePMPrintSettingsdictionary retains these when captured fromNSPrintPanel.Note: #16 covers the full migration to
ICCeryPrintKit, but fixing this defect for v2.0 requires replacinglpwithNSPrintOperationinCupsService.Acceptance Criteria
NSPrintPanel/ Stage 2 (verified against an Epson raster driver, e.g.,EPIJ_Qual,EPIJ_Medi).com.apple.print.PrintSettingsticket is present on the spooled job (vendor PDE state preserved), verified via executingsudo cupsctl --debug-loggingfollowed bysudo grep 'com.apple.print.PrintSettings' /var/log/cups/error_log.lpinvocation remains on the target-print path; TIFF rendering is 1:1 points-to-pixels with interpolation/antialiasing disabled.Dependencies
ICCeryPrintKitQuartz migration)References
docs/issue-printer-quality-ignored.mdPackages/ICCeryCore/Sources/ICCeryCore/Print/CupsService.swiftPackages/ICCeryCore/Sources/ICCeryCore/Print/LpArgs.swiftPackages/ICCeryCore/Sources/ICCeryCore/Print/CupsParsers.swiftPackages/ICCeryCore/Sources/ICCeryCore/Print/PrintPanelService.swiftdocs/14-iccery-cpu-targetprint.mdArchitectural Decisions & Errata (M12 Megaplan)
Following architectural review against the macOS 12 Monterey baseline (
plan-be303e6f3f5e89da.md), the following locked decisions supersede earlier notes:NSPrintOperationspooler will reside in the application target (Sources/ICCery/Print/), not inCupsService.ICCeryCoreremains strictly AppKit-free by contract.CupsService.printTargetwill be deprecated and removed.CupsParsersandCupsOptionsFilterare retained; they remain required for printer capabilities, media/quality detection, and Stage 2 preference mirroring. OnlyLpArgsis deprecated and removed.PMColorMatchingMode=APCustomColorMatching,PMCustomColorMatchingProfile="", and legacy dictionary keys) simultaneously.