Dealing with Rotated Spread Views in a Script
March 10, 2010 | Snippets | en | fr
“Rotate the spread view” is a nice feature introduced in InDesign CS4. It will prevent you from getting a stiff neck when working on rotated contents such as book spine or landscape tables. Great! Now the bad news: it seems that the DOM does not provide any means to check a rotated spread by scripting. No property, no access method. So what?
And worse, the dark side of rotated spread/page environment is that it significantly impacts the geometry handled by your script. As described in this InDesign Scripting Forum thread you can no longer trust the information provided by Page.bounds
, or PageItem.geometricBounds
. You may also have to deal with swapped measurement units, misrepresented object rotation angles, or misleading zero point coordinates.
As a result, a number of existing scripts will have a strange behavior while running in a rotated context —I let you try with Equalizer...
Rotated View Calculation Script
The least we can do for now is to extend the DOM to provide a method which returns the rotation angle of a Spread
/ MasterSpread
/ Page
. Harbs offers a clean solution, provided we temporarily allow the script to ‘hit’ the document viewPreferences
and zeroPoint
in order to process reliable page bounds. Here is another approach using the power of the resolve
method (see also “Work Around the Width/Height Gap” ). The trick is very basic: we convert the coordinates of an horizontal vector of the target Spread into the Pasteboard coordinate space, then we calculate the corresponding angle. This method relies on the invariance of the Pasteboard coordinate space:
Now to the script:
Spread.prototype.getRotationAngle = MasterSpread.prototype.getRotationAngle = function() { if( !('resolve' in this) ) return 0; // CS3 compat. var solver = function(pt) { return this.resolve(pt, CoordinateSpaces.PASTEBOARD_COORDINATES)[0]; }; var o = solver.call(this, AnchorPoint.CENTER_ANCHOR); var m = solver.call(this, AnchorPoint.RIGHT_CENTER_ANCHOR); return ( m[0] != o[0] )? ( ( m[0] > o[0] )? 0 : 180 ): ( ( m[1] > o[1] )? -90 : 90 ); } Page.prototype.getRotationAngle = function() { return this.parent.getRotationAngle(); } // sample code //---------------------------- var myPage = app.activeWindow.activePage; alert( "Active Page Angle: " + myPage.getRotationAngle() );
You can apply the .getRotationAngle()
method on any Spread
, MasterSpread
, or Page
used in your script. It returns the respective rotation angle in degrees: 0 (no rotation), +90 (counter clock wise rotation), -90 (clock wise rotation), or 180 (turned).