      1 /**
      2  * Hilo
      3  * Copyright 2015 alibaba.com
      4  * Licensed under the MIT License
      5  */
      6
      7 /**
      8  * <iframe src='../../../examples/BitmapText.html?noHeader' width = '550' height = '80' scrolling='no'></iframe>
      9  * <br/>
     10  * @class BitmapText  support bitmap text function ,but only support single-line text
     11  * @augments Container
     12  * @param {Object} properties the options of create Instance.It can contains all writable property
     13  * @module hilo/view/BitmapText
     14  * @requires hilo/core/Class
     15  * @requires hilo/core/Hilo
     16  * @requires hilo/view/Container
     17  * @requires hilo/view/Bitmap
     18  * @property {Object} glyphs font glyph set of bitmap. format:{letter:{image:img, rect:[0,0,100,100]}}
     19  * @property {Number} letterSpacing spacing of letter. default:0
     20  * @property {String} text content of bitmap text. Not writable,set this value by 'setText'
     21  * @property {String} textAlign property values:left、center、right, default:left,Not writable,set this property by 'setTextAlign'
     22  */
     23 var BitmapText = Class.create(/** @lends BitmapText.prototype */{
     24     Extends: Container,
     25     constructor: function(properties){
     26         properties = properties || {};
     27         this.id = this.id || properties.id || Hilo.getUid('BitmapText');
     28         BitmapText.superclass.constructor.call(this, properties);
     29
     30         var text = properties.text + '';
     31         if(text){
     32             this.text = '';
     33             this.setText(text);
     34         }
     35
     36         this.pointerChildren = false; //disable user events for single letters
     37     },
     38
     39     glyphs: null,
     40     letterSpacing: 0,
     41     text: '',
     42     textAlign:'left',
     43
     44     /**
     45      * set the content of bitmap text
     46      * @param {String} text content
     47      * @returns {BitmapText} BitmapText Instance,support chained calls
     48      */
     49     setText: function(text){
     50         var me = this, str = text.toString(), len = str.length;
     51         if(me.text == str) return;
     52         me.text = str;
     53
     54         var i, charStr, charGlyph, charObj, width = 0, height = 0, left = 0;
     55         for(i = 0; i < len; i++){
     56             charStr = str.charAt(i);
     57             charGlyph = me.glyphs[charStr];
     58             if(charGlyph){
     59                 left = width + (width > 0 ? me.letterSpacing : 0);
     60                 if(me.children[i]){
     61                     charObj = me.children[i];
     62                     charObj.setImage(charGlyph.image, charGlyph.rect);
     63                 }
     64                 else{
     65                     charObj = me._createBitmap(charGlyph);
     66                     me.addChild(charObj);
     67                 }
     68                 charObj.x = left;
     69                 width = left + charGlyph.rect[2];
     70                 height = Math.max(height, charGlyph.rect[3]);
     71             }
     72         }
     73
     74         for(i = me.children.length - 1;i >= len;i --){
     75             me._releaseBitmap(me.children[i]);
     76             me.children[i].removeFromParent();
     77         }
     78
     79         me.width = width;
     80         me.height = height;
     81         this.setTextAlign();
     82         return me;
     83     },
     84     _createBitmap:function(cfg){
     85         var bmp;
     86         if(BitmapText._pool.length){
     87             bmp = BitmapText._pool.pop();
     88             bmp.setImage(cfg.image, cfg.rect);
     89         }
     90         else{
     91             bmp = new Bitmap({
     92                 image:cfg.image,
     93                 rect:cfg.rect
     94             });
     95         }
     96         return bmp;
     97     },
     98     _releaseBitmap:function(bmp){
     99         BitmapText._pool.push(bmp);
    100     },
    101
    102      /**
    103       * set the textAlign of text。
    104      * @param textAlign value of textAlign:left、center、right
    105      * @returns {BitmapText} itmapText Instance,support chained calls
    106      */
    107     setTextAlign:function(textAlign){
    108         this.textAlign = textAlign||this.textAlign;
    109         switch(this.textAlign){
    110             case "center":
    111                 this.pivotX = this.width * .5;
    112                 break;
    113             case "right":
    114                 this.pivotX = this.width;
    115                 break;
    116             case "left":
    117                 /* falls through */
    118             default:
    119                 this.pivotX = 0;
    120                 break;
    121         }
    122         return this;
    123     },
    124
    125     /**
    126      * detect whether can display the string by the currently assigned font provided
    127      * @param {String} str to detect string
    128      * @returns {Boolean} whether can display the string
    129      */
    130     hasGlyphs: function(str){
    131         var glyphs = this.glyphs;
    132         if(!glyphs) return false;
    133
    134         str = str.toString();
    135         var len = str.length, i;
    136         for(i = 0; i < len; i++){
    137             if(!glyphs[str.charAt(i)]) return false;
    138         }
    139         return true;
    140     },
    141
    142     Statics:/** @lends BitmapText */{
    143         _pool:[],
    144         /**
    145          * easy way to generate a collection of glyphs
    146          * @static
    147          * @param {String} text character text.
    148          * @param {Image} image character image.
    149          * @param {Number} col default:the length of string
    150          * @param {Number} row default:1
    151          * @returns {BitmapText} BitmapText对象本身。链式调用支持。
    152          */
    153         createGlyphs:function(text, image, col, row){
    154             var str = text.toString();
    155             col = col||str.length;
    156             row = row||1;
    157             var w = image.width/col;
    158             var h = image.height/row;
    159             var glyphs = {};
    160             for(var i = 0, l = text.length;i < l;i ++){
    161                 var charStr = str.charAt(i);
    162                 glyphs[charStr] = {
    163                     image:image,
    164                     rect:[w * (i % col), h * Math.floor(i / col), w, h]
    165                 };
    166             }
    167             return glyphs;
    168         }
    169     }
    170
    171 });
    172