Ok, last weeks mix was a great distraction, but my attention is now back on AS3 programming. In particular a very nifty feature of Flash, that is quite tricky to make work.

DisplayObject.scrollRect is a slippery eel of a construct. A scrollRect provides a great way to make sprites, movieclips and bitmaps scroll really efficiently but finding the full height or width of the unmasked content is a total pain in the neck.

Jon Williams posted an interesting idea, using transform.pixelBounds. Which actually gets most of the way to a solution, but it all goes horribly wrong when the any of the parent objects are scaled and/or rotated. It also finds weird values when the object is off the display list (always x5 the actual value).

But as Jon's idea seems to be the only one on the table, and I don't want to step back to regular masks, here's a couple working solutions:

A simple, hacky approach could be: remove the object from the display list, measure it, then put it back. As Jon pointed out in his post, the values are five times larger than expected, so we'd have to divide the result by five. The problem I have with is approach is, it will cause the object to fire a bunch of events we really don't want it to.

So, we're forced to go the long way round with something like this:

1. Save the objects transformation matrix in a local var
2. Get the objects concatenated transformation matrix and invert it
3. Set the objects transform to the inverted matrix
4. Measure the objects pixel bounds
5. Restore the original transformation matrix

Which could look something like...

/**
 * This function works like DisplayObject.getBounds(), except it will find the full
 * bounds of any display object, even after its scrollRect has been set.
 *
 * @param displayObject - a display object that may have a scrollRect applied
 * @return a rectangle describing the dimensions of the unmasked content
 */
public function getFullBounds ( displayObject:DisplayObject ) :Rectangle
{
	var bounds:Rectangle, transform:Transform,
	                    toGlobalMatrix:Matrix, currentMatrix:Matrix;
 
	transform = displayObject.transform;
	currentMatrix = transform.matrix;
	toGlobalMatrix = transform.concatenatedMatrix;
	toGlobalMatrix.invert();
	transform.matrix = toGlobalMatrix;
 
	bounds = transform.pixelBounds.clone();
 
	transform.matrix = currentMatrix;
 
	return bounds;
}

Phew, all that to get the height of the masked content. You have to wonder, if it's really worth it...