In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Antialiased lines on bitmap

Get Adobe Flash player
by hortobagyi.tom 31 Oct 2014
    Embed
/**
 * Copyright hortobagyi.tom ( http://wonderfl.net/user/hortobagyi.tom )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hLYi
 */

package {
    import flash.text.TextField;
    import flash.geom.Matrix;
    import flash.display.Sprite;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.Shape;
    import flash.utils.getTimer;
    import flash.display.StageQuality;
        
    public class FlashTest extends Sprite
    {
        public var bmd:BitmapData;
        public var bm:Bitmap;
        
        public var line:Shape;
        
        public var w:int = 300;
        
        public var txt:TextField;

        private var coeff_1:Number = Math.PI / 4;
        private var coeff_2:Number;
        private var r:Number;
        private var angle:Number;
        private var absY:Number;
        
        public function FlashTest()
        {
            // write as3 code here..
            bmd = new BitmapData(w, w, true, 0x0);
            bm = new Bitmap(bmd, "auto", false);
            
            this.addChild(bm);
            
            txt = new TextField();
            this.addChild(txt)
            txt.width = 400;
            txt.y = w;
            txt.text = "debug";
            
            
            line = new Shape();
            line.graphics.beginFill(0x0, 0.2);
            line.graphics.drawRect(0, 0, 1, 1.0);
            line.graphics.endFill();
            
            var ms:int = getTimer();
            
            bmd.lock();
            for (var i:int = 0; i < 1000; i++) // benchmark
            {
               lineTo( Math.random() * w, Math.random() * w, Math.random() * w, Math.random() * w ); // drawWithQuality
               //efla( Math.random() * w, Math.random() * w, Math.random() * w, Math.random() * w, 0x33000000 ); // draw with setPixel32 - this is still faster
            }
            bmd.unlock();
            
            txt.text = (getTimer() - ms) + " ms";
        }
        /*
        public function atan2(y:Number,x:Number):Number
        {
            coeff_2 = 3 * coeff_1;
            absY = y;
            if (absY < 0) absY = -absY;                    //Math.abs
            if(x >= 0)
            {
                r= (x - absY) / (x + absY);
                angle = coeff_1 - coeff_1 * r;
            } else
            {
                r = (x + absY) / (absY - x);
                angle = coeff_2 - coeff_1 * r;
            }
            return y < 0 ? -angle : angle;
        }
        //*/
        
        public function lineTo(x0:Number, y0:Number, x1:Number, y1:Number):void
        {
           var ydiff:Number = y1 - y0, xdiff:Number = x1 - x0;
           
           var mtx:Matrix = new Matrix();
           mtx.scale(Math.sqrt(ydiff * ydiff + xdiff * xdiff), 1.0);
           //*
           // inplace atan2 - faster a bit
           coeff_2 = 3 * coeff_1;
           absY = ydiff;
           if (absY < 0) absY = -absY;                    //Math.abs
           if(x >= 0)
           {
               r= (xdiff - absY) / (xdiff + absY);
               angle = coeff_1 - coeff_1 * r;
           } else
           {
               r = (xdiff + absY) / (absY - xdiff);
               angle = coeff_2 - coeff_1 * r;
           }
           
          
           mtx.rotate(ydiff < 0 ? -angle : angle);
           //*/
           //mtx.rotate(Math.atan2(ydiff, xdiff));
           mtx.translate(x0, y0);
           
           bmd.drawWithQuality(line, mtx, null, null, null, false, StageQuality.MEDIUM);
        }
        
        /**
            EFLA with antialiasing
        **/
        private function efla(x:int, y:int, x2:int, y2:int, color:uint):void
        {
          var shortLen:int = y2-y;
          var longLen:int = x2-x;
        
          if((shortLen ^ (shortLen >> 31)) - (shortLen >> 31) > (longLen ^ (longLen >> 31)) - (longLen >> 31))
          {
          shortLen ^= longLen;
          longLen ^= shortLen;
          shortLen ^= longLen;
        
          var yLonger:Boolean = true;
          }
          else
         {
          yLonger = false;
         }
        
          var inc:int = longLen < 0 ? -1 : 1;
        
          var multDiff:Number = (longLen == 0 ? shortLen : shortLen / longLen) * inc;
          var tcol:uint = 0, xx:Number = x, yy:Number = y, alfa:uint = color >> 24;
          var a:Number;
          color &= 0xffffff;
          
          //bmd.lock();
          
          if (yLonger)
          {
            for (var i:int = 0; i != longLen; i += inc)
            {
                a = xx - int(xx);
                
                tcol = blendColors( color | (int(alfa * (1.0 - a)) << 24), bmd.getPixel32(int(xx), y + i));
                bmd.setPixel32(int(xx), y + i, tcol);
               
                tcol = blendColors( color | (int(alfa * a) << 24), bmd.getPixel32(int(xx + 1), y + i));
                bmd.setPixel32(int(xx + 1), y + i, tcol);
                
                xx += multDiff;
            }
          }
          else
          {
            for (i = 0; i != longLen; i += inc)
            {
                a = yy - int(yy);
                
                tcol = blendColors( color | (int(alfa * (1.0 - a)) << 24), bmd.getPixel32(x + i, int(yy)));
                bmd.setPixel32(x + i, int(yy), tcol);
                
                tcol = blendColors( color | (int(alfa * a) << 24), bmd.getPixel32(x + i, int(yy + 1)));
                bmd.setPixel32(x + i, int(yy + 1), tcol);
                
                yy += multDiff;
            }
          }
          
          //bmd.unlock();
        }
        
        
        private function blendColors(col1:uint, col2:uint):uint
        {
            var aT:uint = col1 >>> 24;
            var rT:uint = (col1 >>> 16 & 0xFF) * (aT/0xFF);
            var gT:uint = (col1 >>> 8 & 0xFF) * (aT/0xFF);
            var bT:uint = (col1 & 0xFF) * (aT/0xFF);
            var aB:uint = col2 >>> 24;
            var rB:uint = (col2 >>> 16 & 0xFF) * (aB/0xFF);
            var gB:uint = (col2 >>> 8 & 0xFF) * (aB/0xFF);
            var bB:uint = (col2 & 0xFF) * (aB /0xFF);
            var alpValue:Number = (0xFF - aT)/0xFF;
            var aN:uint = Math.min(aB + aT, 0xFF);
            var rN:uint = Math.min(rB * alpValue + rT, 0xFF);
            var gN:uint = Math.min(gB * alpValue + gT, 0xFF);
            var bN:uint = Math.min(bB * alpValue + bT, 0xFF);
            
            return(aN << 24 | rN << 16 | gN << 8 | bN);
        }        
    }
    
 
}