7 Replies Latest reply on Jan 2, 2018 8:10 AM by efosGD

    Is there a way to read the user's Page Display Resolution preference setting from javascript?

    efosGD

      In order to ensure a predefined viewstate reaches the same location for any user, I need to check their display resolution, and modify the scrollposition value based on the resolution it was set with.  This is a thing I need to do thousands of times, and obviously we can't use bookmarks.

       

      Example:  At halfway down an 11" page at 96dpi, pageViewY == ~528;

      If the user has set their resolution to 110dpi, then it needs to be increased by 114%, or ~606.

       

      I have been through the JS API and can find no reference to this value.  I had tried using a script that would just set the viewstate to a given value, check the resulting position like so:

       

      var zeroState = eval(viewState.toSource());

      zeroState.pageViewZoom = 1;

      zeroState.pageViewZoomType = 0;

      zeroState.pageViewPageNum = 1;

      zeroState.pageViewY = 3000 ;

       

      viewState = eval(zeroState.toSource())

       

      var testState = eval(viewState.toSource());

       

      var n,diff;

      n = testState.pageViewPageNum-1;

      diff = 3000-(testState.pageViewY);

      if(n > 0){

           versionHeight = diff/n;

      }

       

      What happens in the console is that the resulting viewstate has its pagenumber increased (since 3000 exceeds the page height), and its pageViewY readjusted to the actual position.  Ex:  it will say page 3, yPos ~600  (3000 - 2 pages at ~1200 height)

       

      But when the function is executed the resulting viewstate has not been modified, and reports as being on page 1 at yPos 3000.  If I split the function up with a messy string of Timeouts, it works, but that's a kludge on a kludge.  If there's some way to just read the user's display resolution, then that's the way to go.

        • 1. Re: Is there a way to read the user's Page Display Resolution preference setting from javascript?
          try67 MVP & Adobe Community Professional

          I think this can be done using the Monitor object.

          For example, this code will return the color depth (ie, number of bits per pixel) for the primary monitor:

           

          var monitors = app.monitors.primary();

          console.println( "Color depth of primary monitor is " + monitors[0].colorDepth );

          • 2. Re: Is there a way to read the user's Page Display Resolution preference setting from javascript?
            Thom Parker Adobe Community Professional

            There's the "monitor.rect" and "monitor.workrect" properties that provide the screen size.  Then there are the "doc.innerAppWindowRect" and related rectangles that give the Acrobat and document rectangles in screen coordinates.  You can use this data along with the viewState properties to calculate the size of the document showing.

             

            These properties are not immediately available. The app.media object has to be activated first.

            1 person found this helpful
            • 3. Re: Is there a way to read the user's Page Display Resolution preference setting from javascript?
              efosGD Level 1

              Ah!

               

              AHHHHH!

               

              YES.  If you check out the post I googled up to figure out how to activate the media (doc.media, not app):

               

              https://acrobatusers.com/forum/javascript/thiswindowrect-properties-all-undefined/

               

              You may have some sense of how excited I am to be rid of this meddlesome issue once and for all, but you may never know the true extent of my relief...

               

               

              //Doc-level variable so we only have to check once as it's pretty unlikely to change.  "Mostly..." -Newt
              var userDPI = undefined;
              
              
              function _getDPI(doc){
              if(doc == undefined){ doc = this;}
              
              //get current view
              var refView = eval(doc.viewState.toSource());
              var n = refView.pageViewPageNum; //ref page to get width and pageWindowRect from.
              var pBox = doc.getPageBox("Bleed",n);
              //Determine page width in inches
              var pWidth = doc.getUserUnitSize(n)*((pBox [2]-pBox [0])/72);
              
              //If pageViewZoomType 2 is "fit width" and that's all we need.
              if(refView.pageViewZoomType != 2){
              //save current view to return to it so user won't notice pageViewZoomType change.
              var curView = eval(doc.viewState.toSource());
              //set control values to sample the zoom level at fitwidth on the target page.
              refView.pageViewPageNum= n;
              refView.pageViewX = 0;  //Ensure we don't somehow wind up on another page.  Though I suspect a pageViewX of > 0 is impossible on fit width...
              refView.pageViewY = 0;  //Ensure we don't somehow wind up on another page.
              refView.pageViewZoomType = 2;
              //update view to get new zoom
              doc.viewState = refView;
              //grab a copy to inspect
              refView = eval(viewState.toSource());
              //restore previous view
              doc.viewState = curView;
              }
              //initialize the media object to read pageWindowRect, because AcrobatJS...
              console.println(this.media);
              //compare pixel width of application page window area, the current zoom level, and the page width in inches to get user display DPI.  Round to clean up FP errors; but +/- 1 PPI isn't the end of the world.
              userDPI  = Math.round((doc.pageWindowRect[2] - doc.pageWindowRect[0])/refView.pageViewZoom/pWidth);
              
              
              console.println("\nUser DPI: "+userDPI );
              return userDPI;
              }
              

               

              Yikes, well that seems to have formatted poolry?  Let's see...

              • 4. Re: Is there a way to read the user's Page Display Resolution preference setting from javascript?
                Thom Parker Adobe Community Professional

                Just as I suggested. A helpful would be  appreciated

                 

                The code may work for most docs, but has some possible issues.  First, this is an interesting use of the undocumented function "getUserUnitSize()", I don't think it is necessary.   The block of code following this function, in the "if", doesn't seem to do anything. You can delete it. And why measure using the Bleed box? This box is rarely defined explicitly, and defaults to the Media Box, which may be out of sync with the user's view of the PDF on the screen. Where did you get this code? 

                • 5. Re: Is there a way to read the user's Page Display Resolution preference setting from javascript?
                  efosGD Level 1

                  https://forums.adobe.com/people/Thom+Parker  wrote

                   

                  Just as I suggested. A helpful would be  appreciated

                   

                  The code may work for most docs, but has some possible issues.  First, this is an interesting use of the undocumented function "getUserUnitSize()", I don't think it is necessary.   The block of code following this function, in the "if", doesn't seem to do anything. You can delete it. And why measure using the Bleed box? This box is rarely defined explicitly, and defaults to the Media Box, which may be out of sync with the user's view of the PDF on the screen. Where did you get this code? 

                  Oh, sorry, I must have clicked it twice!  Or the forum was messing up (it also wouldn't let me edit).

                   

                  Yeah, I don't know if getUserUnitSize, will matter.  I'll have to change it to see if it alters the resulting measurement of the pageBox; as the example in the docs for getUserUnitSize implied it might.

                   

                  (Edit: Though, in hindsight, I'm assuming 72dpi to begin with...  I should probably be trying to ascertain that; should it ever change, as that presumption seems more likely to cause trouble if it ever changes.)

                   

                  Bleed choice was arbitrary.  In all my tests over the years, it has correlated with the page width of our docs, as do the rest.  Just the first one that comes to mind.

                   

                  The code following the "if" does ALL the work, really.  Line 34 determines DPI by comparing page width to the pixel width of the page in the application, at the current zoom level, then sets the userDPI variable for reference by other functions.  The preceding code just gets the pagewidth and zoom level when set to "fill width."

                   

                  Code source:  I just bashed it together as I was mashing the helpful button on your post with, apparently, counter-productive zeal.

                  • 6. Re: Is there a way to read the user's Page Display Resolution preference setting from javascript?
                    Thom Parker Adobe Community Professional

                    The code inside the if block doesn't participate in any of the values used in the calculation on line 34. It saves the current view. Sets the view state to a modified version of the current view, then sets it back to the current view. Nothing has changed by the time the calculation takes place. 

                     

                    PDF page resolution is 72 PPI all the time for the JavaScript coordinate spaces.

                     

                    The Crop box is the size and orientation of the document as seen by the user on the screen. 

                    1 person found this helpful
                    • 7. Re: Is there a way to read the user's Page Display Resolution preference setting from javascript?
                      efosGD Level 1

                      "PDF page resolution is 72 PPI all the time for the JavaScript coordinate spaces."

                       

                      Ah, Excellent!  Thanks!  I will convert the hours I would have spent investigating that into a more detailed explanation, as my comments don't quite seem to capture it; one might even infer I'm not accustomed to including them at all!

                       

                      "The code inside the if block doesn't participate in any of the values used in the calculation on line 34. "

                       

                      The code inside the block sets the zoom level to whatever is appropriate to make the page fill the pageWindowRect, but just long enough to grab a copy of the viewState once so configured; it then reverts it so the user never notices the view change.   Setting pageViewZoomType to 2 ensures we have the zoom value we need to do the calc on 34.

                       

                      /***Note to those unfamiliar with doc.viewState: 

                      You can feed Acrobat any malformed, garbage-object as a viewState, and it will throw out what properties it doesn't understand, apply those that it does, and then update the rest as appropriate.  Some, like pageViewZoomType, will take precedence over others if there's a conflict.  That is being leveraged here, where pageViewZoomType 2 (fitWidth) will override any requested zoom.  It is extremely useful here because the zoom level necessary to fill the screen is exactly what we don't know.

                      ***/

                      Given that:

                      -UserDPI will always equal Page width (Pixels) / Page Width (inches).

                       

                      -Page width (Pixels) will always equal Page width (Screen) / zoom level.

                       

                      There is no simpler way, (that I'm aware of), to actually get Page width (Screen) or directly read it, so the IF-block ensures that Page width (Screen) == Screen width.

                       

                       

                      This modification only executes if pageViewZoomType != 2, because that is a guarantee that the page is presently zoomed to fill the width of the window.  If the user has this viewtype selected in the UI, but has manually zoomed the document with the scrollwheel, the UI will leave it selected, but the viewState will not report it as 2.  So if it's not at 2, then the page is not necessarily filling the pageWindowRect horizontally, thus our calculation on 34 will not know the actual page width on screen and the zoom level used to achieve it, thus probably not return the proper DPI value.

                       

                       

                      Breakdown of 34 for clarity:

                       

                      userDPI  = Math.round((doc.pageWindowRect[2] - doc.pageWindowRect[0])/refView.pageViewZoom/pWidth);

                       

                      UserDPI will always equal:  Page width (Pixels) / Page Width (inches).

                       

                      Page width (Pixels) will always equal:  Page size on screen / zoom level.

                       

                      This line determines both.

                       

                      Assuming and 8.5x11 page, with user setting at 110 dpi:

                       

                      pWidth == 8.5 (Inches)

                      &&

                      pageWindowRect == [222,126,1661,1040];

                       

                      Then:

                      var windowWidth = pageWindowRect[3]-pageWindowRect[0];  //1439.

                       

                      var pagePixelWidth = windowWidth/pageViewZoom;  (The current width of the page in pixels)

                      And therefore DPI == pagePixelWidth/pWidth;

                       

                      Applied to three viewState examples:

                       

                      ({ocgStates:[false, true, true, false, true, false, false, true, true, false, true, true, true, true], overViewMode:7, overViewPos:165, overViewX:0, overViewY:0, pageViewLayoutMode:2, pageViewPageNum:0, pageViewX:-252, pageViewY:183, pageViewZoom:1, pageViewZoomType:0})

                       

                      Zoom == 100%, no guarantee the page is filling the screen; This will lead it to assume the pagePixelWidth is 1439 (1439/1). 

                       

                      1439/8.5  = 160dpi.  Incorrect:  Page was smaller than screen width, DPI too high.

                       

                      ({ocgStates:[false, true, true, false, true, false, false, true, true, false, true, true, true, true], overViewMode:7, overViewPos:165, overViewX:0, overViewY:0, pageViewLayoutMode:2, pageViewPageNum:0, pageViewX:494, pageViewY:313, pageViewZoom:3, pageViewZoomType:0})

                       

                      Zoom == 300%, no guarantee the page is filling the screen; This will lead it to assume the pagePixelWidth is ~480 (1439/3). 

                       

                      480/8.5  = 56dpi.  Incorrect:  Page exceeded screen width, DPI too low.

                       

                      ({ocgStates:[false, true, true, false, true, false, false, true, true, false, true, true, true, true], overViewMode:7, overViewPos:165, overViewX:0, overViewY:0, pageViewLayoutMode:2, pageViewPageNum:0, pageViewX:0, pageViewY:0, pageViewZoom:1.5390167236328125, pageViewZoomType:2})

                       

                      Zoom == a horrible number, but the page is guaranteed to exactly fill the screen horizontally.  This will lead it to assume the pagePixelWidth is 935; and 935/8.5 == 110 dpi, the user's chosen page display DPI.