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 * <p>cc.LabelTTF is a subclass of cc.TextureNode that knows how to render text labels with system font or a ttf font file<br/> 29 * All features from cc.Sprite are valid in cc.LabelTTF<br/> 30 * cc.LabelTTF objects are slow for js-binding on mobile devices.<br/> 31 * Consider using cc.LabelAtlas or cc.LabelBMFont instead.<br/> 32 * You can create a cc.LabelTTF from a font name, alignment, dimension and font size or a cc.FontDefinition object.</p> 33 * @class 34 * @extends cc.Sprite 35 * 36 * @param {String} text 37 * @param {String|cc.FontDefinition} [fontName="Arial"] 38 * @param {Number} [fontSize=16] 39 * @param {cc.Size} [dimensions=cc.size(0,0)] 40 * @param {Number} [hAlignment=cc.TEXT_ALIGNMENT_LEFT] 41 * @param {Number} [vAlignment=cc.VERTICAL_TEXT_ALIGNMENT_TOP] 42 * @example 43 * var myLabel = new cc.LabelTTF('label text', 'Times New Roman', 32, cc.size(320,32), cc.TEXT_ALIGNMENT_LEFT); 44 * 45 * var fontDef = new cc.FontDefinition(); 46 * fontDef.fontName = "Arial"; 47 * fontDef.fontSize = "32"; 48 * var myLabel = new cc.LabelTTF('label text', fontDef); 49 * 50 * @property {String} string - Content string of label 51 * @property {Number} textAlign - Horizontal Alignment of label: cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT 52 * @property {Number} verticalAlign - Vertical Alignment of label: cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM 53 * @property {Number} fontSize - Font size of label 54 * @property {String} fontName - Font name of label 55 * @property {String} font - The label font with a style string: e.g. "18px Verdana" 56 * @property {Number} boundingWidth - Width of the bounding box of label, the real content width is limited by boundingWidth 57 * @property {Number} boundingHeight - Height of the bounding box of label, the real content height is limited by boundingHeight 58 * @property {cc.Color} fillStyle - The fill color 59 * @property {cc.Color} strokeStyle - The stroke color 60 * @property {Number} lineWidth - The line width for stroke 61 * @property {Number} shadowOffsetX - The x axis offset of shadow 62 * @property {Number} shadowOffsetY - The y axis offset of shadow 63 * @property {Number} shadowOpacity - The opacity of shadow 64 * @property {Number} shadowBlur - The blur size of shadow 65 */ 66 cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{ 67 _dimensions: null, 68 _hAlignment: cc.TEXT_ALIGNMENT_CENTER, 69 _vAlignment: cc.VERTICAL_TEXT_ALIGNMENT_TOP, 70 _fontName: null, 71 _fontSize: 0.0, 72 _string: "", 73 _originalText: null, 74 _onCacheCanvasMode: true, 75 76 // font shadow 77 _shadowEnabled: false, 78 _shadowOffset: null, 79 _shadowOpacity: 0, 80 _shadowBlur: 0, 81 _shadowColor: null, 82 83 // font stroke 84 _strokeEnabled: false, 85 _strokeColor: null, 86 _strokeSize: 0, 87 88 // font tint 89 _textFillColor: null, 90 91 _strokeShadowOffsetX: 0, 92 _strokeShadowOffsetY: 0, 93 _needUpdateTexture: false, 94 95 _lineWidths: null, 96 _className: "LabelTTF", 97 98 //for web 99 _fontStyle: "normal", 100 _fontWeight: "normal", 101 _lineHeight: "normal", 102 103 /** 104 * Initializes the cc.LabelTTF with a font name, alignment, dimension and font size, do not call it by yourself, 105 * you should pass the correct arguments in constructor to initialize the label. 106 * @param {String} label string 107 * @param {String} fontName 108 * @param {Number} fontSize 109 * @param {cc.Size} [dimensions=] 110 * @param {Number} [hAlignment=] 111 * @param {Number} [vAlignment=] 112 * @return {Boolean} return false on error 113 */ 114 initWithString: function (label, fontName, fontSize, dimensions, hAlignment, vAlignment) { 115 var strInfo; 116 if (label) 117 strInfo = label + ""; 118 else 119 strInfo = ""; 120 121 fontSize = fontSize || 16; 122 dimensions = dimensions || cc.size(0, 0/*fontSize*/); 123 hAlignment = hAlignment || cc.TEXT_ALIGNMENT_LEFT; 124 vAlignment = vAlignment || cc.VERTICAL_TEXT_ALIGNMENT_TOP; 125 126 this._opacityModifyRGB = false; 127 this._dimensions = cc.size(dimensions.width, dimensions.height); 128 this._fontName = fontName || "Arial"; 129 this._hAlignment = hAlignment; 130 this._vAlignment = vAlignment; 131 132 this._fontSize = fontSize; 133 this._renderCmd._setFontStyle(this._fontName, fontSize, this._fontStyle, this._fontWeight); 134 this.string = strInfo; 135 this._renderCmd._setColorsString(); 136 this._renderCmd._updateTexture(); 137 this._setUpdateTextureDirty(); 138 return true; 139 }, 140 141 _setUpdateTextureDirty: function () { 142 this._needUpdateTexture = true; 143 this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.textDirty); 144 }, 145 146 ctor: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) { 147 cc.Sprite.prototype.ctor.call(this); 148 149 this._dimensions = cc.size(0, 0); 150 this._hAlignment = cc.TEXT_ALIGNMENT_LEFT; 151 this._vAlignment = cc.VERTICAL_TEXT_ALIGNMENT_TOP; 152 this._opacityModifyRGB = false; 153 this._fontName = "Arial"; 154 155 this._shadowEnabled = false; 156 this._shadowOffset = cc.p(0, 0); 157 this._shadowOpacity = 0; 158 this._shadowBlur = 0; 159 160 this._strokeEnabled = false; 161 this._strokeColor = cc.color(255, 255, 255, 255); 162 this._strokeSize = 0; 163 164 this._textFillColor = cc.color(255, 255, 255, 255); 165 this._strokeShadowOffsetX = 0; 166 this._strokeShadowOffsetY = 0; 167 this._needUpdateTexture = false; 168 169 this._lineWidths = []; 170 this._renderCmd._setColorsString(); 171 this._textureLoaded = true; 172 173 if (fontName && fontName instanceof cc.FontDefinition) { 174 this.initWithStringAndTextDefinition(text, fontName); 175 } else { 176 cc.LabelTTF.prototype.initWithString.call(this, text, fontName, fontSize, dimensions, hAlignment, vAlignment); 177 } 178 }, 179 180 init: function () { 181 return this.initWithString(" ", this._fontName, this._fontSize); 182 }, 183 184 description: function () { 185 return "<cc.LabelTTF | FontName =" + this._fontName + " FontSize = " + this._fontSize.toFixed(1) + ">"; 186 }, 187 188 getLineHeight: function () { 189 return !this._lineHeight || this._lineHeight.charAt ? 190 this._renderCmd._getFontClientHeight() : 191 this._lineHeight || this._renderCmd._getFontClientHeight(); 192 }, 193 194 setLineHeight: function (lineHeight) { 195 this._lineHeight = lineHeight; 196 }, 197 198 /** 199 * Returns the text of the label 200 * @return {String} 201 */ 202 getString: function () { 203 return this._string; 204 }, 205 206 /** 207 * Returns Horizontal Alignment of cc.LabelTTF 208 * @return {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} 209 */ 210 getHorizontalAlignment: function () { 211 return this._hAlignment; 212 }, 213 214 /** 215 * Returns Vertical Alignment of cc.LabelTTF 216 * @return {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} 217 */ 218 getVerticalAlignment: function () { 219 return this._vAlignment; 220 }, 221 222 /** 223 * Returns the dimensions of cc.LabelTTF, the dimension is the maximum size of the label, set it so that label will automatically change lines when necessary. 224 * @see cc.LabelTTF#setDimensions, cc.LabelTTF#boundingWidth and cc.LabelTTF#boundingHeight 225 * @return {cc.Size} 226 */ 227 getDimensions: function () { 228 return cc.size(this._dimensions); 229 }, 230 231 /** 232 * Returns font size of cc.LabelTTF 233 * @return {Number} 234 */ 235 getFontSize: function () { 236 return this._fontSize; 237 }, 238 239 /** 240 * Returns font name of cc.LabelTTF 241 * @return {String} 242 */ 243 getFontName: function () { 244 return this._fontName; 245 }, 246 247 /** 248 * Initializes the CCLabelTTF with a font name, alignment, dimension and font size, do not call it by yourself, you should pass the correct arguments in constructor to initialize the label. 249 * @param {String} text 250 * @param {cc.FontDefinition} textDefinition 251 * @return {Boolean} 252 */ 253 initWithStringAndTextDefinition: function (text, textDefinition) { 254 // prepare everything needed to render the label 255 this._updateWithTextDefinition(textDefinition, false); 256 // set the string 257 this.string = text; 258 return true; 259 }, 260 261 /** 262 * Sets the text definition used by this label 263 * @param {cc.FontDefinition} theDefinition 264 */ 265 setTextDefinition: function (theDefinition) { 266 if (theDefinition) 267 this._updateWithTextDefinition(theDefinition, true); 268 }, 269 270 /** 271 * Extract the text definition used by this label 272 * @return {cc.FontDefinition} 273 */ 274 getTextDefinition: function () { 275 return this._prepareTextDefinition(false); 276 }, 277 278 /** 279 * Enable or disable shadow for the label 280 * @param {cc.Color | Number} a Color or The x axis offset of the shadow 281 * @param {cc.Size | Number} b Size or The y axis offset of the shadow 282 * @param {Number} c The blur size of the shadow or The opacity of the shadow (0 to 1) 283 * @param {null | Number} d Null or The blur size of the shadow 284 * @example 285 * old: 286 * labelttf.enableShadow(shadowOffsetX, shadowOffsetY, shadowOpacity, shadowBlur); 287 * new: 288 * labelttf.enableShadow(shadowColor, offset, blurRadius); 289 */ 290 enableShadow: function (a, b, c, d) { 291 if (a.r != null && a.g != null && a.b != null && a.a != null) { 292 this._enableShadow(a, b, c); 293 } else { 294 this._enableShadowNoneColor(a, b, c, d); 295 } 296 }, 297 298 _enableShadowNoneColor: function (shadowOffsetX, shadowOffsetY, shadowOpacity, shadowBlur) { 299 shadowOpacity = shadowOpacity || 0.5; 300 if (false === this._shadowEnabled) 301 this._shadowEnabled = true; 302 303 var locShadowOffset = this._shadowOffset; 304 if (locShadowOffset && (locShadowOffset.x !== shadowOffsetX) || (locShadowOffset._y !== shadowOffsetY)) { 305 locShadowOffset.x = shadowOffsetX; 306 locShadowOffset.y = shadowOffsetY; 307 } 308 309 if (this._shadowOpacity !== shadowOpacity) { 310 this._shadowOpacity = shadowOpacity; 311 } 312 this._renderCmd._setColorsString(); 313 314 if (this._shadowBlur !== shadowBlur) 315 this._shadowBlur = shadowBlur; 316 this._setUpdateTextureDirty(); 317 }, 318 319 _enableShadow: function (shadowColor, offset, blurRadius) { 320 if (!this._shadowColor) { 321 this._shadowColor = cc.color(255, 255, 255, 128); 322 } 323 this._shadowColor.r = shadowColor.r; 324 this._shadowColor.g = shadowColor.g; 325 this._shadowColor.b = shadowColor.b; 326 327 var x, y, a, b; 328 x = offset.width || offset.x || 0; 329 y = offset.height || offset.y || 0; 330 a = (shadowColor.a != null) ? (shadowColor.a / 255) : 0.5; 331 b = blurRadius; 332 333 this._enableShadowNoneColor(x, y, a, b); 334 }, 335 336 _getShadowOffsetX: function () { 337 return this._shadowOffset.x; 338 }, 339 _setShadowOffsetX: function (x) { 340 if (false === this._shadowEnabled) 341 this._shadowEnabled = true; 342 343 if (this._shadowOffset.x !== x) { 344 this._shadowOffset.x = x; 345 this._setUpdateTextureDirty(); 346 } 347 }, 348 349 _getShadowOffsetY: function () { 350 return this._shadowOffset._y; 351 }, 352 _setShadowOffsetY: function (y) { 353 if (false === this._shadowEnabled) 354 this._shadowEnabled = true; 355 356 if (this._shadowOffset._y !== y) { 357 this._shadowOffset._y = y; 358 this._setUpdateTextureDirty(); 359 } 360 }, 361 362 _getShadowOffset: function () { 363 return cc.p(this._shadowOffset.x, this._shadowOffset.y); 364 }, 365 _setShadowOffset: function (offset) { 366 if (false === this._shadowEnabled) 367 this._shadowEnabled = true; 368 369 if (this._shadowOffset.x !== offset.x || this._shadowOffset.y !== offset.y) { 370 this._shadowOffset.x = offset.x; 371 this._shadowOffset.y = offset.y; 372 this._setUpdateTextureDirty(); 373 } 374 }, 375 376 _getShadowOpacity: function () { 377 return this._shadowOpacity; 378 }, 379 _setShadowOpacity: function (shadowOpacity) { 380 if (false === this._shadowEnabled) 381 this._shadowEnabled = true; 382 383 if (this._shadowOpacity !== shadowOpacity) { 384 this._shadowOpacity = shadowOpacity; 385 this._renderCmd._setColorsString(); 386 this._setUpdateTextureDirty(); 387 } 388 }, 389 390 _getShadowBlur: function () { 391 return this._shadowBlur; 392 }, 393 _setShadowBlur: function (shadowBlur) { 394 if (false === this._shadowEnabled) 395 this._shadowEnabled = true; 396 397 if (this._shadowBlur !== shadowBlur) { 398 this._shadowBlur = shadowBlur; 399 this._setUpdateTextureDirty(); 400 } 401 }, 402 403 /** 404 * Disable shadow rendering 405 */ 406 disableShadow: function () { 407 if (this._shadowEnabled) { 408 this._shadowEnabled = false; 409 this._setUpdateTextureDirty(); 410 } 411 }, 412 413 /** 414 * Enable label stroke with stroke parameters 415 * @param {cc.Color} strokeColor The color of stroke 416 * @param {Number} strokeSize The size of stroke 417 */ 418 enableStroke: function (strokeColor, strokeSize) { 419 if (this._strokeEnabled === false) 420 this._strokeEnabled = true; 421 422 var locStrokeColor = this._strokeColor; 423 if ((locStrokeColor.r !== strokeColor.r) || (locStrokeColor.g !== strokeColor.g) || (locStrokeColor.b !== strokeColor.b)) { 424 locStrokeColor.r = strokeColor.r; 425 locStrokeColor.g = strokeColor.g; 426 locStrokeColor.b = strokeColor.b; 427 this._renderCmd._setColorsString(); 428 } 429 430 if (this._strokeSize !== strokeSize) 431 this._strokeSize = strokeSize || 0; 432 this._setUpdateTextureDirty(); 433 }, 434 435 _getStrokeStyle: function () { 436 return this._strokeColor; 437 }, 438 _setStrokeStyle: function (strokeStyle) { 439 if (this._strokeEnabled === false) 440 this._strokeEnabled = true; 441 442 var locStrokeColor = this._strokeColor; 443 if ((locStrokeColor.r !== strokeStyle.r) || (locStrokeColor.g !== strokeStyle.g) || (locStrokeColor.b !== strokeStyle.b)) { 444 locStrokeColor.r = strokeStyle.r; 445 locStrokeColor.g = strokeStyle.g; 446 locStrokeColor.b = strokeStyle.b; 447 this._renderCmd._setColorsString(); 448 this._setUpdateTextureDirty(); 449 } 450 }, 451 452 _getLineWidth: function () { 453 return this._strokeSize; 454 }, 455 _setLineWidth: function (lineWidth) { 456 if (this._strokeEnabled === false) 457 this._strokeEnabled = true; 458 if (this._strokeSize !== lineWidth) { 459 this._strokeSize = lineWidth || 0; 460 this._setUpdateTextureDirty(); 461 } 462 }, 463 464 /** 465 * Disable label stroke 466 */ 467 disableStroke: function () { 468 if (this._strokeEnabled) { 469 this._strokeEnabled = false; 470 this._setUpdateTextureDirty(); 471 } 472 }, 473 474 /** 475 * Sets the text fill color 476 * @function 477 * @param {cc.Color} fillColor The fill color of the label 478 */ 479 setFontFillColor: function (fillColor) { 480 var locTextFillColor = this._textFillColor; 481 if (locTextFillColor.r !== fillColor.r || locTextFillColor.g !== fillColor.g || locTextFillColor.b !== fillColor.b) { 482 locTextFillColor.r = fillColor.r; 483 locTextFillColor.g = fillColor.g; 484 locTextFillColor.b = fillColor.b; 485 this._renderCmd._setColorsString(); 486 this._needUpdateTexture = true; 487 } 488 }, 489 490 _getFillStyle: function () { 491 return this._textFillColor; 492 }, 493 494 //set the text definition for this label 495 _updateWithTextDefinition: function (textDefinition, mustUpdateTexture) { 496 if (textDefinition.fontDimensions) { 497 this._dimensions.width = textDefinition.boundingWidth; 498 this._dimensions.height = textDefinition.boundingHeight; 499 } else { 500 this._dimensions.width = 0; 501 this._dimensions.height = 0; 502 } 503 504 this._hAlignment = textDefinition.textAlign; 505 this._vAlignment = textDefinition.verticalAlign; 506 507 this._fontName = textDefinition.fontName; 508 this._fontSize = textDefinition.fontSize || 12; 509 510 if(textDefinition.lineHeight) 511 this._lineHeight = textDefinition.lineHeight 512 else 513 this._lineHeight = this._fontSize; 514 515 this._renderCmd._setFontStyle(textDefinition); 516 517 518 // shadow 519 if (textDefinition.shadowEnabled) 520 this.enableShadow(textDefinition.shadowOffsetX, 521 textDefinition.shadowOffsetY, 522 textDefinition.shadowOpacity, 523 textDefinition.shadowBlur); 524 525 // stroke 526 if (textDefinition.strokeEnabled) 527 this.enableStroke(textDefinition.strokeStyle, textDefinition.lineWidth); 528 529 // fill color 530 this.setFontFillColor(textDefinition.fillStyle); 531 532 if (mustUpdateTexture) 533 this._renderCmd._updateTexture(); 534 var flags = cc.Node._dirtyFlags; 535 this._renderCmd.setDirtyFlag(flags.colorDirty|flags.opacityDirty|flags.textDirty); 536 }, 537 538 _prepareTextDefinition: function (adjustForResolution) { 539 var texDef = new cc.FontDefinition(); 540 541 if (adjustForResolution) { 542 texDef.fontSize = this._fontSize; 543 texDef.boundingWidth = cc.contentScaleFactor() * this._dimensions.width; 544 texDef.boundingHeight = cc.contentScaleFactor() * this._dimensions.height; 545 } else { 546 texDef.fontSize = this._fontSize; 547 texDef.boundingWidth = this._dimensions.width; 548 texDef.boundingHeight = this._dimensions.height; 549 } 550 551 texDef.fontName = this._fontName; 552 texDef.textAlign = this._hAlignment; 553 texDef.verticalAlign = this._vAlignment; 554 555 // stroke 556 if (this._strokeEnabled) { 557 texDef.strokeEnabled = true; 558 var locStrokeColor = this._strokeColor; 559 texDef.strokeStyle = cc.color(locStrokeColor.r, locStrokeColor.g, locStrokeColor.b); 560 texDef.lineWidth = this._strokeSize; 561 } else 562 texDef.strokeEnabled = false; 563 564 // shadow 565 if (this._shadowEnabled) { 566 texDef.shadowEnabled = true; 567 texDef.shadowBlur = this._shadowBlur; 568 texDef.shadowOpacity = this._shadowOpacity; 569 570 texDef.shadowOffsetX = (adjustForResolution ? cc.contentScaleFactor() : 1) * this._shadowOffset.x; 571 texDef.shadowOffsetY = (adjustForResolution ? cc.contentScaleFactor() : 1) * this._shadowOffset.y; 572 } else 573 texDef._shadowEnabled = false; 574 575 // text tint 576 var locTextFillColor = this._textFillColor; 577 texDef.fillStyle = cc.color(locTextFillColor.r, locTextFillColor.g, locTextFillColor.b); 578 return texDef; 579 }, 580 581 /** 582 * Changes the text content of the label 583 * @warning Changing the string is as expensive as creating a new cc.LabelTTF. To obtain better performance use cc.LabelAtlas 584 * @param {String} text Text content for the label 585 */ 586 setString: function (text) { 587 text = String(text); 588 if (this._originalText !== text) { 589 this._originalText = text + ""; 590 591 this._updateString(); 592 593 // Force update 594 this._setUpdateTextureDirty(); 595 this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty); 596 } 597 }, 598 _updateString: function () { 599 if ((!this._string || this._string === "") && this._string !== this._originalText) 600 cc.renderer.childrenOrderDirty = true; 601 this._string = this._originalText; 602 }, 603 604 /** 605 * Sets Horizontal Alignment of cc.LabelTTF 606 * @param {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} alignment Horizontal Alignment 607 */ 608 setHorizontalAlignment: function (alignment) { 609 if (alignment !== this._hAlignment) { 610 this._hAlignment = alignment; 611 // Force update 612 this._setUpdateTextureDirty(); 613 } 614 }, 615 616 /** 617 * Sets Vertical Alignment of cc.LabelTTF 618 * @param {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} verticalAlignment 619 */ 620 setVerticalAlignment: function (verticalAlignment) { 621 if (verticalAlignment !== this._vAlignment) { 622 this._vAlignment = verticalAlignment; 623 624 // Force update 625 this._setUpdateTextureDirty(); 626 } 627 }, 628 629 /** 630 * Set Dimensions of cc.LabelTTF, the dimension is the maximum size of the label, set it so that label will automatically change lines when necessary. 631 * @param {cc.Size|Number} dim dimensions or width of dimensions 632 * @param {Number} [height] height of dimensions 633 */ 634 setDimensions: function (dim, height) { 635 var width; 636 if (height === undefined) { 637 width = dim.width; 638 height = dim.height; 639 } else 640 width = dim; 641 642 if (width !== this._dimensions.width || height !== this._dimensions.height) { 643 this._dimensions.width = width; 644 this._dimensions.height = height; 645 this._updateString(); 646 // Force update 647 this._setUpdateTextureDirty(); 648 } 649 }, 650 651 _getBoundingWidth: function () { 652 return this._dimensions.width; 653 }, 654 _setBoundingWidth: function (width) { 655 if (width !== this._dimensions.width) { 656 this._dimensions.width = width; 657 this._updateString(); 658 // Force update 659 this._setUpdateTextureDirty(); 660 } 661 }, 662 663 _getBoundingHeight: function () { 664 return this._dimensions.height; 665 }, 666 _setBoundingHeight: function (height) { 667 if (height !== this._dimensions.height) { 668 this._dimensions.height = height; 669 this._updateString(); 670 // Force update 671 this._setUpdateTextureDirty(); 672 } 673 }, 674 675 /** 676 * Sets font size of cc.LabelTTF 677 * @param {Number} fontSize 678 */ 679 setFontSize: function (fontSize) { 680 if (this._fontSize !== fontSize) { 681 this._fontSize = fontSize; 682 this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight); 683 // Force update 684 this._setUpdateTextureDirty(); 685 } 686 }, 687 688 /** 689 * Sets font name of cc.LabelTTF 690 * @param {String} fontName 691 */ 692 setFontName: function (fontName) { 693 if (this._fontName && this._fontName !== fontName) { 694 this._fontName = fontName; 695 this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight); 696 // Force update 697 this._setUpdateTextureDirty(); 698 } 699 }, 700 701 _getFont: function () { 702 return this._renderCmd._getFontStyle(); 703 }, 704 _setFont: function (fontStyle) { 705 var res = cc.LabelTTF._fontStyleRE.exec(fontStyle); 706 if (res) { 707 this._fontSize = parseInt(res[1]); 708 this._fontName = res[2]; 709 this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight); 710 711 // Force update 712 this._setUpdateTextureDirty(); 713 } 714 }, 715 716 /** 717 * Returns the actual content size of the label, the content size is the real size that the label occupied while dimension is the outer bounding box of the label. 718 * @returns {cc.Size} The content size 719 */ 720 getContentSize: function () { 721 if (this._needUpdateTexture) 722 this._renderCmd._updateTTF(); 723 return cc.Sprite.prototype.getContentSize.call(this); 724 }, 725 726 _getWidth: function () { 727 if (this._needUpdateTexture) 728 this._renderCmd._updateTTF(); 729 return cc.Sprite.prototype._getWidth.call(this); 730 }, 731 _getHeight: function () { 732 if (this._needUpdateTexture) 733 this._renderCmd._updateTTF(); 734 return cc.Sprite.prototype._getHeight.call(this); 735 }, 736 737 setTextureRect: function (rect, rotated, untrimmedSize) { 738 //set needConvert to false 739 cc.Sprite.prototype.setTextureRect.call(this, rect, rotated, untrimmedSize, false); 740 }, 741 742 /** 743 * set Target to draw on 744 * @param boolean onCanvas 745 */ 746 setDrawMode: function (onCacheMode) { 747 this._onCacheCanvasMode = onCacheMode; 748 }, 749 750 _createRenderCmd: function () { 751 if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) 752 return new cc.LabelTTF.WebGLRenderCmd(this); 753 else if (this._onCacheCanvasMode) 754 return new cc.LabelTTF.CacheCanvasRenderCmd(this); 755 else 756 return new cc.LabelTTF.CanvasRenderCmd(this); 757 }, 758 759 //For web only 760 _setFontStyle: function(fontStyle){ 761 if (this._fontStyle !== fontStyle) { 762 this._fontStyle = fontStyle; 763 this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight); 764 this._setUpdateTextureDirty(); 765 } 766 }, 767 768 _getFontStyle: function(){ 769 return this._fontStyle; 770 }, 771 772 _setFontWeight: function(fontWeight){ 773 if (this._fontWeight !== fontWeight) { 774 this._fontWeight = fontWeight; 775 this._renderCmd._setFontStyle(this._fontName, this._fontSize, this._fontStyle, this._fontWeight); 776 this._setUpdateTextureDirty(); 777 } 778 }, 779 780 _getFontWeight: function(){ 781 return this._fontWeight; 782 } 783 }); 784 785 cc.assert(cc.isFunction(cc._tmp.PrototypeLabelTTF), cc._LogInfos.MissingFile, "LabelTTFPropertyDefine.js"); 786 cc._tmp.PrototypeLabelTTF(); 787 delete cc._tmp.PrototypeLabelTTF; 788 789 // Only support style in this format: "18px Verdana" or "18px 'Helvetica Neue'" 790 cc.LabelTTF._fontStyleRE = /^(\d+)px\s+['"]?([\w\s\d]+)['"]?$/; 791 792 /** 793 * creates a cc.LabelTTF from a font name, alignment, dimension and font size 794 * @deprecated since v3.0, please use the new construction instead 795 * @see cc.LabelTTF 796 * @static 797 * @param {String} text 798 * @param {String|cc.FontDefinition} [fontName="Arial"] 799 * @param {Number} [fontSize=16] 800 * @param {cc.Size} [dimensions=cc.size(0,0)] 801 * @param {Number} [hAlignment=cc.TEXT_ALIGNMENT_LEFT] 802 * @param {Number} [vAlignment=cc.VERTICAL_TEXT_ALIGNMENT_TOP] 803 * @return {cc.LabelTTF|Null} 804 */ 805 cc.LabelTTF.create = function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) { 806 return new cc.LabelTTF(text, fontName, fontSize, dimensions, hAlignment, vAlignment); 807 }; 808 809 /** 810 * @deprecated since v3.0, please use the new construction instead 811 * @function 812 * @static 813 */ 814 cc.LabelTTF.createWithFontDefinition = cc.LabelTTF.create; 815 816 if (cc.USE_LA88_LABELS) 817 cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTURECOLOR; 818 else 819 cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTUREA8COLOR; 820 821 cc.LabelTTF.__labelHeightDiv = document.createElement("div"); 822 cc.LabelTTF.__labelHeightDiv.style.fontFamily = "Arial"; 823 cc.LabelTTF.__labelHeightDiv.style.position = "absolute"; 824 cc.LabelTTF.__labelHeightDiv.style.left = "-100px"; 825 cc.LabelTTF.__labelHeightDiv.style.top = "-100px"; 826 cc.LabelTTF.__labelHeightDiv.style.lineHeight = "normal"; 827 828 document.body ? 829 document.body.appendChild(cc.LabelTTF.__labelHeightDiv) : 830 window.addEventListener('load', function () { 831 this.removeEventListener('load', arguments.callee, false); 832 document.body.appendChild(cc.LabelTTF.__labelHeightDiv); 833 }, false); 834 835 cc.LabelTTF.__getFontHeightByDiv = function (fontName, fontSize) { 836 837 if(fontName instanceof cc.FontDefinition){ 838 /** @type cc.FontDefinition */ 839 var fontDef = fontName; 840 var clientHeight = cc.LabelTTF.__fontHeightCache[fontDef._getCanvasFontStr()]; 841 if (clientHeight > 0) return clientHeight; 842 var labelDiv = cc.LabelTTF.__labelHeightDiv; 843 labelDiv.innerHTML = "ajghl~!"; 844 labelDiv.style.fontFamily = fontDef.fontName; 845 labelDiv.style.fontSize = fontDef.fontSize + "px"; 846 labelDiv.style.fontStyle = fontDef.fontStyle; 847 labelDiv.style.fontWeight = fontDef.fontWeight; 848 849 clientHeight = labelDiv.clientHeight; 850 cc.LabelTTF.__fontHeightCache[fontDef._getCanvasFontStr()] = clientHeight; 851 labelDiv.innerHTML = ""; 852 return clientHeight; 853 } 854 855 //Default 856 var clientHeight = cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize]; 857 if (clientHeight > 0) return clientHeight; 858 var labelDiv = cc.LabelTTF.__labelHeightDiv; 859 labelDiv.innerHTML = "ajghl~!"; 860 labelDiv.style.fontFamily = fontName; 861 labelDiv.style.fontSize = fontSize + "px"; 862 clientHeight = labelDiv.clientHeight; 863 cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize] = clientHeight; 864 labelDiv.innerHTML = ""; 865 return clientHeight; 866 867 }; 868 869 cc.LabelTTF.__fontHeightCache = {}; 870