On Fri, 21 Oct 2022 08:42:12 GMT, Alexander Scherbatiy <alex...@openjdk.org> 
wrote:

> A printed content is truncated on macOS if the content paper size width 
> larger than height with portrait orientation or width is less than height 
> with landscape orientation.
> 
> To reproduce the issue run the 
> [CutOffImage](https://bugs.openjdk.org/secure/attachment/101145/CutOffImage.java)
>  sample on MacOS.
> 
> Four rectangles are printed:
> 1. size 300x100, portrait orientation
> 2. size 300x100, landscape orientation
> 3. size 100x300, portrait orientation
> 4. size 100x300, landscape orientation
> 
> The first and fourth rectangles are truncated: [cut off 
> content](https://bugs.openjdk.org/secure/attachment/101153/before-fix-all.pdf)
> 
> The reason is that NSPrintInfo class does not allow to set paper size and 
> orientation independently.
> Setting paper size width large than height changes NSPrintInfo orientation to 
> landscape.
> Setting paper size width less than height changes NSPrintInfo orientation to 
> portrait.
> Updating NSPrintInfo orientation from landscape to portrait or from portrait 
> to landscape swaps NSPrintInfo paper width and height.
> 
> The Cocoa code that shows NSPrintInfo behavior:
> 
> #import <Cocoa/Cocoa.h>
> 
> int main()
> {
>     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
>     NSApp = [NSApplication sharedApplication];
> 
>     #ifdef __MAC_10_9 // code for SDK 10.9 or newer
>     #define NS_PORTRAIT NSPaperOrientationPortrait
>     #define NS_LANDSCAPE NSPaperOrientationLandscape
>     #else // code for SDK 10.8 or older
>     #define NS_PORTRAIT NSPortraitOrientation
>     #define NS_LANDSCAPE NSLandscapeOrientation
>     #endif
> 
>     printf("NS_PORTRAIT: %d\n", NS_PORTRAIT);
>     printf("NS_LANDSCAPE: %d\n", NS_LANDSCAPE);
> 
>     printf("create default print info\n");
>     NSPrintInfo* defaultPrintInfo = [[NSPrintInfo sharedPrintInfo] copy];
>     NSSize size = [defaultPrintInfo paperSize];
>     printf("orientation: %d, paper size: [%f, %f]\n", [defaultPrintInfo 
> orientation], size.width, size.height);
> 
>     printf("call setUpPrintOperationDefaultValues\n");
>     [defaultPrintInfo setUpPrintOperationDefaultValues];
>     size = [defaultPrintInfo paperSize];
>     printf("orientation: %d, paper size: [%f, %f]\n", [defaultPrintInfo 
> orientation], size.width, size.height);
> 
>     double w = 300.0;
>     double h = 100.0;
>     printf("set size: [%f, %f]\n", w, h);
>     [defaultPrintInfo setPaperSize:NSMakeSize(w, h)];
>     size = [defaultPrintInfo paperSize];
>     printf("orientation: %d, paper size: [%f, %f]\n", [defaultPrintInfo 
> orientation], size.width, size.height);
> 
>     printf("Set NS_PORTRAIT orientation\n");
>     [defaultPrintInfo setOrientation: NS_PORTRAIT];
>     size = [defaultPrintInfo paperSize];
>     printf("orientation: %d, paper size: [%f, %f]\n", [defaultPrintInfo 
> orientation], size.width, size.height);
> 
>     [NSApp run];
> 
>     [NSApp release];
>     [pool release];
>     return(EXIT_SUCCESS);
> } 
> 
> 
> On macOS Mojave 10.14.5 it prints:
> 
> 
> NS_PORTRAIT: 0
> NS_LANDSCAPE: 1
> create default print info
> orientation: 0, paper size: [612.000000, 792.000000]
> call setUpPrintOperationDefaultValues
> orientation: 0, paper size: [612.000000, 792.000000]
> set size: [300.000000, 100.000000]
> orientation: 1, paper size: [300.000000, 100.000000] // orientation flip
> Set NS_PORTRAIT orientation
> orientation: 0, paper size: [100.000000, 300.000000] // size flip
> ``` 
> 
> There are four possible cases for printing a rectangle with different size 
> and orientation:
> 1. Input: paper size: (w > h), orientation portrait
>   [dstPrintInfo setPaperSize: NSMakeSize(w, h)]  // size: (w, h), 
> orientation: landscape
>   [dstPrintInfo setOrientation: NS_PORTRAIT]     // size: (h, w), 
> orientation: portrait
>   Note: width and height are swapped
> 2. Input: paper size: (w > h), orientation landscape
>   [dstPrintInfo setPaperSize: NSMakeSize(h, w)]  // size: (h, w), 
> orientation: portrait
>   [dstPrintInfo setOrientation: NS_LANDSCAPE]  // size: (w, h), orientation: 
> landscape
> 3. Input: paper size: (w < h), orientation portrait
>   [dstPrintInfo setPaperSize: NSMakeSize(w, h)]  // size: (w, h), 
> orientation: portrait
>   [dstPrintInfo setOrientation: NS_PORTRAIT]     // size: (w, h), 
> orientation: portrait
> 4. Input: paper size: (w < h), orientation landscape
>   [dstPrintInfo setPaperSize: NSMakeSize(h, w)]  // size: (h, w), 
> orientation: landscape
>   [dstPrintInfo setOrientation: NS_LANDSCAPE]  // size: (h, w), orientation: 
> landscape
>   Note: width and height are swapped
> 
> Only for cases 1 and 4 the final width and height are swapped.
> The proposed fix enlarges height for cases 1 and 4 to not cut the printed 
> rectangle.
> 
> It is not full fix which draws rectangles for cases 1 and 4 in the requested 
> size.
> Setting requested size leads that subsequent orientation flips width and 
> height.
> The fix only enlarges the truncated area in height direction. The enlarged 
> area in width is preserved as before the fix.
> 
> Printed rectangles before and after the fix:
> 1. size 300x100, portrait orientation: 
> [before-fix-1.pdf](https://bugs.openjdk.org/secure/attachment/101157/before-fix-1.pdf),
>   
> [after-fix-1.pdf](https://bugs.openjdk.org/secure/attachment/101162/after-fix-1.pdf)
> 2. size 300x100, landscape orientation: 
> [before-fix-2.pdf](https://bugs.openjdk.org/secure/attachment/101156/before-fix-2.pdf),
>   
> [after-fix-2.pdf](https://bugs.openjdk.org/secure/attachment/101161/after-fix-2.pdf)
> 3. size 100x300, portrait orientation: 
> [before-fix-3.pdf](https://bugs.openjdk.org/secure/attachment/101155/before-fix-3.pdf),
>   
> [after-fix-3.pdf](https://bugs.openjdk.org/secure/attachment/101160/after-fix-3.pdf)
> 4. size 100x300, landscape orientation: 
> [before-fix-4.pdf](https://bugs.openjdk.org/secure/attachment/101154/before-fix-4.pdf),
>   
> [after-fix-4.pdf](https://bugs.openjdk.org/secure/attachment/101159/after-fix-4.pdf)
> 
> All four rectangles: 
> [before-fix-all.pdf](https://bugs.openjdk.org/secure/attachment/101153/before-fix-all.pdf),
>   
> [after-fix-all.pdf](https://bugs.openjdk.org/secure/attachment/101158/after-fix-all.pdf)

This is an example which is written in JavaFX and prints a rectangle on page 
with paper size 300x100 with portrait orientation 
[FxPrintImageWithHelper.java](https://bugs.openjdk.org/secure/attachment/101461/FxPrintImageWithHelper.java).
Actually JavaFX has set of predefined paper sizes all of which have width less 
than height: 
[Paper.java](https://github.com/openjdk/jfx/blob/7f17447aa44fbf5b09aaa2b699266dac8b50cea1/modules/javafx.graphics/src/main/java/javafx/print/Paper.java#L127).
 `Paper` class does not allow to create a paper with arbitrary paper size 
because its constructor has default access modifier.

`FxPrintImageWithHelper`  sample uses 
[PrintHelper.java](https://github.com/openjdk/jfx/blob/master/modules/javafx.graphics/src/main/java/com/sun/javafx/print/PrintHelper.java)
 helper class from `com.sun.javafx.print` package with public 
`createPaper(...)` method.

The sample properly prints a rectangle on Linux. The rectangle is truncated 
when it is printed on macOS.

Run `FxPrintImageWithHelper` with jdk8:

<jdk8>/bin/java FxPrintImageWithHelper

Printed page on macOS: 
[jfx-image-300x100-portrait-jdk8.pdf](https://bugs.openjdk.org/secure/attachment/101463/jfx-image-300x100-portrait-jdk8.pdf)


Run `FxPrintImageWithHelper` with jdk17:

<jdk17>/bin/java --add-exports javafx.graphics/com.sun.javafx.print=ALL-UNNAMED 
 FxPrintImageWithHelper

Printed page on macOS: 
[jfx-image-300x100-portrait-jdk17.pdf](https://bugs.openjdk.org/secure/attachment/101462/jfx-image-300x100-portrait-jdk17.pdf)

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

PR: https://git.openjdk.org/jdk/pull/10808

Reply via email to