[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-2d-dev
Subject:    Re: RFR: 8295737: macOS: Print content cut off when width > height with portrait orientation [v4]
From:       Alexander Scherbatiy <alexsch () openjdk ! org>
Date:       2022-11-29 11:19:59
Message-ID: 47LQpQGxZf-QD_1umGWDEmdZhDGHGvWJuTk6fy7ePbs=.ecac3a91-f38d-4fb2-91d1-e404a97126a6 () github ! com
[Download RAW message or body]

On Tue, 29 Nov 2022 10:36:32 GMT, Alexander Scherbatiy <alexsch@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)
> > 
> 
> Alexander Scherbatiy has updated the pull request incrementally with one additional \
> commit since the last revision: 
> Fix typos in FlipPageFormat class comments

Could you review the updated fix?

I updated the sample which prints 4 rectangles: \
[PrintArrowPaperA5](https://bugs.openjdk.org/secure/attachment/101839/PrintArrowPaperA5.java).
 The main difference with the previous sample \
[CutOffImage](https://bugs.openjdk.org/secure/attachment/101145/CutOffImage.java) is \
that the image generation is based on the provided PageFormat class passed to the \
`Printable.print(Graphics graphics, PageFormat pageFormat, int index)` method: ``` 
    private static void paintImage(Graphics2D g, PageFormat page, int pageIndex) {
        BufferedImage img = createImage((int) page.getWidth(), (int) \
page.getHeight(), page.getOrientation(), pageIndex);  g.drawImage(img, 0, 0, null);
    }

    private static class TestPrintable implements Printable {

        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int index) {
            paintImage((Graphics2D) graphics, pageFormat, index);
            return PAGE_EXISTS;
        }
    }
``` 
PrintArrowPaperA5 sample uses A5 paper size which allows to test it with real printer \
where A5 paper could be palced horizontally or vertically in the paper tray.

PrintArrowPaperA5 sample prints  four rectangles
1. size 5.8 × 8.3 inches (width < height), portrait orientation
2. size 5.8 × 8.3 inches (width < height), landscape orientation
3. size 8.3 × 5.8 inches (width > height), portrait orientation
4. size 8.3 × 5.8 inches (width > height), landscape orientation

jdk 19 only correctly prints rectangles 1 and 2 (width < height) on macOS: \
[print-arrow-paper-a5-macos-jdk19.pdf](https://bugs.openjdk.org/secure/attachment/101840/print-arrow-paper-a5-macos-jdk19.pdf)
 Rectangles 3 and 4 (width > height) are truncated.

MacOS NSPrintInfo class has one to one correspondence between a paper size and its \
orientation: a. (w < h) <-> portrait
b. (w > h) <-> landscape

The proposed fix adds FlipPageFormat class which is intermediate between PageFormat \
and NSPrintInfo and is created only if PageFormat contains a paper with width greater \
than height.

FlipPageFormat establish the following relations:

3. PageFormat: (width > height), portrait orientation
-> FlipPageFormat: (width < height), landscape orientation
-> NSPrintInfo: (width > height) (landscape orientation)

4. PageFormat: (width > height), landscape orientation
-> FlipPageFormat: (width < height), portrait orientation
-> NSPrintInfo: (width < height) (portrait orientation)

FlipPageFormat preserves the original PageFormat class to pass it to a user defined \
`Printable.print(Graphics, PageFormat, int)` method.

`PageFormat pageFormat = pageable.getPageFormat(pageIndex);` line is changed to 
`PageFormat pageFormat = getPageFormat(pageIndex);` 
in the method `getPageformatPrintablePeekgraphics(final int pageIndex)`
to uniformly get FlipPageFormat class from `private PageFormat getPageFormat(int \
pageIndex)` method.

With the fix PrintArrowPaperA5 sample prints pages with paper width greater than \
height without truncation on macOS: \
[print-arrow-paper-a5-macos-jdk-fix.pdf](https://bugs.openjdk.org/secure/attachment/101841/print-arrow-paper-a5-macos-jdk-fix.pdf).


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

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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic