forked from: ScalingBitmapFill 速度比較

by zahir forked from ScalingBitmapFill 速度比較 (diff: 12)
FP9版は逐一再計算してるのでFP10版も再計算するようにしてみた。
最適化をする前はFP10 APIは660ms でした。今は 200ms
3倍速くなった!

自分の結果
FP9 API :: 158ms
FP10 API :: 199ms
drawGraphicsData :: 123ms
copyForm :: 101ms
♥0 | Line 299 | Modified 2010-09-18 08:15:12 | MIT License
play

ActionScript3 source code

/**
 * Copyright zahir ( http://wonderfl.net/user/zahir )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4epR
 */

// forked from zahir's ScalingBitmapFill 速度比較
// FP9版は逐一再計算してるのでFP10版も再計算するようにしてみた。
// 最適化をする前はFP10 APIは660ms でした。今は 200ms
// 3倍速くなった!
/*
自分の結果
FP9 API :: 158ms
FP10 API :: 199ms
drawGraphicsData :: 123ms
copyForm :: 101ms
*/
package{
    import flash.display.Bitmap;
    import flash.display.IGraphicsData;
    import flash.display.Loader;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import flash.text.TextField;
    import flash.utils.getTimer;
    
    [SWF(width="465", height="465", backgroundColor="0xFFFFFF")]

    public class ScalingBitmapFill_test extends Sprite{
        private var t:TextField;
        private var l:Loader;
        
        private var sbf9:ScalingBitmapFill_9;
        private var sbf10:ScalingBitmapFill_10;
        private var v:Vector.<IGraphicsData>;
        private var s:Shape;
        
        public function ScalingBitmapFill_test(){
            addChild( (t = new TextField()) );
            t.width = t.height = 465;
            
            s = new Shape();
            
            l = new Loader();
            l.contentLoaderInfo.addEventListener(Event.COMPLETE, onComp);
             l.load( new URLRequest("http://zahir.coresv.com/wonderfl/img/scalingBitmapTest.png"), new LoaderContext(true) );
        }
        private function onComp(e:Event):void{
            l.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComp);
            
            var bmp:Bitmap = l.content as Bitmap;
            sbf9 = new ScalingBitmapFill_9(bmp.bitmapData , 100,100, 40, 40, 40, 40 );
            sbf10 = new ScalingBitmapFill_10(bmp.bitmapData , 100,100, 40, 40, 40, 40 );
            v = sbf10.getGraphicData();
            
            excute();
            
            stage.addEventListener(MouseEvent.CLICK, click);
        }
        private function click(e:MouseEvent):void{
            t.text = "";
            excute();
        }
        private function excute():void{
            var len:int = 10000;
            var i:int = 0;
            var time:int = getTimer();
            
            sbf10.draw( graphics );
            
            // 9 API 
            time = getTimer();
            for(i=0; i<len; i++){
                s.graphics.clear();
                sbf9.draw( s.graphics );
            }
            t.appendText( "FP9 API :: " + ( getTimer() - time) + "ms\n\n" );
            
            // 10 API
            time = getTimer();
            for(i=0; i<len; i++){
                s.graphics.clear();
                sbf10.draw( s.graphics );
            }
            t.appendText( "FP10 API :: " + ( getTimer() - time) + "ms\n\n" );
            
            // 10 drawGraphicsData
            time = getTimer();
            for(i=0; i<len; i++){
                s.graphics.clear();
                s.graphics.drawGraphicsData( v );
            }
            t.appendText( "drawGraphicsData :: " + ( getTimer() - time) + "ms\n\n" );
            
            // 10 copyForm
            time = getTimer();
            for(i=0; i<len; i++){
                s.graphics.clear();
                s.graphics.copyFrom( graphics );
            }
            t.appendText( "copyForm :: " + ( getTimer() - time) + "ms\n\n" );
            
            s.graphics.clear();
            graphics.clear();
        }
        
    }
}

import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.GraphicsBitmapFill;
import flash.display.GraphicsPath;
import flash.display.IGraphicsData;
import flash.geom.Matrix;
import flash.display.GraphicsEndFill;
import flash.display.GraphicsSolidFill;
import __AS3__.vec.Vector;

class AbstScalingBitmapFill
{
    protected var _bitmapData:BitmapData;
    private var _smooth:Boolean;
    
    private var _left:Number;
    private var _top:Number;
    private var _right:Number;
    private var _bottom:Number;
    
    private var _width:Number;
    private var _height:Number;
    private var _innerWidth:Number;
    private var _innerHeight:Number;
    
    protected var v:Vector.<IGraphicsData>;
    
