
Код AS3:
package engine.utils
{
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.filters.BitmapFilter;
import flash.geom.Rectangle;
/**
* Класс для определения границ DisplayObject
* @author pkulikov
*
*/
public class Bounds extends Rectangle
{
static private var instance:Bounds = new Bounds;
public var fx:Number;
public var fy:Number;
public function Bounds(x:Number=0, y:Number=0, width:Number=0, height:Number=0, fx:Number=0, fy:Number=0)
{
super(x, y, width, height);
this.fx = fx;
this.fy = fy;
}
/** Отдать реальные границы изображения с учетом всех вложенностей фильтров */
static public function getBounds(clip:DisplayObject, processFilters:Boolean):Bounds
{
var bounds:Rectangle = clip.getBounds(clip.parent);
bounds.x = Math.floor(bounds.x);
bounds.y = Math.floor(bounds.y);
bounds.height = Math.ceil(bounds.height);
bounds.width = Math.ceil(bounds.width);
var realBounds:Rectangle = new Rectangle(0, 0, bounds.width, bounds.height);
if (processFilters)
realBounds = getFiltersRect(clip, realBounds);
instance.fx = realBounds.x;
instance.fy = realBounds.y;
realBounds.offset(bounds.x, bounds.y);
instance.copyFrom(realBounds);
return instance;
}
static private function getFiltersRect (target:DisplayObject, realBounds:Rectangle):Rectangle
{
if (target is DisplayObjectContainer)
{
var container:DisplayObjectContainer = target as DisplayObjectContainer;
var len:int = container.numChildren;
for (var i:int = 0; i < len; ++i)
realBounds = realBounds.union(getFiltersRect(container.getChildAt(i), realBounds));
realBounds = iterateFilers(target, realBounds);
} else
{
realBounds = iterateFilers(target, realBounds);
}
return realBounds;
}
static private function iterateFilers (target:DisplayObject, realBounds:Rectangle):Rectangle
{
if (target.filters.length > 0)
{
var j:int = 0;
var clipFilters:Array = target.filters;
var clipFiltersLength:int = clipFilters.length;
while (j < clipFiltersLength)
{
realBounds = unionFilter(realBounds, target, clipFilters[j]);
++j;
}
}
return realBounds;
}
static private function unionFilter (realBounds:Rectangle, target:DisplayObject, filter:BitmapFilter):Rectangle
{
var scaleX:Number = 1;
var scaleY:Number = 1;
if (target.parent)
{
scaleX = target.parent.scaleX;
scaleY = target.parent.scaleY;
}
var tmpBData:BitmapData = new BitmapData(target.width * scaleX, target.height * scaleY, false);
var filterRect:Rectangle = tmpBData.generateFilterRect(tmpBData.rect, filter);
tmpBData.dispose();
return realBounds.union(filterRect);
}
}
}