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 _isMultiLine: false, 75 _fontStyleStr: null, 76 77 // font shadow 78 _shadowEnabled: false, 79 _shadowOffset: null, 80 _shadowOpacity: 0, 81 _shadowBlur: 0, 82 _shadowColorStr: null, 83 84 // font stroke 85 _strokeEnabled: false, 86 _strokeColor: null, 87 _strokeSize: 0, 88 _strokeColorStr: null, 89 90 // font tint 91 _textFillColor: null, 92 _fillColorStr: null, 93 94 _strokeShadowOffsetX: 0, 95 _strokeShadowOffsetY: 0, 96 _needUpdateTexture: false, 97 98 _labelCanvas: null, 99 _labelContext: null, 100 _lineWidths: null, 101 _className: "LabelTTF", 102 103 /** 104 * Initializes the cc.LabelTTF 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. 105 * @param {String} label string 106 * @param {String} fontName 107 * @param {Number} fontSize 108 * @param {cc.Size} [dimensions=] 109 * @param {Number} [hAlignment=] 110 * @param {Number} [vAlignment=] 111 * @return {Boolean} return false on error 112 */ 113 initWithString: function (label, fontName, fontSize, dimensions, hAlignment, vAlignment) { 114 var strInfo; 115 if (label) 116 strInfo = label + ""; 117 else 118 strInfo = ""; 119 120 fontSize = fontSize || 16; 121 dimensions = dimensions || cc.size(0, 0/*fontSize*/); 122 hAlignment = hAlignment || cc.TEXT_ALIGNMENT_LEFT; 123 vAlignment = vAlignment || cc.VERTICAL_TEXT_ALIGNMENT_TOP; 124 125 this._opacityModifyRGB = false; 126 this._dimensions = cc.size(dimensions.width, dimensions.height); 127 this._fontName = fontName || "Arial"; 128 this._hAlignment = hAlignment; 129 this._vAlignment = vAlignment; 130 131 //this._fontSize = (cc._renderType === cc._RENDER_TYPE_CANVAS) ? fontSize : fontSize * cc.contentScaleFactor(); 132 this._fontSize = fontSize; 133 this._fontStyleStr = this._fontSize + "px '" + fontName + "'"; 134 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontName, this._fontSize); 135 this.string = strInfo; 136 this._setColorsString(); 137 this._updateTexture(); 138 this._needUpdateTexture = false; 139 return true; 140 }, 141 142 ctor: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) { 143 cc.Sprite.prototype.ctor.call(this); 144 145 this._dimensions = cc.size(0, 0); 146 this._hAlignment = cc.TEXT_ALIGNMENT_LEFT; 147 this._vAlignment = cc.VERTICAL_TEXT_ALIGNMENT_TOP; 148 this._opacityModifyRGB = false; 149 this._fontStyleStr = ""; 150 this._fontName = "Arial"; 151 this._isMultiLine = false; 152 153 this._shadowEnabled = false; 154 this._shadowOffset = cc.p(0, 0); 155 this._shadowOpacity = 0; 156 this._shadowBlur = 0; 157 this._shadowColorStr = "rgba(128, 128, 128, 0.5)"; 158 159 this._strokeEnabled = false; 160 this._strokeColor = cc.color(255, 255, 255, 255); 161 this._strokeSize = 0; 162 this._strokeColorStr = ""; 163 164 this._textFillColor = cc.color(255, 255, 255, 255); 165 this._fillColorStr = "rgba(255,255,255,1)"; 166 this._strokeShadowOffsetX = 0; 167 this._strokeShadowOffsetY = 0; 168 this._needUpdateTexture = false; 169 170 this._lineWidths = []; 171 172 this._setColorsString(); 173 174 if (fontName && fontName instanceof cc.FontDefinition) { 175 this.initWithStringAndTextDefinition(text, fontName); 176 } 177 else { 178 cc.LabelTTF.prototype.initWithString.call(this, text, fontName, fontSize, dimensions, hAlignment, vAlignment); 179 } 180 }, 181 182 init: function () { 183 return this.initWithString(" ", this._fontName, this._fontSize); 184 }, 185 186 _measureConfig: function () { 187 this._getLabelContext().font = this._fontStyleStr; 188 }, 189 _measure: function (text) { 190 return this._getLabelContext().measureText(text).width; 191 }, 192 193 description: function () { 194 return "<cc.LabelTTF | FontName =" + this._fontName + " FontSize = " + this._fontSize.toFixed(1) + ">"; 195 }, 196 197 setColor: null, 198 199 _setColorsString: null, 200 201 updateDisplayedColor: null, 202 203 setOpacity: null, 204 205 updateDisplayedOpacity: null, 206 207 updateDisplayedOpacityForCanvas: function (parentOpacity) { 208 cc.Node.prototype.updateDisplayedOpacity.call(this, parentOpacity); 209 this._setColorsString(); 210 }, 211 212 /** 213 * Returns the text of the label 214 * @return {String} 215 */ 216 getString: function () { 217 return this._string; 218 }, 219 220 /** 221 * Returns Horizontal Alignment of cc.LabelTTF 222 * @return {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} 223 */ 224 getHorizontalAlignment: function () { 225 return this._hAlignment; 226 }, 227 228 /** 229 * Returns Vertical Alignment of cc.LabelTTF 230 * @return {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} 231 */ 232 getVerticalAlignment: function () { 233 return this._vAlignment; 234 }, 235 236 /** 237 * 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. 238 * @see cc.LabelTTF#setDimensions, cc.LabelTTF#boundingWidth and cc.LabelTTF#boundingHeight 239 * @return {cc.Size} 240 */ 241 getDimensions: function () { 242 return cc.size(this._dimensions); 243 }, 244 245 /** 246 * Returns font size of cc.LabelTTF 247 * @return {Number} 248 */ 249 getFontSize: function () { 250 return this._fontSize; 251 }, 252 253 /** 254 * Returns font name of cc.LabelTTF 255 * @return {String} 256 */ 257 getFontName: function () { 258 return this._fontName; 259 }, 260 261 /** 262 * 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. 263 * @param {String} text 264 * @param {cc.FontDefinition} textDefinition 265 * @return {Boolean} 266 */ 267 initWithStringAndTextDefinition: null, 268 269 /** 270 * Sets the text definition used by this label 271 * @param {cc.FontDefinition} theDefinition 272 */ 273 setTextDefinition: function (theDefinition) { 274 if (theDefinition) 275 this._updateWithTextDefinition(theDefinition, true); 276 }, 277 278 /** 279 * Extract the text definition used by this label 280 * @return {cc.FontDefinition} 281 */ 282 getTextDefinition: function () { 283 return this._prepareTextDefinition(false); 284 }, 285 286 /** 287 * Enable or disable shadow for the label 288 * @param {Number} shadowOffsetX The x axis offset of the shadow 289 * @param {Number} shadowOffsetY The y axis offset of the shadow 290 * @param {Number} shadowOpacity The opacity of the shadow (0 to 1) 291 * @param {Number} shadowBlur The blur size of the shadow 292 */ 293 enableShadow: function (shadowOffsetX, shadowOffsetY, shadowOpacity, shadowBlur) { 294 shadowOpacity = shadowOpacity || 0.5; 295 if (false === this._shadowEnabled) 296 this._shadowEnabled = true; 297 298 var locShadowOffset = this._shadowOffset; 299 if (locShadowOffset && (locShadowOffset.x != shadowOffsetX) || (locShadowOffset._y != shadowOffsetY)) { 300 locShadowOffset.x = shadowOffsetX; 301 locShadowOffset.y = shadowOffsetY; 302 } 303 304 if (this._shadowOpacity != shadowOpacity) { 305 this._shadowOpacity = shadowOpacity; 306 } 307 this._setColorsString(); 308 309 if (this._shadowBlur != shadowBlur) 310 this._shadowBlur = shadowBlur; 311 312 this._needUpdateTexture = true; 313 }, 314 315 _getShadowOffsetX: function () { 316 return this._shadowOffset.x; 317 }, 318 _setShadowOffsetX: function (x) { 319 if (false === this._shadowEnabled) 320 this._shadowEnabled = true; 321 322 if (this._shadowOffset.x != x) { 323 this._shadowOffset.x = x; 324 this._needUpdateTexture = true; 325 } 326 }, 327 328 _getShadowOffsetY: function () { 329 return this._shadowOffset._y; 330 }, 331 _setShadowOffsetY: function (y) { 332 if (false === this._shadowEnabled) 333 this._shadowEnabled = true; 334 335 if (this._shadowOffset._y != y) { 336 this._shadowOffset._y = y; 337 this._needUpdateTexture = true; 338 } 339 }, 340 341 _getShadowOffset: function () { 342 return cc.p(this._shadowOffset.x, this._shadowOffset.y); 343 }, 344 _setShadowOffset: function (offset) { 345 if (false === this._shadowEnabled) 346 this._shadowEnabled = true; 347 348 if (this._shadowOffset.x != offset.x || this._shadowOffset.y != offset.y) { 349 this._shadowOffset.x = offset.x; 350 this._shadowOffset.y = offset.y; 351 this._needUpdateTexture = true; 352 } 353 }, 354 355 _getShadowOpacity: function () { 356 return this._shadowOpacity; 357 }, 358 _setShadowOpacity: function (shadowOpacity) { 359 if (false === this._shadowEnabled) 360 this._shadowEnabled = true; 361 362 if (this._shadowOpacity != shadowOpacity) { 363 this._shadowOpacity = shadowOpacity; 364 this._setColorsString(); 365 this._needUpdateTexture = true; 366 } 367 }, 368 369 _getShadowBlur: function () { 370 return this._shadowBlur; 371 }, 372 _setShadowBlur: function (shadowBlur) { 373 if (false === this._shadowEnabled) 374 this._shadowEnabled = true; 375 376 if (this._shadowBlur != shadowBlur) { 377 this._shadowBlur = shadowBlur; 378 this._needUpdateTexture = true; 379 } 380 }, 381 382 /** 383 * Disable shadow rendering 384 */ 385 disableShadow: function () { 386 if (this._shadowEnabled) { 387 this._shadowEnabled = false; 388 this._needUpdateTexture = true; 389 } 390 }, 391 392 /** 393 * Enable label stroke with stroke parameters 394 * @param {cc.Color} strokeColor The color of stroke 395 * @param {Number} strokeSize The size of stroke 396 */ 397 enableStroke: function (strokeColor, strokeSize) { 398 if (this._strokeEnabled === false) 399 this._strokeEnabled = true; 400 401 var locStrokeColor = this._strokeColor; 402 if ((locStrokeColor.r !== strokeColor.r) || (locStrokeColor.g !== strokeColor.g) || (locStrokeColor.b !== strokeColor.b)) { 403 locStrokeColor.r = strokeColor.r; 404 locStrokeColor.g = strokeColor.g; 405 locStrokeColor.b = strokeColor.b; 406 this._setColorsString(); 407 } 408 409 if (this._strokeSize !== strokeSize) 410 this._strokeSize = strokeSize || 0; 411 412 this._needUpdateTexture = true; 413 }, 414 415 _getStrokeStyle: function () { 416 return this._strokeColor; 417 }, 418 _setStrokeStyle: function (strokeStyle) { 419 if (this._strokeEnabled === false) 420 this._strokeEnabled = true; 421 422 var locStrokeColor = this._strokeColor; 423 if ((locStrokeColor.r !== strokeStyle.r) || (locStrokeColor.g !== strokeStyle.g) || (locStrokeColor.b !== strokeStyle.b)) { 424 locStrokeColor.r = strokeStyle.r; 425 locStrokeColor.g = strokeStyle.g; 426 locStrokeColor.b = strokeStyle.b; 427 this._setColorsString(); 428 429 this._needUpdateTexture = true; 430 } 431 }, 432 433 _getLineWidth: function () { 434 return this._strokeSize; 435 }, 436 _setLineWidth: function (lineWidth) { 437 if (this._strokeEnabled === false) 438 this._strokeEnabled = true; 439 440 if (this._strokeSize !== lineWidth) { 441 this._strokeSize = lineWidth || 0; 442 this._needUpdateTexture = true; 443 } 444 }, 445 446 /** 447 * Disable label stroke 448 */ 449 disableStroke: function () { 450 if (this._strokeEnabled) { 451 this._strokeEnabled = false; 452 this._needUpdateTexture = true; 453 } 454 }, 455 456 /** 457 * Sets the text fill color 458 * @function 459 * @param {cc.Color} fillColor The fill color of the label 460 */ 461 setFontFillColor: null, 462 463 _getFillStyle: function () { 464 return this._textFillColor; 465 }, 466 467 //set the text definition for this label 468 _updateWithTextDefinition: function (textDefinition, mustUpdateTexture) { 469 if (textDefinition.fontDimensions) { 470 this._dimensions.width = textDefinition.boundingWidth; 471 this._dimensions.height = textDefinition.boundingHeight; 472 } else { 473 this._dimensions.width = 0; 474 this._dimensions.height = 0; 475 } 476 477 this._hAlignment = textDefinition.textAlign; 478 this._vAlignment = textDefinition.verticalAlign; 479 480 this._fontName = textDefinition.fontName; 481 this._fontSize = textDefinition.fontSize || 12; 482 this._fontStyleStr = this._fontSize + "px '" + this._fontName + "'"; 483 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(this._fontName, this._fontSize); 484 485 // shadow 486 if (textDefinition.shadowEnabled) 487 this.enableShadow(textDefinition.shadowOffsetX, 488 textDefinition.shadowOffsetY, 489 textDefinition.shadowOpacity, 490 textDefinition.shadowBlur); 491 492 // stroke 493 if (textDefinition.strokeEnabled) 494 this.enableStroke(textDefinition.strokeStyle, textDefinition.lineWidth); 495 496 // fill color 497 this.setFontFillColor(textDefinition.fillStyle); 498 499 if (mustUpdateTexture) 500 this._updateTexture(); 501 }, 502 503 _prepareTextDefinition: function (adjustForResolution) { 504 var texDef = new cc.FontDefinition(); 505 506 if (adjustForResolution) { 507 //texDef.fontSize = (cc._renderType === cc._RENDER_TYPE_CANVAS) ? this._fontSize : this._fontSize * cc.contentScaleFactor(); 508 texDef.fontSize = this._fontSize; 509 texDef.boundingWidth = cc.contentScaleFactor() * this._dimensions.width; 510 texDef.boundingHeight = cc.contentScaleFactor() * this._dimensions.height; 511 } else { 512 texDef.fontSize = this._fontSize; 513 texDef.boundingWidth = this._dimensions.width; 514 texDef.boundingHeight = this._dimensions.height; 515 } 516 517 texDef.fontName = this._fontName; 518 texDef.textAlign = this._hAlignment; 519 texDef.verticalAlign = this._vAlignment; 520 521 // stroke 522 if (this._strokeEnabled) { 523 texDef.strokeEnabled = true; 524 var locStrokeColor = this._strokeColor; 525 texDef.strokeStyle = cc.color(locStrokeColor.r, locStrokeColor.g, locStrokeColor.b); 526 texDef.lineWidth = this._strokeSize; 527 } else 528 texDef.strokeEnabled = false; 529 530 // shadow 531 if (this._shadowEnabled) { 532 texDef.shadowEnabled = true; 533 texDef.shadowBlur = this._shadowBlur; 534 texDef.shadowOpacity = this._shadowOpacity; 535 536 texDef.shadowOffsetX = (adjustForResolution ? cc.contentScaleFactor() : 1) * this._shadowOffset.x; 537 texDef.shadowOffsetY = (adjustForResolution ? cc.contentScaleFactor() : 1) * this._shadowOffset.y; 538 } else 539 texDef._shadowEnabled = false; 540 541 // text tint 542 var locTextFillColor = this._textFillColor; 543 texDef.fillStyle = cc.color(locTextFillColor.r, locTextFillColor.g, locTextFillColor.b); 544 return texDef; 545 }, 546 547 _fontClientHeight: 18, 548 549 /** 550 * Changes the text content of the label 551 * @warning Changing the string is as expensive as creating a new cc.LabelTTF. To obtain better performance use cc.LabelAtlas 552 * @param {String} text Text content for the label 553 */ 554 setString: function (text) { 555 text = String(text); 556 if (this._originalText != text) { 557 this._originalText = text + ""; 558 559 this._updateString(); 560 561 // Force update 562 this._needUpdateTexture = true; 563 } 564 }, 565 _updateString: function () { 566 this._string = this._originalText; 567 }, 568 569 /** 570 * Sets Horizontal Alignment of cc.LabelTTF 571 * @param {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} alignment Horizontal Alignment 572 */ 573 setHorizontalAlignment: function (alignment) { 574 if (alignment !== this._hAlignment) { 575 this._hAlignment = alignment; 576 577 // Force update 578 this._needUpdateTexture = true; 579 } 580 }, 581 582 /** 583 * Sets Vertical Alignment of cc.LabelTTF 584 * @param {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} verticalAlignment 585 */ 586 setVerticalAlignment: function (verticalAlignment) { 587 if (verticalAlignment != this._vAlignment) { 588 this._vAlignment = verticalAlignment; 589 590 // Force update 591 this._needUpdateTexture = true; 592 } 593 }, 594 595 /** 596 * 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. 597 * @param {cc.Size|Number} dim dimensions or width of dimensions 598 * @param {Number} [height] height of dimensions 599 */ 600 setDimensions: function (dim, height) { 601 var width; 602 if(height === undefined){ 603 width = dim.width; 604 height = dim.height; 605 }else 606 width = dim; 607 608 if (width != this._dimensions.width || height != this._dimensions.height) { 609 this._dimensions.width = width; 610 this._dimensions.height = height; 611 this._updateString(); 612 // Force udpate 613 this._needUpdateTexture = true; 614 } 615 }, 616 617 _getBoundingWidth: function () { 618 return this._dimensions.width; 619 }, 620 _setBoundingWidth: function (width) { 621 if (width != this._dimensions.width) { 622 this._dimensions.width = width; 623 this._updateString(); 624 // Force udpate 625 this._needUpdateTexture = true; 626 } 627 }, 628 629 _getBoundingHeight: function () { 630 return this._dimensions.height; 631 }, 632 _setBoundingHeight: function (height) { 633 if (height != this._dimensions.height) { 634 this._dimensions.height = height; 635 this._updateString(); 636 // Force udpate 637 this._needUpdateTexture = true; 638 } 639 }, 640 641 /** 642 * Sets font size of cc.LabelTTF 643 * @param {Number} fontSize 644 */ 645 setFontSize: function (fontSize) { 646 if (this._fontSize !== fontSize) { 647 this._fontSize = fontSize; 648 this._fontStyleStr = fontSize + "px '" + this._fontName + "'"; 649 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(this._fontName, fontSize); 650 // Force update 651 this._needUpdateTexture = true; 652 } 653 }, 654 655 /** 656 * Sets font name of cc.LabelTTF 657 * @param {String} fontName 658 */ 659 setFontName: function (fontName) { 660 if (this._fontName && this._fontName != fontName) { 661 this._fontName = fontName; 662 this._fontStyleStr = this._fontSize + "px '" + fontName + "'"; 663 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontName, this._fontSize); 664 // Force update 665 this._needUpdateTexture = true; 666 } 667 }, 668 669 _getFont: function () { 670 return this._fontStyleStr; 671 }, 672 _setFont: function (fontStyle) { 673 var res = cc.LabelTTF._fontStyleRE.exec(fontStyle); 674 if (res) { 675 this._fontSize = parseInt(res[1]); 676 this._fontName = res[2]; 677 this._fontStyleStr = fontStyle; 678 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(this._fontName, this._fontSize); 679 // Force update 680 this._needUpdateTexture = true; 681 } 682 }, 683 684 _drawTTFInCanvas: function (context) { 685 if (!context) 686 return; 687 var locStrokeShadowOffsetX = this._strokeShadowOffsetX, locStrokeShadowOffsetY = this._strokeShadowOffsetY; 688 var locContentSizeHeight = this._contentSize.height - locStrokeShadowOffsetY, locVAlignment = this._vAlignment, locHAlignment = this._hAlignment, 689 locFontHeight = this._fontClientHeight, locStrokeSize = this._strokeSize; 690 691 context.setTransform(1, 0, 0, 1, 0 + locStrokeShadowOffsetX * 0.5, locContentSizeHeight + locStrokeShadowOffsetY * 0.5); 692 693 //this is fillText for canvas 694 if (context.font != this._fontStyleStr) 695 context.font = this._fontStyleStr; 696 context.fillStyle = this._fillColorStr; 697 698 var xOffset = 0, yOffset = 0; 699 //stroke style setup 700 var locStrokeEnabled = this._strokeEnabled; 701 if (locStrokeEnabled) { 702 context.lineWidth = locStrokeSize * 2; 703 context.strokeStyle = this._strokeColorStr; 704 } 705 706 //shadow style setup 707 if (this._shadowEnabled) { 708 var locShadowOffset = this._shadowOffset; 709 context.shadowColor = this._shadowColorStr; 710 context.shadowOffsetX = locShadowOffset.x; 711 context.shadowOffsetY = -locShadowOffset.y; 712 context.shadowBlur = this._shadowBlur; 713 } 714 715 context.textBaseline = cc.LabelTTF._textBaseline[locVAlignment]; 716 context.textAlign = cc.LabelTTF._textAlign[locHAlignment]; 717 718 var locContentWidth = this._contentSize.width - locStrokeShadowOffsetX; 719 if (locHAlignment === cc.TEXT_ALIGNMENT_RIGHT) 720 xOffset += locContentWidth; 721 else if (locHAlignment === cc.TEXT_ALIGNMENT_CENTER) 722 xOffset += locContentWidth / 2; 723 else 724 xOffset += 0; 725 if (this._isMultiLine) { 726 var locStrLen = this._strings.length; 727 if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM) 728 yOffset = locFontHeight + locContentSizeHeight - locFontHeight * locStrLen; 729 else if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_CENTER) 730 yOffset = locFontHeight / 2 + (locContentSizeHeight - locFontHeight * locStrLen) / 2; 731 732 for (var i = 0; i < locStrLen; i++) { 733 var line = this._strings[i]; 734 var tmpOffsetY = -locContentSizeHeight + (locFontHeight * i) + yOffset; 735 if (locStrokeEnabled) 736 context.strokeText(line, xOffset, tmpOffsetY); 737 context.fillText(line, xOffset, tmpOffsetY); 738 } 739 } else { 740 if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM) { 741 if (locStrokeEnabled) 742 context.strokeText(this._string, xOffset, yOffset); 743 context.fillText(this._string, xOffset, yOffset); 744 } else if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_TOP) { 745 yOffset -= locContentSizeHeight; 746 if (locStrokeEnabled) 747 context.strokeText(this._string, xOffset, yOffset); 748 context.fillText(this._string, xOffset, yOffset); 749 } else { 750 yOffset -= locContentSizeHeight * 0.5; 751 if (locStrokeEnabled) 752 context.strokeText(this._string, xOffset, yOffset); 753 context.fillText(this._string, xOffset, yOffset); 754 } 755 } 756 }, 757 758 _getLabelContext: function () { 759 if (this._labelContext) 760 return this._labelContext; 761 762 if (!this._labelCanvas) { 763 var locCanvas = cc.newElement("canvas"); 764 var labelTexture = new cc.Texture2D(); 765 labelTexture.initWithElement(locCanvas); 766 this.texture = labelTexture; 767 this._labelCanvas = locCanvas; 768 } 769 this._labelContext = this._labelCanvas.getContext("2d"); 770 return this._labelContext; 771 }, 772 773 _checkWarp: function(strArr, i, maxWidth){ 774 var text = strArr[i]; 775 var allWidth = this._measure(text); 776 if(allWidth > maxWidth && text.length > 1){ 777 778 var fuzzyLen = text.length * ( maxWidth / allWidth ) | 0; 779 var tmpText = text.substr(fuzzyLen); 780 var width = allWidth - this._measure(tmpText); 781 var sLine; 782 var pushNum = 0; 783 784 //Increased while cycle maximum ceiling. default 100 time 785 var checkWhile = 0; 786 787 //Exceeded the size 788 while(width > maxWidth && checkWhile++ < 100){ 789 fuzzyLen *= maxWidth / width; 790 fuzzyLen = fuzzyLen | 0; 791 tmpText = text.substr(fuzzyLen); 792 width = allWidth - this._measure(tmpText); 793 } 794 795 checkWhile = 0; 796 797 //Find the truncation point 798 while(width < maxWidth && checkWhile++ < 100){ 799 800 if(tmpText){ 801 var exec = cc.LabelTTF._wordRex.exec(tmpText); 802 pushNum = exec ? exec[0].length : 1; 803 sLine = tmpText; 804 } 805 806 fuzzyLen = fuzzyLen + pushNum; 807 808 tmpText = text.substr(fuzzyLen); 809 810 width = allWidth - this._measure(tmpText); 811 } 812 813 fuzzyLen -= pushNum; 814 815 var sText = text.substr(0, fuzzyLen); 816 817 //symbol in the first 818 if(cc.LabelTTF.wrapInspection){ 819 if(cc.LabelTTF._symbolRex.test(sLine || tmpText)){ 820 var result = cc.LabelTTF._lastWordRex.exec(sText); 821 fuzzyLen -= result ? result[0].length : 0; 822 823 sLine = text.substr(fuzzyLen); 824 sText = text.substr(0, fuzzyLen); 825 } 826 } 827 828 //To judge whether a English words are truncated 829 if(cc.LabelTTF._firsrEnglish.test(sLine)){ 830 var result = cc.LabelTTF._lastEnglish.exec(sText); 831 if(result && sText !== result[0]){ 832 fuzzyLen -= result[0].length; 833 sLine = text.substr(fuzzyLen); 834 sText = text.substr(0, fuzzyLen); 835 } 836 } 837 838 strArr[i] = sLine || tmpText; 839 strArr.splice(i, 0, sText); 840 } 841 }, 842 843 _updateTTF: function () { 844 var locDimensionsWidth = this._dimensions.width, i, strLength; 845 var locLineWidth = this._lineWidths; 846 locLineWidth.length = 0; 847 848 this._isMultiLine = false; 849 this._measureConfig(); 850 if (locDimensionsWidth !== 0) { 851 // Content processing 852 this._strings = this._string.split('\n'); 853 854 for(i = 0; i < this._strings.length; i++){ 855 this._checkWarp(this._strings, i, locDimensionsWidth); 856 } 857 } else { 858 this._strings = this._string.split('\n'); 859 for (i = 0, strLength = this._strings.length; i < strLength; i++) { 860 locLineWidth.push(this._measure(this._strings[i])); 861 } 862 } 863 864 if (this._strings.length > 0) 865 this._isMultiLine = true; 866 867 var locSize, locStrokeShadowOffsetX = 0, locStrokeShadowOffsetY = 0; 868 if (this._strokeEnabled) 869 locStrokeShadowOffsetX = locStrokeShadowOffsetY = this._strokeSize * 2; 870 if (this._shadowEnabled) { 871 var locOffsetSize = this._shadowOffset; 872 locStrokeShadowOffsetX += Math.abs(locOffsetSize.x) * 2; 873 locStrokeShadowOffsetY += Math.abs(locOffsetSize.y) * 2; 874 } 875 876 //get offset for stroke and shadow 877 if (locDimensionsWidth === 0) { 878 if (this._isMultiLine) 879 locSize = cc.size(0 | (Math.max.apply(Math, locLineWidth) + locStrokeShadowOffsetX), 880 0 | ((this._fontClientHeight * this._strings.length) + locStrokeShadowOffsetY)); 881 else 882 locSize = cc.size(0 | (this._measure(this._string) + locStrokeShadowOffsetX), 0 | (this._fontClientHeight + locStrokeShadowOffsetY)); 883 } else { 884 if (this._dimensions.height === 0) { 885 if (this._isMultiLine) 886 locSize = cc.size(0 | (locDimensionsWidth + locStrokeShadowOffsetX), 0 | ((this._fontClientHeight * this._strings.length) + locStrokeShadowOffsetY)); 887 else 888 locSize = cc.size(0 | (locDimensionsWidth + locStrokeShadowOffsetX), 0 | (this._fontClientHeight + locStrokeShadowOffsetY)); 889 } else { 890 //dimension is already set, contentSize must be same as dimension 891 locSize = cc.size(0 | (locDimensionsWidth + locStrokeShadowOffsetX), 0 | (this._dimensions.height + locStrokeShadowOffsetY)); 892 } 893 } 894 this.setContentSize(locSize); 895 this._strokeShadowOffsetX = locStrokeShadowOffsetX; 896 this._strokeShadowOffsetY = locStrokeShadowOffsetY; 897 898 // need computing _anchorPointInPoints 899 var locAP = this._anchorPoint; 900 this._anchorPointInPoints.x = (locStrokeShadowOffsetX * 0.5) + ((locSize.width - locStrokeShadowOffsetX) * locAP.x); 901 this._anchorPointInPoints.y = (locStrokeShadowOffsetY * 0.5) + ((locSize.height - locStrokeShadowOffsetY) * locAP.y); 902 }, 903 904 /** 905 * 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. 906 * @returns {cc.Size} The content size 907 */ 908 getContentSize: function () { 909 if (this._needUpdateTexture) 910 this._updateTTF(); 911 return cc.Sprite.prototype.getContentSize.call(this); 912 }, 913 914 _getWidth: function () { 915 if (this._needUpdateTexture) 916 this._updateTTF(); 917 return cc.Sprite.prototype._getWidth.call(this); 918 }, 919 _getHeight: function () { 920 if (this._needUpdateTexture) 921 this._updateTTF(); 922 return cc.Sprite.prototype._getHeight.call(this); 923 }, 924 925 _updateTexture: function () { 926 var locContext = this._getLabelContext(), locLabelCanvas = this._labelCanvas; 927 var locContentSize = this._contentSize; 928 929 if (this._string.length === 0) { 930 locLabelCanvas.width = 1; 931 locLabelCanvas.height = locContentSize.height || 1; 932 this._texture && this._texture.handleLoadedTexture(); 933 this.setTextureRect(cc.rect(0, 0, 1, locContentSize.height)); 934 return true; 935 } 936 937 //set size for labelCanvas 938 locContext.font = this._fontStyleStr; 939 this._updateTTF(); 940 var width = locContentSize.width, height = locContentSize.height; 941 var flag = locLabelCanvas.width == width && locLabelCanvas.height == height; 942 locLabelCanvas.width = width; 943 locLabelCanvas.height = height; 944 if (flag) locContext.clearRect(0, 0, width, height); 945 946 //draw text to labelCanvas 947 this._drawTTFInCanvas(locContext); 948 this._texture && this._texture.handleLoadedTexture(); 949 950 this.setTextureRect(cc.rect(0, 0, width, height)); 951 return true; 952 }, 953 954 visit: function (ctx) { 955 if (!this._string || this._string == "") 956 return; 957 if (this._needUpdateTexture) { 958 this._needUpdateTexture = false; 959 this._updateTexture(); 960 } 961 var context = ctx || cc._renderContext; 962 cc.Sprite.prototype.visit.call(this, context); 963 }, 964 965 draw: null, 966 967 _setTextureCoords: function (rect) { 968 var tex = this._batchNode ? this.textureAtlas.texture : this._texture; 969 if (!tex) 970 return; 971 972 var atlasWidth = tex.pixelsWidth; 973 var atlasHeight = tex.pixelsHeight; 974 975 var left, right, top, bottom, tempSwap, locQuad = this._quad; 976 if (this._rectRotated) { 977 if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) { 978 left = (2 * rect.x + 1) / (2 * atlasWidth); 979 right = left + (rect.height * 2 - 2) / (2 * atlasWidth); 980 top = (2 * rect.y + 1) / (2 * atlasHeight); 981 bottom = top + (rect.width * 2 - 2) / (2 * atlasHeight); 982 } else { 983 left = rect.x / atlasWidth; 984 right = (rect.x + rect.height) / atlasWidth; 985 top = rect.y / atlasHeight; 986 bottom = (rect.y + rect.width) / atlasHeight; 987 }// CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL 988 989 if (this._flippedX) { 990 tempSwap = top; 991 top = bottom; 992 bottom = tempSwap; 993 } 994 995 if (this._flippedY) { 996 tempSwap = left; 997 left = right; 998 right = tempSwap; 999 } 1000 1001 locQuad.bl.texCoords.u = left; 1002 locQuad.bl.texCoords.v = top; 1003 locQuad.br.texCoords.u = left; 1004 locQuad.br.texCoords.v = bottom; 1005 locQuad.tl.texCoords.u = right; 1006 locQuad.tl.texCoords.v = top; 1007 locQuad.tr.texCoords.u = right; 1008 locQuad.tr.texCoords.v = bottom; 1009 } else { 1010 if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) { 1011 left = (2 * rect.x + 1) / (2 * atlasWidth); 1012 right = left + (rect.width * 2 - 2) / (2 * atlasWidth); 1013 top = (2 * rect.y + 1) / (2 * atlasHeight); 1014 bottom = top + (rect.height * 2 - 2) / (2 * atlasHeight); 1015 } else { 1016 left = rect.x / atlasWidth; 1017 right = (rect.x + rect.width) / atlasWidth; 1018 top = rect.y / atlasHeight; 1019 bottom = (rect.y + rect.height) / atlasHeight; 1020 } // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL 1021 1022 if (this._flippedX) { 1023 tempSwap = left; 1024 left = right; 1025 right = tempSwap; 1026 } 1027 1028 if (this._flippedY) { 1029 tempSwap = top; 1030 top = bottom; 1031 bottom = tempSwap; 1032 } 1033 1034 locQuad.bl.texCoords.u = left; 1035 locQuad.bl.texCoords.v = bottom; 1036 locQuad.br.texCoords.u = right; 1037 locQuad.br.texCoords.v = bottom; 1038 locQuad.tl.texCoords.u = left; 1039 locQuad.tl.texCoords.v = top; 1040 locQuad.tr.texCoords.u = right; 1041 locQuad.tr.texCoords.v = top; 1042 } 1043 this._quadDirty = true; 1044 } 1045 }); 1046 1047 if (cc._renderType === cc._RENDER_TYPE_CANVAS) { 1048 1049 var _p = cc.LabelTTF.prototype; 1050 1051 _p.setColor = function (color3) { 1052 cc.Node.prototype.setColor.call(this, color3); 1053 1054 this._setColorsString(); 1055 }; 1056 1057 _p._setColorsString = function () { 1058 this._needUpdateTexture = true; 1059 1060 var locDisplayColor = this._displayedColor, locDisplayedOpacity = this._displayedOpacity; 1061 var locStrokeColor = this._strokeColor, locFontFillColor = this._textFillColor; 1062 1063 this._shadowColorStr = "rgba(" + (0 | (locDisplayColor.r * 0.5)) + "," + (0 | (locDisplayColor.g * 0.5)) + "," + (0 | (locDisplayColor.b * 0.5)) + "," + this._shadowOpacity + ")"; 1064 this._fillColorStr = "rgba(" + (0 | (locDisplayColor.r / 255 * locFontFillColor.r)) + "," + (0 | (locDisplayColor.g / 255 * locFontFillColor.g)) + "," 1065 + (0 | (locDisplayColor.b / 255 * locFontFillColor.b)) + ", " + locDisplayedOpacity / 255 + ")"; 1066 this._strokeColorStr = "rgba(" + (0 | (locDisplayColor.r / 255 * locStrokeColor.r)) + "," + (0 | (locDisplayColor.g / 255 * locStrokeColor.g)) + "," 1067 + (0 | (locDisplayColor.b / 255 * locStrokeColor.b)) + ", " + locDisplayedOpacity / 255 + ")"; 1068 }; 1069 1070 _p.updateDisplayedColor = function (parentColor) { 1071 cc.Node.prototype.updateDisplayedColor.call(this, parentColor); 1072 this._setColorsString(); 1073 }; 1074 1075 _p.setOpacity = function (opacity) { 1076 if (this._opacity === opacity) 1077 return; 1078 cc.Sprite.prototype.setOpacity.call(this, opacity); 1079 this._setColorsString(); 1080 this._needUpdateTexture = true; 1081 }; 1082 1083 //TODO: _p._updateDisplayedOpacityForCanvas 1084 _p.updateDisplayedOpacity = cc.Sprite.prototype.updateDisplayedOpacity; 1085 1086 _p.initWithStringAndTextDefinition = function (text, textDefinition) { 1087 // prepare everything needed to render the label 1088 this._updateWithTextDefinition(textDefinition, false); 1089 1090 // set the string 1091 this.string = text; 1092 1093 return true; 1094 }; 1095 1096 _p.setFontFillColor = function (tintColor) { 1097 var locTextFillColor = this._textFillColor; 1098 if (locTextFillColor.r != tintColor.r || locTextFillColor.g != tintColor.g || locTextFillColor.b != tintColor.b) { 1099 locTextFillColor.r = tintColor.r; 1100 locTextFillColor.g = tintColor.g; 1101 locTextFillColor.b = tintColor.b; 1102 1103 this._setColorsString(); 1104 this._needUpdateTexture = true; 1105 } 1106 }; 1107 1108 _p.draw = cc.Sprite.prototype.draw; 1109 1110 _p.setTextureRect = function (rect, rotated, untrimmedSize) { 1111 this._rectRotated = rotated || false; 1112 untrimmedSize = untrimmedSize || rect; 1113 1114 this.setContentSize(untrimmedSize); 1115 this.setVertexRect(rect); 1116 1117 var locTextureCoordRect = this._textureRect_Canvas; 1118 locTextureCoordRect.x = rect.x; 1119 locTextureCoordRect.y = rect.y; 1120 locTextureCoordRect.width = rect.width; 1121 locTextureCoordRect.height = rect.height; 1122 locTextureCoordRect.validRect = !(locTextureCoordRect.width === 0 || locTextureCoordRect.height === 0 1123 || locTextureCoordRect.x < 0 || locTextureCoordRect.y < 0); 1124 1125 var relativeOffset = this._unflippedOffsetPositionFromCenter; 1126 if (this._flippedX) 1127 relativeOffset.x = -relativeOffset.x; 1128 if (this._flippedY) 1129 relativeOffset.y = -relativeOffset.y; 1130 this._offsetPosition.x = relativeOffset.x + (this._contentSize.width - this._rect.width) / 2; 1131 this._offsetPosition.y = relativeOffset.y + (this._contentSize.height - this._rect.height) / 2; 1132 1133 // rendering using batch node 1134 if (this._batchNode) { 1135 this.dirty = true; 1136 } 1137 }; 1138 _p = null; 1139 1140 } else { 1141 cc.assert(typeof cc._tmp.WebGLLabelTTF === "function", cc._LogInfos.MissingFile, "LabelTTFWebGL.js"); 1142 cc._tmp.WebGLLabelTTF(); 1143 delete cc._tmp.WebGLLabelTTF; 1144 } 1145 1146 cc.assert(typeof cc._tmp.PrototypeLabelTTF === "function", cc._LogInfos.MissingFile, "LabelTTFPropertyDefine.js"); 1147 cc._tmp.PrototypeLabelTTF(); 1148 delete cc._tmp.PrototypeLabelTTF; 1149 1150 cc.LabelTTF._textAlign = ["left", "center", "right"]; 1151 1152 cc.LabelTTF._textBaseline = ["top", "middle", "bottom"]; 1153 1154 //check the first character 1155 cc.LabelTTF.wrapInspection = true; 1156 1157 //Support: English French German 1158 //Other as Oriental Language 1159 cc.LabelTTF._wordRex = /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+|\S)/; 1160 cc.LabelTTF._symbolRex = /^[!,.:;}\]%\?>、‘“》?。,!]/; 1161 cc.LabelTTF._lastWordRex = /([a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+|\S)$/; 1162 cc.LabelTTF._lastEnglish = /[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]+$/; 1163 cc.LabelTTF._firsrEnglish = /^[a-zA-Z0-9ÄÖÜäöüßéèçàùêâîôû]/; 1164 1165 // Only support style in this format: "18px Verdana" or "18px 'Helvetica Neue'" 1166 cc.LabelTTF._fontStyleRE = /^(\d+)px\s+['"]?([\w\s\d]+)['"]?$/; 1167 1168 /** 1169 * creates a cc.LabelTTF from a font name, alignment, dimension and font size 1170 * @deprecated since v3.0, please use the new construction instead 1171 * @see cc.LabelTTF 1172 * @static 1173 * @param {String} text 1174 * @param {String|cc.FontDefinition} [fontName="Arial"] 1175 * @param {Number} [fontSize=16] 1176 * @param {cc.Size} [dimensions=cc.size(0,0)] 1177 * @param {Number} [hAlignment=cc.TEXT_ALIGNMENT_LEFT] 1178 * @param {Number} [vAlignment=cc.VERTICAL_TEXT_ALIGNMENT_TOP] 1179 * @return {cc.LabelTTF|Null} 1180 */ 1181 cc.LabelTTF.create = function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) { 1182 return new cc.LabelTTF(text, fontName, fontSize, dimensions, hAlignment, vAlignment); 1183 }; 1184 1185 /** 1186 * @deprecated since v3.0, please use the new construction instead 1187 * @function 1188 * @static 1189 */ 1190 cc.LabelTTF.createWithFontDefinition = cc.LabelTTF.create; 1191 1192 if (cc.USE_LA88_LABELS) 1193 cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTURECOLOR; 1194 else 1195 cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTUREA8COLOR; 1196 1197 cc.LabelTTF.__labelHeightDiv = cc.newElement("div"); 1198 cc.LabelTTF.__labelHeightDiv.style.fontFamily = "Arial"; 1199 cc.LabelTTF.__labelHeightDiv.style.position = "absolute"; 1200 cc.LabelTTF.__labelHeightDiv.style.left = "-100px"; 1201 cc.LabelTTF.__labelHeightDiv.style.top = "-100px"; 1202 cc.LabelTTF.__labelHeightDiv.style.lineHeight = "normal"; 1203 1204 document.body ? 1205 document.body.appendChild(cc.LabelTTF.__labelHeightDiv) : 1206 cc._addEventListener(window, 'load', function () { 1207 this.removeEventListener('load', arguments.callee, false); 1208 document.body.appendChild(cc.LabelTTF.__labelHeightDiv); 1209 }, false); 1210 1211 1212 cc.LabelTTF.__getFontHeightByDiv = function (fontName, fontSize) { 1213 var clientHeight = cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize]; 1214 if (clientHeight > 0) return clientHeight; 1215 var labelDiv = cc.LabelTTF.__labelHeightDiv; 1216 labelDiv.innerHTML = "ajghl~!"; 1217 labelDiv.style.fontFamily = fontName; 1218 labelDiv.style.fontSize = fontSize + "px"; 1219 clientHeight = labelDiv.clientHeight; 1220 cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize] = clientHeight; 1221 labelDiv.innerHTML = ""; 1222 return clientHeight; 1223 }; 1224 1225 cc.LabelTTF.__fontHeightCache = {};