1 /**
  2  * Hilo
  3  * Copyright 2015 alibaba.com
  4  * Licensed under the MIT License
  5  */
  6 
  7 /**
  8  * @language=zh
  9  * <iframe src='../../../examples/BitmapText.html?noHeader' width = '550' height = '80' scrolling='no'></iframe>
 10  * <br/>
 11  * @class BitmapText类提供使用位图文本的功能。当前仅支持单行文本。
 12  * @augments Container
 13  * @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。
 14  * @module hilo/view/BitmapText
 15  * @requires hilo/core/Class
 16  * @requires hilo/core/Hilo
 17  * @requires hilo/view/Container
 18  * @requires hilo/view/Bitmap
 19  * @property {Object} glyphs 位图字体的字形集合。格式为:{letter:{image:img, rect:[0,0,100,100]}}。
 20  * @property {Number} letterSpacing 字距,即字符间的间隔。默认值为0。
 21  * @property {String} text 位图文本的文本内容。只读属性。设置文本请使用setFont方法。
 22  * @property {String} textAlign 文本对齐方式,值为left、center、right, 默认left。只读属性。设置文本请使用setTextAlign方法。
 23  */
 24 var BitmapText = Class.create(/** @lends BitmapText.prototype */{
 25     Extends: Container,
 26     constructor: function(properties){
 27         properties = properties || {};
 28         this.id = this.id || properties.id || Hilo.getUid('BitmapText');
 29         BitmapText.superclass.constructor.call(this, properties);
 30 
 31         var text = properties.text + '';
 32         if(text){
 33             this.text = '';
 34             this.setText(text);
 35         }
 36 
 37         this.pointerChildren = false; //disable user events for single letters
 38     },
 39 
 40     glyphs: null,
 41     letterSpacing: 0,
 42     text: '',
 43     textAlign:'left',
 44 
 45     /**
 46      * @language=zh
 47      * 设置位图文本的文本内容。
 48      * @param {String} text 要设置的文本内容。
 49      * @returns {BitmapText} BitmapText对象本身。链式调用支持。
 50      */
 51     setText: function(text){
 52         var me = this, str = text.toString(), len = str.length;
 53         if(me.text == str) return;
 54         me.text = str;
 55 
 56         var i, charStr, charGlyph, charObj, width = 0, height = 0, left = 0;
 57         for(i = 0; i < len; i++){
 58             charStr = str.charAt(i);
 59             charGlyph = me.glyphs[charStr];
 60             if(charGlyph){
 61                 left = width + (width > 0 ? me.letterSpacing : 0);
 62                 if(me.children[i]){
 63                     charObj = me.children[i];
 64                     charObj.setImage(charGlyph.image, charGlyph.rect);
 65                 }
 66                 else{
 67                     charObj = me._createBitmap(charGlyph);
 68                     me.addChild(charObj);
 69                 }
 70                 charObj.x = left;
 71                 width = left + charGlyph.rect[2];
 72                 height = Math.max(height, charGlyph.rect[3]);
 73             }
 74         }
 75 
 76         for(i = me.children.length - 1;i >= len;i --){
 77             me._releaseBitmap(me.children[i]);
 78             me.children[i].removeFromParent();
 79         }
 80 
 81         me.width = width;
 82         me.height = height;
 83         this.setTextAlign();
 84         return me;
 85     },
 86     _createBitmap:function(cfg){
 87         var bmp;
 88         if(BitmapText._pool.length){
 89             bmp = BitmapText._pool.pop();
 90             bmp.setImage(cfg.image, cfg.rect);
 91         }
 92         else{
 93             bmp = new Bitmap({
 94                 image:cfg.image,
 95                 rect:cfg.rect
 96             });
 97         }
 98         return bmp;
 99     },
100     _releaseBitmap:function(bmp){
101         BitmapText._pool.push(bmp);
102     },
103 
104      /**
105       * @language=zh
106       * 设置位图文本的对齐方式。
107      * @param textAlign 文本对齐方式,值为left、center、right
108      * @returns {BitmapText} BitmapText对象本身。链式调用支持。
109      */
110     setTextAlign:function(textAlign){
111         this.textAlign = textAlign||this.textAlign;
112         switch(this.textAlign){
113             case "center":
114                 this.pivotX = this.width * .5;
115                 break;
116             case "right":
117                 this.pivotX = this.width;
118                 break;
119             case "left":
120             default:
121                 this.pivotX = 0;
122                 break;
123         }
124         return this;
125     },
126 
127     /**
128      * @language=zh
129      * 返回能否使用当前指定的字体显示提供的字符串。
130      * @param {String} str 要检测的字符串。
131      * @returns {Boolean} 是否能使用指定字体。
132      */
133     hasGlyphs: function(str){
134         var glyphs = this.glyphs;
135         if(!glyphs) return false;
136 
137         var str = str.toString(), len = str.length, i;
138         for(i = 0; i < len; i++){
139             if(!glyphs[str.charAt(i)]) return false;
140         }
141         return true;
142     },
143 
144     Statics:/** @lends BitmapText */{
145         _pool:[],
146         /**
147          * @language=zh
148          * 简易方式生成字形集合。
149          * @static
150          * @param {String} text 字符文本。
151          * @param {Image} image 字符图片。
152          * @param {Number} col 列数  默认和文本字数一样
153          * @param {Number} row 行数 默认1行
154          * @returns {BitmapText} BitmapText对象本身。链式调用支持。
155          */
156         createGlyphs:function(text, image, col, row){
157             var str = text.toString();
158             col = col||str.length;
159             row = row||1;
160             var w = image.width/col;
161             var h = image.height/row;
162             var glyphs = {};
163             for(var i = 0, l = text.length;i < l;i ++){
164                 charStr = str.charAt(i);
165                 glyphs[charStr] = {
166                     image:image,
167                     rect:[w * (i % col), h * Math.floor(i / col), w, h]
168                 }
169             }
170             return glyphs;
171         }
172     }
173 
174 });
175