@next2d/text 1.14.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2661 @@
1
+ import { TextFormat } from "./TextFormat";
2
+ import { InteractiveObject, Sprite } from "@next2d/display";
3
+ import { FocusEvent, Event as Next2DEvent, MouseEvent as Next2DMouseEvent } from "@next2d/events";
4
+ import { Tween } from "@next2d/ui";
5
+ import { Rectangle } from "@next2d/geom";
6
+ import { $currentPlayer, $DIV, $isSafari, $MOUSE_DOWN, $MOUSE_UP, $MOUSE_WHEEL, $P_TAG, $PREFIX, $rendererWorker, $SCROLL, $textContext, $TOUCH_END, $TOUCH_START, $devicePixelRatio, $document, $RegExp } from "@next2d/util";
7
+ import { $doUpdated, $clamp, $getArray, $intToRGBA, $isNaN, $Math, $requestAnimationFrame, $toColorInt, $getMap, $poolFloat32Array6, $boundsMatrix, $multiplicationMatrix, $poolBoundsObject, $multiplicationColor, $Infinity, $Number, $poolArray, $poolFloat32Array8, $generateFontStyle, $getBoundsObject } from "@next2d/share";
8
+ /**
9
+ * TextField クラスは、テキストの表示と入力用の表示オブジェクトを作成するために使用されます。
10
+ * プロパティインスペクターを使用して、テキストフィールドにインスタンス名を付けることができます。
11
+ * また、TextField クラスのメソッドとプロパティを使用して、JavaScript でテキストフィールドを操作できます。
12
+ *
13
+ * The TextField class is used to create display objects for text display and input.
14
+ * You can give a text field an instance name in the Property inspector
15
+ * and use the methods and properties of the TextField class to manipulate it with JavaScript.
16
+ *
17
+ * @class
18
+ * @memberOf next2d.text
19
+ * @extends InteractiveObject
20
+ */
21
+ export class TextField extends InteractiveObject {
22
+ /**
23
+ * @constructor
24
+ * @public
25
+ */
26
+ constructor() {
27
+ super();
28
+ /**
29
+ * @type {boolean}
30
+ * @default false
31
+ * @private
32
+ */
33
+ this._$background = false;
34
+ /**
35
+ * @type {number}
36
+ * @default 0xffffff
37
+ * @private
38
+ */
39
+ this._$backgroundColor = 0xffffff;
40
+ /**
41
+ * @type {boolean}
42
+ * @default false
43
+ * @private
44
+ */
45
+ this._$border = false;
46
+ /**
47
+ * @type {number}
48
+ * @default 0x000000
49
+ * @private
50
+ */
51
+ this._$borderColor = 0x000000;
52
+ /**
53
+ * @type {string}
54
+ * @default ""
55
+ * @private
56
+ */
57
+ this._$htmlText = "";
58
+ /**
59
+ * @type {boolean}
60
+ * @default false
61
+ * @private
62
+ */
63
+ this._$multiline = false;
64
+ /**
65
+ * @type {string}
66
+ * @default ""
67
+ * @private
68
+ */
69
+ this._$text = "";
70
+ /**
71
+ * @type {boolean}
72
+ * @default false
73
+ * @private
74
+ */
75
+ this._$wordWrap = false;
76
+ /**
77
+ * @type {number}
78
+ * @default 0
79
+ * @private
80
+ */
81
+ this._$scrollH = 0;
82
+ /**
83
+ * @type {number}
84
+ * @default 1
85
+ * @private
86
+ */
87
+ this._$scrollV = 1;
88
+ /**
89
+ * @type {number}
90
+ * @default null
91
+ * @private
92
+ */
93
+ this._$maxScrollV = null;
94
+ /**
95
+ * @type {number}
96
+ * @default null
97
+ * @private
98
+ */
99
+ this._$maxScrollH = null;
100
+ /**
101
+ * @type {number}
102
+ * @default 0
103
+ * @private
104
+ */
105
+ this._$maxChars = 0;
106
+ // TextFormat
107
+ const textFormat = new TextFormat();
108
+ textFormat._$setDefault();
109
+ /**
110
+ * @type {TextFormat}
111
+ * @private
112
+ */
113
+ this._$defaultTextFormat = textFormat;
114
+ /**
115
+ * @type {string}
116
+ * @default ""
117
+ * @private
118
+ */
119
+ this._$rawHtmlText = "";
120
+ /**
121
+ * @type {object}
122
+ * @private
123
+ */
124
+ this._$bounds = {
125
+ "xMin": 0,
126
+ "xMax": 100,
127
+ "yMin": 0,
128
+ "yMax": 100
129
+ };
130
+ /**
131
+ * @type {object}
132
+ * @private
133
+ */
134
+ this._$originBounds = {
135
+ "xMin": 0,
136
+ "xMax": 100,
137
+ "yMin": 0,
138
+ "yMax": 100
139
+ };
140
+ /**
141
+ * @type {string}
142
+ * @default null
143
+ * @private
144
+ */
145
+ this._$restrict = "";
146
+ /**
147
+ * @type {boolean}
148
+ * @default false
149
+ * @private
150
+ */
151
+ this._$isHTML = false;
152
+ /**
153
+ * @type {boolean}
154
+ * @default false
155
+ * @private
156
+ */
157
+ this._$createdTextData = false;
158
+ /**
159
+ * @type {array}
160
+ * @private
161
+ */
162
+ this._$textData = $getArray();
163
+ /**
164
+ * @type {number}
165
+ * @default null
166
+ * @private
167
+ */
168
+ this._$textHeight = null;
169
+ /**
170
+ * @type {number}
171
+ * @default null
172
+ * @private
173
+ */
174
+ this._$textWidth = null;
175
+ /**
176
+ * @type {array}
177
+ * @private
178
+ */
179
+ this._$widthTable = $getArray();
180
+ /**
181
+ * @type {HTMLTextAreaElement}
182
+ * @default null
183
+ * @private
184
+ */
185
+ this._$textarea = null;
186
+ /**
187
+ * @type {string}
188
+ * @default TextFieldAutoSize.NONE
189
+ * @private
190
+ */
191
+ this._$autoSize = "none";
192
+ /**
193
+ * @type {boolean}
194
+ * @default false
195
+ * @private
196
+ */
197
+ this._$autoFontSize = false;
198
+ /**
199
+ * @type {array}
200
+ * @default null
201
+ * @private
202
+ */
203
+ this._$heightTable = $getArray();
204
+ /**
205
+ * @type {array}
206
+ * @private
207
+ */
208
+ this._$textFormatTable = $getArray();
209
+ /**
210
+ * @type {boolean}
211
+ * @default false
212
+ * @private
213
+ */
214
+ this._$textAreaActive = false;
215
+ /**
216
+ * @type {number}
217
+ * @default 0
218
+ * @private
219
+ */
220
+ this._$totalWidth = 0;
221
+ /**
222
+ * @type {array}
223
+ * @private
224
+ */
225
+ this._$objectTable = $getArray();
226
+ /**
227
+ * @type {array}
228
+ * @private
229
+ */
230
+ this._$imageData = $getArray();
231
+ /**
232
+ * @type {boolean}
233
+ * @default true
234
+ * @private
235
+ */
236
+ this._$scrollEnabled = true;
237
+ /**
238
+ * @type {Sprite}
239
+ * @default null
240
+ * @private
241
+ */
242
+ this._$scrollSprite = null;
243
+ /**
244
+ * @type {string}
245
+ * @default null
246
+ * @private
247
+ */
248
+ this._$type = "static";
249
+ /**
250
+ * @type {array}
251
+ * @default null
252
+ * @private
253
+ */
254
+ this._$textHeightTable = $getArray();
255
+ /**
256
+ * @type {boolean}
257
+ * @default false
258
+ * @private
259
+ */
260
+ this._$focus = false;
261
+ /**
262
+ * @type {boolean}
263
+ * @default false
264
+ * @private
265
+ */
266
+ this._$isComposing = false;
267
+ /**
268
+ * @type {number}
269
+ * @default 0
270
+ * @private
271
+ */
272
+ this._$thickness = 0;
273
+ /**
274
+ * @type {number}
275
+ * @default 0
276
+ * @private
277
+ */
278
+ this._$thicknessColor = 0;
279
+ /**
280
+ * @type {string}
281
+ * @default TextFormatVerticalAlign.TOP
282
+ * @private
283
+ */
284
+ this._$verticalAlign = "top";
285
+ /**
286
+ * @type {Map}
287
+ * @private
288
+ */
289
+ this._$heightCache = $getMap();
290
+ }
291
+ /**
292
+ * @description 指定されたクラスのストリングを返します。
293
+ * Returns the string representation of the specified class.
294
+ *
295
+ * @return {string}
296
+ * @default [class TextField]
297
+ * @method
298
+ * @static
299
+ */
300
+ static toString() {
301
+ return "[class TextField]";
302
+ }
303
+ /**
304
+ * @description 指定されたクラスの空間名を返します。
305
+ * Returns the space name of the specified class.
306
+ *
307
+ * @return {string}
308
+ * @default next2d.text.TextField
309
+ * @const
310
+ * @static
311
+ */
312
+ static get namespace() {
313
+ return "next2d.text.TextField";
314
+ }
315
+ /**
316
+ * @description 指定されたオブジェクトのストリングを返します。
317
+ * Returns the string representation of the specified object.
318
+ *
319
+ * @return {string}
320
+ * @default [object TextField]
321
+ * @method
322
+ * @public
323
+ */
324
+ toString() {
325
+ return "[object TextField]";
326
+ }
327
+ /**
328
+ * @description 指定されたオブジェクトの空間名を返します。
329
+ * Returns the space name of the specified object.
330
+ *
331
+ * @return {string}
332
+ * @default next2d.text.TextField
333
+ * @const
334
+ * @public
335
+ */
336
+ get namespace() {
337
+ return "next2d.text.TextField";
338
+ }
339
+ /**
340
+ * @description テキストサイズの自動的な拡大 / 縮小および整列を制御します。
341
+ * Controls automatic sizing and alignment of text size.
342
+ *
343
+ * @member {boolean}
344
+ * @default false
345
+ * @public
346
+ */
347
+ get autoFontSize() {
348
+ return this._$autoFontSize;
349
+ }
350
+ set autoFontSize(auto_font_size) {
351
+ if (auto_font_size !== this._$autoFontSize) {
352
+ this._$autoFontSize = auto_font_size;
353
+ this._$reload();
354
+ }
355
+ }
356
+ /**
357
+ * @description テキストフィールドの自動的な拡大 / 縮小および整列を制御します。
358
+ * Controls automatic sizing and alignment of text fields.
359
+ *
360
+ * @member {string}
361
+ * @default TextFieldAutoSize.NONE
362
+ * @public
363
+ */
364
+ get autoSize() {
365
+ return this._$autoSize;
366
+ }
367
+ set autoSize(auto_size) {
368
+ if (auto_size !== this._$autoSize) {
369
+ this._$autoSize = auto_size;
370
+ this._$reload();
371
+ }
372
+ }
373
+ /**
374
+ * @description テキストフィールドに背景の塗りつぶしがあるかどうかを指定します。
375
+ * Specifies whether the text field has a background fill.
376
+ *
377
+ * @member {boolean}
378
+ * @default false
379
+ * @public
380
+ */
381
+ get background() {
382
+ return this._$background;
383
+ }
384
+ set background(background) {
385
+ if (background !== this._$background) {
386
+ this._$background = !!background;
387
+ this._$reset();
388
+ }
389
+ }
390
+ /**
391
+ * @description テキストフィールドの背景の色です。
392
+ * The color of the text field background.
393
+ *
394
+ * @member {number}
395
+ * @default 0xffffff
396
+ * @public
397
+ */
398
+ get backgroundColor() {
399
+ return this._$backgroundColor;
400
+ }
401
+ set backgroundColor(background_color) {
402
+ background_color = $clamp($toColorInt(background_color), 0, 0xffffff, 0xffffff);
403
+ if (background_color !== this._$backgroundColor) {
404
+ this._$backgroundColor = background_color;
405
+ this._$reset();
406
+ }
407
+ }
408
+ /**
409
+ * @description テキストフィールドに境界線があるかどうかを指定します。
410
+ * Specifies whether the text field has a border.
411
+ *
412
+ * @member {boolean}
413
+ * @default false
414
+ * @public
415
+ */
416
+ get border() {
417
+ return this._$border;
418
+ }
419
+ set border(border) {
420
+ if (border !== this._$border) {
421
+ this._$border = !!border;
422
+ this._$reset();
423
+ }
424
+ }
425
+ /**
426
+ * @description テキストフィールドの境界線の色です。
427
+ * The color of the text field border.
428
+ *
429
+ * @member {number}
430
+ * @default 0x000000
431
+ * @public
432
+ */
433
+ get borderColor() {
434
+ return this._$borderColor;
435
+ }
436
+ set borderColor(border_color) {
437
+ border_color = $clamp($toColorInt(border_color), 0, 0xffffff, 0);
438
+ if (border_color !== this._$borderColor) {
439
+ this._$borderColor = border_color;
440
+ this._$reset();
441
+ }
442
+ }
443
+ /**
444
+ * @description テキストに適用するフォーマットを指定します。
445
+ * Specifies the formatting to be applied to the text.
446
+ *
447
+ * @member {TextFormat}
448
+ * @public
449
+ */
450
+ get defaultTextFormat() {
451
+ return this._$defaultTextFormat._$clone();
452
+ }
453
+ set defaultTextFormat(text_format) {
454
+ text_format._$merge(this._$defaultTextFormat);
455
+ this._$defaultTextFormat = text_format;
456
+ this._$reset();
457
+ }
458
+ /**
459
+ * @description このオブジェクトでマウスまたはその他のユーザー入力メッセージを
460
+ *
461
+ * @member {boolean}
462
+ * @default false
463
+ * @public
464
+ */
465
+ get focus() {
466
+ return this._$focus;
467
+ }
468
+ set focus(focus) {
469
+ if (this._$focus === focus) {
470
+ return;
471
+ }
472
+ this._$focus = focus;
473
+ if (this._$focus) {
474
+ if (this._$type === "input") {
475
+ const player = $currentPlayer();
476
+ const div = $document
477
+ .getElementById(player.contentElementId);
478
+ if (!div) {
479
+ return;
480
+ }
481
+ this._$createTextAreaElement(player._$scale);
482
+ // setup
483
+ const element = this._$textarea;
484
+ if (!element) {
485
+ return;
486
+ }
487
+ const matrix = this._$transform.concatenatedMatrix;
488
+ const bounds = this._$getBounds(null);
489
+ const color = $intToRGBA($toColorInt(this._$defaultTextFormat.color), 100);
490
+ element.style.color = `rgb(${color.R},${color.G},${color.B})`;
491
+ element.style.left = `${(matrix.tx + bounds.xMin + player.x / player._$scale / $devicePixelRatio) * player._$scale}px`;
492
+ element.style.top = `${(matrix.ty + bounds.yMin + player.y / player._$scale / $devicePixelRatio) * player._$scale}px`;
493
+ element.style.width = `${$Math.ceil((this.width - 1) * player._$scale)}px`;
494
+ element.style.height = `${$Math.ceil((this.height - 1) * player._$scale)}px`;
495
+ // set text
496
+ element.value = this.text;
497
+ div.appendChild(element);
498
+ $requestAnimationFrame(() => {
499
+ element.focus();
500
+ });
501
+ this._$doChanged();
502
+ $doUpdated();
503
+ this._$textAreaActive = true;
504
+ // focus in event
505
+ if (this.willTrigger(FocusEvent.FOCUS_IN)) {
506
+ this.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_IN));
507
+ }
508
+ }
509
+ }
510
+ else {
511
+ // execute
512
+ if (this._$textarea) {
513
+ this._$textarea.dispatchEvent(new Event(`${$PREFIX}_blur`));
514
+ if (this.willTrigger(FocusEvent.FOCUS_OUT)) {
515
+ this.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_OUT));
516
+ }
517
+ this._$textarea.remove();
518
+ }
519
+ }
520
+ }
521
+ /**
522
+ * @description テキストフィールドの内容を HTML で表します。
523
+ * Contains the HTML representation of the text field contents.
524
+ *
525
+ * @member {string}
526
+ * @default ""
527
+ * @public
528
+ */
529
+ get htmlText() {
530
+ return this._$htmlText;
531
+ }
532
+ set htmlText(html_text) {
533
+ if (this._$htmlText !== html_text) {
534
+ this._$htmlText = `${html_text}`;
535
+ this._$rawHtmlText = "";
536
+ this._$text = "";
537
+ this._$isHTML = true;
538
+ this._$textFormatTable.length = 0;
539
+ this._$reload();
540
+ }
541
+ }
542
+ /**
543
+ * @description テキストフィールド内の文字数です。
544
+ * The int of characters in a text field.
545
+ *
546
+ * @member {number}
547
+ * @readonly
548
+ * @public
549
+ */
550
+ get length() {
551
+ return this.text.length;
552
+ }
553
+ /**
554
+ * @description ユーザーが入力するときに、テキストフィールドに入力できる最大の文字数です。
555
+ * The maximum number of characters that the text field can contain,
556
+ * as entered by a user.
557
+ *
558
+ * @member {number}
559
+ * @default 0
560
+ * @public
561
+ */
562
+ get maxChars() {
563
+ return this._$maxChars;
564
+ }
565
+ set maxChars(max_chars) {
566
+ this._$maxChars = max_chars | 0;
567
+ }
568
+ /**
569
+ * TODO
570
+ * @description scrollH の最大値です。
571
+ * The maximum value of scrollH.
572
+ *
573
+ * @member {number}
574
+ * @readonly
575
+ * @public
576
+ */
577
+ get maxScrollH() {
578
+ if (this._$maxScrollH === null) {
579
+ this._$maxScrollH = 0;
580
+ }
581
+ return this._$maxScrollH;
582
+ }
583
+ /**
584
+ * @description scrollV の最大値です。
585
+ * The maximum value of scrollV.
586
+ *
587
+ * @member {number}
588
+ * @readonly
589
+ * @public
590
+ */
591
+ get maxScrollV() {
592
+ if (this._$maxScrollV === null) {
593
+ this._$maxScrollV = 1;
594
+ this._$getTextData();
595
+ if (!this._$textHeightTable.length) {
596
+ return this._$maxScrollV;
597
+ }
598
+ const length = this._$textHeightTable.length;
599
+ const maxHeight = this.height;
600
+ if (maxHeight > this.textHeight) {
601
+ return this._$maxScrollV;
602
+ }
603
+ let textHeight = 0;
604
+ let idx = 0;
605
+ while (length > idx) {
606
+ textHeight += this._$textHeightTable[idx++];
607
+ if (textHeight > maxHeight) {
608
+ break;
609
+ }
610
+ this._$maxScrollV++;
611
+ }
612
+ }
613
+ return this._$maxScrollV;
614
+ }
615
+ /**
616
+ * @description フィールドが複数行テキストフィールドであるかどうかを示します。
617
+ * Indicates whether field is a multiline text field.
618
+ *
619
+ * @member {boolean}
620
+ * @default false
621
+ * @public
622
+ */
623
+ get multiline() {
624
+ return this._$multiline;
625
+ }
626
+ set multiline(multiline) {
627
+ if (multiline !== this._$multiline) {
628
+ this._$multiline = !!multiline;
629
+ this._$reset();
630
+ }
631
+ }
632
+ /**
633
+ * @description フィールドが複数行テキストフィールドであるかどうかを示します。
634
+ * Indicates whether field is a multiline text field.
635
+ *
636
+ * @member {number}
637
+ * @readonly
638
+ * @public
639
+ */
640
+ get numLines() {
641
+ if (!this._$createdTextData) {
642
+ this._$getTextData();
643
+ }
644
+ return this._$objectTable.length;
645
+ }
646
+ /**
647
+ * @description ユーザーがテキストフィールドに入力できる文字のセットを指定します。
648
+ * Indicates the set of characters that a user can enter into the text field.
649
+ *
650
+ * @member {string}
651
+ * @default null
652
+ * @public
653
+ */
654
+ get restrict() {
655
+ return this._$restrict;
656
+ }
657
+ set restrict(restrict) {
658
+ this._$restrict = `${restrict}`;
659
+ }
660
+ /**
661
+ * @description スクロール機能のON/OFFの制御。
662
+ * Control ON/OFF of the scroll function.
663
+ *
664
+ * @member {boolean}
665
+ * @default true
666
+ * @public
667
+ */
668
+ get scrollEnabled() {
669
+ return this._$scrollEnabled;
670
+ }
671
+ set scrollEnabled(scroll_enabled) {
672
+ this._$scrollEnabled = scroll_enabled;
673
+ }
674
+ /**
675
+ * TODO
676
+ * @description 現在の水平スクロール位置です。
677
+ * The current horizontal scrolling position.
678
+ *
679
+ * @member {number}
680
+ * @public
681
+ */
682
+ get scrollH() {
683
+ return this._$scrollH;
684
+ }
685
+ set scrollH(scroll_h) {
686
+ scroll_h = $clamp(scroll_h | 0, 0, this.maxScrollH);
687
+ if (this._$scrollH !== scroll_h) {
688
+ this._$scrollH = scroll_h;
689
+ this._$reset();
690
+ if (this.willTrigger(Next2DEvent.SCROLL)) {
691
+ this.dispatchEvent(new Next2DEvent(Next2DEvent.SCROLL, true));
692
+ }
693
+ }
694
+ }
695
+ /**
696
+ * @description テキストフィールドのテキストの垂直位置です。
697
+ * The vertical position of text in a text field.
698
+ *
699
+ * @member {number}
700
+ * @public
701
+ */
702
+ get scrollV() {
703
+ return this._$scrollV;
704
+ }
705
+ set scrollV(scroll_v) {
706
+ scroll_v = $clamp(scroll_v | 0, 1, this.maxScrollV);
707
+ if (this._$scrollV !== scroll_v) {
708
+ this._$scrollV = $Math.max(1, scroll_v);
709
+ this._$reset();
710
+ if (this._$scrollSprite && this.textHeight > this.height) {
711
+ this._$scrollSprite.height = this.height * this.height / this.textHeight - 1;
712
+ const parent = this._$parent;
713
+ if (parent) {
714
+ // view start
715
+ this._$scrollSprite.alpha = 1;
716
+ // set position
717
+ this._$scrollSprite.x = this.x + this.width - this._$scrollSprite.width - 0.5;
718
+ this._$scrollSprite.y = this.y + 0.5
719
+ + (this.height - 1 - this._$scrollSprite.height)
720
+ / (this.maxScrollV - 1)
721
+ * (this._$scrollV - 1);
722
+ // added sprite
723
+ parent.addChildAt(this._$scrollSprite, parent.getChildIndex(this) + 1);
724
+ // start animation
725
+ if (this._$scrollSprite.hasLocalVariable("job")) {
726
+ this._$scrollSprite.getLocalVariable("job").stop();
727
+ }
728
+ const job = Tween.add(this._$scrollSprite, { "alpha": 1 }, { "alpha": 0 }, 1);
729
+ job.addEventListener(Next2DEvent.COMPLETE, (event) => {
730
+ const sprite = event.target.target;
731
+ sprite.deleteLocalVariable("job");
732
+ if (sprite.parent) {
733
+ sprite.parent.removeChild(sprite);
734
+ }
735
+ });
736
+ job.start();
737
+ this._$scrollSprite.setLocalVariable("job", job);
738
+ }
739
+ }
740
+ if (this.willTrigger(Next2DEvent.SCROLL)) {
741
+ this.dispatchEvent(new Next2DEvent(Next2DEvent.SCROLL, true));
742
+ }
743
+ }
744
+ }
745
+ /**
746
+ * @description テキストフィールド内の現在のテキストであるストリングです。
747
+ * A string that is the current text in the text field.
748
+ *
749
+ * @member {string}
750
+ * @default ""
751
+ * @public
752
+ */
753
+ get text() {
754
+ if (!this._$isHTML) {
755
+ return this._$text;
756
+ }
757
+ if (this._$rawHtmlText) {
758
+ return this._$rawHtmlText;
759
+ }
760
+ let text = "";
761
+ const textData = this._$getTextData();
762
+ for (let idx = 1; idx < textData.length; ++idx) {
763
+ const object = textData[idx];
764
+ switch (object.mode) {
765
+ case "text":
766
+ text += object.text;
767
+ break;
768
+ case "break":
769
+ text += "\r";
770
+ break;
771
+ }
772
+ }
773
+ this._$rawHtmlText = text;
774
+ return text;
775
+ }
776
+ set text(text) {
777
+ if (text === null) {
778
+ text = "";
779
+ }
780
+ text = `${text}`;
781
+ if (text !== this._$text) {
782
+ this._$text = text;
783
+ this._$htmlText = "";
784
+ this._$isHTML = false;
785
+ this._$textFormatTable.length = 0;
786
+ this._$reload();
787
+ }
788
+ }
789
+ /**
790
+ * @description テキストフィールドのテキストの色です(16 進数形式)。
791
+ * The color of the text in a text field, in hexadecimal format.
792
+ *
793
+ * @member {number}
794
+ * @public
795
+ */
796
+ get textColor() {
797
+ return this._$defaultTextFormat.color || 0;
798
+ }
799
+ set textColor(text_color) {
800
+ this._$defaultTextFormat.color = text_color;
801
+ this._$reload();
802
+ }
803
+ /**
804
+ * @description テキストの高さです(ピクセル単位)。
805
+ * The height of the text in pixels.
806
+ *
807
+ * @member {number}
808
+ * @readonly
809
+ * @public
810
+ */
811
+ get textHeight() {
812
+ if (this.text === "") {
813
+ return 0;
814
+ }
815
+ if (this._$textHeight === null) {
816
+ // setup
817
+ this._$textHeight = 2;
818
+ this._$getTextData();
819
+ const length = this._$textHeightTable.length;
820
+ if (length === 1) {
821
+ this._$textHeight += this._$defaultTextFormat.leading || 0;
822
+ }
823
+ for (let idx = 0; idx < length; ++idx) {
824
+ this._$textHeight += this._$textHeightTable[idx];
825
+ }
826
+ }
827
+ return this._$textHeight;
828
+ }
829
+ /**
830
+ * @description テキストの幅です(ピクセル単位)。
831
+ * The width of the text in pixels.
832
+ *
833
+ * @member {number}
834
+ * @readonly
835
+ * @public
836
+ */
837
+ get textWidth() {
838
+ if (this._$textWidth === null) {
839
+ // setup
840
+ this._$textWidth = 0;
841
+ this._$getTextData();
842
+ for (let idx = 0; idx < this._$widthTable.length; ++idx) {
843
+ this._$textWidth = $Math.max(this._$textWidth, this._$widthTable[idx]);
844
+ }
845
+ }
846
+ return this._$textWidth;
847
+ }
848
+ /**
849
+ * @description 輪郭のテキスト幅です。0(デフォルト値)で無効にできます。
850
+ * The text width of the outline, which can be disabled with 0 (the default value).
851
+ *
852
+ * @member {number}
853
+ * @default 0
854
+ * @public
855
+ */
856
+ get thickness() {
857
+ return this._$thickness;
858
+ }
859
+ set thickness(thickness) {
860
+ thickness |= 0;
861
+ if (thickness !== this._$thickness) {
862
+ this._$thickness = thickness;
863
+ this._$reset();
864
+ }
865
+ }
866
+ /**
867
+ * @description 輪郭のテキストの色です(16 進数形式)。
868
+ * The color of the outline text. (Hexadecimal format)
869
+ *
870
+ * @member {number}
871
+ * @default 0
872
+ * @public
873
+ */
874
+ get thicknessColor() {
875
+ return this._$thicknessColor;
876
+ }
877
+ set thicknessColor(thickness_color) {
878
+ thickness_color = $clamp($toColorInt(thickness_color), 0, 0xffffff, 0);
879
+ if (thickness_color !== this._$thicknessColor) {
880
+ this._$thicknessColor = thickness_color;
881
+ this._$reset();
882
+ }
883
+ }
884
+ /**
885
+ * @description テキストフィールドのタイプです。
886
+ * The type of the text field.
887
+ *
888
+ * @member {string}
889
+ * @default TextFieldType.STATIC
890
+ * @public
891
+ */
892
+ get type() {
893
+ return this._$type;
894
+ }
895
+ set type(type) {
896
+ this._$type = type;
897
+ if (type === "static") {
898
+ this._$textarea = null;
899
+ }
900
+ }
901
+ /**
902
+ * @description 縦方向の揃え位置を指定するプロパティです。
903
+ * This property specifies the vertical alignment position.
904
+ *
905
+ * @member {string}
906
+ * @default TextFormatVerticalAlign.TOP
907
+ * @public
908
+ */
909
+ get verticalAlign() {
910
+ return this._$verticalAlign;
911
+ }
912
+ set verticalAlign(vertical_align) {
913
+ if (vertical_align !== this._$verticalAlign) {
914
+ this._$verticalAlign = vertical_align;
915
+ this._$reset();
916
+ }
917
+ }
918
+ /**
919
+ * @description テキストフィールドのテキストを折り返すかどうかを示すブール値です。
920
+ * A Boolean value that indicates whether the text field has word wrap.
921
+ *
922
+ * @member {boolean}
923
+ * @default false
924
+ * @public
925
+ */
926
+ get wordWrap() {
927
+ return this._$wordWrap;
928
+ }
929
+ set wordWrap(word_wrap) {
930
+ if (this._$wordWrap !== word_wrap) {
931
+ this._$wordWrap = !!word_wrap;
932
+ this._$reset();
933
+ }
934
+ }
935
+ /**
936
+ * @description 表示オブジェクトの幅を示します(ピクセル単位)。
937
+ * Indicates the width of the display object, in pixels.
938
+ *
939
+ * @member {number}
940
+ * @public
941
+ */
942
+ get width() {
943
+ return super.width;
944
+ }
945
+ set width(width) {
946
+ width = +width;
947
+ if (!$isNaN(width) && width > -1) {
948
+ const bounds = this._$getBounds(null);
949
+ const xMin = $Math.abs(bounds.xMin);
950
+ this._$originBounds.xMax = width + xMin;
951
+ this._$originBounds.xMin = xMin;
952
+ this._$bounds.xMax = this._$originBounds.xMax;
953
+ this._$bounds.xMin = this._$originBounds.xMin;
954
+ super.width = width;
955
+ this._$reload();
956
+ }
957
+ }
958
+ /**
959
+ * @description 表示オブジェクトの高さを示します(ピクセル単位)。
960
+ * Indicates the height of the display object, in pixels.
961
+ *
962
+ * @member {number}
963
+ * @public
964
+ */
965
+ get height() {
966
+ return super.height;
967
+ }
968
+ set height(height) {
969
+ height = +height;
970
+ if (!$isNaN(height) && height > -1) {
971
+ const bounds = this._$getBounds(null);
972
+ const yMin = $Math.abs(bounds.yMin);
973
+ this._$originBounds.yMax = height + yMin;
974
+ this._$bounds.yMax = this._$originBounds.yMax;
975
+ this._$bounds.yMin = this._$originBounds.yMin;
976
+ super.height = height;
977
+ this._$reload();
978
+ }
979
+ }
980
+ /**
981
+ * @description 親 DisplayObjectContainer のローカル座標を基準にした
982
+ * DisplayObject インスタンスの x 座標を示します。
983
+ * Indicates the x coordinate
984
+ * of the DisplayObject instance relative to the local coordinates
985
+ * of the parent DisplayObjectContainer.
986
+ *
987
+ * @member {number}
988
+ * @public
989
+ */
990
+ get x() {
991
+ const matrix = this._$transform.matrix;
992
+ const bounds = this._$getBounds(null);
993
+ return matrix._$matrix[4] + bounds.xMin;
994
+ }
995
+ set x(x) {
996
+ const bounds = this._$getBounds(null);
997
+ super.x = x - bounds.xMin;
998
+ }
999
+ /**
1000
+ * @description 親 DisplayObjectContainer のローカル座標を基準にした
1001
+ * DisplayObject インスタンスの y 座標を示します。
1002
+ * Indicates the y coordinate
1003
+ * of the DisplayObject instance relative to the local coordinates
1004
+ * of the parent DisplayObjectContainer.
1005
+ *
1006
+ * @member {number}
1007
+ * @public
1008
+ */
1009
+ get y() {
1010
+ const matrix = this._$transform.matrix;
1011
+ const bounds = this._$getBounds(null);
1012
+ return matrix._$matrix[5] + bounds.yMin;
1013
+ }
1014
+ set y(y) {
1015
+ const bounds = this._$getBounds(null);
1016
+ super.y = y - bounds.yMin;
1017
+ }
1018
+ /**
1019
+ * @description newText パラメーターで指定されたストリングを、
1020
+ * テキストフィールドのテキストの最後に付加します。
1021
+ * Appends the string specified by the newText parameter
1022
+ * to the end of the text of the text field.
1023
+ *
1024
+ * @param {string} new_text
1025
+ * @return void
1026
+ * @method
1027
+ * @public
1028
+ */
1029
+ appendText(new_text) {
1030
+ const currentText = this.text;
1031
+ this.text = currentText + `${new_text}`;
1032
+ }
1033
+ /**
1034
+ * @description beginIndex パラメーターと endIndex パラメーターで指定された範囲の
1035
+ * テキストのフォーマット情報を含む TextFormat オブジェクトを返します。
1036
+ * Returns a TextFormat object that contains formatting information
1037
+ * for the range of text that the beginIndex and endIndex parameters specify.
1038
+ *
1039
+ * @param {int} [begin_index=-1]
1040
+ * @param {int} [end_index=-1]
1041
+ * @return {TextFormat}
1042
+ * @method
1043
+ * @public
1044
+ */
1045
+ getTextFormat(begin_index = -1, end_index = -1) {
1046
+ begin_index |= 0;
1047
+ end_index |= 0;
1048
+ const data = this._$getTextData();
1049
+ const length = end_index > -1 ? end_index : data.length;
1050
+ let init = false;
1051
+ let textFormat = new TextFormat();
1052
+ let idx = begin_index > -1 ? begin_index : 0;
1053
+ for (; idx < length; ++idx) {
1054
+ if (data[idx].mode === "break") {
1055
+ continue;
1056
+ }
1057
+ const tf = data[idx].textFormat;
1058
+ if (!init) {
1059
+ init = true;
1060
+ textFormat = tf._$clone();
1061
+ continue;
1062
+ }
1063
+ textFormat.align = textFormat.align !== tf.align ? null : tf.align;
1064
+ textFormat.blockIndent = textFormat.blockIndent !== tf.blockIndent ? null : tf.blockIndent;
1065
+ textFormat.bold = textFormat.bold !== tf.bold ? null : tf.bold;
1066
+ textFormat.color = textFormat.color !== tf.color ? null : tf.color;
1067
+ textFormat.font = textFormat.font !== tf.font ? null : tf.font;
1068
+ textFormat.indent = textFormat.indent !== tf.indent ? null : tf.indent;
1069
+ textFormat.italic = textFormat.italic !== tf.italic ? null : tf.italic;
1070
+ textFormat.leading = textFormat.leading !== tf.leading ? null : tf.leading;
1071
+ textFormat.leftMargin = textFormat.leftMargin !== tf.leftMargin ? null : tf.leftMargin;
1072
+ textFormat.letterSpacing = textFormat.letterSpacing !== tf.letterSpacing ? null : tf.letterSpacing;
1073
+ textFormat.rightMargin = textFormat.rightMargin !== tf.rightMargin ? null : tf.rightMargin;
1074
+ textFormat.size = textFormat.size !== tf.size ? null : tf.size;
1075
+ textFormat.underline = textFormat.underline !== tf.underline ? null : tf.underline;
1076
+ }
1077
+ return textFormat;
1078
+ }
1079
+ /**
1080
+ * @description lineIndex パラメーターで指定された行のテキストを返します。
1081
+ * Returns the text of the line specified by the lineIndex parameter.
1082
+ *
1083
+ * @param {number} line_index
1084
+ * @return {string}
1085
+ * @public
1086
+ */
1087
+ getLineText(line_index) {
1088
+ if (!this._$text && !this._$htmlText) {
1089
+ return "";
1090
+ }
1091
+ line_index |= 0;
1092
+ let lineText = "";
1093
+ const textData = this._$getTextData();
1094
+ for (let idx = 0; idx < textData.length; idx++) {
1095
+ const obj = textData[idx];
1096
+ if (obj.yIndex > line_index) {
1097
+ break;
1098
+ }
1099
+ if (obj.yIndex !== line_index) {
1100
+ continue;
1101
+ }
1102
+ if (obj.mode !== "text") {
1103
+ continue;
1104
+ }
1105
+ lineText += obj.text;
1106
+ }
1107
+ return lineText;
1108
+ }
1109
+ /**
1110
+ * @description beginIndex パラメーターと endIndex パラメーターで指定された文字範囲を、
1111
+ * newText パラメーターの内容に置き換えます。
1112
+ * Replaces the range of characters that the beginIndex
1113
+ * and endIndex parameters specify with the contents of the newText parameter.
1114
+ *
1115
+ * @param {number} begin_index
1116
+ * @param {number} end_index
1117
+ * @param {string} new_text
1118
+ * @return {void}
1119
+ * @method
1120
+ * @public
1121
+ */
1122
+ replaceText(begin_index, end_index, new_text) {
1123
+ begin_index |= 0;
1124
+ end_index |= 0;
1125
+ if (begin_index > -1 && end_index > -1 && end_index >= begin_index) {
1126
+ const text = this.text;
1127
+ if (begin_index >= text.length) {
1128
+ if (end_index >= text.length && end_index >= begin_index) {
1129
+ this.text = text + `${new_text}`;
1130
+ }
1131
+ }
1132
+ else {
1133
+ this.text = text.slice(0, begin_index)
1134
+ + `${new_text}`
1135
+ + text.slice(end_index, text.length);
1136
+ }
1137
+ }
1138
+ }
1139
+ /**
1140
+ * @description format パラメーターで指定したテキストフォーマットを、
1141
+ * テキストフィールド内の指定されたテキストに適用します。
1142
+ * Applies the text formatting that the format parameter specifies
1143
+ * to the specified text in a text field.
1144
+ *
1145
+ * @param {TextFormat} text_format
1146
+ * @param {number} [begin_index=-1]
1147
+ * @param {number} [end_index=-1]
1148
+ * @return {void}
1149
+ * @method
1150
+ * @public
1151
+ */
1152
+ setTextFormat(text_format, begin_index = -1, end_index = -1) {
1153
+ // setup
1154
+ begin_index |= 0;
1155
+ end_index |= 0;
1156
+ const textData = this._$getTextData();
1157
+ this._$reset();
1158
+ switch (true) {
1159
+ case begin_index === -1 && end_index === -1:
1160
+ for (let idx = 0; idx < textData.length; ++idx) {
1161
+ this._$textFormatTable[idx] = text_format._$clone();
1162
+ }
1163
+ break;
1164
+ case begin_index > -1 && end_index === -1:
1165
+ {
1166
+ let idx = begin_index + 1;
1167
+ let obj = textData[idx];
1168
+ if (obj.mode === "wrap") {
1169
+ obj = textData[++idx];
1170
+ }
1171
+ this._$textFormatTable[idx] = text_format._$clone();
1172
+ }
1173
+ break;
1174
+ case begin_index > -1 && end_index > -1 && end_index > begin_index:
1175
+ {
1176
+ let offset = 0;
1177
+ for (let idx = begin_index; idx < end_index; ++idx) {
1178
+ const obj = textData[idx];
1179
+ if (!obj) {
1180
+ continue;
1181
+ }
1182
+ if (obj.mode === "wrap" || obj.mode === "break") {
1183
+ ++end_index;
1184
+ --offset;
1185
+ continue;
1186
+ }
1187
+ this._$textFormatTable[idx + offset] = text_format._$clone();
1188
+ }
1189
+ }
1190
+ break;
1191
+ }
1192
+ this._$getTextData();
1193
+ this._$resize();
1194
+ }
1195
+ /**
1196
+ * @return {array}
1197
+ * @method
1198
+ * @private
1199
+ */
1200
+ _$getTextData() {
1201
+ if (!this._$createdTextData) {
1202
+ this._$createdTextData = true;
1203
+ // reset
1204
+ this._$textData.length = 0;
1205
+ this._$imageData.length = 0;
1206
+ this._$heightTable.length = 0;
1207
+ this._$textHeightTable.length = 0;
1208
+ this._$objectTable.length = 0;
1209
+ this._$widthTable.length = 0;
1210
+ this._$heightCache.clear();
1211
+ let tfCopyOffset = -1;
1212
+ if (this._$isHTML) {
1213
+ // html text
1214
+ let htmlText = this._$htmlText;
1215
+ const index = htmlText.search(/(< .*>|<>)/g);
1216
+ if (index > -1) {
1217
+ htmlText = htmlText.slice(0, index);
1218
+ }
1219
+ htmlText = htmlText.replace(/\r\n/g, "\r\r");
1220
+ if ($P_TAG.innerHTML !== htmlText) {
1221
+ $P_TAG.textContent = "";
1222
+ $P_TAG.insertAdjacentHTML("afterbegin", htmlText);
1223
+ }
1224
+ // setup
1225
+ let tf = this._$defaultTextFormat;
1226
+ if (this._$textData.length in this._$textFormatTable) {
1227
+ const tft = this._$textFormatTable[this._$textData.length]._$clone();
1228
+ tft._$merge(tf);
1229
+ tf = tft;
1230
+ }
1231
+ // init
1232
+ this._$totalWidth = 0;
1233
+ this._$heightTable[0] = 0;
1234
+ this._$textHeightTable[0] = this._$getTextHeight(tf);
1235
+ this._$widthTable[0] = 0;
1236
+ const obj = {
1237
+ "mode": "break",
1238
+ "x": 0,
1239
+ "yIndex": 0,
1240
+ "textFormat": tf._$clone()
1241
+ };
1242
+ this._$objectTable[0] = obj;
1243
+ this._$textData[0] = obj;
1244
+ this._$parseTag($P_TAG, tf._$clone(), tfCopyOffset);
1245
+ }
1246
+ else {
1247
+ // plain text
1248
+ const texts = this._$multiline
1249
+ ? this._$text.split("\n")
1250
+ : [this._$text.replace("\n", "")];
1251
+ for (let idx = 0; idx < texts.length; ++idx) {
1252
+ // reset
1253
+ this._$totalWidth = 0;
1254
+ let tf = this.defaultTextFormat;
1255
+ const yIndex = this._$wordWrap || this._$multiline
1256
+ ? this._$heightTable.length
1257
+ : 0;
1258
+ this._$heightTable[yIndex] = 0;
1259
+ this._$textHeightTable[yIndex] = this._$getTextHeight(tf);
1260
+ this._$widthTable[yIndex] = 0;
1261
+ if (yIndex) {
1262
+ this._$heightTable[yIndex] = this._$heightTable[yIndex - 1];
1263
+ this._$textHeightTable[yIndex] = this._$textHeightTable[yIndex - 1];
1264
+ }
1265
+ if (this._$textData.length in this._$textFormatTable) {
1266
+ const tft = this._$textFormatTable[this._$textData.length]._$clone();
1267
+ tft._$merge(tf);
1268
+ tf = tft;
1269
+ }
1270
+ const obj = {
1271
+ "mode": "break",
1272
+ "x": 0,
1273
+ "yIndex": yIndex,
1274
+ "textFormat": tf._$clone()
1275
+ };
1276
+ tf = this.defaultTextFormat;
1277
+ this._$objectTable[yIndex] = obj;
1278
+ this._$textData[this._$textData.length] = obj;
1279
+ // parse text data
1280
+ const text = texts[idx];
1281
+ if (text) {
1282
+ tfCopyOffset = this._$parseText(text, tf, tfCopyOffset);
1283
+ }
1284
+ }
1285
+ }
1286
+ // clear
1287
+ this._$heightCache.clear();
1288
+ }
1289
+ return this._$textData;
1290
+ }
1291
+ /**
1292
+ * @param {Element} tag
1293
+ * @param {TextFormat} text_format
1294
+ * @param {number} tf_copy_offset
1295
+ * @return {void}
1296
+ * @private
1297
+ */
1298
+ _$parseTag(tag, text_format, tf_copy_offset) {
1299
+ const childNodes = tag.childNodes;
1300
+ const length = childNodes.length;
1301
+ for (let idx = 0; idx < length; ++idx) {
1302
+ let tf = text_format._$clone();
1303
+ const node = childNodes[idx];
1304
+ if (node.nodeType === 3) {
1305
+ tf_copy_offset = this._$parseText(node.nodeValue || "", tf, tf_copy_offset);
1306
+ continue;
1307
+ }
1308
+ switch (node.nodeName) {
1309
+ case "P":
1310
+ {
1311
+ if (node.hasAttribute("align")) {
1312
+ const align = node.getAttribute("align");
1313
+ if (align === "center" || align === "left" || align === "right") {
1314
+ tf.align = align;
1315
+ if (this._$textData.length === 1) {
1316
+ this._$textData[0].textFormat.align = tf.align;
1317
+ }
1318
+ }
1319
+ }
1320
+ this._$parseTag(node, tf, tf_copy_offset);
1321
+ if (!this._$multiline) {
1322
+ break;
1323
+ }
1324
+ // reset
1325
+ this._$totalWidth = this._$getImageOffsetX();
1326
+ const yIndex = this._$heightTable.length;
1327
+ this._$heightTable[yIndex] = 0;
1328
+ this._$textHeightTable[yIndex] = 0;
1329
+ this._$widthTable[yIndex] = 0;
1330
+ if (yIndex) {
1331
+ this._$heightTable[yIndex] = this._$heightTable[yIndex - 1];
1332
+ this._$textHeightTable[yIndex] = this._$textHeightTable[yIndex - 1];
1333
+ }
1334
+ if (this._$textData.length in this._$textFormatTable) {
1335
+ const tft = this._$textFormatTable[this._$textData.length]._$clone();
1336
+ tft._$merge(tf);
1337
+ tf = tft;
1338
+ }
1339
+ const obj = {
1340
+ "mode": "break",
1341
+ "x": 0,
1342
+ "yIndex": yIndex,
1343
+ "textFormat": tf
1344
+ };
1345
+ this._$objectTable[yIndex] = obj;
1346
+ this._$textData.push(obj);
1347
+ }
1348
+ break;
1349
+ case "B": // bold
1350
+ tf.bold = true;
1351
+ this._$parseTag(node, tf, tf_copy_offset);
1352
+ break;
1353
+ case "I": // italic
1354
+ tf.italic = true;
1355
+ this._$parseTag(node, tf, tf_copy_offset);
1356
+ break;
1357
+ case "U": // underline
1358
+ tf.underline = true;
1359
+ this._$parseTag(node, tf, tf_copy_offset);
1360
+ break;
1361
+ case "FONT": // FONT
1362
+ if (node.hasAttribute("face")) {
1363
+ tf.font = node.getAttribute("face");
1364
+ }
1365
+ if (node.hasAttribute("size")) {
1366
+ const size = node.getAttribute("size");
1367
+ if (size) {
1368
+ tf.size = +size;
1369
+ }
1370
+ }
1371
+ if (node.hasAttribute("color")) {
1372
+ tf.color = $toColorInt(node.getAttribute("color"));
1373
+ }
1374
+ if (node.hasAttribute("letterSpacing")) {
1375
+ const letterSpacing = node.getAttribute("size");
1376
+ if (letterSpacing) {
1377
+ tf.letterSpacing = +letterSpacing;
1378
+ }
1379
+ }
1380
+ this._$parseTag(node, tf, tf_copy_offset);
1381
+ break;
1382
+ case "BR": // br
1383
+ {
1384
+ if (!this._$multiline) {
1385
+ break;
1386
+ }
1387
+ // add y index
1388
+ const yIndex = this._$heightTable.length;
1389
+ this._$heightTable[yIndex] = this._$heightTable[yIndex - 1];
1390
+ this._$textHeightTable[yIndex] = this._$textHeightTable[yIndex - 1];
1391
+ this._$widthTable[yIndex] = 0;
1392
+ // reset
1393
+ this._$totalWidth = this._$getImageOffsetX();
1394
+ // new clone
1395
+ tf.indent = 0;
1396
+ // set x offset
1397
+ const obj = {
1398
+ "mode": "break",
1399
+ "x": 0,
1400
+ "yIndex": yIndex,
1401
+ "textFormat": tf
1402
+ };
1403
+ this._$objectTable[yIndex] = obj;
1404
+ this._$textData[this._$textData.length] = obj;
1405
+ }
1406
+ break;
1407
+ case "IMG":
1408
+ {
1409
+ if (!node.hasAttribute("src")) {
1410
+ break;
1411
+ }
1412
+ const src = node.getAttribute("src");
1413
+ if (!src) {
1414
+ break;
1415
+ }
1416
+ let width = 0;
1417
+ if (node.hasAttribute("width")) {
1418
+ const attribute = node.getAttribute("width");
1419
+ if (attribute) {
1420
+ width = +attribute;
1421
+ }
1422
+ }
1423
+ let height = 0;
1424
+ if (node.hasAttribute("height")) {
1425
+ const attribute = node.getAttribute("height");
1426
+ if (attribute) {
1427
+ height = +attribute;
1428
+ }
1429
+ }
1430
+ let vspace = 8;
1431
+ if (node.hasAttribute("vspace")) {
1432
+ const attribute = node.getAttribute("vspace");
1433
+ if (attribute) {
1434
+ vspace = +attribute;
1435
+ }
1436
+ }
1437
+ let hspace = 8;
1438
+ if (node.hasAttribute("hspace")) {
1439
+ const attribute = node.getAttribute("hspace");
1440
+ if (attribute) {
1441
+ hspace = +attribute;
1442
+ }
1443
+ }
1444
+ let totalTextHeight = 0;
1445
+ for (let idx = 0; idx < this._$textHeightTable.length; idx++) {
1446
+ totalTextHeight += this._$textHeightTable[idx];
1447
+ }
1448
+ const image = new Image();
1449
+ const obj = {
1450
+ "mode": "image",
1451
+ "image": image,
1452
+ "src": src,
1453
+ "loaded": false,
1454
+ "x": 0,
1455
+ "y": totalTextHeight,
1456
+ "width": width,
1457
+ "height": height,
1458
+ "hspace": hspace,
1459
+ "vspace": vspace,
1460
+ "textFormat": tf._$clone()
1461
+ };
1462
+ image.crossOrigin = "anonymous";
1463
+ image.addEventListener("load", () => {
1464
+ if (!obj.width) {
1465
+ obj.width = image.width;
1466
+ }
1467
+ if (!obj.height) {
1468
+ obj.height = image.height;
1469
+ }
1470
+ obj.loaded = true;
1471
+ this._$reload();
1472
+ });
1473
+ image.src = src;
1474
+ if (this._$imageData.length > 0) {
1475
+ const prevImage = this._$imageData[this._$imageData.length - 1];
1476
+ const imageBottom = prevImage.y + prevImage.height + prevImage.vspace * 2;
1477
+ obj.y = $Math.max(totalTextHeight, imageBottom);
1478
+ }
1479
+ this._$textData[this._$textData.length] = obj;
1480
+ this._$imageData[this._$imageData.length] = obj;
1481
+ }
1482
+ break;
1483
+ default:
1484
+ this._$parseTag(node, tf, tf_copy_offset);
1485
+ break;
1486
+ }
1487
+ }
1488
+ }
1489
+ /**
1490
+ * @param {string} text
1491
+ * @param {TextFormat} text_format
1492
+ * @param {number} tf_copy_offset
1493
+ * @returns {number}
1494
+ * @method
1495
+ * @private
1496
+ */
1497
+ _$parseText(text, text_format, tf_copy_offset) {
1498
+ let yIndex = this._$heightTable.length - 1;
1499
+ // new format
1500
+ let tf = text_format._$clone();
1501
+ const matrix = this._$transform.concatenatedMatrix._$matrix;
1502
+ const boundsWidth = (this._$originBounds.xMax - this._$originBounds.xMin)
1503
+ * (matrix[0] / matrix[3]);
1504
+ $poolFloat32Array6(matrix);
1505
+ const maxWidth = boundsWidth - tf._$widthMargin() - 4;
1506
+ for (let idx = 0; idx < text.length; ++idx) {
1507
+ tf = text_format._$clone();
1508
+ if (this._$textData.length + tf_copy_offset in this._$textFormatTable) {
1509
+ const tft = this._$textFormatTable[this._$textData.length + tf_copy_offset]._$clone();
1510
+ tft._$merge(tf);
1511
+ tf = tft;
1512
+ }
1513
+ // reset object
1514
+ const obj = {
1515
+ "mode": "text",
1516
+ "text": text[idx],
1517
+ "x": 0,
1518
+ "width": 0,
1519
+ "height": 0,
1520
+ "yIndex": yIndex,
1521
+ "textFormat": tf
1522
+ };
1523
+ let breakCode = false;
1524
+ if (this._$multiline) {
1525
+ breakCode = obj.text === "\n" || obj.text === "\r" || obj.text === "\n\r";
1526
+ }
1527
+ const leading = yIndex ? tf.leading || 0 : 0;
1528
+ let width = 0;
1529
+ let height = 0;
1530
+ let textHeight = 0;
1531
+ let wrapObj;
1532
+ if (!$textContext) {
1533
+ continue;
1534
+ }
1535
+ $textContext.font = tf._$generateFontStyle();
1536
+ width = $textContext.measureText(obj.text || "").width;
1537
+ width += tf.letterSpacing || 0;
1538
+ height = this._$getTextHeight(tf);
1539
+ textHeight = height + leading;
1540
+ obj.height = height;
1541
+ if (breakCode ||
1542
+ this._$wordWrap && this._$totalWidth + width > maxWidth) {
1543
+ // add y index
1544
+ this._$widthTable[++yIndex] = 0;
1545
+ obj.yIndex = yIndex;
1546
+ this._$heightTable[yIndex] = this._$heightTable[yIndex - 1];
1547
+ this._$textHeightTable[yIndex] = this._$textHeightTable[yIndex - 1];
1548
+ // reset
1549
+ this._$totalWidth = this._$getImageOffsetX();
1550
+ // new clone
1551
+ tf = tf._$clone();
1552
+ tf.indent = 0;
1553
+ // set x offset
1554
+ const mode = breakCode ? "break" : "wrap";
1555
+ wrapObj = {
1556
+ "mode": mode,
1557
+ "x": 0,
1558
+ "yIndex": yIndex,
1559
+ "textFormat": tf
1560
+ };
1561
+ this._$objectTable[yIndex] = wrapObj;
1562
+ if (!breakCode) {
1563
+ --tf_copy_offset;
1564
+ }
1565
+ let text = obj.text || "";
1566
+ let chunkLength = 0;
1567
+ let isSeparated = true;
1568
+ const pattern = /[0-9a-zA-Z?!;:.,?!。、;:〜]/g;
1569
+ while (text.match(pattern)) {
1570
+ ++chunkLength;
1571
+ const prevObj = this._$textData[this._$textData.length - chunkLength];
1572
+ if (prevObj.mode !== "text") {
1573
+ isSeparated = false;
1574
+ break;
1575
+ }
1576
+ text = prevObj.text || "";
1577
+ }
1578
+ if (chunkLength > 1 && this._$textData) {
1579
+ const text = this._$textData[this._$textData.length - chunkLength + 1].text || "";
1580
+ if (text.match(/[0-9a-zA-Z]/g)) {
1581
+ --chunkLength;
1582
+ }
1583
+ }
1584
+ if (chunkLength > 0 && isSeparated) {
1585
+ const insertIdx = this._$textData.length - chunkLength;
1586
+ this._$textData.splice(insertIdx, 0, wrapObj);
1587
+ // prev line
1588
+ let offset = 1;
1589
+ let targetObj = this._$textData[insertIdx - offset];
1590
+ this._$widthTable[yIndex - 1] = 0;
1591
+ this._$heightTable[yIndex - 1] = 0;
1592
+ this._$textHeightTable[yIndex - 1] = 0;
1593
+ while (targetObj.mode === "text") {
1594
+ height = this._$getTextHeight(targetObj.textFormat);
1595
+ textHeight = height + leading;
1596
+ this._$widthTable[yIndex - 1] += targetObj.width || 0;
1597
+ this._$heightTable[yIndex - 1] = $Math.max(this._$heightTable[yIndex - 1], height);
1598
+ this._$textHeightTable[yIndex - 1] = $Math.max(this._$textHeightTable[yIndex - 1], textHeight);
1599
+ ++offset;
1600
+ targetObj = this._$textData[insertIdx - offset];
1601
+ }
1602
+ // new line
1603
+ offset = 1;
1604
+ while (this._$textData.length > insertIdx + offset) {
1605
+ targetObj = this._$textData[insertIdx + offset];
1606
+ ++offset;
1607
+ height = this._$getTextHeight(targetObj.textFormat);
1608
+ textHeight = height + leading;
1609
+ this._$heightTable[yIndex] = $Math.max(this._$heightTable[yIndex], height);
1610
+ this._$textHeightTable[yIndex] = $Math.max(this._$textHeightTable[yIndex], textHeight);
1611
+ targetObj.x = this._$totalWidth;
1612
+ targetObj.yIndex = yIndex;
1613
+ this._$totalWidth += targetObj.width || 0;
1614
+ }
1615
+ }
1616
+ else {
1617
+ this._$textData[this._$textData.length] = wrapObj;
1618
+ }
1619
+ }
1620
+ if (!breakCode) {
1621
+ // width data
1622
+ obj.width = width;
1623
+ obj.x = this._$totalWidth;
1624
+ this._$totalWidth += width;
1625
+ if (this._$widthTable) {
1626
+ this._$widthTable[yIndex] = $Math.max(this._$widthTable[yIndex], this._$totalWidth);
1627
+ }
1628
+ // height data
1629
+ this._$heightTable[yIndex] = $Math.max(this._$heightTable[yIndex], height);
1630
+ this._$textHeightTable[yIndex] = $Math.max(this._$textHeightTable[yIndex], textHeight);
1631
+ this._$textData[this._$textData.length] = obj;
1632
+ }
1633
+ }
1634
+ return tf_copy_offset;
1635
+ }
1636
+ /**
1637
+ * @param {TextFormat} text_format
1638
+ * @return {number}
1639
+ * @private
1640
+ */
1641
+ _$getTextHeight(text_format) {
1642
+ const size = text_format.size || 0;
1643
+ const font = text_format.font || "";
1644
+ const weight = text_format.bold ? "bold" : "normal";
1645
+ // use cache
1646
+ const key = `${size}_${font}_${weight}`;
1647
+ if (this._$heightCache.has(key)) {
1648
+ return this._$heightCache.get(key) || 0;
1649
+ }
1650
+ // update dom data
1651
+ const style = $DIV.style;
1652
+ const fontSize = `${size}px`;
1653
+ if (style.fontSize !== fontSize) {
1654
+ style.fontSize = fontSize;
1655
+ }
1656
+ if (style.fontFamily !== font) {
1657
+ style.fontFamily = font;
1658
+ }
1659
+ if (style.fontWeight !== weight) {
1660
+ style.fontWeight = weight;
1661
+ }
1662
+ const height = 10 > size
1663
+ ? $DIV.clientHeight * size * 0.1
1664
+ : $DIV.clientHeight;
1665
+ // cache
1666
+ this._$heightCache.set(key, height);
1667
+ return height;
1668
+ }
1669
+ /**
1670
+ * @return {number}
1671
+ * @private
1672
+ */
1673
+ _$getImageOffsetX() {
1674
+ if (!this._$imageData.length) {
1675
+ return 0;
1676
+ }
1677
+ let totalTextHeight = 0;
1678
+ for (let idx = 0; idx < this._$textHeightTable.length; ++idx) {
1679
+ totalTextHeight += this._$textHeightTable[idx];
1680
+ }
1681
+ if (this._$imageData) {
1682
+ for (let idx = 0; idx < this._$imageData.length; ++idx) {
1683
+ const image = this._$imageData[idx];
1684
+ const imageHeight = image.height + image.vspace * 2;
1685
+ if (image.y <= totalTextHeight
1686
+ && totalTextHeight < image.y + imageHeight) {
1687
+ return image.width + image.hspace * 2;
1688
+ }
1689
+ }
1690
+ }
1691
+ return 0;
1692
+ }
1693
+ /**
1694
+ * @return {void}
1695
+ * @method
1696
+ * @private
1697
+ */
1698
+ _$reset() {
1699
+ this._$createdTextData = false;
1700
+ this._$textData.length = 0;
1701
+ this._$imageData.length = 0;
1702
+ this._$heightTable.length = 0;
1703
+ this._$textHeightTable.length = 0;
1704
+ this._$widthTable.length = 0;
1705
+ this._$objectTable.length = 0;
1706
+ this._$textHeight = null;
1707
+ this._$textWidth = null;
1708
+ this._$totalWidth = 0;
1709
+ this._$maxScrollH = null;
1710
+ this._$maxScrollV = null;
1711
+ this._$doChanged();
1712
+ $doUpdated();
1713
+ // cache clear
1714
+ const player = $currentPlayer();
1715
+ player.cacheStore.removeCache(this._$instanceId);
1716
+ }
1717
+ /**
1718
+ * @return {void}
1719
+ * @method
1720
+ * @private
1721
+ */
1722
+ _$reload() {
1723
+ this._$reset();
1724
+ this._$getTextData();
1725
+ if (this._$autoSize === "none" && this._$autoFontSize) {
1726
+ let fontSize = this._$defaultTextFormat.size || 0;
1727
+ const cacheSize = fontSize;
1728
+ if (this.width && this.textWidth
1729
+ && this.textWidth > this.width) {
1730
+ while (this.textWidth > this.width) {
1731
+ this._$defaultTextFormat.size = fontSize--;
1732
+ if (1 > fontSize) {
1733
+ this._$defaultTextFormat.size = 1;
1734
+ break;
1735
+ }
1736
+ this._$reset();
1737
+ this._$getTextData();
1738
+ }
1739
+ }
1740
+ if (this.height && this.textHeight
1741
+ && this.textHeight > this.height) {
1742
+ while (this.textHeight > this.height) {
1743
+ this._$defaultTextFormat.size = fontSize--;
1744
+ if (1 > fontSize) {
1745
+ this._$defaultTextFormat.size = 1;
1746
+ break;
1747
+ }
1748
+ this._$reset();
1749
+ this._$getTextData();
1750
+ }
1751
+ }
1752
+ // restore
1753
+ this._$defaultTextFormat.size = cacheSize;
1754
+ }
1755
+ this._$resize();
1756
+ }
1757
+ /**
1758
+ * @return {void}
1759
+ * @method
1760
+ * @private
1761
+ */
1762
+ _$resize() {
1763
+ // update bounds
1764
+ if (this._$autoSize !== "none") {
1765
+ const tf = this._$defaultTextFormat;
1766
+ const width = this.textWidth + 4 + tf._$widthMargin();
1767
+ if (this._$wordWrap) {
1768
+ this._$bounds.xMax = this._$originBounds.xMax;
1769
+ this._$bounds.xMin = this._$originBounds.xMin;
1770
+ }
1771
+ else {
1772
+ switch (this._$autoSize) {
1773
+ case "left":
1774
+ this._$bounds.xMax = width + this._$bounds.xMin;
1775
+ break;
1776
+ case "center":
1777
+ this._$bounds.xMax = width + this._$bounds.xMin;
1778
+ break;
1779
+ case "right":
1780
+ this._$bounds.xMax = this._$originBounds.xMax
1781
+ - (this._$originBounds.xMax - this._$originBounds.xMin
1782
+ - (width - this._$originBounds.xMin));
1783
+ break;
1784
+ default:
1785
+ break;
1786
+ }
1787
+ }
1788
+ // set height
1789
+ this._$bounds.yMax = this.textHeight
1790
+ + 4 + this._$originBounds.yMin;
1791
+ }
1792
+ else {
1793
+ if (this._$scrollEnabled && !this._$scrollSprite) {
1794
+ this._$scrollSprite = new Sprite();
1795
+ this._$scrollSprite
1796
+ .graphics
1797
+ .beginFill("#000", 0.3)
1798
+ .drawRoundRect(0, 0, 3, 3, 3);
1799
+ this._$scrollSprite.scale9Grid = new Rectangle(1.5, 1.5, 0.1, 0.1);
1800
+ }
1801
+ }
1802
+ }
1803
+ /**
1804
+ * @param {object} obj
1805
+ * @param {number} width
1806
+ * @return {number}
1807
+ * @private
1808
+ */
1809
+ _$getAlignOffset(obj, width) {
1810
+ // default
1811
+ const totalWidth = this._$widthTable[obj.yIndex];
1812
+ const textFormat = obj.textFormat;
1813
+ let indent = 0;
1814
+ indent += textFormat.blockIndent || 0;
1815
+ indent += textFormat.leftMargin || 0;
1816
+ const rightMargin = textFormat.rightMargin || 0;
1817
+ switch (true) {
1818
+ // wordWrap case
1819
+ case !this._$wordWrap && totalWidth > width:
1820
+ return $Math.max(0, indent);
1821
+ case textFormat.align === "center": // format CENTER
1822
+ case this._$autoSize === "center": // autoSize CENTER
1823
+ return $Math.max(0, width / 2 - indent - rightMargin - totalWidth / 2);
1824
+ case textFormat.align === "right": // format RIGHT
1825
+ case this._$autoSize === "right": // autoSize RIGHT
1826
+ return $Math.max(0, width - indent - totalWidth - rightMargin - 2);
1827
+ // autoSize LEFT
1828
+ // format LEFT
1829
+ default:
1830
+ return $Math.max(0, indent + 2);
1831
+ }
1832
+ }
1833
+ /**
1834
+ * @param {Float32Array} [matrix=null]
1835
+ * @returns {object}
1836
+ * @method
1837
+ * @private
1838
+ */
1839
+ _$getBounds(matrix = null) {
1840
+ if (matrix) {
1841
+ let multiMatrix = matrix;
1842
+ const rawMatrix = this._$transform._$rawMatrix();
1843
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
1844
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
1845
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
1846
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1847
+ }
1848
+ return $boundsMatrix(this._$bounds, multiMatrix);
1849
+ }
1850
+ return $getBoundsObject(this._$bounds.xMin, this._$bounds.xMax, this._$bounds.yMin, this._$bounds.yMax);
1851
+ }
1852
+ /**
1853
+ * @param {object} character
1854
+ * @return {void}
1855
+ * @method
1856
+ * @private
1857
+ */
1858
+ _$buildCharacter(character) {
1859
+ const textFormat = this._$defaultTextFormat;
1860
+ textFormat.font = character.font;
1861
+ textFormat.size = character.size | 0;
1862
+ textFormat.align = character.align;
1863
+ textFormat.color = character.color | 0;
1864
+ textFormat.leading = character.leading;
1865
+ textFormat.letterSpacing = character.letterSpacing;
1866
+ textFormat.leftMargin = character.leftMargin;
1867
+ textFormat.rightMargin = character.rightMargin;
1868
+ switch (character.fontType) {
1869
+ case 1:
1870
+ textFormat.bold = true;
1871
+ break;
1872
+ case 2:
1873
+ textFormat.italic = true;
1874
+ break;
1875
+ case 3:
1876
+ textFormat.bold = true;
1877
+ textFormat.italic = true;
1878
+ break;
1879
+ }
1880
+ // setup
1881
+ this._$type = character.inputType;
1882
+ this._$multiline = !!character.multiline;
1883
+ this._$wordWrap = !!character.wordWrap;
1884
+ this._$border = !!character.border;
1885
+ this._$scrollEnabled = !!character.scroll;
1886
+ this._$thickness = character.thickness | 0;
1887
+ this._$thicknessColor = character.thicknessColor | 0;
1888
+ // bounds
1889
+ this._$bounds.xMin = character.originBounds.xMin;
1890
+ this._$bounds.xMax = character.originBounds.xMax;
1891
+ this._$bounds.yMin = character.originBounds.yMin;
1892
+ this._$bounds.yMax = character.originBounds.yMax;
1893
+ this._$originBounds.xMin = character.originBounds.xMin;
1894
+ this._$originBounds.xMax = character.originBounds.xMax;
1895
+ this._$originBounds.yMin = character.originBounds.yMin;
1896
+ this._$originBounds.yMax = character.originBounds.yMax;
1897
+ switch (character.autoSize) {
1898
+ case 1:
1899
+ this.autoSize = character.align;
1900
+ break;
1901
+ case 2:
1902
+ this.autoFontSize = true;
1903
+ break;
1904
+ }
1905
+ this.text = character.text;
1906
+ if ($rendererWorker && this._$stage) {
1907
+ this._$createWorkerInstance();
1908
+ }
1909
+ }
1910
+ /**
1911
+ * @param {object} character
1912
+ * @return {void}
1913
+ * @method
1914
+ * @private
1915
+ */
1916
+ _$sync(character) {
1917
+ this._$buildCharacter(character);
1918
+ }
1919
+ /**
1920
+ * @param {object} tag
1921
+ * @param {DisplayObjectContainer} parent
1922
+ * @return {object}
1923
+ * @method
1924
+ * @private
1925
+ */
1926
+ _$build(tag, parent) {
1927
+ const character = this
1928
+ ._$baseBuild(tag, parent);
1929
+ this._$buildCharacter(character);
1930
+ return character;
1931
+ }
1932
+ /**
1933
+ * @param {CanvasToWebGLContext} context
1934
+ * @param {Float32Array} matrix
1935
+ * @returns {void}
1936
+ * @method
1937
+ * @private
1938
+ */
1939
+ _$clip(context, matrix) {
1940
+ // size
1941
+ const bounds = this._$getBounds();
1942
+ const xMax = bounds.xMax;
1943
+ const xMin = bounds.xMin;
1944
+ const yMax = bounds.yMax;
1945
+ const yMin = bounds.yMin;
1946
+ $poolBoundsObject(bounds);
1947
+ const width = $Math.ceil($Math.abs(xMax - xMin));
1948
+ const height = $Math.ceil($Math.abs(yMax - yMin));
1949
+ if (!width || !height) {
1950
+ return;
1951
+ }
1952
+ let multiMatrix = matrix;
1953
+ const rawMatrix = this._$transform._$rawMatrix();
1954
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
1955
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
1956
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
1957
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1958
+ }
1959
+ context.reset();
1960
+ context.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
1961
+ context.beginPath();
1962
+ context.moveTo(0, 0);
1963
+ context.lineTo(width, 0);
1964
+ context.lineTo(width, height);
1965
+ context.lineTo(0, height);
1966
+ context.lineTo(0, 0);
1967
+ context.clip();
1968
+ if (multiMatrix !== matrix) {
1969
+ $poolFloat32Array6(multiMatrix);
1970
+ }
1971
+ }
1972
+ /**
1973
+ * @param {CanvasToWebGLContext} context
1974
+ * @param {Float32Array} matrix
1975
+ * @param {Float32Array} color_transform
1976
+ * @return {void}
1977
+ * @method
1978
+ * @private
1979
+ */
1980
+ _$draw(context, matrix, color_transform) {
1981
+ if (!this._$visible || this._$textAreaActive) {
1982
+ return;
1983
+ }
1984
+ if (!this._$background && !this._$border && !this.text) {
1985
+ return;
1986
+ }
1987
+ let multiColor = color_transform;
1988
+ const rawColor = this._$transform._$rawColorTransform();
1989
+ if (rawColor[0] !== 1 || rawColor[1] !== 1
1990
+ || rawColor[2] !== 1 || rawColor[3] !== 1
1991
+ || rawColor[4] !== 0 || rawColor[5] !== 0
1992
+ || rawColor[6] !== 0 || rawColor[7] !== 0) {
1993
+ multiColor = $multiplicationColor(color_transform, rawColor);
1994
+ }
1995
+ const alpha = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1);
1996
+ if (!alpha) {
1997
+ return;
1998
+ }
1999
+ let multiMatrix = matrix;
2000
+ const rawMatrix = this._$transform._$rawMatrix();
2001
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
2002
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
2003
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
2004
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
2005
+ }
2006
+ const baseBounds = this._$getBounds(null);
2007
+ baseBounds.xMin -= this._$thickness;
2008
+ baseBounds.xMax += this._$thickness;
2009
+ baseBounds.yMin -= this._$thickness;
2010
+ baseBounds.yMax += this._$thickness;
2011
+ const bounds = $boundsMatrix(baseBounds, multiMatrix);
2012
+ const xMax = +bounds.xMax;
2013
+ const xMin = +bounds.xMin;
2014
+ const yMax = +bounds.yMax;
2015
+ const yMin = +bounds.yMin;
2016
+ $poolBoundsObject(bounds);
2017
+ const width = $Math.ceil($Math.abs(xMax - xMin));
2018
+ const height = $Math.ceil($Math.abs(yMax - yMin));
2019
+ switch (true) {
2020
+ case width === 0:
2021
+ case height === 0:
2022
+ case width === -$Infinity:
2023
+ case height === -$Infinity:
2024
+ case width === $Infinity:
2025
+ case height === $Infinity:
2026
+ return;
2027
+ default:
2028
+ break;
2029
+ }
2030
+ if (0 > xMin + width || 0 > yMin + height) {
2031
+ return;
2032
+ }
2033
+ // cache current buffer
2034
+ const manager = context.frameBuffer;
2035
+ const currentAttachment = manager.currentAttachment;
2036
+ if (!currentAttachment
2037
+ || xMin > currentAttachment.width
2038
+ || yMin > currentAttachment.height) {
2039
+ return;
2040
+ }
2041
+ let xScale = +$Math.sqrt(multiMatrix[0] * multiMatrix[0]
2042
+ + multiMatrix[1] * multiMatrix[1]);
2043
+ if (!$Number.isInteger(xScale)) {
2044
+ const value = xScale.toString();
2045
+ const index = value.indexOf("e");
2046
+ if (index !== -1) {
2047
+ xScale = +value.slice(0, index);
2048
+ }
2049
+ xScale = +xScale.toFixed(4);
2050
+ }
2051
+ let yScale = +$Math.sqrt(multiMatrix[2] * multiMatrix[2]
2052
+ + multiMatrix[3] * multiMatrix[3]);
2053
+ if (!$Number.isInteger(yScale)) {
2054
+ const value = yScale.toString();
2055
+ const index = value.indexOf("e");
2056
+ if (index !== -1) {
2057
+ yScale = +value.slice(0, index);
2058
+ }
2059
+ yScale = +yScale.toFixed(4);
2060
+ }
2061
+ const filters = this._$filters || this.filters;
2062
+ if (0 > xMin + width || 0 > yMin + height) {
2063
+ if (filters.length && this._$canApply(filters)) {
2064
+ let filterBounds = $getBoundsObject(0, width, 0, height);
2065
+ for (let idx = 0; idx < filters.length; ++idx) {
2066
+ filterBounds = filters[idx]
2067
+ ._$generateFilterRect(filterBounds, xScale, yScale);
2068
+ }
2069
+ if (0 > filterBounds.xMin + filterBounds.xMax
2070
+ || 0 > filterBounds.yMin + filterBounds.yMax) {
2071
+ $poolBoundsObject(filterBounds);
2072
+ return;
2073
+ }
2074
+ $poolBoundsObject(filterBounds);
2075
+ }
2076
+ else {
2077
+ return;
2078
+ }
2079
+ }
2080
+ const blendMode = this._$blendMode || this.blendMode;
2081
+ const keys = $getArray(xScale, yScale);
2082
+ const instanceId = this._$instanceId;
2083
+ const player = $currentPlayer();
2084
+ const cacheStore = player.cacheStore;
2085
+ const cacheKeys = cacheStore.generateKeys(instanceId, keys);
2086
+ let texture = cacheStore.get(cacheKeys);
2087
+ // texture is small or renew
2088
+ if (this._$isUpdated()) {
2089
+ cacheStore.removeCache(instanceId);
2090
+ texture = null;
2091
+ }
2092
+ if (!texture) {
2093
+ // resize
2094
+ const lineWidth = $Math.min(1, $Math.max(xScale, yScale));
2095
+ const baseWidth = $Math.ceil($Math.abs(baseBounds.xMax - baseBounds.xMin) * xScale);
2096
+ const baseHeight = $Math.ceil($Math.abs(baseBounds.yMax - baseBounds.yMin) * yScale);
2097
+ // alpha reset
2098
+ multiColor[3] = 1;
2099
+ // new canvas
2100
+ const canvas = cacheStore.getCanvas();
2101
+ canvas.width = baseWidth + lineWidth * 2;
2102
+ canvas.height = baseHeight + lineWidth * 2;
2103
+ const ctx = canvas.getContext("2d");
2104
+ if (!ctx) {
2105
+ throw new Error("the context is null.");
2106
+ }
2107
+ // border and background
2108
+ if (this._$background || this._$border) {
2109
+ ctx.beginPath();
2110
+ ctx.moveTo(0, 0);
2111
+ ctx.lineTo(baseWidth, 0);
2112
+ ctx.lineTo(baseWidth, baseHeight);
2113
+ ctx.lineTo(0, baseHeight);
2114
+ ctx.lineTo(0, 0);
2115
+ if (this._$background) {
2116
+ const rgb = $intToRGBA(this._$backgroundColor);
2117
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 * multiColor[3] + multiColor[7], 255)) / 255;
2118
+ ctx.fillStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
2119
+ ctx.fill();
2120
+ }
2121
+ if (this._$border) {
2122
+ const rgb = $intToRGBA(this._$borderColor);
2123
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 * multiColor[3] + multiColor[7], 255)) / 255;
2124
+ ctx.lineWidth = lineWidth;
2125
+ ctx.strokeStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
2126
+ ctx.stroke();
2127
+ }
2128
+ }
2129
+ // mask start
2130
+ ctx.save();
2131
+ ctx.beginPath();
2132
+ ctx.moveTo(2, 2);
2133
+ ctx.lineTo(baseWidth - 2, 2);
2134
+ ctx.lineTo(baseWidth - 2, baseHeight - 2);
2135
+ ctx.lineTo(2, baseHeight - 2);
2136
+ ctx.lineTo(2, 2);
2137
+ ctx.clip();
2138
+ ctx.beginPath();
2139
+ ctx.setTransform(xScale, 0, 0, yScale, 0, 0);
2140
+ this._$doDraw(ctx, matrix, multiColor, baseWidth / xScale);
2141
+ ctx.restore();
2142
+ texture = manager.createTextureFromCanvas(ctx.canvas);
2143
+ // set cache
2144
+ cacheStore.set(cacheKeys, texture);
2145
+ // destroy cache
2146
+ cacheStore.destroy(ctx);
2147
+ }
2148
+ let drawFilter = false;
2149
+ let offsetX = 0;
2150
+ let offsetY = 0;
2151
+ if (filters && filters.length
2152
+ && this._$canApply(filters)) {
2153
+ drawFilter = true;
2154
+ texture = this._$drawFilter(context, texture, multiMatrix, filters, width, height);
2155
+ offsetX = texture._$offsetX;
2156
+ offsetY = texture._$offsetY;
2157
+ }
2158
+ const radianX = $Math.atan2(multiMatrix[1], multiMatrix[0]);
2159
+ const radianY = $Math.atan2(-multiMatrix[2], multiMatrix[3]);
2160
+ if (!drawFilter && (radianX || radianY)) {
2161
+ const tx = baseBounds.xMin * xScale;
2162
+ const ty = baseBounds.yMin * yScale;
2163
+ const cosX = $Math.cos(radianX);
2164
+ const sinX = $Math.sin(radianX);
2165
+ const cosY = $Math.cos(radianY);
2166
+ const sinY = $Math.sin(radianY);
2167
+ context.setTransform(cosX, sinX, -sinY, cosY, tx * cosX - ty * sinY + multiMatrix[4], tx * sinX + ty * cosY + multiMatrix[5]);
2168
+ }
2169
+ else {
2170
+ context.setTransform(1, 0, 0, 1, xMin - offsetX, yMin - offsetY);
2171
+ }
2172
+ // draw
2173
+ context.reset();
2174
+ context.globalAlpha = alpha;
2175
+ context.imageSmoothingEnabled = true;
2176
+ context.globalCompositeOperation = blendMode;
2177
+ context.drawImage(texture, 0, 0, texture.width, texture.height, multiColor);
2178
+ // get cache
2179
+ $poolArray(cacheKeys);
2180
+ $poolBoundsObject(baseBounds);
2181
+ // pool
2182
+ if (multiMatrix !== matrix) {
2183
+ $poolFloat32Array6(multiMatrix);
2184
+ }
2185
+ if (multiColor !== color_transform) {
2186
+ $poolFloat32Array8(multiColor);
2187
+ }
2188
+ }
2189
+ /**
2190
+ * @param {CanvasRenderingContext2D} context
2191
+ * @param {Float32Array} matrix
2192
+ * @param {Float32Array} color_transform
2193
+ * @param {number} width
2194
+ * @return {void}
2195
+ * @method
2196
+ * @private
2197
+ */
2198
+ _$doDraw(context, matrix, color_transform, width) {
2199
+ // init
2200
+ const textData = this._$getTextData();
2201
+ const limitWidth = this.width;
2202
+ const limitHeight = this.height;
2203
+ // setup
2204
+ let xOffset = 0;
2205
+ let offsetHeight = 0;
2206
+ let currentV = 0;
2207
+ let yOffset = 0;
2208
+ if (this._$verticalAlign !== "top"
2209
+ && this.height > this.textHeight) {
2210
+ switch (this._$verticalAlign) {
2211
+ case "middle":
2212
+ yOffset = (this.height - this.textHeight + 2) / 2;
2213
+ break;
2214
+ case "bottom":
2215
+ yOffset = this.height - this.textHeight + 2;
2216
+ break;
2217
+ }
2218
+ }
2219
+ for (let idx = 0; idx < textData.length; ++idx) {
2220
+ const obj = textData[idx];
2221
+ if (obj.width === 0) {
2222
+ continue;
2223
+ }
2224
+ // check
2225
+ const offsetWidth = xOffset + obj.x;
2226
+ if (this._$autoSize === "none"
2227
+ && (offsetHeight > limitHeight || offsetWidth > limitWidth)) {
2228
+ continue;
2229
+ }
2230
+ const tf = obj.textFormat;
2231
+ // color
2232
+ const rgb = $intToRGBA(tf.color || 0);
2233
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 * color_transform[3] + color_transform[7], 255)) / 255;
2234
+ context.fillStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
2235
+ if (this._$thickness) {
2236
+ const rgb = $intToRGBA(this._$thicknessColor);
2237
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 * color_transform[3] + color_transform[7], 255)) / 255;
2238
+ context.lineWidth = this._$thickness;
2239
+ context.strokeStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
2240
+ }
2241
+ const yIndex = obj.yIndex | 0;
2242
+ switch (obj.mode) {
2243
+ case "break":
2244
+ case "wrap":
2245
+ currentV++;
2246
+ if (this.scrollV > currentV) {
2247
+ continue;
2248
+ }
2249
+ offsetHeight += this._$textHeightTable[yIndex];
2250
+ xOffset = this._$getAlignOffset(this._$objectTable[yIndex], width);
2251
+ if (tf.underline) {
2252
+ const offset = tf.size ? tf.size / 12 : 0;
2253
+ const rgb = $intToRGBA(tf.color || 0);
2254
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 * color_transform[3] + color_transform[7], 255)) / 255;
2255
+ context.lineWidth = $Math.max(1, 1 / $Math.min(matrix[0], matrix[3]));
2256
+ context.strokeStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
2257
+ context.beginPath();
2258
+ context.moveTo(xOffset, yOffset + offsetHeight - offset);
2259
+ context.lineTo(xOffset + this._$widthTable[yIndex], yOffset + offsetHeight - offset);
2260
+ context.stroke();
2261
+ }
2262
+ break;
2263
+ case "text":
2264
+ {
2265
+ if (this.scrollV > currentV) {
2266
+ continue;
2267
+ }
2268
+ let offsetY = offsetHeight - this._$heightTable[0];
2269
+ if (!$isSafari && tf.size) {
2270
+ offsetY += $devicePixelRatio * (tf.size / 12);
2271
+ }
2272
+ context.beginPath();
2273
+ context.textBaseline = "top";
2274
+ context.font = $generateFontStyle(tf.font || "", tf.size || 0, !!tf.italic, !!tf.bold);
2275
+ if (this._$thickness) {
2276
+ context.strokeText(obj.text, offsetWidth, yOffset + offsetY);
2277
+ }
2278
+ context.fillText(obj.text, offsetWidth, yOffset + offsetY);
2279
+ }
2280
+ break;
2281
+ case "image":
2282
+ if (!obj.loaded) {
2283
+ continue;
2284
+ }
2285
+ context.beginPath();
2286
+ context.drawImage(obj.image, obj.hspace, yOffset + obj.y, obj.width, obj.height);
2287
+ break;
2288
+ }
2289
+ }
2290
+ }
2291
+ /**
2292
+ * @param {CanvasRenderingContext2D} context
2293
+ * @param {Float32Array} matrix
2294
+ * @param {object} options
2295
+ * @return {boolean}
2296
+ * @method
2297
+ * @private
2298
+ */
2299
+ _$mouseHit(context, matrix, options) {
2300
+ if (!this._$visible) {
2301
+ return false;
2302
+ }
2303
+ return this._$hit(context, matrix, options);
2304
+ }
2305
+ /**
2306
+ * @param {CanvasRenderingContext2D} context
2307
+ * @param {Float32Array} matrix
2308
+ * @param {object} options
2309
+ * @return {boolean}
2310
+ * @method
2311
+ * @private
2312
+ */
2313
+ _$hit(context, matrix, options) {
2314
+ let multiMatrix = matrix;
2315
+ const rawMatrix = this._$transform._$rawMatrix();
2316
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
2317
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
2318
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
2319
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
2320
+ }
2321
+ const baseBounds = this._$getBounds(null);
2322
+ const bounds = $boundsMatrix(baseBounds, multiMatrix);
2323
+ const xMax = +bounds.xMax;
2324
+ const xMin = +bounds.xMin;
2325
+ const yMax = +bounds.yMax;
2326
+ const yMin = +bounds.yMin;
2327
+ $poolBoundsObject(bounds);
2328
+ $poolBoundsObject(baseBounds);
2329
+ const width = $Math.ceil($Math.abs(xMax - xMin));
2330
+ const height = $Math.ceil($Math.abs(yMax - yMin));
2331
+ context.setTransform(1, 0, 0, 1, xMin, yMin);
2332
+ context.beginPath();
2333
+ context.moveTo(0, 0);
2334
+ context.lineTo(width, 0);
2335
+ context.lineTo(width, height);
2336
+ context.lineTo(0, height);
2337
+ context.lineTo(0, 0);
2338
+ if (multiMatrix !== matrix) {
2339
+ $poolFloat32Array6(multiMatrix);
2340
+ }
2341
+ return context.isPointInPath(options.x, options.y);
2342
+ }
2343
+ /**
2344
+ * @param {number} scale
2345
+ * @return {void}
2346
+ * @method
2347
+ * @private
2348
+ */
2349
+ _$createTextAreaElement(scale) {
2350
+ // new text area
2351
+ if (!this._$textarea) {
2352
+ this._$textarea = $document.createElement("textarea");
2353
+ this._$textarea.value = this.text;
2354
+ this._$textarea.id = `${$PREFIX}_TextField_${this._$instanceId}`;
2355
+ if (!this._$wordWrap) {
2356
+ this._$textarea.wrap = "off";
2357
+ }
2358
+ const textFormat = this._$defaultTextFormat;
2359
+ // setup
2360
+ let style = "";
2361
+ style += "position: absolute;";
2362
+ style += "outline: 0;";
2363
+ style += `padding: 2px 2px 2px ${$Math.max(3, textFormat.leftMargin || 0)}px;`;
2364
+ style += "margin: 0;";
2365
+ style += "appearance: none;";
2366
+ style += "resize: none;";
2367
+ style += "overflow: hidden;";
2368
+ style += `z-index: ${0x7fffffff};`;
2369
+ style += "vertical-align: top;";
2370
+ this._$textarea.setAttribute("style", style);
2371
+ // add blur event
2372
+ this._$textarea.addEventListener(`${$PREFIX}_blur`, (event) => {
2373
+ // set new text
2374
+ const element = event.target;
2375
+ let value = element.value;
2376
+ if (value && this._$restrict) {
2377
+ let pattern = this._$restrict;
2378
+ if (pattern[0] !== "[") {
2379
+ pattern = "[" + pattern;
2380
+ }
2381
+ if (pattern[pattern.length - 1] !== "]") {
2382
+ pattern += "]";
2383
+ }
2384
+ const found = value.match(new $RegExp(pattern, "gm"));
2385
+ value = found ? found.join("") : "";
2386
+ }
2387
+ const player = $currentPlayer();
2388
+ const div = $document.getElementById(player.contentElementId);
2389
+ if (div) {
2390
+ const element = $document.getElementById(`${$PREFIX}_TextField_${this._$instanceId}`);
2391
+ if (element) {
2392
+ element.remove();
2393
+ }
2394
+ }
2395
+ this.text = value;
2396
+ this._$focus = false;
2397
+ this._$textAreaActive = false;
2398
+ this._$doChanged();
2399
+ $doUpdated();
2400
+ });
2401
+ // input event
2402
+ this._$textarea.addEventListener("input", (event) => {
2403
+ // set new text
2404
+ const element = event.target;
2405
+ const player = $currentPlayer();
2406
+ let value = element.value;
2407
+ // SafariではInputEvent.isComposingがundefined
2408
+ if (this._$restrict && !this._$isComposing && value) {
2409
+ let pattern = this._$restrict;
2410
+ if (pattern[0] !== "[") {
2411
+ pattern = "[" + pattern;
2412
+ }
2413
+ if (pattern[pattern.length - 1] !== "]") {
2414
+ pattern += "]";
2415
+ }
2416
+ const found = value.match(new $RegExp(pattern, "gm"));
2417
+ value = found ? found.join("") : "";
2418
+ }
2419
+ if (!this._$isComposing && this.text !== value) {
2420
+ // update
2421
+ this.text = value;
2422
+ element.value = value;
2423
+ if (this.willTrigger(Next2DEvent.CHANGE)) {
2424
+ this.dispatchEvent(new Next2DEvent(Next2DEvent.CHANGE, true));
2425
+ }
2426
+ // setup
2427
+ // const element = this._$textarea;
2428
+ const matrix = this._$transform.concatenatedMatrix;
2429
+ const bounds = this._$getBounds(null);
2430
+ element.style.left = `${$Math.floor((matrix.tx + bounds.xMin + player.x / player._$scale / $devicePixelRatio) * player._$scale)}px`;
2431
+ element.style.top = `${$Math.floor((matrix.ty + bounds.yMin + player.y / player._$scale / $devicePixelRatio) * player._$scale)}px`;
2432
+ element.style.width = `${$Math.ceil((this.width - 1) * player._$scale)}px`;
2433
+ element.style.height = `${$Math.ceil((this.height - 1) * player._$scale)}px`;
2434
+ }
2435
+ });
2436
+ // IME入力開始時のevent
2437
+ this._$textarea.addEventListener("compositionstart", () => {
2438
+ this._$isComposing = true;
2439
+ });
2440
+ // IME入力確定時のevent
2441
+ this._$textarea.addEventListener("compositionend", (event) => {
2442
+ this._$isComposing = false;
2443
+ const element = event.target;
2444
+ let value = element.value;
2445
+ if (!this._$restrict || !value) {
2446
+ return;
2447
+ }
2448
+ let pattern = this._$restrict;
2449
+ if (pattern[0] !== "[") {
2450
+ pattern = "[" + pattern;
2451
+ }
2452
+ if (pattern[pattern.length - 1] !== "]") {
2453
+ pattern += "]";
2454
+ }
2455
+ const found = value.match(new $RegExp(pattern, "gm"));
2456
+ value = found ? found.join("") : "";
2457
+ // update
2458
+ this.text = value;
2459
+ element.value = value;
2460
+ });
2461
+ // add click event
2462
+ this._$textarea.addEventListener("click", () => {
2463
+ if (this.willTrigger(Next2DMouseEvent.CLICK)) {
2464
+ this.dispatchEvent(new Next2DMouseEvent(Next2DMouseEvent.CLICK));
2465
+ }
2466
+ });
2467
+ // add mousewheel event
2468
+ this._$textarea.addEventListener($MOUSE_WHEEL, (event) => {
2469
+ this.scrollV += event.deltaY;
2470
+ });
2471
+ // add scroll event
2472
+ this._$textarea.addEventListener($SCROLL, (event) => {
2473
+ const element = event.target;
2474
+ this.scrollV = element.scrollTop
2475
+ / (element.scrollHeight - element.clientHeight)
2476
+ * this.maxScrollV + 1;
2477
+ });
2478
+ // down event
2479
+ this._$textarea.addEventListener($TOUCH_START, () => {
2480
+ const player = $currentPlayer();
2481
+ player._$state = "down";
2482
+ });
2483
+ // up event
2484
+ this._$textarea.addEventListener($TOUCH_END, () => {
2485
+ const player = $currentPlayer();
2486
+ player._$state = "up";
2487
+ });
2488
+ // down event
2489
+ this._$textarea.addEventListener($MOUSE_DOWN, () => {
2490
+ const player = $currentPlayer();
2491
+ player._$state = "down";
2492
+ });
2493
+ // up event
2494
+ this._$textarea.addEventListener($MOUSE_UP, () => {
2495
+ const player = $currentPlayer();
2496
+ player._$state = "up";
2497
+ });
2498
+ }
2499
+ // change style
2500
+ const tf = this._$defaultTextFormat;
2501
+ const fontSize = tf.size
2502
+ ? $Math.ceil(tf.size * scale * this._$transform.concatenatedMatrix.d)
2503
+ : 0;
2504
+ this._$textarea.style.fontSize = `${fontSize}px`;
2505
+ this._$textarea.style.fontFamily = tf.font || "Times New Roman";
2506
+ this._$textarea.style.lineHeight = `${(fontSize + $Math.max(0, tf.leading || 0)) / fontSize}em`;
2507
+ if (this._$autoSize !== "none") {
2508
+ this._$textarea.style.textAlign = "center";
2509
+ }
2510
+ else {
2511
+ this._$textarea.style.textAlign = tf.align || "none";
2512
+ }
2513
+ this._$textarea.addEventListener("keydown", (event) => {
2514
+ const element = event.target;
2515
+ let value = element.value;
2516
+ // SafariではInputEvent.isComposingがundefined
2517
+ if (this._$restrict && !this._$isComposing && value) {
2518
+ let pattern = this._$restrict;
2519
+ if (pattern[0] !== "[") {
2520
+ pattern = "[" + pattern;
2521
+ }
2522
+ if (pattern[pattern.length - 1] !== "]") {
2523
+ pattern += "]";
2524
+ }
2525
+ const found = value.match(new $RegExp(pattern, "gm"));
2526
+ value = found ? found.join("") : "";
2527
+ }
2528
+ // update
2529
+ if (!this._$isComposing) {
2530
+ this.text = value;
2531
+ element.value = value;
2532
+ }
2533
+ // enter off
2534
+ if (event.code === "Enter" && !this._$multiline) {
2535
+ return false;
2536
+ }
2537
+ });
2538
+ const style = this._$textarea.style;
2539
+ if (this._$border) {
2540
+ style.border = `solid 1px #${this.borderColor.toString(16)}`;
2541
+ }
2542
+ else {
2543
+ style.border = "none";
2544
+ }
2545
+ if (this._$border || this._$background) {
2546
+ style.backgroundColor = `#${this.backgroundColor.toString(16)}`;
2547
+ }
2548
+ else {
2549
+ style.backgroundColor = "transparent";
2550
+ }
2551
+ //reset
2552
+ this._$textarea.maxLength = this._$maxChars ? this._$maxChars : 0x7fffffff;
2553
+ }
2554
+ /**
2555
+ * @return {void}
2556
+ * @method
2557
+ * @private
2558
+ */
2559
+ _$createWorkerInstance() {
2560
+ if (this._$created || !$rendererWorker) {
2561
+ return;
2562
+ }
2563
+ this._$created = true;
2564
+ const bounds = this._$getBounds();
2565
+ const message = {
2566
+ "command": "createTextField",
2567
+ "instanceId": this._$instanceId,
2568
+ "parentId": this._$parent ? this._$parent._$instanceId : -1,
2569
+ "xMin": bounds.xMin,
2570
+ "yMin": bounds.yMin,
2571
+ "xMax": bounds.xMax,
2572
+ "yMax": bounds.yMax,
2573
+ "textData": this._$getTextData(),
2574
+ "scrollV": this.scrollV,
2575
+ "widthTable": this._$widthTable,
2576
+ "heightTable": this._$heightTable,
2577
+ "textHeightTable": this._$textHeightTable,
2578
+ "objectTable": this._$objectTable,
2579
+ "limitWidth": this.width,
2580
+ "limitHeight": this.height,
2581
+ "textHeight": this.textHeight,
2582
+ "verticalAlign": this._$verticalAlign,
2583
+ "autoSize": this._$autoSize,
2584
+ "wordWrap": this._$wordWrap,
2585
+ "border": this._$border,
2586
+ "background": this._$background,
2587
+ "thickness": this._$thickness
2588
+ };
2589
+ if (this._$border) {
2590
+ message.borderColor = this._$borderColor;
2591
+ }
2592
+ if (this._$background) {
2593
+ message.backgroundColor = this._$backgroundColor;
2594
+ }
2595
+ if (this._$thickness) {
2596
+ message.thicknessColor = this._$backgroundColor;
2597
+ }
2598
+ if (this._$characterId > -1) {
2599
+ message.characterId = this._$characterId;
2600
+ }
2601
+ if (this._$loaderInfo) {
2602
+ message.loaderInfoId = this._$loaderInfo._$id;
2603
+ }
2604
+ if (this._$scale9Grid) {
2605
+ message.grid = {
2606
+ "x": this._$scale9Grid.x,
2607
+ "y": this._$scale9Grid.y,
2608
+ "w": this._$scale9Grid.width,
2609
+ "h": this._$scale9Grid.height
2610
+ };
2611
+ }
2612
+ $rendererWorker.postMessage(message);
2613
+ }
2614
+ /**
2615
+ * @return {void}
2616
+ * @method
2617
+ * @private
2618
+ */
2619
+ _$postProperty() {
2620
+ if (!$rendererWorker) {
2621
+ return;
2622
+ }
2623
+ const message = this._$createMessage();
2624
+ message.textAreaActive = this._$textAreaActive;
2625
+ const bounds = this._$getBounds(null);
2626
+ message.xMin = bounds.xMin;
2627
+ message.yMin = bounds.yMin;
2628
+ message.xMax = bounds.xMax;
2629
+ message.yMax = bounds.yMax;
2630
+ $poolBoundsObject(bounds);
2631
+ if (this._$isUpdated()) {
2632
+ message.textData = this._$getTextData();
2633
+ message.scrollV = this.scrollV;
2634
+ message.widthTable = this._$widthTable;
2635
+ message.heightTable = this._$heightTable;
2636
+ message.textHeightTable = this._$textHeightTable;
2637
+ message.objectTable = this._$objectTable;
2638
+ message.limitWidth = this.width;
2639
+ message.limitHeight = this.height;
2640
+ message.textHeight = this.textHeight;
2641
+ message.verticalAlign = this._$verticalAlign;
2642
+ message.autoSize = this._$autoSize;
2643
+ message.wordWrap = this._$wordWrap;
2644
+ message.border = this._$border;
2645
+ if (this._$border) {
2646
+ message.borderColor = this._$borderColor;
2647
+ }
2648
+ message.background = this._$background;
2649
+ if (this._$background) {
2650
+ message.backgroundColor = this._$backgroundColor;
2651
+ }
2652
+ message.thickness = this._$thickness;
2653
+ if (this._$thickness) {
2654
+ message.thicknessColor = this._$backgroundColor;
2655
+ }
2656
+ }
2657
+ $rendererWorker.postMessage(message);
2658
+ this._$posted = true;
2659
+ this._$updated = false;
2660
+ }
2661
+ }