1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga 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 * cc.LabelTTF is a subclass of cc.TextureNode that knows how to render text labels<br/> 29 * All features from cc.TextureNode are valid in cc.LabelTTF<br/> 30 * cc.LabelTTF objects are slow for js-binding on mobile devices.Consider using cc.LabelAtlas or cc.LabelBMFont instead. <br/> 31 * Consider using cc.LabelAtlas or cc.LabelBMFont instead.<br/> 32 * @class 33 * @extends cc.Sprite 34 * 35 * @property {String} string - Content string of label 36 * @property {Number} textAlign - Horizontal Alignment of label: cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT 37 * @property {Number} verticalAlign - Vertical Alignment of label: cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM 38 * @property {Number} fontSize - Font size of label 39 * @property {String} fontName - Font name of label 40 * @property {String} font - The label font with a style string: e.g. "18px Verdana" 41 * @property {Number} boundingWidth - Width of the bounding box of label, the real content width is limited by boundingWidth 42 * @property {Number} boundingHeight - Height of the bounding box of label, the real content height is limited by boundingHeight 43 * @property {cc.Color} fillStyle - The fill color 44 * @property {cc.Color} strokeStyle - The stroke color 45 * @property {Number} lineWidth - The line width for stroke 46 * @property {Number} shadowOffsetX - The x axis offset of shadow 47 * @property {Number} shadowOffsetY - The y axis offset of shadow 48 * @property {Number} shadowOpacity - The opacity of shadow 49 * @property {Number} shadowBlur - The blur size of shadow 50 * 51 */ 52 cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{ 53 _dimensions:null, 54 _hAlignment:cc.TEXT_ALIGNMENT_CENTER, 55 _vAlignment:cc.VERTICAL_TEXT_ALIGNMENT_TOP, 56 _fontName: null, 57 _fontSize:0.0, 58 _string:"", 59 _originalText: null, 60 _isMultiLine:false, 61 _fontStyleStr:null, 62 63 // font shadow 64 _shadowEnabled:false, 65 _shadowOffset:null, 66 _shadowOpacity:0, 67 _shadowBlur:0, 68 _shadowColorStr:null, 69 70 // font stroke 71 _strokeEnabled:false, 72 _strokeColor:null, 73 _strokeSize:0, 74 _strokeColorStr:null, 75 76 // font tint 77 _textFillColor:null, 78 _fillColorStr:null, 79 80 _strokeShadowOffsetX:0, 81 _strokeShadowOffsetY:0, 82 _needUpdateTexture:false, 83 84 _labelCanvas:null, 85 _labelContext:null, 86 _lineWidths:null, 87 _className:"LabelTTF", 88 89 90 /** 91 * Constructor 92 */ 93 ctor:function () { 94 cc.Sprite.prototype.ctor.call(this); 95 96 this._dimensions = cc.size(0, 0); 97 this._hAlignment = cc.TEXT_ALIGNMENT_LEFT; 98 this._vAlignment = cc.VERTICAL_TEXT_ALIGNMENT_TOP; 99 this._opacityModifyRGB = false; 100 this._fontStyleStr = ""; 101 this._fontName = "Arial"; 102 this._isMultiLine = false; 103 104 this._shadowEnabled = false; 105 this._shadowOffset = cc.p(0,0); 106 this._shadowOpacity = 0; 107 this._shadowBlur = 0; 108 this._shadowColorStr = "rgba(128, 128, 128, 0.5)"; 109 110 this._strokeEnabled = false; 111 this._strokeColor = cc.color(255, 255, 255, 255); 112 this._strokeSize = 0; 113 this._strokeColorStr = ""; 114 115 this._textFillColor = cc.color(255, 255, 255, 255); 116 this._fillColorStr = "rgba(255,255,255,1)"; 117 this._strokeShadowOffsetX = 0; 118 this._strokeShadowOffsetY = 0; 119 this._needUpdateTexture = false; 120 121 this._lineWidths = []; 122 123 this._setColorsString(); 124 }, 125 126 init:function () { 127 return this.initWithString(" ", this._fontName, this._fontSize); 128 }, 129 130 _measureConfig: function() { 131 this._getLabelContext().font = this._fontStyleStr; 132 }, 133 _measure: function(text) { 134 return this._getLabelContext().measureText(text).width; 135 }, 136 _checkNextline: function( text, width){ 137 var tWidth = this._measure(text); 138 // Estimated word number per line 139 var baseNb = Math.floor( text.length * width / tWidth ); 140 // Next line is a line with line break 141 var nextlinebreak = text.indexOf('\n'); 142 if(baseNb*0.8 >= nextlinebreak && nextlinebreak > 0) return nextlinebreak+1; 143 // Text width smaller than requested width 144 if(tWidth < width) return text.length; 145 146 var found = false, l = width + 1, idfound = -1, index = baseNb, result, 147 re = cc.LabelTTF._checkRegEx, 148 reversre = cc.LabelTTF._reverseCheckRegEx, 149 enre = cc.LabelTTF._checkEnRegEx, 150 substr = text.substr(baseNb); 151 152 // Forward check 153 // Find next special caracter or chinese caracters 154 while (result = re.exec(substr)) { 155 index += result[0].length; 156 var tem = text.substr(0, index); 157 l = this._measure(tem); 158 if(result[2] == '\n' && l < width) { 159 found = true; 160 idfound = index; 161 break; 162 } 163 if(l > width) { 164 if(idfound != -1) 165 found = true; 166 break; 167 } 168 idfound = index; 169 substr = text.substr(index); 170 } 171 if(found) return idfound; 172 173 // Backward check when forward check failed 174 substr = text.substr(0, baseNb); 175 idfound = baseNb; 176 while (result = reversre.exec(substr)) { 177 // BUG: Not secured if check with result[0] 178 idfound = result[1].length; 179 substr = result[1]; 180 l = this._measure(substr); 181 if(l < width) { 182 if(enre.test(result[2])) 183 idfound++; 184 break; 185 } 186 } 187 188 // Avoid when idfound == 0, the process may enter in a infinite loop 189 return idfound || 1; 190 }, 191 192 /** 193 * Prints out a description of this class 194 * @return {String} 195 */ 196 description:function () { 197 return "<cc.LabelTTF | FontName =" + this._fontName + " FontSize = " + this._fontSize.toFixed(1) + ">"; 198 }, 199 200 setColor: null, 201 202 _setColorForCanvas: function (color3) { 203 cc.NodeRGBA.prototype.setColor.call(this, color3); 204 205 this._setColorsStringForCanvas(); 206 }, 207 208 _setColorsString: null, 209 210 _setColorsStringForCanvas: function () { 211 this._needUpdateTexture = true; 212 213 var locDisplayColor = this._displayedColor, locDisplayedOpacity = this._displayedOpacity; 214 var locStrokeColor = this._strokeColor, locFontFillColor = this._textFillColor; 215 216 this._shadowColorStr = "rgba(" + (0 | (locDisplayColor.r * 0.5)) + "," + (0 | (locDisplayColor.g * 0.5)) + "," + (0 | (locDisplayColor.b * 0.5)) + "," + this._shadowOpacity + ")"; 217 this._fillColorStr = "rgba(" + (0 | (locDisplayColor.r /255 * locFontFillColor.r)) + "," + (0 | (locDisplayColor.g / 255 * locFontFillColor.g)) + "," 218 + (0 | (locDisplayColor.b / 255 * locFontFillColor.b)) + ", " + locDisplayedOpacity / 255 + ")"; 219 this._strokeColorStr = "rgba(" + (0 | (locDisplayColor.r / 255 * locStrokeColor.r)) + "," + (0 | (locDisplayColor.g / 255 * locStrokeColor.g)) + "," 220 + (0 | (locDisplayColor.b / 255 * locStrokeColor.b)) + ", " + locDisplayedOpacity / 255 + ")"; 221 }, 222 223 _setColorsStringForWebGL:function(){ 224 this._needUpdateTexture = true; 225 var locStrokeColor = this._strokeColor, locFontFillColor = this._textFillColor; 226 this._shadowColorStr = "rgba(128,128,128," + this._shadowOpacity + ")"; 227 this._fillColorStr = "rgba(" + (0 | locFontFillColor.r) + "," + (0 | locFontFillColor.g) + "," + (0 | locFontFillColor.b) + ", 1)"; 228 this._strokeColorStr = "rgba(" + (0 | locStrokeColor.r) + "," + (0 | locStrokeColor.g) + "," + (0 | locStrokeColor.b) + ", 1)"; 229 }, 230 231 updateDisplayedColor:null, 232 _updateDisplayedColorForCanvas:function(parentColor){ 233 cc.NodeRGBA.prototype.updateDisplayedColor.call(this,parentColor); 234 this._setColorsString(); 235 }, 236 237 setOpacity: null, 238 239 _setOpacityForCanvas: function (opacity) { 240 if (this._opacity === opacity) 241 return; 242 cc.Sprite.prototype.setOpacity.call(this, opacity); 243 this._setColorsString(); 244 this._needUpdateTexture = true; 245 }, 246 247 updateDisplayedOpacity: null, 248 updateDisplayedOpacityForCanvas: function(parentOpacity){ 249 cc.NodeRGBA.prototype.updateDisplayedOpacity.call(this, parentOpacity); 250 this._setColorsString(); 251 }, 252 253 /** 254 * returns the text of the label 255 * @return {String} 256 */ 257 getString:function () { 258 return this._string; 259 }, 260 261 /** 262 * return Horizontal Alignment of cc.LabelTTF 263 * @return {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} 264 */ 265 getHorizontalAlignment:function () { 266 return this._hAlignment; 267 }, 268 269 /** 270 * return Vertical Alignment of cc.LabelTTF 271 * @return {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} 272 */ 273 getVerticalAlignment:function () { 274 return this._vAlignment; 275 }, 276 277 /** 278 * return Dimensions of cc.LabelTTF 279 * @return {cc.Size} 280 */ 281 getDimensions:function () { 282 return cc.size(this._dimensions.width, this._dimensions.height); 283 }, 284 285 /** 286 * return font size of cc.LabelTTF 287 * @return {Number} 288 */ 289 getFontSize:function () { 290 return this._fontSize; 291 }, 292 293 /** 294 * return font name of cc.LabelTTF 295 * @return {String} 296 */ 297 getFontName:function () { 298 return this._fontName; 299 }, 300 301 /** 302 * initializes the cc.LabelTTF with a font name, alignment, dimension and font size 303 * @param {String} label string 304 * @param {String} fontName 305 * @param {Number} fontSize 306 * @param {cc.Size} [dimensions=] 307 * @param {Number} [hAlignment=] 308 * @param {Number} [vAlignment=] 309 * @return {Boolean} return false on error 310 */ 311 initWithString:function (label, fontName, fontSize, dimensions, hAlignment, vAlignment) { 312 var strInfo; 313 if(label) 314 strInfo = label + ""; 315 else 316 strInfo = ""; 317 318 fontSize = fontSize || 16; 319 dimensions = dimensions || cc.size(0, fontSize); 320 hAlignment = hAlignment || cc.TEXT_ALIGNMENT_LEFT; 321 vAlignment = vAlignment || cc.VERTICAL_TEXT_ALIGNMENT_TOP; 322 323 if (cc.Sprite.prototype.init.call(this)) { 324 this._opacityModifyRGB = false; 325 this._dimensions = cc.size(dimensions.width, dimensions.height); 326 this._fontName = fontName || "Arial"; 327 this._hAlignment = hAlignment; 328 this._vAlignment = vAlignment; 329 330 //this._fontSize = (cc._renderType === cc._RENDER_TYPE_CANVAS) ? fontSize : fontSize * cc.CONTENT_SCALE_FACTOR(); 331 this._fontSize = fontSize; 332 this._fontStyleStr = this._fontSize + "px '" + fontName + "'"; 333 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontName,this._fontSize); 334 this.string = strInfo; 335 this._setColorsString(); 336 this._updateTexture(); 337 this._needUpdateTexture = false; 338 return true; 339 } 340 return false; 341 }, 342 343 /** 344 * initializes the CCLabelTTF with a font name, alignment, dimension and font size 345 * @param {String} text 346 * @param {cc.FontDefinition} textDefinition 347 * @return {Boolean} 348 */ 349 initWithStringAndTextDefinition:null, 350 351 _initWithStringAndTextDefinitionForCanvas:function(text, textDefinition){ 352 if(!cc.Sprite.prototype.init.call(this)) 353 return false; 354 355 // prepare everything needed to render the label 356 this._updateWithTextDefinition(textDefinition, false); 357 358 // set the string 359 this.string = text; 360 361 return true; 362 }, 363 364 _initWithStringAndTextDefinitionForWebGL:function(text, textDefinition){ 365 if(!cc.Sprite.prototype.init.call(this)) 366 return false; 367 368 // shader program 369 this.shaderProgram = cc.shaderCache.programForKey(cc.LabelTTF._SHADER_PROGRAM); 370 371 // prepare everything needed to render the label 372 this._updateWithTextDefinition(textDefinition, false); 373 374 // set the string 375 this.string = text; 376 377 return true; 378 }, 379 380 /** 381 * set the text definition used by this label 382 * @param {cc.FontDefinition} theDefinition 383 */ 384 setTextDefinition:function(theDefinition){ 385 if (theDefinition) 386 this._updateWithTextDefinition(theDefinition, true); 387 }, 388 389 /** 390 * get the text definition used by this label 391 * @return {cc.FontDefinition} 392 */ 393 getTextDefinition:function(){ 394 return this._prepareTextDefinition(false); 395 }, 396 397 /** 398 * enable or disable shadow for the label 399 * @param {cc.Point} shadowOffset 400 * @param {Number} shadowOpacity (0 to 1) 401 * @param {Number} shadowBlur 402 */ 403 enableShadow:function(shadowOffsetX, shadowOffsetY, shadowOpacity, shadowBlur){ 404 shadowOpacity = shadowOpacity || 0.5; 405 if (false === this._shadowEnabled) 406 this._shadowEnabled = true; 407 408 var locShadowOffset = this._shadowOffset; 409 if (locShadowOffset && (locShadowOffset.x != shadowOffsetX) || (locShadowOffset._y != shadowOffsetY)) { 410 locShadowOffset.x = shadowOffsetX; 411 locShadowOffset.y = shadowOffsetY; 412 } 413 414 if (this._shadowOpacity != shadowOpacity ){ 415 this._shadowOpacity = shadowOpacity; 416 } 417 this._setColorsString(); 418 419 if (this._shadowBlur != shadowBlur) 420 this._shadowBlur = shadowBlur; 421 422 this._needUpdateTexture = true; 423 }, 424 425 _getShadowOffsetX: function () { 426 return this._shadowOffset.x; 427 }, 428 _setShadowOffsetX: function (x) { 429 if (false === this._shadowEnabled) 430 this._shadowEnabled = true; 431 432 if (this._shadowOffset.x != x) { 433 this._shadowOffset.x = x; 434 this._needUpdateTexture = true; 435 } 436 }, 437 438 _getShadowOffsetY: function () { 439 return this._shadowOffset._y; 440 }, 441 _setShadowOffsetY: function (y) { 442 if (false === this._shadowEnabled) 443 this._shadowEnabled = true; 444 445 if (this._shadowOffset._y != y) { 446 this._shadowOffset._y = y; 447 this._needUpdateTexture = true; 448 } 449 }, 450 451 _getShadowOffset: function () { 452 return cc.p(this._shadowOffset.x, this._shadowOffset.y); 453 }, 454 _setShadowOffset: function (offset) { 455 if (false === this._shadowEnabled) 456 this._shadowEnabled = true; 457 458 if (this._shadowOffset.x != offset.x || this._shadowOffset.y != offset.y) { 459 this._shadowOffset.x = offset.x; 460 this._shadowOffset.y = offset.y; 461 this._needUpdateTexture = true; 462 } 463 }, 464 465 _getShadowOpacity: function () { 466 return this._shadowOpacity; 467 }, 468 _setShadowOpacity: function (shadowOpacity) { 469 if (false === this._shadowEnabled) 470 this._shadowEnabled = true; 471 472 if (this._shadowOpacity != shadowOpacity ){ 473 this._shadowOpacity = shadowOpacity; 474 this._setColorsString(); 475 this._needUpdateTexture = true; 476 } 477 }, 478 479 _getShadowBlur: function () { 480 return this._shadowBlur; 481 }, 482 _setShadowBlur: function (shadowBlur) { 483 if (false === this._shadowEnabled) 484 this._shadowEnabled = true; 485 486 if (this._shadowBlur != shadowBlur) { 487 this._shadowBlur = shadowBlur; 488 this._needUpdateTexture = true; 489 } 490 }, 491 492 /** 493 * disable shadow rendering 494 */ 495 disableShadow:function(){ 496 if (this._shadowEnabled) { 497 this._shadowEnabled = false; 498 this._needUpdateTexture = true; 499 } 500 }, 501 502 /** 503 * enable or disable stroke 504 * @param {cc.Color} strokeColor 505 * @param {Number} strokeSize 506 */ 507 enableStroke:function(strokeColor, strokeSize){ 508 if(this._strokeEnabled === false) 509 this._strokeEnabled = true; 510 511 var locStrokeColor = this._strokeColor; 512 if ( (locStrokeColor.r !== strokeColor.r) || (locStrokeColor.g !== strokeColor.g) || (locStrokeColor.b !== strokeColor.b) ) { 513 locStrokeColor.r = strokeColor.r; 514 locStrokeColor.g = strokeColor.g; 515 locStrokeColor.b = strokeColor.b; 516 this._setColorsString(); 517 } 518 519 if (this._strokeSize!== strokeSize) 520 this._strokeSize = strokeSize || 0; 521 522 this._needUpdateTexture = true; 523 }, 524 525 _getStrokeStyle: function () { 526 return this._strokeColor; 527 }, 528 _setStrokeStyle: function (strokeStyle) { 529 if(this._strokeEnabled === false) 530 this._strokeEnabled = true; 531 532 var locStrokeColor = this._strokeColor; 533 if ( (locStrokeColor.r !== strokeStyle.r) || (locStrokeColor.g !== strokeStyle.g) || (locStrokeColor.b !== strokeStyle.b) ) { 534 locStrokeColor.r = strokeStyle.r; 535 locStrokeColor.g = strokeStyle.g; 536 locStrokeColor.b = strokeStyle.b; 537 this._setColorsString(); 538 539 this._needUpdateTexture = true; 540 } 541 }, 542 543 _getLineWidth: function () { 544 return this._strokeSize; 545 }, 546 _setLineWidth: function (lineWidth) { 547 if(this._strokeEnabled === false) 548 this._strokeEnabled = true; 549 550 if (this._strokeSize !== lineWidth) { 551 this._strokeSize = lineWidth || 0; 552 this._needUpdateTexture = true; 553 } 554 }, 555 556 /** 557 * disable stroke 558 */ 559 disableStroke:function(){ 560 if (this._strokeEnabled){ 561 this._strokeEnabled = false; 562 this._needUpdateTexture = true; 563 } 564 }, 565 566 /** 567 * set text tinting 568 * @function 569 * @param {cc.Color} tintColor 570 */ 571 setFontFillColor:null, 572 573 _setFontFillColorForCanvas: function (tintColor) { 574 var locTextFillColor = this._textFillColor; 575 if (locTextFillColor.r != tintColor.r || locTextFillColor.g != tintColor.g || locTextFillColor.b != tintColor.b) { 576 locTextFillColor.r = tintColor.r; 577 locTextFillColor.g = tintColor.g; 578 locTextFillColor.b = tintColor.b; 579 580 this._setColorsString(); 581 this._needUpdateTexture = true; 582 } 583 }, 584 585 _setFontFillColorForWebGL: function (tintColor) { 586 var locTextFillColor = this._textFillColor; 587 if (locTextFillColor.r != tintColor.r || locTextFillColor.g != tintColor.g || locTextFillColor.b != tintColor.b) { 588 locTextFillColor.r = tintColor.r; 589 locTextFillColor.g = tintColor.g; 590 locTextFillColor.b = tintColor.b; 591 this._setColorsString(); 592 this._needUpdateTexture = true; 593 } 594 }, 595 596 _getFillStyle: function () { 597 return this._textFillColor; 598 }, 599 600 //set the text definition for this label 601 _updateWithTextDefinition:function(textDefinition, mustUpdateTexture){ 602 if(textDefinition.fontDimensions){ 603 this._dimensions.width = textDefinition.boundingWidth; 604 this._dimensions.height = textDefinition.boundingHeight; 605 } else { 606 this._dimensions.width = 0; 607 this._dimensions.height = 0; 608 } 609 610 this._hAlignment = textDefinition.textAlign; 611 this._vAlignment = textDefinition.verticalAlign; 612 613 this._fontName = textDefinition.fontName; 614 this._fontSize = textDefinition.fontSize || 12; 615 this._fontStyleStr = this._fontSize + "px '" + this._fontName + "'"; 616 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(this._fontName,this._fontSize); 617 618 // shadow 619 if ( textDefinition.shadowEnabled) 620 this.enableShadow(textDefinition.shadowOffsetX, 621 textDefinition.shadowOffsetY, 622 textDefinition.shadowOpacity, 623 textDefinition.shadowBlur); 624 625 // stroke 626 if ( textDefinition.strokeEnabled ) 627 this.enableStroke(textDefinition.strokeStyle, textDefinition.lineWidth); 628 629 // fill color 630 this.setFontFillColor(textDefinition.fillStyle); 631 632 if (mustUpdateTexture) 633 this._updateTexture(); 634 }, 635 636 _prepareTextDefinition:function(adjustForResolution){ 637 var texDef = new cc.FontDefinition(); 638 639 if (adjustForResolution){ 640 //texDef.fontSize = (cc._renderType === cc._RENDER_TYPE_CANVAS) ? this._fontSize : this._fontSize * cc.CONTENT_SCALE_FACTOR(); 641 texDef.fontSize = this._fontSize; 642 texDef.boundingWidth = cc.CONTENT_SCALE_FACTOR() * this._dimensions.width; 643 texDef.boundingHeight = cc.CONTENT_SCALE_FACTOR() * this._dimensions.height; 644 } else { 645 texDef.fontSize = this._fontSize; 646 texDef.boundingWidth = this._dimensions.width; 647 texDef.boundingHeight = this._dimensions.height; 648 } 649 650 texDef.fontName = this._fontName; 651 texDef.textAlign = this._hAlignment; 652 texDef.verticalAlign = this._vAlignment; 653 654 // stroke 655 if ( this._strokeEnabled ){ 656 texDef.strokeEnabled = true; 657 var locStrokeColor = this._strokeColor; 658 texDef.strokeStyle = cc.color(locStrokeColor.r, locStrokeColor.g, locStrokeColor.b); 659 texDef.lineWidth = this._strokeSize; 660 }else 661 texDef.strokeEnabled = false; 662 663 // shadow 664 if ( this._shadowEnabled ){ 665 texDef.shadowEnabled = true; 666 texDef.shadowBlur = this._shadowBlur; 667 texDef.shadowOpacity = this._shadowOpacity; 668 669 texDef.shadowOffsetX = (adjustForResolution ? cc.CONTENT_SCALE_FACTOR() : 1) * this._shadowOffset.x; 670 texDef.shadowOffsetY = (adjustForResolution ? cc.CONTENT_SCALE_FACTOR() : 1) * this._shadowOffset.y; 671 } else 672 texDef._shadowEnabled = false; 673 674 // text tint 675 var locTextFillColor = this._textFillColor; 676 texDef.fillStyle = cc.color(locTextFillColor.r, locTextFillColor.g, locTextFillColor.b); 677 return texDef; 678 }, 679 680 _fontClientHeight:18, 681 /** 682 * changes the string to render 683 * @warning Changing the string is as expensive as creating a new cc.LabelTTF. To obtain better performance use cc.LabelAtlas 684 * @param {String} text text for the label 685 */ 686 setString:function (text) { 687 text = String(text); 688 if (this._originalText != text) { 689 this._originalText = text + ""; 690 691 this._updateString(); 692 693 // Force update 694 this._needUpdateTexture = true; 695 } 696 }, 697 _updateString: function() { 698 this._string = this._originalText; 699 }, 700 /** 701 * set Horizontal Alignment of cc.LabelTTF 702 * @param {cc.TEXT_ALIGNMENT_LEFT|cc.TEXT_ALIGNMENT_CENTER|cc.TEXT_ALIGNMENT_RIGHT} alignment Horizontal Alignment 703 */ 704 setHorizontalAlignment:function (alignment) { 705 if (alignment !== this._hAlignment) { 706 this._hAlignment = alignment; 707 708 // Force update 709 this._needUpdateTexture = true; 710 } 711 }, 712 713 /** 714 * set Vertical Alignment of cc.LabelTTF 715 * @param {cc.VERTICAL_TEXT_ALIGNMENT_TOP|cc.VERTICAL_TEXT_ALIGNMENT_CENTER|cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM} verticalAlignment 716 */ 717 setVerticalAlignment:function (verticalAlignment) { 718 if (verticalAlignment != this._vAlignment) { 719 this._vAlignment = verticalAlignment; 720 721 // Force update 722 this._needUpdateTexture = true; 723 } 724 }, 725 726 /** 727 * set Dimensions of cc.LabelTTF 728 * @param {cc.Size} dim 729 */ 730 setDimensions:function (dim) { 731 if (dim.width != this._dimensions.width || dim.height != this._dimensions.height) { 732 this._dimensions = dim; 733 this._updateString(); 734 // Force udpate 735 this._needUpdateTexture = true; 736 } 737 }, 738 739 _getBoundingWidth: function () { 740 return this._dimensions.width; 741 }, 742 _setBoundingWidth: function (width) { 743 if (width != this._dimensions.width) { 744 this._dimensions.width = width; 745 this._updateString(); 746 // Force udpate 747 this._needUpdateTexture = true; 748 } 749 }, 750 751 _getBoundingHeight: function () { 752 return this._dimensions.height; 753 }, 754 _setBoundingHeight: function (height) { 755 if (height != this._dimensions.height) { 756 this._dimensions.height = height; 757 this._updateString(); 758 // Force udpate 759 this._needUpdateTexture = true; 760 } 761 }, 762 763 /** 764 * set font size of cc.LabelTTF 765 * @param {Number} fontSize 766 */ 767 setFontSize:function (fontSize) { 768 if (this._fontSize !== fontSize) { 769 this._fontSize = fontSize; 770 this._fontStyleStr = fontSize + "px '" + this._fontName + "'"; 771 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(this._fontName, fontSize); 772 // Force update 773 this._needUpdateTexture = true; 774 } 775 }, 776 777 /** 778 * set font name of cc.LabelTTF 779 * @param {String} fontName 780 */ 781 setFontName:function (fontName) { 782 if (this._fontName && this._fontName != fontName ) { 783 this._fontName = fontName; 784 this._fontStyleStr = this._fontSize + "px '" + fontName + "'"; 785 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(fontName, this._fontSize); 786 // Force update 787 this._needUpdateTexture = true; 788 } 789 }, 790 791 _getFont: function () { 792 return this._fontStyleStr; 793 }, 794 _setFont: function (fontStyle) { 795 var res = cc.LabelTTF._fontStyleRE.exec(fontStyle); 796 if(res) { 797 this._fontSize = parseInt(res[1]); 798 this._fontName = res[2]; 799 this._fontStyleStr = fontStyle; 800 this._fontClientHeight = cc.LabelTTF.__getFontHeightByDiv(this._fontName, this._fontSize); 801 // Force update 802 this._needUpdateTexture = true; 803 } 804 }, 805 806 _drawTTFInCanvas: function (context) { 807 if (!context) 808 return; 809 var locStrokeShadowOffsetX = this._strokeShadowOffsetX, locStrokeShadowOffsetY = this._strokeShadowOffsetY; 810 var locContentSizeHeight = this._contentSize.height - locStrokeShadowOffsetY, locVAlignment = this._vAlignment, locHAlignment = this._hAlignment, 811 locFontHeight = this._fontClientHeight, locStrokeSize = this._strokeSize; 812 813 context.setTransform(1, 0, 0, 1, 0 + locStrokeShadowOffsetX * 0.5 , locContentSizeHeight + locStrokeShadowOffsetY * 0.5); 814 815 //this is fillText for canvas 816 if (context.font != this._fontStyleStr) 817 context.font = this._fontStyleStr; 818 context.fillStyle = this._fillColorStr; 819 820 var xOffset = 0, yOffset = 0; 821 //stroke style setup 822 var locStrokeEnabled = this._strokeEnabled; 823 if (locStrokeEnabled) { 824 context.lineWidth = locStrokeSize * 2; 825 context.strokeStyle = this._strokeColorStr; 826 } 827 828 //shadow style setup 829 if (this._shadowEnabled) { 830 var locShadowOffset = this._shadowOffset; 831 context.shadowColor = this._shadowColorStr; 832 context.shadowOffsetX = locShadowOffset.x; 833 context.shadowOffsetY = -locShadowOffset.y; 834 context.shadowBlur = this._shadowBlur; 835 } 836 837 context.textBaseline = cc.LabelTTF._textBaseline[locVAlignment]; 838 context.textAlign = cc.LabelTTF._textAlign[locHAlignment]; 839 840 var locContentWidth = this._contentSize.width - locStrokeShadowOffsetX; 841 if (locHAlignment === cc.TEXT_ALIGNMENT_RIGHT) 842 xOffset += locContentWidth; 843 else if (locHAlignment === cc.TEXT_ALIGNMENT_CENTER) 844 xOffset += locContentWidth / 2; 845 else 846 xOffset += 0; 847 if (this._isMultiLine) { 848 var locStrLen = this._strings.length; 849 if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM) 850 yOffset = locFontHeight + locContentSizeHeight - locFontHeight * locStrLen; 851 else if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_CENTER) 852 yOffset = locFontHeight / 2 + (locContentSizeHeight - locFontHeight * locStrLen) / 2; 853 854 for (var i = 0; i < locStrLen; i++) { 855 var line = this._strings[i]; 856 var tmpOffsetY = -locContentSizeHeight + (locFontHeight * i) + yOffset; 857 if (locStrokeEnabled) 858 context.strokeText(line, xOffset, tmpOffsetY); 859 context.fillText(line, xOffset, tmpOffsetY); 860 } 861 } else { 862 if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_BOTTOM) { 863 if (locStrokeEnabled) 864 context.strokeText(this._string, xOffset, yOffset); 865 context.fillText(this._string, xOffset, yOffset); 866 } else if (locVAlignment === cc.VERTICAL_TEXT_ALIGNMENT_TOP) { 867 yOffset -= locContentSizeHeight ; 868 if (locStrokeEnabled) 869 context.strokeText(this._string, xOffset, yOffset); 870 context.fillText(this._string, xOffset, yOffset); 871 } else { 872 yOffset -= locContentSizeHeight * 0.5; 873 if (locStrokeEnabled) 874 context.strokeText(this._string, xOffset, yOffset); 875 context.fillText(this._string, xOffset, yOffset); 876 } 877 } 878 }, 879 880 _getLabelContext:function () { 881 if (this._labelContext) 882 return this._labelContext; 883 884 if (!this._labelCanvas) { 885 var locCanvas = document.createElement("canvas"); 886 var labelTexture = new cc.Texture2D(); 887 labelTexture.initWithElement(locCanvas); 888 this.texture = labelTexture; 889 this._labelCanvas = locCanvas; 890 } 891 this._labelContext = this._labelCanvas.getContext("2d"); 892 return this._labelContext; 893 }, 894 895 _updateTTF: function () { 896 var locDimensionsWidth = this._dimensions.width, i, strLength; 897 var locLineWidth = this._lineWidths; 898 locLineWidth.length = 0; 899 900 this._isMultiLine = false ; 901 this._measureConfig(); 902 if (locDimensionsWidth !== 0) { 903 // Content processing 904 var text = this._string; 905 this._strings = []; 906 for (i = 0, strLength = this._string.length; i < strLength;) { 907 // Find the index of next line 908 var next = this._checkNextline(text.substr(i), locDimensionsWidth); 909 var append = text.substr(i, next); 910 this._strings.push(append); 911 i += next; 912 } 913 } else { 914 this._strings = this._string.split('\n'); 915 for (i = 0, strLength = this._strings.length; i < strLength; i++) { 916 locLineWidth.push(this._measure(this._strings[i])); 917 } 918 } 919 920 if (this._strings.length > 0) 921 this._isMultiLine = true; 922 923 var locSize, locStrokeShadowOffsetX = 0, locStrokeShadowOffsetY = 0; 924 if (this._strokeEnabled) 925 locStrokeShadowOffsetX = locStrokeShadowOffsetY = this._strokeSize * 2; 926 if (this._shadowEnabled) { 927 var locOffsetSize = this._shadowOffset; 928 locStrokeShadowOffsetX += Math.abs(locOffsetSize.x) * 2; 929 locStrokeShadowOffsetY += Math.abs(locOffsetSize.y) * 2; 930 } 931 932 //get offset for stroke and shadow 933 if (locDimensionsWidth === 0) { 934 if (this._isMultiLine) 935 locSize = cc.size(0 | (Math.max.apply(Math, locLineWidth) + locStrokeShadowOffsetX), 936 0 | ((this._fontClientHeight * this._strings.length) + locStrokeShadowOffsetY)); 937 else 938 locSize = cc.size(0 | (this._measure(this._string) + locStrokeShadowOffsetX), 0 | (this._fontClientHeight + locStrokeShadowOffsetY)); 939 } else { 940 if (this._dimensions.height === 0) { 941 if (this._isMultiLine) 942 locSize = cc.size(0 | (locDimensionsWidth + locStrokeShadowOffsetX), 0 | ((this._fontClientHeight * this._strings.length) + locStrokeShadowOffsetY)); 943 else 944 locSize = cc.size(0 | (locDimensionsWidth + locStrokeShadowOffsetX), 0 | (this._fontClientHeight + locStrokeShadowOffsetY)); 945 } else { 946 //dimension is already set, contentSize must be same as dimension 947 locSize = cc.size(0 | (locDimensionsWidth + locStrokeShadowOffsetX), 0 | (this._dimensions.height + locStrokeShadowOffsetY)); 948 } 949 } 950 this.setContentSize(locSize); 951 this._strokeShadowOffsetX = locStrokeShadowOffsetX; 952 this._strokeShadowOffsetY = locStrokeShadowOffsetY; 953 954 // need computing _anchorPointInPoints 955 var locAP = this._anchorPoint; 956 this._anchorPointInPoints.x = (locStrokeShadowOffsetX * 0.5) + ((locSize.width - locStrokeShadowOffsetX) * locAP.x); 957 this._anchorPointInPoints.y = (locStrokeShadowOffsetY * 0.5) + ((locSize.height - locStrokeShadowOffsetY) * locAP.y); 958 }, 959 960 getContentSize:function(){ 961 if(this._needUpdateTexture) 962 this._updateTTF(); 963 return cc.Sprite.prototype.getContentSize.call(this); 964 }, 965 966 _getWidth:function(){ 967 if(this._needUpdateTexture) 968 this._updateTTF(); 969 return cc.Sprite.prototype._getWidth.call(this); 970 }, 971 _getHeight:function(){ 972 if(this._needUpdateTexture) 973 this._updateTTF(); 974 return cc.Sprite.prototype._getHeight.call(this); 975 }, 976 977 _updateTexture:function () { 978 var locContext = this._getLabelContext(), locLabelCanvas = this._labelCanvas; 979 var locContentSize = this._contentSize; 980 981 if(this._string.length === 0){ 982 locLabelCanvas.width = 1; 983 locLabelCanvas.height = locContentSize.height; 984 this.setTextureRect(cc.rect(0, 0, 1, locContentSize.height)); 985 return true; 986 } 987 988 //set size for labelCanvas 989 locContext.font = this._fontStyleStr; 990 this._updateTTF(); 991 var width = locContentSize.width, height = locContentSize.height; 992 var flag = locLabelCanvas.width == width && locLabelCanvas.height == height; 993 locLabelCanvas.width = width; 994 locLabelCanvas.height = height; 995 if(flag) locContext.clearRect(0, 0, width, height); 996 997 //draw text to labelCanvas 998 this._drawTTFInCanvas(locContext); 999 this._texture.handleLoadedTexture(); 1000 1001 this.setTextureRect(cc.rect(0, 0, width, height)); 1002 return true; 1003 }, 1004 1005 visit:function(ctx){ 1006 if(!this._string || this._string == "") 1007 return; 1008 if(this._needUpdateTexture ){ 1009 this._needUpdateTexture = false; 1010 this._updateTexture(); 1011 } 1012 var context = ctx || cc._renderContext; 1013 cc.Sprite.prototype.visit.call(this,context); 1014 }, 1015 1016 /** 1017 * Draw sprite to canvas 1018 * @function 1019 * @param {CanvasRenderingContext2D|WebGLRenderingContext} ctx Render context of canvas, 2d or 3d 1020 */ 1021 draw: null, 1022 1023 _drawForWebGL: function (ctx) { 1024 if (!this._string || this._string == "") 1025 return; 1026 1027 var gl = ctx || cc._renderContext, locTexture = this._texture; 1028 1029 if (locTexture && locTexture._isLoaded) { 1030 this._shaderProgram.use(); 1031 this._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4(); 1032 1033 cc.glBlendFunc(this._blendFunc.src, this._blendFunc.dst); 1034 cc.glBindTexture2D(locTexture); 1035 1036 cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); 1037 1038 gl.bindBuffer(gl.ARRAY_BUFFER, this._quadWebBuffer); 1039 if (this._quadDirty) { 1040 gl.bufferData(gl.ARRAY_BUFFER, this._quad.arrayBuffer, gl.STATIC_DRAW); 1041 this._quadDirty = false; 1042 } 1043 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0); 1044 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16); 1045 gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); 1046 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 1047 } 1048 1049 if (cc.SPRITE_DEBUG_DRAW === 1) { 1050 // draw bounding box 1051 var locQuad = this._quad; 1052 var verticesG1 = [ 1053 cc.p(locQuad.tl.vertices.x, locQuad.tl.vertices.y), 1054 cc.p(locQuad.bl.vertices.x, locQuad.bl.vertices.y), 1055 cc.p(locQuad.br.vertices.x, locQuad.br.vertices.y), 1056 cc.p(locQuad.tr.vertices.x, locQuad.tr.vertices.y) 1057 ]; 1058 cc._drawingUtil.drawPoly(verticesG1, 4, true); 1059 } else if (cc.SPRITE_DEBUG_DRAW === 2) { 1060 // draw texture box 1061 var drawSizeG2 = this.getTextureRect()._size; 1062 var offsetPixG2X = this.offsetX, offsetPixG2Y = this.offsetY; 1063 var verticesG2 = [cc.p(offsetPixG2X, offsetPixG2Y), cc.p(offsetPixG2X + drawSizeG2.width, offsetPixG2Y), 1064 cc.p(offsetPixG2X + drawSizeG2.width, offsetPixG2Y + drawSizeG2.height), cc.p(offsetPixG2X, offsetPixG2Y + drawSizeG2.height)]; 1065 cc._drawingUtil.drawPoly(verticesG2, 4, true); 1066 } // CC_SPRITE_DEBUG_DRAW 1067 cc.g_NumberOfDraws++; 1068 }, 1069 1070 _setTextureRectForCanvas: function (rect, rotated, untrimmedSize) { 1071 this._rectRotated = rotated || false; 1072 untrimmedSize = untrimmedSize || rect; 1073 1074 this.setContentSize(untrimmedSize); 1075 this.setVertexRect(rect); 1076 1077 var locTextureCoordRect = this._textureRect_Canvas; 1078 locTextureCoordRect.x = rect.x; 1079 locTextureCoordRect.y = rect.y; 1080 locTextureCoordRect.width = rect.width; 1081 locTextureCoordRect.height = rect.height; 1082 locTextureCoordRect.validRect = !(locTextureCoordRect.width === 0 || locTextureCoordRect.height === 0 1083 || locTextureCoordRect.x < 0 || locTextureCoordRect.y < 0); 1084 1085 var relativeOffset = this._unflippedOffsetPositionFromCenter; 1086 if (this._flippedX) 1087 relativeOffset.x = -relativeOffset.x; 1088 if (this._flippedY) 1089 relativeOffset.y = -relativeOffset.y; 1090 this._offsetPosition.x = relativeOffset.x + (this._contentSize.width - this._rect.width) / 2; 1091 this._offsetPosition.y = relativeOffset.y + (this._contentSize.height - this._rect.height) / 2; 1092 1093 // rendering using batch node 1094 if (this._batchNode) { 1095 this.dirty = true; 1096 } 1097 }, 1098 1099 _setTextureCoords:function (rect) { 1100 var tex = this._batchNode ? this.textureAtlas.texture : this._texture; 1101 if (!tex) 1102 return; 1103 1104 var atlasWidth = tex.pixelsWidth; 1105 var atlasHeight = tex.pixelsHeight; 1106 1107 var left, right, top, bottom, tempSwap, locQuad = this._quad; 1108 if (this._rectRotated) { 1109 if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) { 1110 left = (2 * rect.x + 1) / (2 * atlasWidth); 1111 right = left + (rect.height * 2 - 2) / (2 * atlasWidth); 1112 top = (2 * rect.y + 1) / (2 * atlasHeight); 1113 bottom = top + (rect.width * 2 - 2) / (2 * atlasHeight); 1114 } else { 1115 left = rect.x / atlasWidth; 1116 right = (rect.x + rect.height) / atlasWidth; 1117 top = rect.y / atlasHeight; 1118 bottom = (rect.y + rect.width) / atlasHeight; 1119 }// CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL 1120 1121 if (this._flippedX) { 1122 tempSwap = top; 1123 top = bottom; 1124 bottom = tempSwap; 1125 } 1126 1127 if (this._flippedY) { 1128 tempSwap = left; 1129 left = right; 1130 right = tempSwap; 1131 } 1132 1133 locQuad.bl.texCoords.u = left; 1134 locQuad.bl.texCoords.v = top; 1135 locQuad.br.texCoords.u = left; 1136 locQuad.br.texCoords.v = bottom; 1137 locQuad.tl.texCoords.u = right; 1138 locQuad.tl.texCoords.v = top; 1139 locQuad.tr.texCoords.u = right; 1140 locQuad.tr.texCoords.v = bottom; 1141 } else { 1142 if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) { 1143 left = (2 * rect.x + 1) / (2 * atlasWidth); 1144 right = left + (rect.width * 2 - 2) / (2 * atlasWidth); 1145 top = (2 * rect.y + 1) / (2 * atlasHeight); 1146 bottom = top + (rect.height * 2 - 2) / (2 * atlasHeight); 1147 } else { 1148 left = rect.x / atlasWidth; 1149 right = (rect.x + rect.width) / atlasWidth; 1150 top = rect.y / atlasHeight; 1151 bottom = (rect.y + rect.height) / atlasHeight; 1152 } // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL 1153 1154 if (this._flippedX) { 1155 tempSwap = left; 1156 left = right; 1157 right = tempSwap; 1158 } 1159 1160 if (this._flippedY) { 1161 tempSwap = top; 1162 top = bottom; 1163 bottom = tempSwap; 1164 } 1165 1166 locQuad.bl.texCoords.u = left; 1167 locQuad.bl.texCoords.v = bottom; 1168 locQuad.br.texCoords.u = right; 1169 locQuad.br.texCoords.v = bottom; 1170 locQuad.tl.texCoords.u = left; 1171 locQuad.tl.texCoords.v = top; 1172 locQuad.tr.texCoords.u = right; 1173 locQuad.tr.texCoords.v = top; 1174 } 1175 this._quadDirty = true; 1176 } 1177 }); 1178 1179 window._p = cc.LabelTTF.prototype; 1180 if (cc._renderType === cc._RENDER_TYPE_WEBGL) { 1181 _p.setColor = cc.Sprite.prototype.setColor; 1182 _p._setColorsString = _p._setColorsStringForWebGL; 1183 _p.updateDisplayedColor = cc.Sprite.prototype.updateDisplayedColor; 1184 _p.setOpacity = cc.Sprite.prototype.setOpacity; 1185 _p.updateDisplayedOpacity = cc.Sprite.prototype.updateDisplayedOpacity; 1186 _p.initWithStringAndTextDefinition = _p._initWithStringAndTextDefinitionForWebGL; 1187 _p.setFontFillColor = _p._setFontFillColorForWebGL; 1188 _p.draw = _p._drawForWebGL; 1189 _p.setTextureRect = cc.Sprite.prototype._setTextureRectForWebGL; 1190 } else { 1191 _p.setColor = _p._setColorForCanvas; 1192 _p._setColorsString = _p._setColorsStringForCanvas; 1193 _p.updateDisplayedColor = _p._updateDisplayedColorForCanvas; 1194 _p.setOpacity = _p._setOpacityForCanvas; 1195 _p.updateDisplayedOpacity = _p._updateDisplayedOpacityForCanvas; 1196 _p.initWithStringAndTextDefinition = _p._initWithStringAndTextDefinitionForCanvas; 1197 _p.setFontFillColor = _p._setFontFillColorForCanvas; 1198 _p.draw = cc.Sprite.prototype.draw; 1199 _p.setTextureRect = _p._setTextureRectForCanvas; 1200 } 1201 1202 // Override properties 1203 cc.defineGetterSetter(_p, "color", _p.getColor, _p.setColor); 1204 cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity); 1205 1206 // Extended properties 1207 /** @expose */ 1208 _p.string; 1209 cc.defineGetterSetter(_p, "string", _p.getString, _p.setString); 1210 /** @expose */ 1211 _p.textAlign; 1212 cc.defineGetterSetter(_p, "textAlign", _p.getHorizontalAlignment, _p.setHorizontalAlignment); 1213 /** @expose */ 1214 _p.verticalAlign; 1215 cc.defineGetterSetter(_p, "verticalAlign", _p.getVerticalAlignment, _p.setVerticalAlignment); 1216 /** @expose */ 1217 _p.fontSize; 1218 cc.defineGetterSetter(_p, "fontSize", _p.getFontSize, _p.setFontSize); 1219 /** @expose */ 1220 _p.fontName; 1221 cc.defineGetterSetter(_p, "fontName", _p.getFontName, _p.setFontName); 1222 /** @expose */ 1223 _p.font; 1224 cc.defineGetterSetter(_p, "font", _p._getFont, _p._setFont); 1225 /** @expose */ 1226 _p.boundingSize; 1227 //cc.defineGetterSetter(_p, "boundingSize", _p.getDimensions, _p.setDimensions); 1228 /** @expose */ 1229 _p.boundingWidth; 1230 cc.defineGetterSetter(_p, "boundingWidth", _p._getBoundingWidth, _p._setBoundingWidth); 1231 /** @expose */ 1232 _p.boundingHeight; 1233 cc.defineGetterSetter(_p, "boundingHeight", _p._getBoundingHeight, _p._setBoundingHeight); 1234 /** @expose */ 1235 _p.fillStyle; 1236 cc.defineGetterSetter(_p, "fillStyle", _p._getFillStyle, _p.setFontFillColor); 1237 /** @expose */ 1238 _p.strokeStyle; 1239 cc.defineGetterSetter(_p, "strokeStyle", _p._getStrokeStyle, _p._setStrokeStyle); 1240 /** @expose */ 1241 _p.lineWidth; 1242 cc.defineGetterSetter(_p, "lineWidth", _p._getLineWidth, _p._setLineWidth); 1243 /** @expose */ 1244 _p.shadowOffset; 1245 //cc.defineGetterSetter(_p, "shadowOffset", _p._getShadowOffset, _p._setShadowOffset); 1246 /** @expose */ 1247 _p.shadowOffsetX; 1248 cc.defineGetterSetter(_p, "shadowOffsetX", _p._getShadowOffsetX, _p._setShadowOffsetX); 1249 /** @expose */ 1250 _p.shadowOffsetY; 1251 cc.defineGetterSetter(_p, "shadowOffsetY", _p._getShadowOffsetY, _p._setShadowOffsetY); 1252 /** @expose */ 1253 _p.shadowOpacity; 1254 cc.defineGetterSetter(_p, "shadowOpacity", _p._getShadowOpacity, _p._setShadowOpacity); 1255 /** @expose */ 1256 _p.shadowBlur; 1257 cc.defineGetterSetter(_p, "shadowBlur", _p._getShadowBlur, _p._setShadowBlur); 1258 1259 delete window._p; 1260 1261 cc.LabelTTF._textAlign = ["left", "center", "right"]; 1262 1263 cc.LabelTTF._textBaseline = ["top", "middle", "bottom"]; 1264 1265 // Class static properties for measure util 1266 cc.LabelTTF._checkRegEx = /(.+?)([\s\n\r\-\/\\\:]|[\u4E00-\u9FA5]|[\uFE30-\uFFA0])/; 1267 cc.LabelTTF._reverseCheckRegEx = /(.*)([\s\n\r\-\/\\\:]|[\u4E00-\u9FA5]|[\uFE30-\uFFA0])/; 1268 cc.LabelTTF._checkEnRegEx = /[\s\-\/\\\:]/; 1269 1270 // Only support style in this format: "18px Verdana" or "18px 'Helvetica Neue'" 1271 cc.LabelTTF._fontStyleRE = /^(\d+)px\s+['"]?([\w\s\d]+)['"]?$/; 1272 1273 /** 1274 * creates a cc.LabelTTF from a font name, alignment, dimension and font size 1275 * @param {String} text 1276 * @param {String|cc.FontDefinition} fontName 1277 * @param {Number} fontSize 1278 * @param {cc.Size} [dimensions=cc.size(0,0)] 1279 * @param {Number} [hAlignment=] 1280 * @param {Number} [vAlignment=cc.VERTICAL_TEXT_ALIGNMENT_TOP] 1281 * @return {cc.LabelTTF|Null} 1282 * @example 1283 * // Example 1284 * 1. 1285 * var myLabel = cc.LabelTTF.create('label text', 'Times New Roman', 32, cc.size(320,32), cc.TEXT_ALIGNMENT_LEFT); 1286 * 2. 1287 * var fontDef = new cc.FontDefinition(); 1288 * fontDef.fontName = "Arial"; 1289 * fontDef.fontSize = "32"; 1290 * var myLabel = cc.LabelTTF.create('label text', fontDef); 1291 */ 1292 cc.LabelTTF.create = function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) { 1293 var ret = new cc.LabelTTF(); 1294 if (fontName && fontName instanceof cc.FontDefinition) { 1295 if (ret.initWithStringAndTextDefinition(text, fontName)) 1296 return ret; 1297 } 1298 if (ret.initWithString(text, fontName, fontSize, dimensions, hAlignment, vAlignment)) 1299 return ret; 1300 return null; 1301 }; 1302 1303 1304 if(cc.USE_LA88_LABELS) 1305 cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTURECOLOR; 1306 else 1307 cc.LabelTTF._SHADER_PROGRAM = cc.SHADER_POSITION_TEXTUREA8COLOR; 1308 1309 cc.LabelTTF.__labelHeightDiv = document.createElement("div"); 1310 cc.LabelTTF.__labelHeightDiv.style.fontFamily = "Arial"; 1311 cc.LabelTTF.__labelHeightDiv.style.position = "absolute"; 1312 cc.LabelTTF.__labelHeightDiv.style.left = "-100px"; 1313 cc.LabelTTF.__labelHeightDiv.style.top = "-100px"; 1314 cc.LabelTTF.__labelHeightDiv.style.lineHeight = "normal"; 1315 document.body.appendChild(cc.LabelTTF.__labelHeightDiv); 1316 1317 cc.LabelTTF.__getFontHeightByDiv = function(fontName, fontSize){ 1318 var clientHeight = cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize]; 1319 if (clientHeight > 0) return clientHeight; 1320 var labelDiv = cc.LabelTTF.__labelHeightDiv; 1321 labelDiv.innerHTML = "ajghl~!"; 1322 labelDiv.style.fontFamily = fontName; 1323 labelDiv.style.fontSize = fontSize + "px"; 1324 clientHeight = labelDiv.clientHeight ; 1325 cc.LabelTTF.__fontHeightCache[fontName + "." + fontSize] = clientHeight; 1326 labelDiv.innerHTML = ""; 1327 return clientHeight; 1328 }; 1329 1330 cc.LabelTTF.__fontHeightCache = {}; 1331 1332 1333 1334