    protected var flg:Boolean = false;
    
    public function AbstScalingBitmapFill(
                                        bitmapData:BitmapData, 
                                        width:int, height:int,
                                        left:int = 0, top:int = 0, right:int = 0, bottom:int = 0,
                                        smooth:Boolean = false) {
        v = new Vector.<IGraphicsData>;
        setData( bitmapData, width, height, left, top, right, bottom, smooth);
    }
    
    public function setData(
                                        bitmapData:BitmapData, 
                                        width:int, height:int,
                                        left:int = 0, top:int = 0, right:int = 0, bottom:int = 0,
                                        smooth:Boolean = false):void{
        this.bitmapData = bitmapData;
        this.width = width;
        this.height = height;
        this.left = left;
        this.top = top;
        this.right = right;
        this.bottom = bottom;
        this.smooth = smooth;
    }
    
    public function draw( graphics:Graphics ):Graphics{
        return null;
    }
    
    
    public function set bitmapData(value:BitmapData):void {
        _bitmapData = value.clone();
        flg = false;
    }
    
    public function get left():Number { return _left; }
    public function set left(value:Number):void 
    {
        if (value == _left) return;
        value = (value < 0) ? 0 : value;
        _left = value;
        flg = false;
    }
    
    public function get top():Number { return _top; }
    public function set top(value:Number):void 
    {
        if (value == _top) return;
        value = (value < 0) ? 0 : value;
        _top = value;
        flg = false;
    }
    
    public function get right():Number { return _right; }
    public function set right(value:Number):void 
    {
        if (value == _right) return;
        value = (value < 0) ? 0 : value;
        _right = value;
        flg = false;
    }
    
    public function get bottom():Number { return _bottom; }
    public function set bottom(value:Number):void 
    {
        if (value == _bottom) return;
        value = (value < 0) ? 0 : value;
        _bottom = value;
        flg = false;
    }
    
    public function get width():Number { return _width; }
    public function set width(value:Number):void 
    {
        if (value == _width) return;
        value = (value < 0) ? 0 : value;
        _width = value;
        flg = false;
    }
    
    public function get height():Number { return _height; }
    public function set height(value:Number):void 
    {
        if (value == _height) return;
        value = (value < 0) ? 0 : value;
        _height = value;
        flg = false;
    }
    
    public function get smooth():Boolean { return _smooth; }
    public function set smooth(value:Boolean):void 
    {
        if (value == _smooth) return;
        _smooth = value;
        flg = false;
    }
    
    public function get innerWidth():Number { return width - (left + top); }
    public function get innerHeight():Number { return height - (top + bottom); }
    
    protected function box( dx:int = 0, dy:int = 0, scaleX:Number = 1, scaleY:Number = 1):Matrix{
        var m:Matrix = new Matrix();
        m.scale( scaleX, scaleY );
        m.translate( dx, dy );
        return m;
    }
}

class ScalingBitmapFill_9 extends AbstScalingBitmapFill{
    private var g:Graphics;
    public function ScalingBitmapFill_9(
                                        bitmapData:BitmapData, 
                                        width:int, height:int,
                                        left:int = 0, top:int = 0, right:int = 0, bottom:int = 0,
                                        smooth:Boolean = false) {
        super(bitmapData, width, height, left, top, right, bottom, smooth);
    }
    override public function draw(graphics:Graphics):Graphics{
        g = graphics;
        
        var minWidth:Number = left + right;
        var minHeight:Number = top + bottom;
        
        var innerWidth:Number = this.innerWidth, innerHeight:Number = this.innerHeight;
        if (minWidth >= width) width = minWidth, innerWidth = 0;
        if (minHeight >= height) height = minHeight, innerHeight = 0;
        
        var r:int = width - right;
        var b:int = height - bottom;
        var sx:Number = innerWidth / (_bitmapData.width - minWidth);
        var sy:Number = innerHeight / (_bitmapData.height - minHeight);
        
        var offsetX1:Number = left - left * sx;
        var offsetX2:Number = width % _bitmapData.width;
        var offsetY1:Number = top - top * sy;
        var offsetY2:Number = height % _bitmapData.height;
        
        // top
        drawRect(0,0, left,top );
        drawRect(left,0, innerWidth,top, box(offsetX1,0,sx) );
        drawRect(r,0, right,top, box(offsetX2) );
        
        // middle
        drawRect(0,top, left, innerHeight, box(0,offsetY1, 1,sy) );
        drawRect(left,top, innerWidth, innerHeight, box( offsetX1, offsetY1, sx,sy ) );
        drawRect(r,top, right, innerHeight, box( offsetX2,offsetY1, 1,sy ) );
        
        // bottom
        drawRect(0, b, left,top , box( 0, offsetY2 ));
        drawRect(left,b, innerWidth,top, box( offsetX1, offsetY2, sx ) );
        drawRect(r,b, right,top, box( offsetX2, offsetY2 ) );
        
        return graphics;
    }
    private function drawRect(x:Number, y:Number, width:Number, height:Number, matrix:Matrix = null):void{
        g.beginBitmapFill( _bitmapData, matrix, true, smooth );
        g.drawRect( x, y, width,height );
        g.endFill();
    }
}
class ScalingBitmapFill_10 extends AbstScalingBitmapFill{
    private var command:Vector.<int> = Vector.<int>([1, 2, 2, 2, 2]);
    private var paths:Vector.<GraphicsPath>;
    private var fills:Vector.<GraphicsBitmapFill>;
    
