mozilla / pdf.js

PDF Reader in JavaScript
https://mozilla.github.io/pdf.js/
Apache License 2.0
48.51k stars 9.98k forks source link

missing support for "viewrect" parameter in URL fragment identifiers #10772

Open markmatney opened 5 years ago

markmatney commented 5 years ago

According to Parameters for Opening PDF Files (version 9.0) (and referenced in RFC 8118):

viewrect=left,top,wd,ht

Sets the view rectangle using float or integer values in a coordinate system where 0,0 represents the top left corner of the visible page, regardless of document rotation.

It appears that the viewrect parameter in PDF URL fragment identifiers is currently unsupported. To verify, I tested as follows:


Configuration:

Steps to reproduce the problem:

  1. Check out the repository, run npm install and gulp server, then navigate the viewer to a PDF with page dimensions of 8.5" x 11" (e.g. http://localhost:8888/web/viewer.html?file=%2Ftest%2Fpdfs%2Ftracemonkey.pdf).
  2. Append #page=1&viewrect=72,72,288,432 to the URL in the address bar, and reload the page.

What is the expected behavior?

The viewer should zoom into a (roughly) 4" x 6" rectangle that is offset 1" from the top and 1" from the left edge of the page.

What went wrong?

The viewport was not transformed as expected because PDF JS does not support viewrect.


I also ran

$ git grep viewrect

which yielded 0 results, and did the following searches on GitHub, which both returned nothing:

AndrewMyint commented 4 years ago

Hi, I am new here, looking for an issue to fix, and I would like to fix this issue unless someone's already doing it. And I also read the documentation about viewRect, I am not quite sure, what does wd and ht is referring to. Can anybody enlighten me about that wd, and ht, please? Thanks in advance.

timvandermeij commented 4 years ago

Feel free to work on this. I think wd is "width" and ht is "height".

markmatney commented 4 years ago

Hi @AndrewMyint, I just wanted to point you to a couple issues related to this one, which document the erroneous behavior of the current implementation of the (erroneously-named) "zoom" parameter: https://github.com/mozilla/pdf.js/issues/10773 and https://github.com/mozilla/pdf.js/issues/2843.

AndrewMyint commented 4 years ago

Thank @markmatney I've been looking through pdf_link_service.js, and I am surprised that "zoom " parameter is handling Fit argument whereas it should be handled in "view" parameter according to documentation.

AndrewMyint commented 4 years ago

@markmatney If I am not wrong, all the value that provided as arguments such as (left, top, scale, Fit, ...) are being used in BaseViewer.scrollPageIntoView. And, there are a number of switch case (Fit, FitB, FitH,......) handling in scrollPageIntoView. And, one interesting case I found is FitR which I don't even see that FitR argument in documentation.

But it seems to me that "FitR" is producing the "viewrect" behavior if you append #zoom=FitR,72,72,288,432 to the URL address bar.

Can you confirm that is the expected behavior for viewrect, please? Thank you.

markmatney commented 4 years ago

Yes, I believe BaseViewer.scrollPageIntoView is the method that looks at all those arguments and then somehow transforms the viewport based on them.

I also recall seeing FitR when I initially looked into this. It was introduced into master at d30fac0 (Sep 4, 2011) along with the rest of the Fit* args, and is defined in the PDF Reference spec. I'm not sure why it was omitted from the "Parameters for Opening PDF Files" spec (or why there are even two separate specs, for that matter).

Anyway, I have a strong opinion that viewrect should be implemented differently than FitR. This is certainly debatable, but:

I would hope to see an implementation of viewrect where, unlike FitR, the resulting view does not depend on the dimensions of the user's web browser window. To see what I mean, go to https://mozilla.github.io/pdf.js/web/viewer.html#zoom=FitR,0,0,144,144. That URL fragment asks the viewer to show a roughly 2" x 2" square region (w x h, 1" ~ 72 px). Currently, if my browser is full-screen in a 1080 x 720 (3:2 ratio) display oriented landscape, then I am actually shown a 3" x 2" region. If I rotate my display 90 degrees and view the same rectangle in a full-screen browser, then I am shown a 2" x 3" region. This is because PDF.JS fills the rest of the available space, per the PDF Reference spec pp. 583:

[page /FitR left bottom right top]

Display the page designated by page, with its contents magnified just enough to fit the rectangle specified by the coordinates [...] entirely within the window [...] If the required horizontal and vertical magnification factors are different, use the smaller of the two [...]

"Parameters for Opening PDF Files" defines viewrect much more loosely (see the opening comment on this issue for the definition). I would like to see an implementation that displays the same region regardless of browser window size, so that anything outside of the specified region would be made out-of-focus ("grayed out" or "blacked-out"). Unless I'm missing something, such an implementation would still be spec-compliant.

markmatney commented 4 years ago

Reading over my comment, I just realized that the PDFjs implementation of FitR diverges from the PDF Reference spec. It interprets the rectangle as x,y,w,h when it should be interpreted as left,bottom,right,top.