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)

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

Commit messages:
 - 8295737: macOS: Print content cut off when width > height with portrait 
orientation

Changes: https://git.openjdk.org/jdk/pull/10808/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=10808&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8295737
  Stats: 360 lines in 2 files changed: 356 ins; 0 del; 4 mod
  Patch: https://git.openjdk.org/jdk/pull/10808.diff
  Fetch: git fetch https://git.openjdk.org/jdk pull/10808/head:pull/10808

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

Reply via email to