    public function ScalingBitmapFill_10(
                                        bitmapData:BitmapData, 
                                        width:int, height:int,
                                        left:int = 0, top:int = 0, right:int = 0, bottom:int = 0,
                                        smooth:Boolean = false) {
        paths = new Vector.<GraphicsPath>();
        fills = new Vector.<GraphicsBitmapFill>();
        
        for(var i:int = 0; i<9; i++){
            paths[i] = new GraphicsPath(command, new Vector.<Number>(10));
            fills[i] = new GraphicsBitmapFill(bitmapData, null, true, smooth);
        }
        
        super(bitmapData, width, height, left, top, right, bottom, smooth);
    }
    
    public function getGraphicData():Vector.<IGraphicsData>{
        return v;
    }
    
    override public function draw(graphics:Graphics):Graphics
    {
        //if (flg == false) 
            calc();
        graphics.drawGraphicsData( v );
        return graphics;
    }
    
    private function calc():void 
    {
        var minWidth:Number = left + right;
        var minHeight:Number = top + bottom;
        
        var innerWidth:Number = this.innerWidth, innerHeight:Number = this.innerHeight;
        if (minWidth >= width) width = minWidth, innerWidth = 0;
        if (minHeight >= height) height = minHeight, innerHeight = 0;
        
        var r:int = width - right;
        var b:int = height - bottom;
        var sx:Number = innerWidth / (_bitmapData.width - minWidth);
        var sy:Number = innerHeight / (_bitmapData.height - minHeight);
        
        var offsetX1:Number = left - left * sx;
        var offsetX2:Number = width % _bitmapData.width;
        var offsetY1:Number = top - top * sy;
        var offsetY2:Number = height % _bitmapData.height;
        
        v.length = 0;
        
        // LT
        v.push( setFill( fills[0] ), drawRect(paths[0], 0, 0, left, top));
        // T
        v.push( setFill( fills[1], box( offsetX1,0,sx)), drawRect(paths[1], left,0, innerWidth,top));
        // RT
        v.push( setFill( fills[2], box(offsetX2)), drawRect(paths[2], r,0, right,top));
        
        // L
        v.push( setFill( fills[3], box( 0,offsetY1, 1,sy )), drawRect(paths[3], 0,top, left, innerHeight));
        // Center
        v.push( setFill( fills[4], box( offsetX1, offsetY1, sx,sy )), drawRect(paths[4], left,top, innerWidth, innerHeight));
        // right
        v.push( setFill( fills[5], box( offsetX2,offsetY1, 1,sy )), drawRect(paths[5], r,top, right, innerHeight));
        
        // LB
        v.push( setFill( fills[6], box( 0, offsetY2 )), drawRect(paths[6], 0, b, left,top) );
        // B
        v.push( setFill( fills[7], box( offsetX1, offsetY2, sx )), drawRect(paths[7], left,b, innerWidth,top) );
        // RB
        v.push( setFill( fills[8], box( offsetX2, offsetY2 )), drawRect(paths[8], r,b, right,top) );
        
        flg = true;
    }
    
    private function drawRect( path:GraphicsPath, x:Number, y:Number, width:Number, height:Number):GraphicsPath {
        path.data[0] = path.data[6] = path.data[8] = x;
        path.data[1] = path.data[3] = path.data[9] = y;
        path.data[2] = path.data[4] = x + width;
        path.data[5] = path.data[7] = y + height;
        
        return path;
    }
    private function setFill( fill:GraphicsBitmapFill, matrix:Matrix = null):GraphicsBitmapFill{
        fill.bitmapData = _bitmapData;
        fill.matrix = matrix;
        fill.smooth = smooth;
        return fill;
    }
}