1 /** 2 * The MIT License (MIT) 3 * 4 * Copyright (c) 2016 DeNA Co., Ltd. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 /// <reference path="base.js"/> 26 /// <reference path="display_object.js"/> 27 /// <reference path="word_breaker.js"/> 28 /// <reference path="tween_target.js"/> 29 /// <reference path="shadow.js"/> 30 /// <reference path="counter.js"/> 31 32 /** 33 * A class that displays one-line text or multi-line text. 34 * @param {string} text 35 * @param {string} font 36 * @param {string} color 37 * @extends {createjs.DisplayObject} 38 * @constructor 39 */ 40 createjs.Text = function(text, font, color) { 41 /// <param type="string" name="text"/> 42 /// <param type="string" name="font"/> 43 /// <param type="string" name="color"/> 44 createjs.DisplayObject.call(this); 45 46 /** 47 * The text to be displayed. 48 * @type {string} 49 * @private 50 */ 51 this.text_ = text; 52 53 /** 54 * The font style to use. Any valid value for the CSS font attribute is 55 * acceptable (ex. "bold 36px Arial"). 56 * @type {string} 57 * @private 58 */ 59 this.font_ = font; 60 61 /** 62 * The color to draw the text in. Any valid value for the CSS color attribute 63 * is acceptable (ex. "#F00"). Default is "#000". It will also accept valid 64 * canvas fillStyle values. 65 * @type {string} 66 * @private 67 */ 68 this.textColor_ = color; 69 70 /** 71 * The offset position of the text. 72 * @type {createjs.Point} 73 * @private 74 */ 75 this.offset_ = new createjs.Point(0, 0); 76 }; 77 createjs.inherits('Text', createjs.Text, createjs.DisplayObject); 78 79 /** 80 * An inner class that draws text onto the specified canvas with the Canvas 2D 81 * API. 82 * @constructor 83 */ 84 createjs.Text.Renderer = function() { 85 /** 86 * The output <canvas> element. 87 * @type {HTMLCanvasElement} 88 * @private 89 */ 90 this.canvas_ = createjs.createCanvas(); 91 92 /** 93 * The 2D rendering context attached to the output <canvas> element. 94 * @type {CanvasRenderingContext2D} 95 * @private 96 */ 97 this.context_ = createjs.getRenderingContext2D(this.canvas_); 98 99 // Use a low-color texture to save memory. 100 this.canvas_.format_ = createjs.Renderer.Format.RGBA4444; 101 }; 102 103 /** 104 * The current width of the output <canvas> element. 105 * @type {number} 106 * @private 107 */ 108 createjs.Text.Renderer.prototype.width_ = 0; 109 110 /** 111 * The current height of the output <canvas> element. 112 * @type {number} 113 * @private 114 */ 115 createjs.Text.Renderer.prototype.height_ = 0; 116 117 /** 118 * The current font style of the output <canvas> element. 119 * @type {string} 120 * @private 121 */ 122 createjs.Text.Renderer.prototype.font_ = ''; 123 124 /** 125 * Deletes all resources attached to this renderer. 126 * @private 127 */ 128 createjs.Text.Renderer.prototype.destroy_ = function() { 129 if (this.canvas_) { 130 this.canvas_.width = 0; 131 this.context_ = null; 132 this.canvas_ = null; 133 } 134 }; 135 136 /** 137 * Returns the HTMLCanvasElement object attached to this renderer. 138 * @return {HTMLCanvasElement} 139 * @private 140 */ 141 createjs.Text.Renderer.prototype.getCanvas_ = function() { 142 /// <returns type="HTMLCanvasElement"/> 143 return this.canvas_; 144 }; 145 146 /** 147 * Returns the ID assigned to this renderer. 148 * @return {string} 149 * @private 150 */ 151 createjs.Text.Renderer.prototype.getId_ = function() { 152 /// <returns type="string"/> 153 return this.canvas_.id; 154 }; 155 156 /** 157 * Sets the specified ID to this renderer. 158 * @param {string} id 159 * @private 160 */ 161 createjs.Text.Renderer.prototype.setId_ = function(id) { 162 /// <param type="string" name="id"/> 163 if (createjs.DEBUG) { 164 this.canvas_.id = id; 165 } 166 }; 167 168 /** 169 * Sets the output size. 170 * @param {number} width 171 * @param {number} height 172 * @private 173 */ 174 createjs.Text.Renderer.prototype.setSize_ = function(width, height) { 175 /// <param type="number" name="width"/> 176 /// <param type="number" name="height"/> 177 if (this.width_ != width) { 178 this.width_ = width; 179 this.canvas_.width = width; 180 this.font_ = ''; 181 } 182 if (this.height_ != height) { 183 this.height_ = height; 184 this.canvas_.height = height; 185 this.font_ = ''; 186 } 187 }; 188 189 /** 190 * Sets the font. 191 * @param {string} font 192 * @private 193 */ 194 createjs.Text.Renderer.prototype.setFont_ = function(font) { 195 /// <param type="string" name="font"/> 196 if (this.font_ != font) { 197 this.font_ = font; 198 this.context_.font = font; 199 } 200 }; 201 202 /** 203 * Sets the alignment of text. 204 * @param {string} textAlign 205 * @private 206 */ 207 createjs.Text.Renderer.prototype.setTextAlign_ = function(textAlign) { 208 /// <param type="string" name="textAlign"/> 209 this.context_.textAlign = textAlign; 210 }; 211 212 /** 213 * Sets the baseline of text. 214 * @param {string} textBaseline 215 * @private 216 */ 217 createjs.Text.Renderer.prototype.setTextBaseline_ = function(textBaseline) { 218 /// <param type="string" name="textBaseline"/> 219 this.context_.textBaseline = textBaseline; 220 }; 221 222 /** 223 * Sets the text shadow. 224 * @param {createjs.Shadow} shadow 225 * @private 226 */ 227 createjs.Text.Renderer.prototype.setShadow_ = function(shadow) { 228 /// <param type="createjs.Shadow" name="shadow"/> 229 if (shadow) { 230 this.context_.shadowColor = shadow.color; 231 this.context_.shadowOffsetX = shadow.offsetX; 232 this.context_.shadowOffsetY = shadow.offsetY; 233 this.context_.shadowBlur = shadow.blur; 234 } else { 235 this.context_.shadowColor = '#000'; 236 this.context_.shadowOffsetX = 0; 237 this.context_.shadowOffsetY = 0; 238 this.context_.shadowBlur = 0; 239 } 240 }; 241 242 /** 243 * Sets the line width. 244 * @param {number} lineWidth 245 * @private 246 */ 247 createjs.Text.Renderer.prototype.setLineWidth_ = function(lineWidth) { 248 /// <param type="number" name="lineWidth"/> 249 this.context_.lineWidth = lineWidth; 250 }; 251 252 /** 253 * Sets the fill color. 254 * @param {string} color 255 * @private 256 */ 257 createjs.Text.Renderer.prototype.setFillColor_ = function(color) { 258 /// <param type="string" name="color"/> 259 this.context_.fillStyle = color; 260 }; 261 262 /** 263 * Sets the stroke color. 264 * @param {string} color 265 * @private 266 */ 267 createjs.Text.Renderer.prototype.setStrokeColor_ = function(color) { 268 /// <param type="string" name="color"/> 269 this.context_.strokeStyle = color; 270 }; 271 272 /** 273 * Clears an rectangle. 274 * @param {number} x 275 * @param {number} y 276 * @param {number} width 277 * @param {number} height 278 * @private 279 */ 280 createjs.Text.Renderer.prototype.clearRect_ = function(x, y, width, height) { 281 /// <param type="number" name="x"/> 282 /// <param type="number" name="y"/> 283 /// <param type="number" name="width"/> 284 /// <param type="number" name="height"/> 285 this.context_.clearRect(x, y, width, height); 286 this.canvas_.dirty_ = true; 287 }; 288 289 /** 290 * Draws filled text. 291 * @param {string} text 292 * @param {number} x 293 * @param {number} y 294 * @param {number} maxWidth 295 * @private 296 */ 297 createjs.Text.Renderer.prototype.fillText_ = function(text, x, y, maxWidth) { 298 /// <param type="string" name="text"/> 299 /// <param type="number" name="x"/> 300 /// <param type="number" name="y"/> 301 /// <param type="number" name="maxWidth"/> 302 this.context_.fillText(text, x, y, maxWidth); 303 }; 304 305 /** 306 * Draws an outline of text. 307 * @param {string} text 308 * @param {number} x 309 * @param {number} y 310 * @param {number} maxWidth 311 * @private 312 */ 313 createjs.Text.Renderer.prototype.strokeText_ = function(text, x, y, maxWidth) { 314 /// <param type="string" name="text"/> 315 /// <param type="number" name="x"/> 316 /// <param type="number" name="y"/> 317 /// <param type="number" name="maxWidth"/> 318 this.context_.strokeText(text, x, y, maxWidth); 319 }; 320 321 /** 322 * Returns text width. 323 * @param {string} text 324 * @return {TextMetrics} 325 * @private 326 */ 327 createjs.Text.Renderer.prototype.measureText_ = function(text) { 328 /// <param type="string" name="text"/> 329 return this.context_.measureText(text); 330 }; 331 332 /** 333 * The font heights. 334 * @type {Object.<string,number>} 335 * @private 336 */ 337 createjs.Text.lineAdvances_ = {}; 338 339 /** 340 * The horizontal text alignment. This value must be one of "start", "end", 341 * "left", "right", and "center". 342 * @type {string} 343 * @private 344 */ 345 createjs.Text.prototype.textAlign_ = 'left'; 346 347 /** 348 * The vertical alignment point on the font. This value must be one of "top", 349 * "hanging", "middle", "alphabetic", "ideographic", or "bottom". 350 * @type {string} 351 * @private 352 */ 353 createjs.Text.prototype.textBaseline_ = 'top'; 354 355 /** 356 * The maximum width to draw the text. 357 * @type {number} 358 * @private 359 */ 360 createjs.Text.prototype.maxWidth_ = 0; 361 362 /** 363 * The line width of the text outline. This object draws only the outline of 364 * its text if this value is not 0. 365 * @type {number} 366 * @private 367 */ 368 createjs.Text.prototype.outline_ = 0; 369 370 /** 371 * The line height (vertical distance between baselines) for multi-line text. 372 * If this value is 0, the value of getMeasuredLineHeight is used. 373 * @type {number} 374 * @private 375 */ 376 createjs.Text.prototype.lineHeight_ = 0; 377 378 /** 379 * Indicates the maximum width for a line of text before it is wrapped to 380 * multiple lines. If this value is 0, the text will not be wrapped. 381 * @type {number} 382 * @private 383 */ 384 createjs.Text.prototype.lineWidth_ = 0; 385 386 /** 387 * Whether this object needs to redraw its text. 388 * @type {boolean} 389 * @private 390 */ 391 createjs.Text.prototype.textDirty_ = true; 392 393 /** 394 * A list of text lines split from the source text to fit them into the source 395 * width. 396 * @type {Array.<string>} 397 * @private 398 */ 399 createjs.Text.prototype.lines_ = null; 400 401 /** 402 * The height of a line. 403 * @type {number} 404 * @private 405 */ 406 createjs.Text.prototype.lineAdvance_ = 0; 407 408 /** 409 * The width of a cached image. 410 * @type {number} 411 * @private 412 */ 413 createjs.Text.prototype.width_ = 0; 414 415 /** 416 * The height of a cached image. 417 * @type {number} 418 * @private 419 */ 420 createjs.Text.prototype.height_ = 0; 421 422 /** 423 * The renderer that draws text. 424 * @type {createjs.Text.Renderer} 425 * @private 426 */ 427 createjs.Text.prototype.renderer_ = null; 428 429 /** 430 * The renderer that draws this object. 431 * @type {createjs.Renderer} 432 * @private 433 */ 434 createjs.Text.prototype.output_ = null; 435 436 /** 437 * Returns the cache renderer used for drawing text to a cache. 438 * @return {createjs.Text.Renderer} 439 * @private 440 */ 441 createjs.Text.prototype.getRenderer_ = function() { 442 /// <returns type="createjs.Text.Renderer"/> 443 if (!this.renderer_) { 444 if (createjs.DEBUG) { 445 ++createjs.Counter.totalRenderers; 446 } 447 this.renderer_= new createjs.Text.Renderer(); 448 } 449 return this.renderer_; 450 }; 451 452 /** 453 * Breaks text into lines so the specified renderer can render each of them at 454 * one fillText() or strokeText() call. 455 * @param {createjs.Text.Renderer} renderer 456 * @param {string} text 457 * @return {Array.<string>} lines; 458 * @private 459 */ 460 createjs.Text.prototype.breakText_ = function(renderer, text) { 461 /// <param type="createjs.JsonText.Renderer" name="renderer"/> 462 /// <param type="string" name="text"/> 463 /// <returns type="Array" elementType="string"/> 464 465 // Return without calculating the line width (which is used as the width of a 466 // cache <canvas> element) when the it is specified by a game. 467 var lines = text.split('\n'); 468 var width = this.maxWidth_; 469 if (width > 0) { 470 this.width_ = width; 471 return lines; 472 } 473 474 // When the line width is not specified by a game, calculate the maximum line 475 // width as use it so each line of this text can be rendered without inserting 476 // line breaks. 477 var length = lines.length; 478 if (this.lineWidth_ <= 0) { 479 width = 0; 480 for (var i = 0; i < length; ++i) { 481 var lineWidth = renderer.measureText_(lines[i]).width; 482 width = createjs.max(lineWidth, width); 483 } 484 this.width_ = width; 485 return lines; 486 } 487 488 // Insert line breaks to fit all lines into the specified line width. 489 this.width_ = this.lineWidth_ / this.getScaleX(); 490 width = this.width_; 491 var renderLines = []; 492 for (var i = 0; i < length; ++i) { 493 var line = lines[i]; 494 var lineWidth = renderer.measureText_(line).width; 495 if (lineWidth <= width) { 496 renderLines.push(line); 497 continue; 498 } 499 var words = createjs.WordBreaker.breakText(line); 500 if (words.length == 1) { 501 renderLines.push(line); 502 continue; 503 } 504 lineWidth = 0; 505 var lineText = ''; 506 for (var j = 0; j < words.length; ++j) { 507 var wordWidth = renderer.measureText_(words[j]).width; 508 lineWidth += wordWidth; 509 if (lineWidth > width) { 510 renderLines.push(lineText); 511 lineText = words[j]; 512 lineWidth = wordWidth; 513 } else { 514 lineText += words[j]; 515 } 516 } 517 if (lineText) { 518 renderLines.push(lineText); 519 } 520 } 521 return renderLines; 522 }; 523 524 /** 525 * Draws multi-line text to the cache of this object. 526 * @private 527 */ 528 createjs.Text.prototype.paintCache_ = function() { 529 // Break text into lines. 530 this.textDirty_ = false; 531 var renderer = this.getRenderer_(); 532 renderer.setId_(this.text_); 533 if (!this.lines_) { 534 renderer.setFont_(this.font_); 535 this.lines_ = this.breakText_(renderer, this.text_); 536 } 537 538 // Set the size of the cache HTMLCanvasElement object. 539 var lines = this.lines_; 540 var length = lines.length; 541 this.lineAdvance_ = this.lineHeight_ || this.getMeasuredLineHeight(); 542 var lineAdvance = this.lineAdvance_; 543 this.height_ = (length + 0.5) * lineAdvance; 544 var margin = 0; 545 if (this.outline_) { 546 margin = this.outline_; 547 } 548 var shadow = this.getShadow(); 549 if (shadow) { 550 var offset = 551 createjs.max(createjs.abs(shadow.offsetX), createjs.abs(shadow.offsetY)); 552 margin = createjs.max(margin, offset + shadow.blur); 553 } 554 var padding = margin << 1; 555 this.width_ += padding; 556 this.height_ += padding; 557 renderer.setSize_(this.width_, this.height_); 558 renderer.setFont_(this.font_); 559 renderer.setTextAlign_(this.textAlign_); 560 renderer.setTextBaseline_(this.textBaseline_); 561 renderer.setShadow_(shadow); 562 renderer.clearRect_(0, 0, this.width_, this.height_); 563 564 // Draw text to the cache line by line. 565 var x = margin; 566 if (this.textAlign_ == 'center') { 567 x = this.width_ >> 1; 568 } else if (this.textAlign_ == 'right') { 569 x = this.width_; 570 } 571 var y = margin; 572 this.offset_.x = -x; 573 this.offset_.y = -y; 574 var maxWidth = this.maxWidth_ || 10000; 575 if (this.outline_) { 576 renderer.setStrokeColor_(this.textColor_); 577 renderer.setLineWidth_(this.outline_); 578 for (var i = 0; i < length; ++i) { 579 renderer.strokeText_(lines[i], x, y, maxWidth); 580 y += lineAdvance; 581 } 582 } else { 583 renderer.setFillColor_(this.textColor_); 584 for (var i = 0; i < length; ++i) { 585 renderer.fillText_(lines[i], x, y, maxWidth); 586 y += lineAdvance; 587 } 588 } 589 this.setBoundingBox(-x, -y, this.width_ - x, this.height_ - y); 590 }; 591 592 /** 593 * Returns the text. 594 * @return {string} 595 */ 596 createjs.Text.prototype.getText = function() { 597 /// <returns type="string"/> 598 return this.text_; 599 }; 600 601 /** 602 * Sets the text. 603 * @param {string} text 604 */ 605 createjs.Text.prototype.setText = function(text) { 606 /// <param type="string" name="text"/> 607 text = (text == null) ? '' : createjs.parseString(text); 608 if (this.text_ != text) { 609 this.text_ = text; 610 this.lines_ = null; 611 this.textDirty_ = true; 612 } 613 }; 614 615 /** 616 * Returns the text font. 617 * @return {string} 618 */ 619 createjs.Text.prototype.getFont = function() { 620 /// <returns type="string"/> 621 return this.text_; 622 }; 623 624 /** 625 * Sets the text font. 626 * @param {string} font 627 */ 628 createjs.Text.prototype.setFont = function(font) { 629 /// <param type="string" name="font"/> 630 if (this.font_ != font) { 631 this.font_ = font; 632 this.lineAdvance_ = 0; 633 this.textDirty_ = true; 634 } 635 }; 636 637 /** 638 * Returns the text color. 639 * @return {string} 640 */ 641 createjs.Text.prototype.getColor = function() { 642 /// <returns type="string"/> 643 return this.textColor_; 644 }; 645 646 /** 647 * Sets the text color. 648 * @param {string} value 649 */ 650 createjs.Text.prototype.setColor = function(value) { 651 /// <param type="string" name="value"/> 652 var color = value || '#000'; 653 if (this.textColor_ != color) { 654 this.textColor_ = color; 655 this.textDirty_ = true; 656 } 657 }; 658 659 /** 660 * Returns the text alignment. 661 * @return {string} 662 */ 663 createjs.Text.prototype.getTextAlign = function() { 664 /// <returns type="string"/> 665 return this.textAlign_; 666 }; 667 668 /** 669 * Sets the text alignment. 670 * @param {string} value 671 */ 672 createjs.Text.prototype.setTextAlign = function(value) { 673 /// <param type="string" name="value"/> 674 var textAlign = value || 'left'; 675 if (this.textAlign_ != textAlign) { 676 this.textAlign_ = textAlign; 677 this.textDirty_ = true; 678 } 679 }; 680 681 /** 682 * Returns the text baseline. 683 * @return {string} 684 */ 685 createjs.Text.prototype.getTextBaseline = function() { 686 /// <returns type="string"/> 687 return this.textBaseline_; 688 }; 689 690 /** 691 * Sets the text baseline. 692 * @param {string} value 693 */ 694 createjs.Text.prototype.setTextBaseline = function(value) { 695 /// <param type="string" name="value"/> 696 var textBaseline = value || 'top'; 697 if (this.textBaseline_ != textBaseline) { 698 this.textBaseline_ = textBaseline; 699 this.textDirty_ = true; 700 } 701 }; 702 703 /** 704 * Returns the maximum width. 705 * @return {number} 706 */ 707 createjs.Text.prototype.getMaxWidth = function() { 708 /// <returns type="number"/> 709 return this.maxWidth_; 710 }; 711 712 /** 713 * Sets the maximum width. 714 * @param {number} maxWidth 715 */ 716 createjs.Text.prototype.setMaxWidth = function(maxWidth) { 717 /// <param type="number" name="maxWidth"/> 718 if (this.maxWidth_ != maxWidth) { 719 this.maxWidth_ = maxWidth; 720 this.lines_ = null; 721 this.textDirty_ = true; 722 } 723 }; 724 725 /** 726 * Returns the thickness of text outlines. 727 * @return {number} 728 */ 729 createjs.Text.prototype.getOutline = function() { 730 /// <returns type="number"/> 731 return this.outline_; 732 }; 733 734 /** 735 * Sets the thickness of text outlines. 736 * @param {number} outline 737 */ 738 createjs.Text.prototype.setOutline = function(outline) { 739 /// <param type="number" name="outline"/> 740 var thickness = createjs.parseFloat(outline); 741 if (this.outline_ != outline) { 742 this.outline_ = outline; 743 this.textDirty_ = true; 744 } 745 }; 746 747 /** 748 * Returns the line height. 749 * @return {number} 750 */ 751 createjs.Text.prototype.getLineHeight = function() { 752 /// <returns type="number"/> 753 return this.lineHeight_; 754 }; 755 756 /** 757 * Sets the line height. 758 * @param {number} lineHeight 759 */ 760 createjs.Text.prototype.setLineHeight = function(lineHeight) { 761 /// <param type="number" name="lineHeight"/> 762 if (this.lineHeight_ != lineHeight) { 763 this.lineHeight_ = lineHeight; 764 this.textDirty_ = true; 765 } 766 }; 767 768 /** 769 * Returns the line width. 770 * @return {number} 771 */ 772 createjs.Text.prototype.getLineWidth = function() { 773 /// <returns type="number"/> 774 return this.lineWidth_; 775 }; 776 777 /** 778 * Sets the line width. 779 * @param {number} lineWidth 780 */ 781 createjs.Text.prototype.setLineWidth = function(lineWidth) { 782 /// <param type="number" name="lineWidth"/> 783 if (this.lineWidth_ != lineWidth) { 784 this.lineWidth_ = lineWidth; 785 this.lines_ = null; 786 this.textDirty_ = true; 787 } 788 }; 789 790 /** 791 * Returns the measured, untransformed width of the text without wrapping. Use 792 * Text.getBounds() for a more robust value. 793 * @return {number} The measured, untransformed width of the text. 794 */ 795 createjs.Text.prototype.getMeasuredWidth = function() { 796 /// <returns type="number"/> 797 if (this.textDirty_ && this.text_) { 798 this.paintCache_(); 799 } 800 return this.width_; 801 }; 802 803 /** 804 * Returns an approximate line height of the text. 805 * @return {number} 806 */ 807 createjs.Text.prototype.getMeasuredLineHeight = function() { 808 /// <returns type="number"/> 809 if (!this.lineAdvance_) { 810 if (!createjs.Text.lineAdvances_[this.font_]) { 811 // Multiply 1.2 with the width of 'M' to get the measured line height used 812 // by CreateJS. 813 var renderer = this.getRenderer_(); 814 renderer.setFont_(this.font_); 815 createjs.Text.lineAdvances_[this.font_] = 816 renderer.measureText_('M').width * 1.2; 817 } 818 this.lineAdvance_ = createjs.Text.lineAdvances_[this.font_]; 819 } 820 return this.lineAdvance_; 821 }; 822 823 /** 824 * Returns the approximate height of multi-line text. 825 * @return {number} 826 */ 827 createjs.Text.prototype.getMeasuredHeight = function() { 828 /// <returns type="number"/> 829 if (this.textDirty_ && this.text_) { 830 this.paintCache_(); 831 } 832 return this.lineAdvance_ * this.lines_.length; 833 }; 834 835 /** @override */ 836 createjs.Text.prototype.isVisible = function() { 837 /// <returns type="boolean"/> 838 return !!this.text_ && createjs.Text.superClass_.isVisible.call(this); 839 }; 840 841 /** @override */ 842 createjs.Text.prototype.handleAttach = function(flag) { 843 /// <param type="number" name="flag"/> 844 if (flag && this.textDirty_ && this.text_) { 845 this.paintCache_(); 846 } 847 }; 848 849 /** @override */ 850 createjs.Text.prototype.removeAllChildren = function(opt_destroy) { 851 /// <param type="boolean" optional="true" name="opt_destroy"/> 852 this.handleDetach(); 853 this.text_ = ''; 854 }; 855 856 /** @override */ 857 createjs.Text.prototype.handleDetach = function() { 858 if (createjs.DEBUG) { 859 --createjs.Counter.totalRenderers; 860 } 861 if (this.output_ && this.renderer_) { 862 this.output_.uncache(this.renderer_.getCanvas_()); 863 } 864 this.output_ = null; 865 if (this.renderer_) { 866 this.renderer_.destroy_(); 867 } 868 this.renderer_ = null; 869 this.textDirty_ = true; 870 }; 871 872 /** @override */ 873 createjs.Text.prototype.layout = 874 function(renderer, parent, dirty, time, draw) { 875 /// <param type="createjs.Renderer" name="renderer"/> 876 /// <param type="createjs.DisplayObject" name="parent"/> 877 /// <param type="number" name="dirty"/> 878 /// <param type="number" name="time"/> 879 /// <param type="number" name="draw"/> 880 /// <returns type="number"/> 881 if (this.textDirty_ && draw) { 882 this.paintCache_(); 883 this.setDirty(createjs.DisplayObject.DIRTY_SHAPE); 884 } 885 if (!this.output_) { 886 this.output_ = renderer; 887 } 888 return createjs.Text.superClass_.layout.call( 889 this, renderer, parent, dirty, time, draw); 890 }; 891 892 /** @override */ 893 createjs.Text.prototype.paintObject = function(renderer) { 894 /// <param type="createjs.Renderer" name="renderer"/> 895 renderer.drawCanvas(this.renderer_.getCanvas_(), 896 this.offset_.x, this.offset_.y, this.width_, this.height_); 897 }; 898 899 /** @override */ 900 createjs.Text.prototype.set = function(properties) { 901 createjs.Text.superClass_.set.call(this, properties); 902 var KEYS = { 903 'text': createjs.Text.prototype.setText, 904 'font': createjs.Text.prototype.setFont, 905 'color': createjs.Text.prototype.setColor, 906 'textAlign': createjs.Text.prototype.setTextAlign, 907 'textBaseline': createjs.Text.prototype.setTextBaseline, 908 'maxWidth': createjs.Text.prototype.setMaxWidth, 909 'outline': createjs.Text.prototype.setOutline, 910 'lineHeight': createjs.Text.prototype.setLineHeight, 911 'lineWidth': createjs.Text.prototype.setLineWidth, 912 'shadow': createjs.Text.prototype.setShadow 913 }; 914 for (var key in properties) { 915 var setter = KEYS[key]; 916 if (setter) { 917 var value = properties[key]; 918 setter.call(this, value); 919 } 920 } 921 return this; 922 }; 923 924 /** @override */ 925 createjs.Text.prototype.getBounds = function() { 926 if (this.getBoundingBox().isEmpty()) { 927 var width = this.getMeasuredWidth(); 928 this.setBoundingBox(0, 0, width, 0); 929 } 930 return createjs.Text.superClass_.getBounds.call(this); 931 }; 932 933 /** @override */ 934 createjs.Text.prototype.getSetters = function() { 935 /// <return type="Object" elementType="createjs.TweenTarget.Setter"/> 936 var setters = createjs.Text.superClass_.getSetters.call(this); 937 setters['text'].setString(this.text_); 938 return setters; 939 }; 940 941 // Add a setter to allow tweens to change this object. 942 createjs.TweenTarget.Property.addSetters({ 943 'text': createjs.Text.prototype.setText 944 }); 945 946 // Add getters and setters for applications to access internal variables. 947 Object.defineProperties(createjs.Text.prototype, { 948 'text': { 949 get: createjs.Text.prototype.getText, 950 set: createjs.Text.prototype.setText 951 }, 952 'font': { 953 get: createjs.Text.prototype.getFont, 954 set: createjs.Text.prototype.setFont 955 }, 956 'color': { 957 get: createjs.Text.prototype.getColor, 958 set: createjs.Text.prototype.setColor 959 }, 960 'textAlign': { 961 get: createjs.Text.prototype.getTextAlign, 962 set: createjs.Text.prototype.setTextAlign 963 }, 964 'textBaseline': { 965 get: createjs.Text.prototype.getTextBaseline, 966 set: createjs.Text.prototype.setTextBaseline 967 }, 968 'maxWidth': { 969 get: createjs.Text.prototype.getMaxWidth, 970 set: createjs.Text.prototype.setMaxWidth 971 }, 972 'outline': { 973 get: createjs.Text.prototype.getOutline, 974 set: createjs.Text.prototype.setOutline 975 }, 976 'lineHeight': { 977 get: createjs.Text.prototype.getLineHeight, 978 set: createjs.Text.prototype.setLineHeight 979 }, 980 'lineWidth': { 981 get: createjs.Text.prototype.getLineWidth, 982 set: createjs.Text.prototype.setLineWidth 983 } 984 }); 985 986 // Export the createjs.Text object to the global namespace. 987 createjs.exportObject('createjs.Text', createjs.Text, { 988 // createjs.Text methods 989 'getMeasuredWidth': createjs.Text.prototype.getMeasuredWidth, 990 'getMeasuredLineHeight': createjs.Text.prototype.getMeasuredLineHeight, 991 'getMeasuredHeight': createjs.Text.prototype.getMeasuredHeight 992 // createjs.DisplayObject methods 993 // createjs.EventDispatcher methods 994 // createjs.Object methods. 995 }); 996