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