Skip to main content
Inspiring
December 28, 2017
Answered

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

  • December 28, 2017
  • 2 replies
  • 1925 views

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.

This topic has been closed for replies.
Correct answer efosGD

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...

2 replies

Thom Parker
Community Expert
Community Expert
December 28, 2017

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.

Thom Parker - Software Developer at PDFScriptingUse the Acrobat JavaScript Reference early and often
efosGDAuthorCorrect answer
Inspiring
December 29, 2017

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...

Thom Parker
Community Expert
Community Expert
December 29, 2017

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? 

Thom Parker - Software Developer at PDFScriptingUse the Acrobat JavaScript Reference early and often
try67
Community Expert
Community Expert
December 28, 2017

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 );