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             texture.addEventListener("load", function (sender) {
147                 this.initWithTexture(texture, width, height, label.length);
148                 this.string = label;
149                 this.dispatchEvent("load");
150             }, this);
151         }
152         if (this.initWithTexture(texture, width, height, label.length)) {
153             this._mapStartChar = startChar;
154             this.string = label;
155             return true;
156         }
157         return false;
158     },
159 
160     /**
161      * Set the color.
162      * @param {cc.Color} color3
163      */
164     setColor: function (color3) {
165         cc.AtlasNode.prototype.setColor.call(this, color3);
166         this._renderCmd.updateAtlasValues();
167     },
168 
169     /**
170      * return the text of this label
171      * @return {String}
172      */
173     getString: function () {
174         return this._string;
175     },
176 
177     addChild: function(child, localZOrder, tag){
178         this._renderCmd._addChild(child);
179         cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
180     },
181 
182     /**
183      * Atlas generation
184      * @function
185      */
186     updateAtlasValues: function(){
187         this._renderCmd.updateAtlasValues();
188     },
189 
190     /**
191      * set the display string
192      * @function
193      * @param {String} label
194      */
195     setString: function(label){
196         label = String(label);
197         var len = label.length;
198         this._string = label;
199         this.setContentSize(len * this._itemWidth, this._itemHeight);
200         this._renderCmd.setString(label);
201 
202         this._renderCmd.updateAtlasValues();
203         this.quadsToDraw = len;
204     }
205 });
206 
207 (function(){
208     var proto = cc.LabelAtlas.prototype;
209     // Override properties
210     cc.defineGetterSetter(proto, "opacity", proto.getOpacity, proto.setOpacity);
211     cc.defineGetterSetter(proto, "color", proto.getColor, proto.setColor);
212 
213     // Extended properties
214     /** @expose */
215     proto.string;
216     cc.defineGetterSetter(proto, "string", proto.getString, proto.setString);
217 })();
218 
219 /**
220  * <p>
221  *     Please use new cc.LabelAtlas instead. <br />
222  *     Create a label atlas. <br />
223  *     It accepts two groups of parameters:                                                            <br/>
224  *         a) string, fntFile                                                                               <br/>
225  *         b) label, textureFilename, width, height, startChar                                              <br/>
226  * </p>
227  * @deprecated since v3.0 please use new cc.LabelAtlas
228  * @param {String} strText
229  * @param {String} charMapFile  charMapFile or fntFile
230  * @param {Number} [itemWidth=0]
231  * @param {Number} [itemHeight=0]
232  * @param {Number} [startCharMap=""]
233  * @return {cc.LabelAtlas} returns the LabelAtlas object on success
234  */
235 cc.LabelAtlas.create = function (strText, charMapFile, itemWidth, itemHeight, startCharMap) {
236     return new cc.LabelAtlas(strText, charMapFile, itemWidth, itemHeight, startCharMap);
237 };
238 
239