rodrigolopezpeker

Genome2D > GTextureTextExtended

Apr 8th, 2013
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  *
  3.  * GTextureTextExtended
  4.  *
  5.  * Recreates GTextureText
  6.  * Considerations:
  7.  * - no mouse processing!
  8.  * - fixes the align issue, is not based in the texture align, as the original, is based on the text width.
  9.  *   to the original node position.
  10.  * - change size with .textSize (must set .originalSize first).
  11.  * - basic support for textformat (font and color), only 1 textformat at a time.
  12.  * - ::setTextureAtlas now public :)
  13.  *
  14.  * Example:
  15.  *
  16.  * // add font textures (or create them in runtime)
  17.  * GTextureAtlasFactory.createFromFont('arial', new TextFormat( new arial_fnt().fontName, 20, 0xFFFFFF), CHAR_LIST) ;
  18.  * GTextureAtlasFactory.createFromFont('bauhaus', new TextFormat( new bauhaus_fnt().fontName, 20, 0xFFFFFF), CHAR_LIST) ;
  19.  *
  20.  * var field:GTextureTextExtended = GNodeFactory.createNodeWithComponent(GTextureTextExtended) as GTextureTextExtended ;
  21.  * tf.originalTextSize = 20 ;
  22.  * tf.textSize = 14 ;
  23.  * tf.textureAtlasId = 'arial' ;
  24.  * tf.tracking = -3 ;
  25.  * tf.lineSeparation = 2 ;
  26.  * tf.text = 'First line of text' ;
  27.  * tf.text += '\nSecond line of text, longer' ;
  28.  * tf.text += '\3rd line of text' ;
  29.  *
  30.  * var alignType:int = 0 ; // equals GTextureTextAlignType.TOP_LEFT
  31.  * tf.align = alignType ;
  32.  *
  33.  * stage.addEventListener('click', function(e:MouseEvent):void {
  34.  *      tf.align = ++alignType%3 ;
  35.  * }) ;
  36.  *
  37.  */
  38.  
  39.  
  40. package {
  41.     import ar.com.rodrigolopezpeker.genome.utils.GUtils;
  42.  
  43.     import com.genome2d.components.GTransform;
  44.  
  45.     import com.genome2d.components.renderables.GRenderable;
  46.     import com.genome2d.components.renderables.GSprite;
  47.     import com.genome2d.components.renderables.GTextureTextAlignType;
  48.     import com.genome2d.core.GNode;
  49.     import com.genome2d.core.GNodeFactory;
  50.     import com.genome2d.error.GError;
  51.     import com.genome2d.g2d;
  52.     import com.genome2d.textures.GTexture;
  53.     import com.genome2d.textures.GTextureAlignType;
  54.     import com.genome2d.textures.GTextureAtlas;
  55.     import com.genome2d.textures.factories.GTextureFactory;
  56.     import flash.text.TextFormat;
  57.  
  58.     use namespace g2d ;
  59.  
  60.     public class GTextureTextExtended extends GRenderable {
  61.  
  62.         private var _textureAtlas:GTextureAtlas ;
  63.         private var _invalidate:Boolean = false ;
  64.         private var _tracking:Number = 0 ;
  65.         private var _text:String = '' ;
  66.         private var _align:int = 0;
  67.         private var _w:int ;
  68.         private var _h:int ;
  69.         private var _breakLinesIndexes: Array = [];
  70.         private var _textLinesWidth: Array = [];
  71.         private var _lineSeparation: int = 0 ;
  72.         private var _lineH: int = 0 ;
  73.  
  74.         private var _textScale: Number = 1 ;
  75.         private var _textSize: int = 0 ;
  76.  
  77.         public var originalTextSize: int = 0 ;
  78.  
  79.         private static var _backgroundTx:GTexture = GTextureFactory.createFromColor('tf_back', 0x212121, 8, 8 ) ;
  80.  
  81.         private var _background: GSprite;
  82.         private var _textFormat: Object;
  83.         private var _showBackground = false ;
  84.  
  85.         public function GTextureTextExtended(pNode:GNode) {
  86.             super(pNode);
  87.             _backgroundTx.alignTexture(GTextureAlignType.TOP_LEFT);
  88.             _background = GNodeFactory.createNodeWithComponent(GSprite) as GSprite ;
  89.             _background.textureId = 'tf_back' ;
  90.             _background.node.transform.alpha = 0.3 ;
  91.         }
  92.  
  93.         override public function update(p_deltaTime: Number, p_parentTransformUpdate: Boolean, p_parentColorUpdate: Boolean): void {
  94.             if(!_invalidate) return ;
  95.             invalidateText() ;
  96.         }
  97.  
  98.         private function invalidateText(): void {
  99.             if(!_textureAtlas) return ;
  100.             var offsetX:int = 0 ;
  101.             var charSprite:GSprite ;
  102.  
  103.             // remove everything....
  104.             while(cNode.numChildren) cNode.removeChild(cNode.firstChild);
  105.             if(_showBackground){
  106.                 cNode.addChild(_background.node) ;
  107.             }
  108.  
  109.             // break lines counter.
  110.             var nextBreakCounter:int = 0 ;
  111.             var nextBreak:int = _breakLinesIndexes.length ? _breakLinesIndexes[0] : -1 ;
  112.             var lineIndex:int = 0 ;
  113.             if( _textSize > 0 && originalTextSize > 0 ){
  114.                 _lineH = _textSize ;
  115.                 _textScale = _textSize / originalTextSize ;
  116.             } else {
  117.                 _lineH = findMaxLineHeight() ;
  118.                 _textScale = 1 ;
  119.             }
  120.             _textLinesWidth.length = 0 ;
  121.             var tx:GTexture ;
  122.             var atlasId:String = _textureAtlas.id ;
  123.             for (var i: int = 0; i < _text.length; i++) {
  124.                 if( i == nextBreak ){
  125.                     _textLinesWidth[lineIndex] = offsetX ;
  126.                     if( _w < offsetX ) {
  127.                         _w = offsetX - _tracking ;
  128.                     }
  129.                     offsetX = 0 ;
  130.                     if( ++nextBreakCounter < _breakLinesIndexes.length ){
  131.                         nextBreak = _breakLinesIndexes[nextBreakCounter] ;
  132.                     }
  133.                     lineIndex++ ;
  134.                     continue ;
  135.                 }
  136.                 charSprite = GNodeFactory.createNodeWithComponent(GSprite) as GSprite ;
  137.                 cNode.addChild(charSprite.node);
  138.                 if( _textFormat ) {
  139.                     if( i >= _textFormat.from && i <= _textFormat.to ){
  140.                         if('font' in _textFormat.format ){
  141.                             atlasId = _textFormat.format.font ;
  142.                         }
  143.                         if('color' in _textFormat.format ){
  144.                             Utils.setColor( charSprite.node.transform, _textFormat.format.color ) ;
  145.                         }
  146.                     } else {
  147.                         atlasId = _textureAtlas.id ;
  148.                     }
  149.                 }
  150.                 tx = GTexture.getTextureById( atlasId + '_' + _text.charCodeAt(i)) ;
  151.                 if(!tx) throw new GError(GError.NO_TEXTURE_FOR_CHARACTER_FOUND+ _text.charCodeAt(i)+" "+_text.charAt(i));
  152.                 var charW: Number = tx.width / 2 * _textScale ;
  153.                 var charH: Number = tx.height / 2 * _textScale ;
  154.                 charSprite.node.userData.isChar = true ;
  155.                 charSprite.node.userData.numLine = lineIndex ;
  156.                 charSprite.node.userData.charW = charW ;
  157.                 charSprite.node.userData.charH = charH ;
  158.                 charSprite.node.cameraGroup = node.cameraGroup ;
  159.                 charSprite.setTexture(tx) ;
  160.                 charSprite.node.transform.setScale( _textScale, _textScale );
  161.                 offsetX += charW ;
  162.                 charSprite.cNode.cTransform.x = offsetX ;
  163.                 charSprite.cNode.cTransform.y = charH + lineIndex * ( _lineH + _lineSeparation ) ;
  164.                 offsetX += charW + _tracking ;
  165.                 _h = charSprite.cNode.cTransform.y + charH ;
  166.             }
  167.             if( _w < offsetX ) _w = offsetX - _tracking ;
  168.             _background.node.transform.setScale( _w / _backgroundTx.width, _h / _backgroundTx.height ) ;
  169.             _textLinesWidth.push(offsetX) ;
  170.             invalidateAlign();
  171.             _invalidate = false ;
  172.         }
  173.  
  174.         private function invalidateAlign(): void {
  175.             var node:GNode, lineW:Number;
  176.             switch (_align) {
  177.                 case GTextureTextAlignType.MIDDLE:
  178.                     for (node = cNode.firstChild; node; node = node.next) {
  179.                         if( node.userData.isChar ){
  180.                             lineW = _textLinesWidth[ node.userData.numLine ] ;
  181.                             node.transform.x += _w + _tracking - lineW >> 1 ;
  182.                         }
  183.                     }
  184.                     break;
  185.                 case GTextureTextAlignType.TOP_RIGHT:
  186.                     for (node = cNode.firstChild; node; node = node.next) {
  187.                         if( node.userData.isChar ){
  188.                             lineW = _textLinesWidth[ node.userData.numLine ] ;
  189.                             node.transform.x += _w + _tracking - lineW ;
  190.                         }
  191.                     }
  192.                     break;
  193.                 case GTextureTextAlignType.TOP_LEFT:
  194.                     break;
  195.             }
  196.         }
  197.  
  198.         public function get tracking(): Number { return _tracking;}
  199.         public function set tracking(value: Number): void {
  200.             _tracking = value;
  201.             _invalidate = true ;
  202.         }
  203.  
  204.         public function get text(): String {return _text;}
  205.         public function set text(value: String): void {
  206.             _text = value;
  207.             searchChar(_breakLinesIndexes, '\n') ;
  208.             _invalidate = true ;
  209.         }
  210.  
  211.         private function findMaxLineHeight(): Number {
  212.             var charH:Number = 0 ;
  213.             for (var i: int = 0; i < _text.length; i++) {
  214.                 var tx:GTexture = _textureAtlas.getTexture(String(_text.charCodeAt(i))) ;
  215.                 if( tx && tx.height > charH ) {
  216.                     charH = tx.height
  217.                 }
  218.             }
  219.             return charH ;
  220.         }
  221.  
  222.         private function searchChar( pOutput:Array, pChar:String ): void {
  223.             var idx:int = 0 ;
  224.             pOutput.length = 0 ;
  225.             while(( idx = _text.indexOf(pChar, idx)) > -1 ) {
  226.                 pOutput.push(idx) ;
  227.                 idx++ ;
  228.             }
  229.         }
  230.  
  231.         public function get align(): int {return _align;}
  232.         public function set align(value: int): void {
  233.             _align = value;
  234.             _invalidate = true ;
  235.         }
  236.  
  237.         public function get textureAtlasId():String {
  238.             return _textureAtlas ? _textureAtlas.id : '';
  239.         }
  240.  
  241.         public function set textureAtlasId(pId:String):void{
  242.             setTextureAtlas(GTextureAtlas.getTextureAtlasById(pId)) ;
  243.         }
  244.  
  245.         public function setTextureAtlas( pValue: GTextureAtlas): void {
  246.             _textureAtlas = pValue ;
  247.             _invalidate = true ;
  248.         }
  249.  
  250.         public function get lineSeparation(): int {return _lineSeparation;}
  251.         public function set lineSeparation(value: int): void {
  252.             _lineSeparation = value;
  253.             _invalidate = true ;
  254.         }
  255.  
  256.         public function get textSize(): int {return _textSize;}
  257.         public function set textSize(value: int): void {
  258.             _textSize = value;
  259.             _invalidate = true ;
  260.         }
  261.  
  262.         public function setTextFormat( pFormat: TextFormat, pFrom:int =-1, pTo:int = -1): void {
  263.             _textFormat = {format:pFormat, from:pFrom, to:pTo} ;
  264.         }
  265.  
  266.         public function get width(): int {
  267.             if (_invalidate) invalidateText();
  268.             return _w;
  269.         }
  270.  
  271.         public function get height(): int {
  272.             if (_invalidate) invalidateText();
  273.             return _h;
  274.         }
  275.     }
  276. }
  277.  
  278. import com.genome2d.components.GTransform;
  279. class Utils {
  280.  
  281.     /**
  282.      * Quick utility function to apply a hex color to a node.
  283.      * @param pTransform
  284.      * @param pHex
  285.      */
  286.     static function setColor(pTransform: GTransform, pHex: uint): void {
  287.         pTransform.red = ((pHex & 0xFF0000) >> 16 ) / 255
  288.         pTransform.green = ((pHex & 0x00FF00) >> 8 ) / 255
  289.         pTransform.blue = (pHex & 0x0000FF) / 255
  290.     }
  291. }
Advertisement
Add Comment
Please, Sign In to add comment