 import flash.display.DisplayObject;
 import flash.display.IBitmapDrawable;
 import flash.geom.Matrix;
+import flash.geom.Point;
 import flash.geom.Rectangle;
 import flash.utils.ByteArray;
 

        bmd.draw(src, m, null, null, null, true);
        return bmd;
    }
}
}
        return new XML(bytes.readUTFBytes(bytes.length));
    }

    /**
     * Extends src's border pixels by the given amount.
     * (We do this to textures in an atlas in order to prevent artifacts that come from
     * the GPU sampling just beyond a texture's bounds.)
     */
    public static function padBitmapBorder (src :IBitmapDrawable, paddingSize :int) :BitmapData {
        var srcBounds :Rectangle = getBitmapDrawableBounds(src);
        var w :int = Math.ceil(srcBounds.width);
        var h :int = Math.ceil(srcBounds.height);

        var bmd :BitmapData = new BitmapData(w + (paddingSize * 2), h + (paddingSize * 2), true, 0x00);

        // draw the original bitmap
        var m :Matrix = new Matrix();
        m.translate(-srcBounds.x + paddingSize, -srcBounds.y + paddingSize);
        bmd.draw(src, m, null, null, null, /*smoothing=*/false);

        var srcRect :Rectangle = new Rectangle();
        var dst :Point = new Point();
        var yy :int;
        var xx :int;

        // copy top row
        srcRect.x = paddingSize;
        srcRect.y = paddingSize;
        srcRect.width = w;
        srcRect.height = 1;
        dst.x = paddingSize;
        for (yy = 0; yy < paddingSize; ++yy) {
            dst.y = yy;
            bmd.copyPixels(bmd, srcRect, dst);
        }

        // copy bottom row
        srcRect.x = paddingSize;
        srcRect.y = h + paddingSize - 1;
        srcRect.width = w;
        srcRect.height = 1;
        dst.x = paddingSize;
        for (yy = 0; yy < paddingSize; ++yy) {
            dst.y = h + paddingSize + yy;
            bmd.copyPixels(bmd, srcRect, dst);
        }

        // copy left column
        srcRect.x = paddingSize;
        srcRect.y = paddingSize;
        srcRect.width = 1;
        srcRect.height = h;
        dst.y = paddingSize;
        for (xx = 0; xx < paddingSize; ++xx) {
            dst.x = xx;
            bmd.copyPixels(bmd, srcRect, dst);
        }

        // copy right column
        srcRect.x = w + paddingSize - 1;
        srcRect.y = paddingSize;
        srcRect.width = 1;
        srcRect.height = h;
        dst.y = paddingSize;
        for (xx = 0; xx < paddingSize; ++xx) {
            dst.x = w + paddingSize + xx;
            bmd.copyPixels(bmd, srcRect, dst);
        }

        return bmd;
    }

    public static function renderToBitmapData (src :IBitmapDrawable, w :int, h :int,
        scale :Number = 1, multipassScaleThreshold :Number = 0.5) :BitmapData {

        var bounds :Rectangle = getBitmapDrawableBounds(src);

        if (scale != 1 && !(src is BitmapData)) {
            // for down or up-scaling, render at normal size first, then scale to get the
            // benefit of bitmap smoothing. BitmapData.draw smoothing only works
            // when the source is itself a BitmapData object.
            src = renderToBitmapData(src, Math.ceil(bounds.width), Math.ceil(bounds.height), 1);
            bounds = getBitmapDrawableBounds(src);
        }

        // Don't downscale by more than 50% at a time - this causes Flash's
