On Fri, 18 Jul 2025 13:19:10 GMT, Christian Heilmann <[email protected]> wrote:

>> This PR fixes a bug that caused no or the wrong set of pages to be printed 
>> when using page ranges on macOS.
>> 
>> The main fix is to change the 'location' value of the returned NSRange from 
>> the knowsPageRange method to 1 in the native class PrinterView.m.
>
> Christian Heilmann has updated the pull request with a new target base due to 
> a merge or a rebase. The incremental webrev excludes the unrelated changes 
> brought in by the merge/rebase. The pull request contains five additional 
> commits since the last revision:
> 
>  - 8297191 fixed printing page range for e.g. page 2 to 2 on macOS
>  - 8297191 fixed printing page range for e.g. page 2 to 2 on macOS
>  - Merge branch 'master' of https://github.com/openjdk/jdk into pr/11266
>  - Merge branch 'master' into pr/11266
>  - 8297191 fixed printing page range for e.g. page 2 to 2 on macOS

I wasn't entirely happy with the explanation that there must be a bug in macOS 
and the "it now works" seeming to be good enough,
I also didn't understand where the wrong first page number was arrived at.
Also it wasn't explained how setting the first page to 1 magically caused the 
actual first page to be rendered to be the first page in the range.

So I did some looking around and I have a rough idea what is happening.

In CPrinterJob there is a method called javaPrinterJobToNSPrintInfo()
This is invoked from within the printing loop and has this code 

    [printingDictionary setObject:[NSNumber numberWithInteger:fromPage] 
forKey:NSPrintFirstPage];
    [printingDictionary setObject:[NSNumber numberWithInteger:toPage] 
forKey:NSPrintLastPage];

That sets the range based on calling 
RasterPrinterJob.getFromPageAttrib() and RasterPrinterJob.getToPageAttrib()

So what I think happens is we are setting a range within a range.

If the user set the range from 2 to 3 that is supplied first to macOS in the 
implementation of knowsPageRange

But when dictionary is applied on top of that it becomes
FROM Page 2 of the range[2->3] which is Page 3
TO Page 3 of the range[2->3] which would be Page 4 but that is out of range so 
isn't printed.
So only Page 3 is in range and printed.

similarly if the user asks for 2-5 it becomes
FROM Page 2 of the range[2->5] which is Page 3
TO Page 5 of the range[2->5] which would be Page 6 but that is out of range so 
isn't printed.
So you get 3, 4, 5

And any starting page that is > half the range max means nothing is printed.

This also explains why a range that starts from 1 works.

So deleting/commenting out these lines 
    [printingDictionary setObject:[NSNumber numberWithInteger:fromPage] 
forKey:NSPrintFirstPage];
    [printingDictionary setObject:[NSNumber numberWithInteger:toPage] 
forKey:NSPrintLastPage];
and ensuring we always set
[printingDictionary setObject:[NSNumber numberWithBool:YES] 
forKey:NSPrintAllPages];
Also fixes this bug.

It seems odd that we have these two ways of doing a similar thing and that they 
interact like this.

I think this all bears a bit more studying as to which code to update for the 
fix - one of these has to go (although
knowsPageRange probably needs to exist and return YES, else the peek won't 
happen if I correctly read the Apple docs)
Also I'd like to make sure we test more cases than the simple native dialog 
there's the cross platform dialog, and PageRanges attributes too.

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

PR Comment: https://git.openjdk.org/jdk/pull/11266#issuecomment-3247397993

Reply via email to