These changes fix https://bugs.openjdk.org/browse/JDK-8372952 "Printed content 
is cut off when width > height". 

There are three issues which cause this bug.
#### The first issue
Media printable area does not match the corresponding media size for the 
landscape-oriented medias. \
An example of the actual prints on a paper 80mmx40mm (Epson T-TA88V) 
[actual_cut_off.pdf](https://github.com/user-attachments/files/25064646/actual_cut_off.pdf)

#### The second issue
_MediaSize_ does not allow landscape-oriented medias (X dimension bigger than Y 
dimension of the media) so rotated size is used, but the media printable area 
stays the same - landscape-oriented. 
Current implementation does not allow to use landscape-oriented paper because 
_MediaSize_
constructor allows portrait paper only (width < height). 

I read comments about _MediaSize_ restrictions (width<height) in 
https://bugs.openjdk.org/browse/JDK-8041911, which states that this is "by 
design" and specification. But I did not find media size restrictions in the 
https://datatracker.ietf.org/doc/html/rfc2911.
The RFC defines "orientation-requested" attribute, that was mentioned in the 
JDK-8041911 comments, but this attribute indicates the desired orientation for 
printed print-stream pages and is used for only a subset of the supported 
document formats ('text/plain' or 'text/html') to format the document. \
As described in the RFC 
https://datatracker.ietf.org/doc/html/rfc2911#section-15.3
> If the document data has been formatted, then go to step 2. Otherwise, the 
> document data MUST be formatted. The formatting detection algorithm is 
> implementation defined and is not specified by this document.  The formatting 
> of the document data uses the "orientation-requested" attribute to determine 
> how the formatted print data should be placed on a print-stream page

Therefore, if a printer object uses a landscape-oriented paper, a document 
format is "text/plain" and an "orientation-requested" attribute contains 
"portrait" value then the printer object should rotate the document 90 degrees. 
\
If a printer uses a portrait-oriented paper, a document format is "text/plain," 
and an "orientation-requested" attribute contains value "portrait" then the 
printer object does no rotation.

Also, https://datatracker.ietf.org/doc/html/rfc3382 defines a "media-size" IPP 
attribute which identifies the size of the media. The RFC contains an example 
of this attribute where the X-dimension (the width of the media in inch) larger 
than the Y-dimension (the height of the media in inch units).

>       "media-col" =
>         {  "media-color" =  'blue';
>            "media-size" =
>            {    "x-dimension" = 6;
>                 "y-dimension" = 4
>              }
>         },


#### The third issue
Implicit selection of the paper on macOS. Desired paper size and orientation is 
set during printer job setup and there is no explicit paper selection 
(landscape-oriented or portrait-oriented), so users cannot choose 
landscape-oriented paper if portrait-oriented paper with the same size exists 
and unable to set valid margins for landscape-oriented prints. If a label 
printer charged with landscape-oriented sticks but has a portrait sticks in 
settings with the same size then printer prints on the landscape-oriented 
sticks with portrait-oriented settings. \
An examples: \
Incorrect margins.
[incorrect_margins_landscape.pdf](https://github.com/user-attachments/files/25064640/incorrect_margins_landscape.pdf)
 \
A landscape-oriented (Ledger) is selected by a user but portrait-oriented 
(Tabloid) paper is used.
[incorrect_orientation.pdf](https://github.com/user-attachments/files/25064638/incorrect_orientation.pdf)

#### Changes
To solve the first and the second issues I added a new class _CustomMediaSize_, 
a wrapper for the _MediaSize_,
that allows to create a landscape media size (width > height). The getX, getY 
methods of the new class return the real
size of the media depending on paper orientation. The _CustomMediaSize_ is used 
in _CustomMediaSizeName_ during new _MediaSize_ creation and catches 
_IllegalArgumentException_ exception (X dimension > Y dimension) instead of 
swapping the width and height of the paper. The _CustomMediaSize_ 
implementation fixes the media printable area mismatch.

To solve the third problem I changed _CPrinterJob_ and _PrinterView_ files and 
added explicit paper selection. The _PMPaper_ and _PMPageFormat_ classes are 
used to choose desired paper. First of all, new approach tries to find existing 
paper with desired size and margins and use it, if the paper doesn't exist - it 
creates a new one. Also, this approach takes into account page format 
orientation to set paper margins properly, so this solves the issue with 
incorrect margins during landscape printing and allows reverse landscape 
printing.

An example of printings with this fix
[fixed_wo_cut_off.pdf](https://github.com/user-attachments/files/25064627/fixed_wo_cut_off.pdf)

#### Tests
I've run jtreg tests from the _java.awt.print_ and _javax.print_, there is no 
regression after updates. \
Two new test added to check media printable area and margins.

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

Commit messages:
 - landscape paper

Changes: https://git.openjdk.org/jdk/pull/29560/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=29560&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8372952
  Stats: 990 lines in 7 files changed: 809 ins; 127 del; 54 mod
  Patch: https://git.openjdk.org/jdk/pull/29560.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/29560/head:pull/29560

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

Reply via email to