On Tue, 8 Jul 2025 22:44:41 GMT, Phil Race <p...@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 ?

To achieve good image printing quality, the printed image must be drawn using 
the printer's DPI or close to it if the DPI isn't known.
The page is rendered in the following sequence 
  "User Image" ->  CPrinterGraphics -> SunGraphics2D -> CPrinterSurfaceData -> 
OSXSurfaceData -> "Native macOS User space".
  
CPrinterSurfaceData, OSXSurfaceData, and "Native macOS User space" from the 
rendering sequence are tightly coupled and contain data that is used in both 
native code and java, as well as CPrinterSurfaceData and OSXSurfaceData reflect 
the user space provided by macOS for rendering, including size and DPI, which 
is convenient and expected, and all the work on translations from the user 
space to the device space are performed automatically by macOS. Thus, I assumed 
that it is not reasonable to change anything in CPrinterSurfaceData and 
OSXSurfaceData.

To enable the user to determine the actual DPI of the printer, it remains 
possible to make changes to CPrinterGraphics or SunGraphics2D. I decided to add 
changes to SunGraphics2D because it is closer in the chain to rendering in 
macOS, and it also provides means for setting the necessary parameters through 
the existing public methods (setDevClip), and perform the reverse translation 
into the macOS user space in native code using scale methods specifically 
designed for this purpose.
It is possible to add an additional constructor to SunGraphics2D that takes 
into account the necessary scaling, and thus avoid using setDevClip, but this 
changes the actual API of SunGraphics2D, which I tried to avoid.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/25489#discussion_r2198816927

Reply via email to