Sunday, May 28, 2006

 

Working with Heights and Widths

One of the frustrations of InDesign's object model is that you can't work directly with the height and width of most items (tables are an exception). PageItems, in all their flavors, come with geometricBounds (and visibleBounds, but I've seldom been moved to use that property).

Often, when working with geometry, you want to know the height or width of an object, so you'll often find yourself doing something like:
myBds = myPI.geometricBounds;
myHeight = myBds[2] - myBds[0];
where myPI is a reference to some PageItem.
Well, there's more than one problem here:
  1. The height of an object ought to take into consideration its rotation. Geometric bounds gives you the coordinates (top, left, bottom, right -- don't forget that bottom is lower on the page and therefore has a larger y value because of the way that InDesign's coordinate system works) of the bounding box, so the height returned here is the height consumed by the item's current position on the page and not its real height.
  2. It takes up two lines of code (more if we solve the rotation problem) when really all you wanted to do was:
    myHeight = myPI.height;

I confess that I don't know how to let you just write this very simple statement, but I can very easily get you a whole lot closer. Just add this method definition to your script:
Object.prototype.height = function() {
  var bds = this.geometricBounds;
  return bds[2] - bds[0];
}
and you can now get the height by simply writing:
myHeight = myPI.height();
While remembering to include the parentheses is a tad irksome, we can put to use the fact that this is a call to a method.
  1. If we want to solve the rotation problem, we can do so in the method, so the calling code's purpose remains clear and easy to read.
  2. We can extend the method to accept a parameter which would set rather than get the height.
Another confession: in all the work I've done, I don't think I've ever cared about the possibility that a page item is rotated when I've needed its height (or width). That's largely because in my own work, I've seldom used rotation and in those cases where I have, I have usually finished processing the items with my scripts before I do the rotation.

However, setting the height (or width) is something that has come up fairly often, and I've usually done that with code that clutters up my mainline scripts, making them harder to read when I need to come back to them.

It is perhaps worth a moment or two to discuss the merits of having a single height method (which returns the height if no argument is provided, but which sets the height if the first argument is a number). Perhaps having two methods: getHeight() and setHeight(ht) would be a better solution. I think this is a personal choice. In my case, I'd prefer to have just the single method. So, that's how I'll spend this Sunday morning of a holiday weekend, writing the methods height(ht) and width(wd) to return the appropriate values if the argument is missing, but to set them if present.

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?