1 /****************************************************************************
  2  Copyright (c) 2008-2010 Ricardo Quesada
  3  Copyright (c) 2011-2012 cocos2d-x.org
  4  Copyright (c) 2013-2014 Chukong Technologies Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 /**
 28  * using image file to print text label on the screen, might be a bit slower than cc.Label, similar to cc.LabelBMFont
 29  * @class
 30  * @extends cc.AtlasNode
 31  *
 32  * @property {String}   string  - Content string of label
 33  *
 34  * @param {String} strText
 35  * @param {String} charMapFile  charMapFile or fntFile
 36  * @param {Number} [itemWidth=0]
 37  * @param {Number} [itemHeight=0]
 38  * @param {Number} [startCharMap=""]
 39  * @example
 40  * //creates the cc.LabelAtlas with a string, a char map file(the atlas), the width and height of each element and the starting char of the atlas
 41  * var myLabel = new cc.LabelAtlas('Text to display', 'CharMapfile.png', 12, 20, ' ')
 42  *
 43  * //creates the cc.LabelAtlas with a string, a fnt file
 44  * var myLabel = new cc.LabelAtlas('Text to display', 'CharMapFile.plist‘);
 45  */
 46 cc.LabelAtlas = cc.AtlasNode.extend(/** @lends cc.LabelAtlas# */{
 47     //property String is Getter and Setter
 48     // string to render
 49     _string: null,
 50     // the first char in the charmap
 51     _mapStartChar: null,
 52 
 53     _textureLoaded: false,
 54     _className: "LabelAtlas",
 55 
 56     /**
 57      * <p>
 58      *  Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. <br />
 59      *  Create a label atlas. <br />
 60      *  It accepts two groups of parameters: <br/>
 61      * a) string, fntFile <br/>
 62      * b) label, textureFilename, width, height, startChar <br/>
 63      * </p>
 64      * @param {String} strText
 65      * @param {String} charMapFile  charMapFile or fntFile
 66      * @param {Number} [itemWidth=0]
 67      * @param {Number} [itemHeight=0]
 68      * @param {Number} [startCharMap=""]
 69      */
 70     ctor: function (strText, charMapFile, itemWidth, itemHeight, startCharMap) {
 71         cc.AtlasNode.prototype.ctor.call(this);
 72 
 73         this._renderCmd.setCascade();
 74         charMapFile && cc.LabelAtlas.prototype.initWithString.call(this, strText, charMapFile, itemWidth, itemHeight, startCharMap);
 75     },
 76 
 77     _createRenderCmd: function(){
 78         if(cc._renderType === cc._RENDER_TYPE_WEBGL)
 79             return new cc.LabelAtlas.WebGLRenderCmd(this);
 80         else
 81             return new cc.LabelAtlas.CanvasRenderCmd(this);
 82     },
 83 
 84     /**
 85      * Return  texture is loaded.
 86      * @returns {boolean}
 87      */
 88     textureLoaded: function () {
 89         return this._textureLoaded;
 90     },
 91 
 92     /**
 93      * Add texture loaded event listener.
 94      * @param {Function} callback
 95      * @param {cc.Node} target
 96      * @deprecated since 3.1, please use addEventListener instead
 97      */
 98     addLoadedEventListener: function (callback, target) {
 99         this.addEventListener("load", callback, target);
100     },
101 
102     /**
103      * <p>
104      *  initializes the cc.LabelAtlas with a string, a char map file(the atlas), <br/>
105      *  the width and height of each element and the starting char of the atlas <br/>
106      *  It accepts two groups of parameters: <br/>
107      * a) string, fntFile <br/>
108      * b) label, textureFilename, width, height, startChar <br/>
109      * </p>
110      * @param {String} strText
111      * @param {String|cc.Texture2D} charMapFile  charMapFile or fntFile or texture file
112      * @param {Number} [itemWidth=0]
113      * @param {Number} [itemHeight=0]
114      * @param {Number} [startCharMap=""]
115      * @return {Boolean} returns true on success
116      */
117     initWithString: function (strText, charMapFile, itemWidth, itemHeight, startCharMap) {
118         var label = strText + "", textureFilename, width, height, startChar;
119         if (itemWidth === undefined) {
120             var dict = cc.loader.getRes(charMapFile);
121             if (parseInt(dict["version"], 10) !== 1) {
122                 cc.log("cc.LabelAtlas.initWithString(): Unsupported version. Upgrade cocos2d version");
123                 return false;
124             }
125 
126             textureFilename = cc.path.changeBasename(charMapFile, dict["textureFilename"]);
127             var locScaleFactor = cc.contentScaleFactor();
128             width = parseInt(dict["itemWidth"], 10) / locScaleFactor;
129             height = parseInt(dict["itemHeight"], 10) / locScaleFactor;
130             startChar = String.fromCharCode(parseInt(dict["firstChar"], 10));
131         } else {
132             textureFilename = charMapFile;
133             width = itemWidth || 0;
134             height = itemHeight || 0;
135             startChar = startCharMap || " ";
136         }
137 
138         var texture = null;
139         if (textureFilename instanceof cc.Texture2D)
140             texture = textureFilename;
141         else
142             texture = cc.textureCache.addImage(textureFilename);
143         var locLoaded = texture.isLoaded();
144         this._textureLoaded = locLoaded;
145         if (!locLoaded) {
146             this._string = label;
147             texture.addEventListener("load", function (sender) {
148                 this.initWithTexture(texture, width, height, label.length);
149                 this.string = this._string;
150                 this.setColor(this._renderCmd._displayedColor);
151                 this.dispatchEvent("load");
152             }, this);
153         }
154         if (this.initWithTexture(texture, width, height, label.length)) {
155             this._mapStartChar = startChar;
156             this.string = label;
157             return true;
158         }
159         return false;
160     },
161 
162     /**
163      * Set the color.
164      * @param {cc.Color} color3
165      */
166     setColor: function (color3) {
167         cc.AtlasNode.prototype.setColor.call(this, color3);
168         this._renderCmd.updateAtlasValues();
169     },
170 
171     /**
172      * return the text of this label
173      * @return {String}
174      */
175     getString: function () {
176         return this._string;
177     },
178 
179     addChild: function(child, localZOrder, tag){
180         this._renderCmd._addChild(child);
181         cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
182     },
183 
184     /**
185      * Atlas generation
186      * @function
187      */
188     updateAtlasValues: function(){
189         this._renderCmd.updateAtlasValues();
190     },
191 
192     /**
193      * set the display string
194      * @function
195      * @param {String} label
196      */
197     setString: function(label){
198         label = String(label);
199         var len = label.length;
200         this._string = label;
201         this.setContentSize(len * this._itemWidth, this._itemHeight);
202         this._renderCmd.setString(label);
203 
204         this._renderCmd.updateAtlasValues();
205         this.quadsToDraw = len;
206     }
207 });
208 
209 (function(){
210     var proto = cc.LabelAtlas.prototype;
211     // Override properties
212     cc.defineGetterSetter(proto, "opacity", proto.getOpacity, proto.setOpacity);
213     cc.defineGetterSetter(proto, "color", proto.getColor, proto.setColor);
214 
215     // Extended properties
216     /** @expose */
217     proto.string;
218     cc.defineGetterSetter(proto, "string", proto.getString, proto.setString);
219 })();
220 
221 /**
222  * <p>
223  *     Please use new cc.LabelAtlas instead. <br />
224  *     Create a label atlas. <br />
225  *     It accepts two groups of parameters:                                                            <br/>
226  *         a) string, fntFile                                                                               <br/>
227  *         b) label, textureFilename, width, height, startChar                                              <br/>
228  * </p>
229  * @deprecated since v3.0 please use new cc.LabelAtlas
230  * @param {String} strText
231  * @param {String} charMapFile  charMapFile or fntFile
232  * @param {Number} [itemWidth=0]
233  * @param {Number} [itemHeight=0]
234  * @param {Number} [startCharMap=""]
235  * @return {cc.LabelAtlas} returns the LabelAtlas object on success
236  */
237 cc.LabelAtlas.create = function (strText, charMapFile, itemWidth, itemHeight, startCharMap) {
238     return new cc.LabelAtlas(strText, charMapFile, itemWidth, itemHeight, startCharMap);
239 };
240 
241