GEOMETRIC COORDINATES

If you have worked with any scripts for InDesign, you are more than aware that the location and size of a page item is defined in terms of its geometric coordinates within the two-dimensional page space. This is often described as two points defining its top left and bottom right coordinates. Each point is a coordinate representing its horizontal and vertical location in reference to a given origin. The coordinate pair is often represented by the variables x (for horizontal) and y (for vertical). This may be represented by two lists (or arrays) (topLeftX, topLeftY) and (bottomRightX, bottomRightY). When represented as geometric bounds in a script this is written as a single list (or array) of the coordinate pairs in the order {topY, leftX, bottomY, rightX} or {y0, x0, y1, x1}.

What you may not be aware of is that InDesign handles multiple coordinate systems. How the item displays depends on the orientation of the item and the acting coordinate system.

Suppose you have a script that creates a page item and then later in the script needs to change the width of that item. There are several ways that this can be done. The simplest way to to change the geometric bounds of the item. The following example script demonstrates:

   tell application "Adobe InDesign CC 2015"
	set measurement unit of script preferences to points
	tell document 1
	   set rectRef to make rectangle with properties {geometric bounds:{30, 50, 230, 250}, fill color:"Black", fill tint:30}
	end tell
	copy geometric bounds of rectRef to {y0, x0, y1, x1}
	--add 100 to horizontal coordinate
	set newBounds to {y0, x0, y1, x1 + 100}
	--set the geometric bounds of the rectangle to the new geometry
	set geometric bounds of rectRef to newBounds
	--just for testing, calculate width of the rectangle
	copy geometric bounds of rectRef to {y0, x0, y1, x1}
	set rWid to x1 - x0
       rWid
   end tell 

Should the page item be at any angle other than zero, however, the result of the script may not be as expected. Change the property statement that creates the rectangle to in the above script example to include a rotation angle.

   tell document 1
      set rectRef to make rectangle with properties {geometric bounds:{30, 50, 230, 250}, fill color:"Black", fill tint:30, rotation angle:30}
   end tell

When you run the modified script, you will see the problem. Your page no longer has a rectangle, and the distance between horizontal coordinates (x1 – x0) is not as expected.

If savvy on calculating geometric cartesian coordinates, you could calculate the new x1 coordinate such that the distance between x0 and x1 are as needed. But there is an easier way.

INTRODUCING RESIZE

Resize is an interesting InDesign scripting method. It can be used to resize just about any object in InDesign including a page. The problem with resize is that it is very powerful, and with power comes complexity. Take a look at its entry in the Dictionary for AppleScript Editor. (Select Open Dictionary from AppleScript Editor’s File menu, and choose your version of InDesign from the applications listed. When the dictionary opens, enter resize in the search window.)

The entry starts with resize v: Resize the page item. So far, so good. Reading through the entries for in any, from any, by, and values can cause a major brain freeze. What’s all this? Let’s take it little by little.

To start with there are four properties required for resize:

  1. in (any) – the bounding box to resize
    can accept pasteboard coordinates, parent coordinates, inner coordinates, page coordinates, spread coordinates, outer stroke bounds, geometric path bounds or a list of any of the previous
  2. from (any) – the transform origin
    accepts an anchor point, a series of coordinates, outer stroke bounds, or geometric path bounds.
  3. by – the method to resize by
    adding current dimensions to, multiplying current dimensions by, replacing current dimensions with, reshaping area to ratio, reshaping border to ratio
  4. values (any) – Width and height values, optionally with coordinate space
    Legal values to use change with the method used for resizing. We will look at some examples below.

FROM (TRANSFORM ORIGIN)

This can be any point within geometric space that the transformation for the object will be calculated from. The following exercise should help to understand this concept.

Enter the Transform from Anchor script below in Script Editor. Notice that the transformation values {100, 0} list horizontal before vertical.

Transform from Anchor

   tell application "Adobe InDesign CC 2015"
	set measurement unit of script preferences to points
	tell document 1
		set rectRef to make rectangle with properties {geometric bounds:{30, 50, 230, 250}, fill color:"Black", fill tint:30}
	end tell
        --delay allows ability to see original rectangle before transformation
	delay 2
	--later when rectangle is to be resized
	resize rectRef in inner coordinates from center anchor by adding current dimensions to values {100, 0}
	--for testing
	copy geometric bounds of rectRef to {y0, x0, y1, x1}
	set rWid to x1 - x0
   end tell 

When you run the script pay attention to how the rectangle is resized. Notice that both the original x0 and x1 points were changed to resize the rectangle from center.

Change the resize statement to use the top left anchor. The statement will read as follows.

   resize rectRef in inner coordinates from top left anchor by adding current dimensions to values {100, 0}

Run the script again. Notice that only the right horizontal coordinate changes to effect the resize.

