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