On Wed, 28 May 2025 10:29:17 GMT, GennadiyKrivoshein <d...@openjdk.org> wrote:
> The fix for the https://bugs.openjdk.org/browse/JDK-8251928. > > **Description**. > This PR contains changes to be able to print with DPI higher than 72 on > macOS, set default CPrinterJob DPI is 300 like in the PSPrinterJob. > > As described in the macOS drawing guide, the following steps are required to > draw with high DPI > (https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Transforms/Transforms.html#//apple_ref/doc/uid/TP40003290-CH204-BCICIJAJ): > 1. Convert the user-space point, size, or rectangle value to device space > coordinates; > 2. Normalize the value in device space so that it is aligned to the > appropriate pixel boundary; > 3. Convert the normalized value back to user space; > 4. Draw your content using the adjusted value. > > The 1-st step is now implemented in the CPrinterJob, a Graphics provided to > the print method adjusted to a printer's DPI. > The 2-nd step is a drawing process in the java code (without changes). > The 3-rd step is now implemented in the PrinterView.m, the drawing scaled > back to the 72 DPI. > The 4-th step is a drawing process in the native code (without changes). > > **Tests**. > I run all tests from javax.print package and there is no any regression. > New test covers macOS and Linux only because we know its default DPI - 300. src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java line 821: > 819: Graphics2D delegate = new SunGraphics2D(sd, Color.black, > Color.white, defaultFont); > 820: if (scaleX != 1 && scaleY != 1) { > 821: ((SunGraphics2D) delegate).setDevClip(0, 0, Only SunGraphics2D itself uses this (internally). Regardless of the scale, if the clip needs to be set, to the page dimensions, it must be set somewhere already. So this feels like it might be the wrong way to do this. Why did you do it this way ? src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java line 825: > 823: } > 824: Graphics2D pathGraphics = new CPrinterGraphics(delegate, > printerJob); // Just stores delegate into an ivar > 825: Rectangle2D pageFormatArea = getPageFormatArea(page, > scaleX, scaleY); I don't think this is right. scaleX is presumably the un-rotated X resolution, but these PageFormat methods take into account the rotation. So if you have a printer that has a resolution of x=300dpi, y=600dpi, and you go into landscape mode, then the scales will be the wrong way around. src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java line 869: > 867: new BufferedImage( > 868: (int)Math.round(pageFormat.getWidth() > * scaleX), > 869: (int)Math.round(pageFormat.getHeight() > * scaleY), I don't think this is right. getXRes() is presumably the un-rotated X resolution, but these PageFormat methods take into account the rotation. So if you have a printer that has a resolution of x=300dpi, y=600dpi, and you go into landscape mode, then the scales will be the wrong way around. src/java.desktop/macosx/native/libawt_lwawt/awt/PrinterView.m line 109: > 107: CGContextRef cgRef = (CGContextRef)[[printLoop context] > graphicsPort]; > 108: > 109: //Scale to default device DPI Not really, you are just scaling to a JDK default, not a device one. If you want to do this properly you need to get the resolution from CUPS - like you do in the test - and pass it through to the printing resolution set up. src/java.desktop/macosx/native/libawt_lwawt/awt/PrinterView.m line 117: > 115: double scaleX = DEFAULT_DEVICE_DPI/hRes; > 116: double scaleY = DEFAULT_DEVICE_DPI/vRes; > 117: if (scaleX != 1 && scaleY != 1) { yet another case where you need || ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25489#discussion_r2193555859 PR Review Comment: https://git.openjdk.org/jdk/pull/25489#discussion_r2193543602 PR Review Comment: https://git.openjdk.org/jdk/pull/25489#discussion_r2193419303 PR Review Comment: https://git.openjdk.org/jdk/pull/25489#discussion_r2193424886 PR Review Comment: https://git.openjdk.org/jdk/pull/25489#discussion_r2193424954