From this it is easy to see how the anchor point can make a big difference in how an object is resized. But what about an object that is rotated? To see how resize works with a rotated object, modify the script above to read as follows. Note: You may need to change the fill color for the blueRect to another color that is available in your document.

   tell application "Adobe InDesign CC 2015"
      set measurement unit of script preferences to points
      tell document 1
	 set rectRef to make rectangle with properties {geometric bounds:{30, 150, 230, 350}, fill color:"Black", fill tint:30, rotation angle:30}
	 set blueRect to make rectangle with properties {geometric bounds:{30, 150, 330, 450}, fill color:"Proc Cyan", fill tint:30}
      end tell
      --delay allows ability to see original rectangle before transformation
      delay 2
      --later when rectangle is to be resized
      resize rectRef in inner coordinates from top left anchor by adding current dimensions to values {100, 0}
   end tell

After running the script, manually rotate the blue rectangle to verify that the new dimension for the distance between the horizontal coordinates of the black rectangle is as anticipated.

Geometric Bounds

If the script then uses the geometric bounds of the rotated item to create another rectangle, we can see how the bounds now reflect the item’s coordinates in page space. Change the original script to read as follows:

   tell application "Adobe InDesign CC 2015"
	set measurement unit of script preferences to points
	tell document 1
	   set rectRef to make rectangle with properties {geometric bounds:{130, 100, 330, 350}, fill color:"Black", fill tint:30, rotation angle:30}
	   --delay allows ability to see original rectangle before transformation
	   delay 2
	   --later when rectangle is to be resized
	   resize rectRef in inner coordinates from center anchor by adding current dimensions to values {100, 0}
	   --for testing
	   set gBounds to geometric bounds of rectRef
	   set newRect to make rectangle with properties {geometric bounds:gBounds, stroke weight:2, stroke color:"Black", fill color:"None"}
	end tell
   end tell
   gBounds 

As you can see when you run the script, the new rectangle touches each of the geometric bounds coordinates, but does not resemble the original page item. This is the bounding box for the rectangle within its parent coordinate space.

What you need to know is that the bounding box of a page item provides a number of distinct bounding boxes depending on the coordinate space involved.

IN (COORDINATE SPACES)

The page item, itself, has its own coordinate space as does each of its parent items in InDesign’s hierarchy. 

Inner Coordinates
The coordinate space in which the object itself was created.

Parent Coordinates
The coordinate space of the parent of the object. Any transformations applied to the parent affect the parent coordinates; for example, rotating the parent object changes the angle of the horizontal and vertical axes of this coordinate space. In this case, the parent object refers to the group or page item containing the object. If the parent of the object is a page or spread, parent coordinates are the same as spread coordinates.

Spread Coordinates
The coordinate space of the spread. The origin of this space is at the center of the spread, and does not correspond to the rulers you see in the user interface.

Pasteboard Coordinates
The coordinate space of the entire InDesign document. This coordinate space extends behind all spreads in a document. It does not correspond to InDesign’s rulers or zero point, nor does it have anything to do with the pasteboard area you can see around pages in the InDesign user interface.

Depending on the coordinate space involved, the bounding box for the page item reflects its orientation and transformation state.

BY (METHOD TO USE FOR RESIZE)

In our example scripts above, we use by adding current dimensions to for our transformation. Before we leave the subject, you may want to experiment with other methods: by multiplying current dimensions by, by replacing current dimensions with, or reshaping area to ratio. Let’s look at a few examples:

Multiplying Current Dimensions

   tell application "Adobe InDesign CC 2015"
      set measurement unit of script preferences to points
      tell document 1
	 set rectRef to make rectangle with properties {geometric bounds:{30, 50, 230, 250}, fill color:"Black", fill tint:30, rotation angle:30}
	 delay 2
	 resize rectRef in inner coordinates from center anchor by multiplying current dimensions by values {1.5, 1}
      end tell
   end tell 

Reshaping Area to Ratio

Replace the resize statement above with the following and test:

   resize rectRef in inner coordinates from center anchor by reshaping area to ratio values {3, 4}

Similar to reshaping area to ratio is reshaping border to ratio. This considers the border of the page item when performing the resize; similar to visible bounds.

Values (any)

In our examples we used real numbers for the values and ignored coordinate space. For the optional values, we suggest that you do some experimenting on your own.

Bounds of Rotated Item

Once a rotated page item is resized, your script may need to know the bounds coordinates for the item. The best way to do this is to get the entire path of its path.

   tell application "Adobe InDesign CC 2015"
	set selList to selection
	set selItem to item 1 of selList
	set pointList to entire path of path 1 of selItem
   end tell 
   pointList

This returns a list of four coordinate pairs in the order of top left, bottom left, bottom right, and top right as {x, y} values.

ONWARD AND UPWARD

Coordinate systems become an even more interesting subject when it comes to transformations where more than one method is involved. We will look at some of these in next week’s post. Until then, do some experimenting with resize. You will find it something your scripts will use quite often.