@next2d/display 1.16.0 → 1.17.1

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,2031 @@
1
+ import { InteractiveObject, Shape } from "@next2d/display";
2
+ import { FocusEvent, Event as Next2DEvent, MouseEvent as Next2DMouseEvent } from "@next2d/events";
3
+ import { Tween, Easing } from "@next2d/ui";
4
+ import { TextFormat, parsePlainText, parseHtmlText } from "@next2d/text";
5
+ import { Rectangle } from "@next2d/geom";
6
+ import { $currentPlayer, $MOUSE_DOWN, $MOUSE_UP, $MOUSE_WHEEL, $PREFIX, $rendererWorker, $SCROLL, $TOUCH_END, $TOUCH_START, $document, $RegExp } from "@next2d/util";
7
+ import { $cacheStore, $doUpdated, $clamp, $getArray, $intToRGBA, $isNaN, $Math, $requestAnimationFrame, $toColorInt, $poolFloat32Array6, $boundsMatrix, $multiplicationMatrix, $poolBoundsObject, $multiplicationColor, $Infinity, $Number, $poolArray, $poolFloat32Array8, $generateFontStyle, $devicePixelRatio, $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.display
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._$scrollX = 0;
82
+ /**
83
+ * @type {number}
84
+ * @default 0
85
+ * @private
86
+ */
87
+ this._$scrollY = 0;
88
+ /**
89
+ * @type {number}
90
+ * @default 0
91
+ * @private
92
+ */
93
+ this._$maxChars = 0;
94
+ // TextFormat
95
+ const textFormat = new TextFormat();
96
+ textFormat._$setDefault();
97
+ /**
98
+ * @type {TextFormat}
99
+ * @private
100
+ */
101
+ this._$defaultTextFormat = textFormat;
102
+ /**
103
+ * @type {string}
104
+ * @default ""
105
+ * @private
106
+ */
107
+ this._$rawHtmlText = "";
108
+ /**
109
+ * @type {object}
110
+ * @private
111
+ */
112
+ this._$bounds = {
113
+ "xMin": 0,
114
+ "xMax": 100,
115
+ "yMin": 0,
116
+ "yMax": 100
117
+ };
118
+ /**
119
+ * @type {object}
120
+ * @private
121
+ */
122
+ this._$originBounds = {
123
+ "xMin": 0,
124
+ "xMax": 100,
125
+ "yMin": 0,
126
+ "yMax": 100
127
+ };
128
+ /**
129
+ * @type {string}
130
+ * @default null
131
+ * @private
132
+ */
133
+ this._$restrict = "";
134
+ /**
135
+ * @type {boolean}
136
+ * @default false
137
+ * @private
138
+ */
139
+ this._$isHTML = false;
140
+ /**
141
+ * @type {TextData}
142
+ * @private
143
+ */
144
+ this._$textData = null;
145
+ /**
146
+ * @type {HTMLTextAreaElement}
147
+ * @default null
148
+ * @private
149
+ */
150
+ this._$textarea = null;
151
+ /**
152
+ * @type {string}
153
+ * @default TextFieldAutoSize.NONE
154
+ * @private
155
+ */
156
+ this._$autoSize = "none";
157
+ /**
158
+ * @type {boolean}
159
+ * @default false
160
+ * @private
161
+ */
162
+ this._$autoFontSize = false;
163
+ /**
164
+ * @type {boolean}
165
+ * @default false
166
+ * @private
167
+ */
168
+ this._$textAreaActive = false;
169
+ /**
170
+ * @type {boolean}
171
+ * @default true
172
+ * @private
173
+ */
174
+ this._$scrollEnabled = true;
175
+ /**
176
+ * @type {Shape}
177
+ * @default null
178
+ * @private
179
+ */
180
+ this._$xScrollShape = null;
181
+ /**
182
+ * @type {Shape}
183
+ * @default null
184
+ * @private
185
+ */
186
+ this._$yScrollShape = null;
187
+ /**
188
+ * @type {string}
189
+ * @default null
190
+ * @private
191
+ */
192
+ this._$type = "static";
193
+ /**
194
+ * @type {boolean}
195
+ * @default false
196
+ * @private
197
+ */
198
+ this._$focus = false;
199
+ /**
200
+ * @type {boolean}
201
+ * @default false
202
+ * @private
203
+ */
204
+ this._$isComposing = false;
205
+ /**
206
+ * @type {number}
207
+ * @default 0
208
+ * @private
209
+ */
210
+ this._$thickness = 0;
211
+ /**
212
+ * @type {number}
213
+ * @default 0
214
+ * @private
215
+ */
216
+ this._$thicknessColor = 0;
217
+ /**
218
+ * @type {string}
219
+ * @default "bottom"
220
+ * @private
221
+ */
222
+ this._$verticalAlign = "bottom";
223
+ /**
224
+ * @type {array}
225
+ * @private
226
+ */
227
+ this._$cacheKeys = $getArray();
228
+ /**
229
+ * @type {array}
230
+ * @private
231
+ */
232
+ this._$cacheParams = $getArray(0, 0, 0);
233
+ }
234
+ /**
235
+ * @description 指定されたクラスのストリングを返します。
236
+ * Returns the string representation of the specified class.
237
+ *
238
+ * @return {string}
239
+ * @default [class TextField]
240
+ * @method
241
+ * @static
242
+ */
243
+ static toString() {
244
+ return "[class TextField]";
245
+ }
246
+ /**
247
+ * @description 指定されたクラスの空間名を返します。
248
+ * Returns the space name of the specified class.
249
+ *
250
+ * @return {string}
251
+ * @default next2d.display.TextField
252
+ * @const
253
+ * @static
254
+ */
255
+ static get namespace() {
256
+ return "next2d.display.TextField";
257
+ }
258
+ /**
259
+ * @description 指定されたオブジェクトのストリングを返します。
260
+ * Returns the string representation of the specified object.
261
+ *
262
+ * @return {string}
263
+ * @default [object TextField]
264
+ * @method
265
+ * @public
266
+ */
267
+ toString() {
268
+ return "[object TextField]";
269
+ }
270
+ /**
271
+ * @description 指定されたオブジェクトの空間名を返します。
272
+ * Returns the space name of the specified object.
273
+ *
274
+ * @return {string}
275
+ * @default next2d.display.TextField
276
+ * @const
277
+ * @public
278
+ */
279
+ get namespace() {
280
+ return "next2d.display.TextField";
281
+ }
282
+ /**
283
+ * @description テキストサイズの自動的な拡大 / 縮小および整列を制御します。
284
+ * Controls automatic sizing and alignment of text size.
285
+ *
286
+ * @member {boolean}
287
+ * @default false
288
+ * @public
289
+ */
290
+ get autoFontSize() {
291
+ return this._$autoFontSize;
292
+ }
293
+ set autoFontSize(auto_font_size) {
294
+ if (auto_font_size !== this._$autoFontSize) {
295
+ this._$autoFontSize = auto_font_size;
296
+ this._$reload();
297
+ }
298
+ }
299
+ /**
300
+ * @description テキストフィールドの自動的な拡大 / 縮小および整列を制御します。
301
+ * Controls automatic sizing and alignment of text fields.
302
+ *
303
+ * @member {string}
304
+ * @default TextFieldAutoSize.NONE
305
+ * @public
306
+ */
307
+ get autoSize() {
308
+ return this._$autoSize;
309
+ }
310
+ set autoSize(auto_size) {
311
+ if (auto_size !== this._$autoSize) {
312
+ this._$autoSize = auto_size;
313
+ this._$reload();
314
+ }
315
+ }
316
+ /**
317
+ * @description テキストフィールドに背景の塗りつぶしがあるかどうかを指定します。
318
+ * Specifies whether the text field has a background fill.
319
+ *
320
+ * @member {boolean}
321
+ * @default false
322
+ * @public
323
+ */
324
+ get background() {
325
+ return this._$background;
326
+ }
327
+ set background(background) {
328
+ if (background !== this._$background) {
329
+ this._$background = !!background;
330
+ this._$reset();
331
+ }
332
+ }
333
+ /**
334
+ * @description テキストフィールドの背景の色です。
335
+ * The color of the text field background.
336
+ *
337
+ * @member {number}
338
+ * @default 0xffffff
339
+ * @public
340
+ */
341
+ get backgroundColor() {
342
+ return this._$backgroundColor;
343
+ }
344
+ set backgroundColor(background_color) {
345
+ background_color = $clamp($toColorInt(background_color), 0, 0xffffff, 0xffffff);
346
+ if (background_color !== this._$backgroundColor) {
347
+ this._$backgroundColor = background_color;
348
+ this._$reset();
349
+ }
350
+ }
351
+ /**
352
+ * @description テキストフィールドに境界線があるかどうかを指定します。
353
+ * Specifies whether the text field has a border.
354
+ *
355
+ * @member {boolean}
356
+ * @default false
357
+ * @public
358
+ */
359
+ get border() {
360
+ return this._$border;
361
+ }
362
+ set border(border) {
363
+ if (border !== this._$border) {
364
+ this._$border = !!border;
365
+ this._$reset();
366
+ }
367
+ }
368
+ /**
369
+ * @description テキストフィールドの境界線の色です。
370
+ * The color of the text field border.
371
+ *
372
+ * @member {number}
373
+ * @default 0x000000
374
+ * @public
375
+ */
376
+ get borderColor() {
377
+ return this._$borderColor;
378
+ }
379
+ set borderColor(border_color) {
380
+ border_color = $clamp($toColorInt(border_color), 0, 0xffffff, 0);
381
+ if (border_color !== this._$borderColor) {
382
+ this._$borderColor = border_color;
383
+ this._$reset();
384
+ }
385
+ }
386
+ /**
387
+ * @description テキストに適用するフォーマットを指定します。
388
+ * Specifies the formatting to be applied to the text.
389
+ *
390
+ * @member {TextFormat}
391
+ * @public
392
+ */
393
+ get defaultTextFormat() {
394
+ return this._$defaultTextFormat._$clone();
395
+ }
396
+ set defaultTextFormat(text_format) {
397
+ text_format._$merge(this._$defaultTextFormat);
398
+ this._$defaultTextFormat = text_format;
399
+ this._$reset();
400
+ }
401
+ /**
402
+ * @description このオブジェクトでマウスまたはその他のユーザー入力メッセージを
403
+ *
404
+ * @member {boolean}
405
+ * @default false
406
+ * @public
407
+ */
408
+ get focus() {
409
+ return this._$focus;
410
+ }
411
+ set focus(focus) {
412
+ if (this._$focus === focus) {
413
+ return;
414
+ }
415
+ if (this._$type !== "input") {
416
+ return;
417
+ }
418
+ this._$focus = focus;
419
+ if (this._$focus) {
420
+ const player = $currentPlayer();
421
+ const div = $document
422
+ .getElementById(player.contentElementId);
423
+ if (!div) {
424
+ return;
425
+ }
426
+ this._$createTextAreaElement(player._$scale);
427
+ // setup
428
+ const element = this._$textarea;
429
+ if (!element) {
430
+ return;
431
+ }
432
+ const matrix = this._$transform.concatenatedMatrix;
433
+ const bounds = this._$getBounds(null);
434
+ const color = $intToRGBA($toColorInt(this._$defaultTextFormat.color), 100);
435
+ element.style.color = `rgb(${color.R},${color.G},${color.B})`;
436
+ element.style.left = `${(matrix.tx + bounds.xMin + player.x / player._$scale / $devicePixelRatio) * player._$scale}px`;
437
+ element.style.top = `${(matrix.ty + bounds.yMin + player.y / player._$scale / $devicePixelRatio) * player._$scale}px`;
438
+ element.style.width = `${$Math.ceil(this.width * player._$scale)}px`;
439
+ element.style.height = `${$Math.ceil(this.height * player._$scale)}px`;
440
+ // set text
441
+ element.value = this.text;
442
+ div.appendChild(element);
443
+ $requestAnimationFrame(() => {
444
+ element.focus();
445
+ });
446
+ this._$doChanged();
447
+ $doUpdated();
448
+ this._$textAreaActive = true;
449
+ // focus in event
450
+ if (this.willTrigger(FocusEvent.FOCUS_IN)) {
451
+ this.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_IN));
452
+ }
453
+ }
454
+ else {
455
+ // execute
456
+ if (this._$textarea) {
457
+ this._$textarea.dispatchEvent(new Event(`${$PREFIX}_blur`));
458
+ if (this.willTrigger(FocusEvent.FOCUS_OUT)) {
459
+ this.dispatchEvent(new FocusEvent(FocusEvent.FOCUS_OUT));
460
+ }
461
+ this._$textarea.remove();
462
+ }
463
+ }
464
+ }
465
+ /**
466
+ * @description テキストフィールドの内容を HTML で表します。
467
+ * Contains the HTML representation of the text field contents.
468
+ *
469
+ * @member {string}
470
+ * @default ""
471
+ * @public
472
+ */
473
+ get htmlText() {
474
+ return this._$htmlText;
475
+ }
476
+ set htmlText(html_text) {
477
+ if (this._$htmlText !== html_text) {
478
+ this._$htmlText = `${html_text}`;
479
+ this._$rawHtmlText = "";
480
+ this._$text = "";
481
+ this._$isHTML = true;
482
+ this._$reload();
483
+ }
484
+ }
485
+ /**
486
+ * @description テキストフィールド内の文字数です。
487
+ * The int of characters in a text field.
488
+ *
489
+ * @member {number}
490
+ * @readonly
491
+ * @public
492
+ */
493
+ get length() {
494
+ return this.text.length;
495
+ }
496
+ /**
497
+ * @description ユーザーが入力するときに、テキストフィールドに入力できる最大の文字数です。
498
+ * The maximum number of characters that the text field can contain,
499
+ * as entered by a user.
500
+ *
501
+ * @member {number}
502
+ * @default 0
503
+ * @public
504
+ */
505
+ get maxChars() {
506
+ return this._$maxChars;
507
+ }
508
+ set maxChars(max_chars) {
509
+ this._$maxChars = max_chars | 0;
510
+ }
511
+ /**
512
+ * @description フィールドが複数行テキストフィールドであるかどうかを示します。
513
+ * Indicates whether field is a multiline text field.
514
+ *
515
+ * @member {boolean}
516
+ * @default false
517
+ * @public
518
+ */
519
+ get multiline() {
520
+ return this._$multiline;
521
+ }
522
+ set multiline(multiline) {
523
+ if (multiline !== this._$multiline) {
524
+ this._$multiline = !!multiline;
525
+ this._$reset();
526
+ }
527
+ }
528
+ /**
529
+ * @description フィールドが複数行テキストフィールドであるかどうかを示します。
530
+ * Indicates whether field is a multiline text field.
531
+ *
532
+ * @member {number}
533
+ * @readonly
534
+ * @public
535
+ */
536
+ get numLines() {
537
+ return this.getTextData().lineTable.length;
538
+ }
539
+ /**
540
+ * @description ユーザーがテキストフィールドに入力できる文字のセットを指定します。
541
+ * Indicates the set of characters that a user can enter into the text field.
542
+ *
543
+ * @member {string}
544
+ * @default null
545
+ * @public
546
+ */
547
+ get restrict() {
548
+ return this._$restrict;
549
+ }
550
+ set restrict(restrict) {
551
+ this._$restrict = `${restrict}`;
552
+ }
553
+ /**
554
+ * @description スクロール機能のON/OFFの制御。
555
+ * Control ON/OFF of the scroll function.
556
+ *
557
+ * @member {boolean}
558
+ * @default true
559
+ * @public
560
+ */
561
+ get scrollEnabled() {
562
+ return this._$scrollEnabled;
563
+ }
564
+ set scrollEnabled(scroll_enabled) {
565
+ this._$scrollEnabled = scroll_enabled;
566
+ }
567
+ /**
568
+ * @description テキストフィールドのスクロール垂直位置です。
569
+ * The scroll vertical position of the text field.
570
+ *
571
+ * @member {number}
572
+ * @public
573
+ */
574
+ get scrollX() {
575
+ return this._$scrollX;
576
+ }
577
+ set scrollX(scroll_x) {
578
+ if (!this._$scrollEnabled
579
+ || this._$autoSize !== "none") {
580
+ return;
581
+ }
582
+ // check y animation
583
+ if (this._$yScrollShape
584
+ && this._$yScrollShape.hasLocalVariable("job")) {
585
+ return;
586
+ }
587
+ scroll_x = $clamp(scroll_x, 0, this.width, 0);
588
+ if (this._$scrollX !== scroll_x) {
589
+ const width = this.width;
590
+ if (this._$xScrollShape && this.textWidth > width) {
591
+ this._$doChanged();
592
+ this._$scrollX = scroll_x;
593
+ this._$xScrollShape.width = width * width / this.textWidth;
594
+ const parent = this._$parent;
595
+ if (parent) {
596
+ // view start
597
+ Tween.add(this._$xScrollShape, { "alpha": 0 }, { "alpha": 0.8 }, 0, 0.3, Easing.outQuad);
598
+ // set position
599
+ this._$xScrollShape.x = this.x + 1
600
+ + (width - 1 - this._$xScrollShape.width)
601
+ / (width - 1)
602
+ * (this._$scrollX - 1);
603
+ this._$xScrollShape.y = this.y + this.height - this._$xScrollShape.height - 0.5;
604
+ // added sprite
605
+ parent.addChildAt(this._$xScrollShape, parent.getChildIndex(this) + 1);
606
+ // start animation
607
+ if (this._$xScrollShape.hasLocalVariable("job")) {
608
+ this._$xScrollShape.getLocalVariable("job").stop();
609
+ }
610
+ const job = Tween.add(this._$xScrollShape, { "alpha": 0.8 }, { "alpha": 0 }, 0.2, 0.6, Easing.outQuad);
611
+ job.addEventListener(Next2DEvent.COMPLETE, (event) => {
612
+ const shape = event.target.target;
613
+ shape.deleteLocalVariable("job");
614
+ if (shape.parent) {
615
+ shape.parent.removeChild(shape);
616
+ }
617
+ });
618
+ job.start();
619
+ this._$xScrollShape.setLocalVariable("job", job);
620
+ }
621
+ }
622
+ if (this.willTrigger(Next2DEvent.SCROLL)) {
623
+ this.dispatchEvent(new Next2DEvent(Next2DEvent.SCROLL, true));
624
+ }
625
+ }
626
+ }
627
+ /**
628
+ * @description テキストフィールドのスクロール垂直位置です。
629
+ * The scroll vertical position of the text field.
630
+ *
631
+ * @member {number}
632
+ * @public
633
+ */
634
+ get scrollY() {
635
+ return this._$scrollY;
636
+ }
637
+ set scrollY(scroll_y) {
638
+ if (!this._$scrollEnabled
639
+ || this._$autoSize !== "none"
640
+ || !this._$multiline && !this._$wordWrap) {
641
+ return;
642
+ }
643
+ // check x animation
644
+ if (this._$xScrollShape
645
+ && this._$xScrollShape.hasLocalVariable("job")) {
646
+ return;
647
+ }
648
+ scroll_y = $clamp(scroll_y, 0, this.height, 0);
649
+ if (this._$scrollY !== scroll_y) {
650
+ const height = this.height;
651
+ if (this._$yScrollShape && this.textHeight > height) {
652
+ this._$doChanged();
653
+ this._$scrollY = scroll_y;
654
+ this._$yScrollShape.height = height * height / this.textHeight;
655
+ const parent = this._$parent;
656
+ if (parent) {
657
+ // view start
658
+ Tween.add(this._$yScrollShape, { "alpha": 0 }, { "alpha": 0.8 }, 0, 0.3, Easing.outQuad);
659
+ // set position
660
+ this._$yScrollShape.x = this.x + this.width - this._$yScrollShape.width - 0.5;
661
+ this._$yScrollShape.y = this.y + 0.5
662
+ + (height - 1 - this._$yScrollShape.height)
663
+ / (height - 1)
664
+ * (this._$scrollY - 1);
665
+ // added sprite
666
+ parent.addChildAt(this._$yScrollShape, parent.getChildIndex(this) + 1);
667
+ // start animation
668
+ if (this._$yScrollShape.hasLocalVariable("job")) {
669
+ this._$yScrollShape.getLocalVariable("job").stop();
670
+ }
671
+ const job = Tween.add(this._$yScrollShape, { "alpha": 0.8 }, { "alpha": 0 }, 0.2, 0.6, Easing.outQuad);
672
+ job.addEventListener(Next2DEvent.COMPLETE, (event) => {
673
+ const shape = event.target.target;
674
+ shape.deleteLocalVariable("job");
675
+ if (shape.parent) {
676
+ shape.parent.removeChild(shape);
677
+ }
678
+ });
679
+ job.start();
680
+ this._$yScrollShape.setLocalVariable("job", job);
681
+ }
682
+ }
683
+ if (this.willTrigger(Next2DEvent.SCROLL)) {
684
+ this.dispatchEvent(new Next2DEvent(Next2DEvent.SCROLL, true));
685
+ }
686
+ }
687
+ }
688
+ /**
689
+ * @description テキストフィールド内の現在のテキストであるストリングです。
690
+ * A string that is the current text in the text field.
691
+ *
692
+ * @member {string}
693
+ * @default ""
694
+ * @public
695
+ */
696
+ get text() {
697
+ if (!this._$isHTML) {
698
+ return this._$text;
699
+ }
700
+ if (this._$rawHtmlText) {
701
+ return this._$rawHtmlText;
702
+ }
703
+ let text = "";
704
+ const textData = this.getTextData();
705
+ for (let idx = 1; idx < textData.textTable.length; ++idx) {
706
+ const object = textData.textTable[idx];
707
+ switch (object.mode) {
708
+ case "text":
709
+ text += object.text;
710
+ break;
711
+ case "break":
712
+ text += "\r";
713
+ break;
714
+ }
715
+ }
716
+ this._$rawHtmlText = text;
717
+ return text;
718
+ }
719
+ set text(text) {
720
+ if (text === null) {
721
+ text = "";
722
+ }
723
+ text = `${text}`;
724
+ if (text !== this._$text) {
725
+ this._$text = text;
726
+ this._$htmlText = "";
727
+ this._$isHTML = false;
728
+ this._$reload();
729
+ }
730
+ }
731
+ /**
732
+ * @description テキストフィールドのテキストの色です(16 進数形式)。
733
+ * The color of the text in a text field, in hexadecimal format.
734
+ *
735
+ * @member {number}
736
+ * @public
737
+ */
738
+ get textColor() {
739
+ return this._$defaultTextFormat.color || 0;
740
+ }
741
+ set textColor(text_color) {
742
+ this._$defaultTextFormat.color = text_color;
743
+ this._$reload();
744
+ }
745
+ /**
746
+ * @description テキストの高さです(ピクセル単位)。
747
+ * The height of the text in pixels.
748
+ *
749
+ * @member {number}
750
+ * @readonly
751
+ * @public
752
+ */
753
+ get textHeight() {
754
+ return this.getTextData().textHeight;
755
+ }
756
+ /**
757
+ * @description テキストの幅です(ピクセル単位)。
758
+ * The width of the text in pixels.
759
+ *
760
+ * @member {number}
761
+ * @readonly
762
+ * @public
763
+ */
764
+ get textWidth() {
765
+ return this.getTextData().textWidth;
766
+ }
767
+ /**
768
+ * @description 輪郭のテキスト幅です。0(デフォルト値)で無効にできます。
769
+ * The text width of the outline, which can be disabled with 0 (the default value).
770
+ *
771
+ * @member {number}
772
+ * @default 0
773
+ * @public
774
+ */
775
+ get thickness() {
776
+ return this._$thickness;
777
+ }
778
+ set thickness(thickness) {
779
+ thickness |= 0;
780
+ if (thickness !== this._$thickness) {
781
+ this._$thickness = thickness;
782
+ this._$reset();
783
+ }
784
+ }
785
+ /**
786
+ * @description 輪郭のテキストの色です(16 進数形式)。
787
+ * The color of the outline text. (Hexadecimal format)
788
+ *
789
+ * @member {number}
790
+ * @default 0
791
+ * @public
792
+ */
793
+ get thicknessColor() {
794
+ return this._$thicknessColor;
795
+ }
796
+ set thicknessColor(thickness_color) {
797
+ thickness_color = $clamp($toColorInt(thickness_color), 0, 0xffffff, 0);
798
+ if (thickness_color !== this._$thicknessColor) {
799
+ this._$thicknessColor = thickness_color;
800
+ this._$reset();
801
+ }
802
+ }
803
+ /**
804
+ * @description テキストフィールドのタイプです。
805
+ * The type of the text field.
806
+ *
807
+ * @member {string}
808
+ * @default TextFieldType.STATIC
809
+ * @public
810
+ */
811
+ get type() {
812
+ return this._$type;
813
+ }
814
+ set type(type) {
815
+ this._$type = type;
816
+ if (type === "static") {
817
+ this._$textarea = null;
818
+ }
819
+ }
820
+ /**
821
+ * @description 縦方向の揃え位置を指定するプロパティです。
822
+ * This property specifies the vertical alignment position.
823
+ *
824
+ * @member {string}
825
+ * @default "bottom"
826
+ * @public
827
+ */
828
+ get verticalAlign() {
829
+ return this._$verticalAlign;
830
+ }
831
+ set verticalAlign(vertical_align) {
832
+ if (vertical_align !== this._$verticalAlign) {
833
+ this._$verticalAlign = vertical_align;
834
+ this._$reset();
835
+ }
836
+ }
837
+ /**
838
+ * @description テキストフィールドのテキストを折り返すかどうかを示すブール値です。
839
+ * A Boolean value that indicates whether the text field has word wrap.
840
+ *
841
+ * @member {boolean}
842
+ * @default false
843
+ * @public
844
+ */
845
+ get wordWrap() {
846
+ return this._$wordWrap;
847
+ }
848
+ set wordWrap(word_wrap) {
849
+ if (this._$wordWrap !== word_wrap) {
850
+ this._$wordWrap = !!word_wrap;
851
+ this._$reset();
852
+ }
853
+ }
854
+ /**
855
+ * @description 表示オブジェクトの幅を示します(ピクセル単位)。
856
+ * Indicates the width of the display object, in pixels.
857
+ *
858
+ * @member {number}
859
+ * @public
860
+ */
861
+ get width() {
862
+ return super.width;
863
+ }
864
+ set width(width) {
865
+ width = +width;
866
+ if (!$isNaN(width) && width > -1) {
867
+ const bounds = this._$getBounds(null);
868
+ const xMin = $Math.abs(bounds.xMin);
869
+ this._$originBounds.xMax = width + xMin;
870
+ this._$originBounds.xMin = xMin;
871
+ this._$bounds.xMax = this._$originBounds.xMax;
872
+ this._$bounds.xMin = this._$originBounds.xMin;
873
+ super.width = width;
874
+ this._$reload();
875
+ }
876
+ }
877
+ /**
878
+ * @description 表示オブジェクトの高さを示します(ピクセル単位)。
879
+ * Indicates the height of the display object, in pixels.
880
+ *
881
+ * @member {number}
882
+ * @public
883
+ */
884
+ get height() {
885
+ return super.height;
886
+ }
887
+ set height(height) {
888
+ height = +height;
889
+ if (!$isNaN(height) && height > -1) {
890
+ const bounds = this._$getBounds(null);
891
+ const yMin = $Math.abs(bounds.yMin);
892
+ this._$originBounds.yMax = height + yMin;
893
+ this._$bounds.yMax = this._$originBounds.yMax;
894
+ this._$bounds.yMin = this._$originBounds.yMin;
895
+ super.height = height;
896
+ this._$reload();
897
+ }
898
+ }
899
+ /**
900
+ * @description 親 DisplayObjectContainer のローカル座標を基準にした
901
+ * DisplayObject インスタンスの x 座標を示します。
902
+ * Indicates the x coordinate
903
+ * of the DisplayObject instance relative to the local coordinates
904
+ * of the parent DisplayObjectContainer.
905
+ *
906
+ * @member {number}
907
+ * @public
908
+ */
909
+ get x() {
910
+ const matrix = this._$transform.matrix;
911
+ const bounds = this._$getBounds(null);
912
+ return matrix._$matrix[4] + bounds.xMin;
913
+ }
914
+ set x(x) {
915
+ const bounds = this._$getBounds(null);
916
+ super.x = x - bounds.xMin;
917
+ }
918
+ /**
919
+ * @description 親 DisplayObjectContainer のローカル座標を基準にした
920
+ * DisplayObject インスタンスの y 座標を示します。
921
+ * Indicates the y coordinate
922
+ * of the DisplayObject instance relative to the local coordinates
923
+ * of the parent DisplayObjectContainer.
924
+ *
925
+ * @member {number}
926
+ * @public
927
+ */
928
+ get y() {
929
+ const matrix = this._$transform.matrix;
930
+ const bounds = this._$getBounds(null);
931
+ return matrix._$matrix[5] + bounds.yMin;
932
+ }
933
+ set y(y) {
934
+ const bounds = this._$getBounds(null);
935
+ super.y = y - bounds.yMin;
936
+ }
937
+ /**
938
+ * @description newText パラメーターで指定されたストリングを、
939
+ * テキストフィールドのテキストの最後に付加します。
940
+ * Appends the string specified by the newText parameter
941
+ * to the end of the text of the text field.
942
+ *
943
+ * @param {string} new_text
944
+ * @return void
945
+ * @method
946
+ * @public
947
+ */
948
+ appendText(new_text) {
949
+ const currentText = this.text;
950
+ this.text = currentText + `${new_text}`;
951
+ }
952
+ /**
953
+ * @description lineIndex パラメーターで指定された行のテキストを返します。
954
+ * Returns the text of the line specified by the lineIndex parameter.
955
+ *
956
+ * @param {number} line_index
957
+ * @return {string}
958
+ * @public
959
+ */
960
+ getLineText(line_index) {
961
+ if (!this._$text && !this._$htmlText) {
962
+ return "";
963
+ }
964
+ line_index |= 0;
965
+ let lineText = "";
966
+ const textData = this.getTextData();
967
+ for (let idx = 0; idx < textData.textTable.length; idx++) {
968
+ const textObject = textData.textTable[idx];
969
+ if (textObject.line > line_index) {
970
+ break;
971
+ }
972
+ if (textObject.line !== line_index) {
973
+ continue;
974
+ }
975
+ if (textObject.mode !== "text") {
976
+ continue;
977
+ }
978
+ lineText += textObject.text;
979
+ }
980
+ return lineText;
981
+ }
982
+ /**
983
+ * @description beginIndex パラメーターと endIndex パラメーターで指定された文字範囲を、
984
+ * newText パラメーターの内容に置き換えます。
985
+ * Replaces the range of characters that the beginIndex
986
+ * and endIndex parameters specify with the contents of the newText parameter.
987
+ *
988
+ * @param {number} begin_index
989
+ * @param {number} end_index
990
+ * @param {string} new_text
991
+ * @return {void}
992
+ * @method
993
+ * @public
994
+ */
995
+ replaceText(begin_index, end_index, new_text) {
996
+ begin_index |= 0;
997
+ end_index |= 0;
998
+ if (begin_index > -1 && end_index > -1 && end_index >= begin_index) {
999
+ const text = this.text;
1000
+ if (begin_index >= text.length) {
1001
+ if (end_index >= text.length && end_index >= begin_index) {
1002
+ this.text = text + `${new_text}`;
1003
+ }
1004
+ }
1005
+ else {
1006
+ this.text = text.slice(0, begin_index)
1007
+ + `${new_text}`
1008
+ + text.slice(end_index, text.length);
1009
+ }
1010
+ }
1011
+ }
1012
+ /**
1013
+ * @description text、htmlTextに登録したテキスト情報をTextDataクラスで返却
1014
+ * Return text information registered in text and htmlText with TextData class.
1015
+ *
1016
+ * @param {number} [sub_font_size = 0]
1017
+ * @return {array}
1018
+ * @method
1019
+ * @public
1020
+ */
1021
+ getTextData(sub_font_size = 0) {
1022
+ if (this._$textData !== null) {
1023
+ return this._$textData;
1024
+ }
1025
+ if (!this._$isHTML) {
1026
+ this._$textData = parsePlainText(this._$text, this._$defaultTextFormat, {
1027
+ "width": this.width,
1028
+ "multiline": this._$multiline,
1029
+ "wordWrap": this._$wordWrap,
1030
+ "subFontSize": sub_font_size
1031
+ });
1032
+ }
1033
+ else {
1034
+ this._$textData = parseHtmlText(this._$htmlText, this._$defaultTextFormat, {
1035
+ "width": this.width,
1036
+ "multiline": this._$multiline,
1037
+ "wordWrap": this._$wordWrap,
1038
+ "subFontSize": sub_font_size
1039
+ });
1040
+ }
1041
+ return this._$textData;
1042
+ }
1043
+ /**
1044
+ * @return {void}
1045
+ * @method
1046
+ * @private
1047
+ */
1048
+ _$reset() {
1049
+ this._$textData = null;
1050
+ this._$doChanged();
1051
+ $doUpdated();
1052
+ // cache clear
1053
+ $cacheStore.removeCache(this._$instanceId);
1054
+ }
1055
+ /**
1056
+ * @return {void}
1057
+ * @method
1058
+ * @private
1059
+ */
1060
+ _$reload() {
1061
+ this._$reset();
1062
+ this.getTextData();
1063
+ if (this._$autoSize === "none" && this._$autoFontSize) {
1064
+ let maxFontSize = 0;
1065
+ const textData = this.getTextData();
1066
+ for (let idx = 0; idx < textData.textTable.length; ++idx) {
1067
+ const textObject = textData.textTable[idx];
1068
+ maxFontSize = $Math.max(maxFontSize, textObject.textFormat.size || 0);
1069
+ }
1070
+ let subSize = 1;
1071
+ if (this.width && this.textWidth) {
1072
+ while (maxFontSize > subSize
1073
+ && this.textWidth + 4 > this.width) {
1074
+ this._$reset();
1075
+ this.getTextData(subSize++);
1076
+ }
1077
+ }
1078
+ if (this.height && this.textHeight) {
1079
+ while (maxFontSize > subSize
1080
+ && this.textHeight + 4 > this.height) {
1081
+ this._$reset();
1082
+ this.getTextData(subSize++);
1083
+ }
1084
+ }
1085
+ }
1086
+ this._$resize();
1087
+ }
1088
+ /**
1089
+ * @return {void}
1090
+ * @method
1091
+ * @private
1092
+ */
1093
+ _$resize() {
1094
+ // update bounds
1095
+ if (this._$autoSize !== "none") {
1096
+ const tf = this._$defaultTextFormat;
1097
+ const width = this.textWidth + 4 + tf._$widthMargin();
1098
+ if (this._$wordWrap) {
1099
+ this._$bounds.xMax = this._$originBounds.xMax;
1100
+ this._$bounds.xMin = this._$originBounds.xMin;
1101
+ }
1102
+ else {
1103
+ switch (this._$autoSize) {
1104
+ case "left":
1105
+ this._$bounds.xMax = width + this._$bounds.xMin;
1106
+ break;
1107
+ case "center":
1108
+ this._$bounds.xMax = width + this._$bounds.xMin;
1109
+ break;
1110
+ case "right":
1111
+ this._$bounds.xMax = this._$originBounds.xMax
1112
+ - (this._$originBounds.xMax - this._$originBounds.xMin
1113
+ - (width - this._$originBounds.xMin));
1114
+ break;
1115
+ default:
1116
+ break;
1117
+ }
1118
+ }
1119
+ // set height
1120
+ this._$bounds.yMax = this.textHeight + this._$originBounds.yMin;
1121
+ }
1122
+ else {
1123
+ if (this._$scrollEnabled) {
1124
+ if (!this._$xScrollShape) {
1125
+ this._$xScrollShape = new Shape();
1126
+ this
1127
+ ._$xScrollShape
1128
+ .graphics
1129
+ .beginFill("#000", 0.3)
1130
+ .drawRoundRect(0, 0, 3, 3, 3);
1131
+ this
1132
+ ._$xScrollShape
1133
+ .scale9Grid = new Rectangle(1.5, 1.5, 0.1, 0.1);
1134
+ }
1135
+ if (!this._$yScrollShape) {
1136
+ this._$yScrollShape = new Shape();
1137
+ this
1138
+ ._$yScrollShape
1139
+ .graphics
1140
+ .beginFill("#000", 0.3)
1141
+ .drawRoundRect(0, 0, 3, 3, 3);
1142
+ this
1143
+ ._$yScrollShape
1144
+ .scale9Grid = new Rectangle(1.5, 1.5, 0.1, 0.1);
1145
+ }
1146
+ }
1147
+ }
1148
+ }
1149
+ /**
1150
+ * @param {object} text_object
1151
+ * @param {number} width
1152
+ * @return {number}
1153
+ * @method
1154
+ * @private
1155
+ */
1156
+ _$getAlignOffset(text_object, width) {
1157
+ // default
1158
+ const lineWidth = this
1159
+ .getTextData()
1160
+ .getLineWidth(text_object.line);
1161
+ const textFormat = text_object.textFormat;
1162
+ const leftMargin = textFormat.leftMargin || 0;
1163
+ if (!this._$wordWrap && lineWidth > width) {
1164
+ return $Math.max(0, leftMargin);
1165
+ }
1166
+ const rightMargin = textFormat.rightMargin || 0;
1167
+ if (textFormat.align === "center" // format CENTER
1168
+ || this._$autoSize === "center" // autoSize CENTER
1169
+ ) {
1170
+ return $Math.max(0, width / 2 - leftMargin - rightMargin - lineWidth / 2 - 2);
1171
+ }
1172
+ if (textFormat.align === "right" // format RIGHT
1173
+ || this._$autoSize === "right" // autoSize RIGHT
1174
+ ) {
1175
+ return $Math.max(0, width - leftMargin - lineWidth - rightMargin - 4);
1176
+ }
1177
+ // autoSize LEFT
1178
+ // format LEFT
1179
+ return $Math.max(0, leftMargin);
1180
+ }
1181
+ /**
1182
+ * @param {Float32Array} [matrix=null]
1183
+ * @returns {object}
1184
+ * @method
1185
+ * @private
1186
+ */
1187
+ _$getBounds(matrix = null) {
1188
+ if (matrix) {
1189
+ let multiMatrix = matrix;
1190
+ const rawMatrix = this._$transform._$rawMatrix();
1191
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
1192
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
1193
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
1194
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1195
+ }
1196
+ return $boundsMatrix(this._$bounds, multiMatrix);
1197
+ }
1198
+ return $getBoundsObject(this._$bounds.xMin, this._$bounds.xMax, this._$bounds.yMin, this._$bounds.yMax);
1199
+ }
1200
+ /**
1201
+ * @param {object} character
1202
+ * @return {void}
1203
+ * @method
1204
+ * @private
1205
+ */
1206
+ _$buildCharacter(character) {
1207
+ const textFormat = this._$defaultTextFormat;
1208
+ textFormat.font = character.font;
1209
+ textFormat.size = character.size | 0;
1210
+ textFormat.align = character.align;
1211
+ textFormat.color = character.color | 0;
1212
+ textFormat.leading = character.leading;
1213
+ textFormat.letterSpacing = character.letterSpacing;
1214
+ textFormat.leftMargin = character.leftMargin;
1215
+ textFormat.rightMargin = character.rightMargin;
1216
+ switch (character.fontType) {
1217
+ case 1:
1218
+ textFormat.bold = true;
1219
+ break;
1220
+ case 2:
1221
+ textFormat.italic = true;
1222
+ break;
1223
+ case 3:
1224
+ textFormat.bold = true;
1225
+ textFormat.italic = true;
1226
+ break;
1227
+ }
1228
+ // setup
1229
+ this._$type = character.inputType;
1230
+ this._$multiline = !!character.multiline;
1231
+ this._$wordWrap = !!character.wordWrap;
1232
+ this._$border = !!character.border;
1233
+ this._$scrollEnabled = !!character.scroll;
1234
+ this._$thickness = character.thickness | 0;
1235
+ this._$thicknessColor = character.thicknessColor | 0;
1236
+ // bounds
1237
+ this._$bounds.xMin = character.originBounds.xMin;
1238
+ this._$bounds.xMax = character.originBounds.xMax;
1239
+ this._$bounds.yMin = character.originBounds.yMin;
1240
+ this._$bounds.yMax = character.originBounds.yMax;
1241
+ this._$originBounds.xMin = character.originBounds.xMin;
1242
+ this._$originBounds.xMax = character.originBounds.xMax;
1243
+ this._$originBounds.yMin = character.originBounds.yMin;
1244
+ this._$originBounds.yMax = character.originBounds.yMax;
1245
+ switch (character.autoSize) {
1246
+ case 1:
1247
+ this.autoSize = character.align;
1248
+ break;
1249
+ case 2:
1250
+ this.autoFontSize = true;
1251
+ break;
1252
+ }
1253
+ this.text = character.text;
1254
+ if ($rendererWorker && this._$stage) {
1255
+ this._$createWorkerInstance();
1256
+ }
1257
+ }
1258
+ /**
1259
+ * @param {object} character
1260
+ * @return {void}
1261
+ * @method
1262
+ * @private
1263
+ */
1264
+ _$sync(character) {
1265
+ this._$buildCharacter(character);
1266
+ }
1267
+ /**
1268
+ * @param {object} tag
1269
+ * @param {DisplayObjectContainer} parent
1270
+ * @return {object}
1271
+ * @method
1272
+ * @private
1273
+ */
1274
+ _$build(tag, parent) {
1275
+ const character = this
1276
+ ._$baseBuild(tag, parent);
1277
+ this._$buildCharacter(character);
1278
+ return character;
1279
+ }
1280
+ /**
1281
+ * @param {CanvasToWebGLContext} context
1282
+ * @param {Float32Array} matrix
1283
+ * @returns {void}
1284
+ * @method
1285
+ * @private
1286
+ */
1287
+ _$clip(context, matrix) {
1288
+ // size
1289
+ const bounds = this._$getBounds();
1290
+ const xMax = bounds.xMax;
1291
+ const xMin = bounds.xMin;
1292
+ const yMax = bounds.yMax;
1293
+ const yMin = bounds.yMin;
1294
+ $poolBoundsObject(bounds);
1295
+ const width = $Math.ceil($Math.abs(xMax - xMin));
1296
+ const height = $Math.ceil($Math.abs(yMax - yMin));
1297
+ if (!width || !height) {
1298
+ return;
1299
+ }
1300
+ let multiMatrix = matrix;
1301
+ const rawMatrix = this._$transform._$rawMatrix();
1302
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
1303
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
1304
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
1305
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1306
+ }
1307
+ context.reset();
1308
+ context.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
1309
+ context.beginPath();
1310
+ context.moveTo(0, 0);
1311
+ context.lineTo(width, 0);
1312
+ context.lineTo(width, height);
1313
+ context.lineTo(0, height);
1314
+ context.lineTo(0, 0);
1315
+ context.clip();
1316
+ if (multiMatrix !== matrix) {
1317
+ $poolFloat32Array6(multiMatrix);
1318
+ }
1319
+ }
1320
+ /**
1321
+ * @param {CanvasToWebGLContext} context
1322
+ * @param {Float32Array} matrix
1323
+ * @param {Float32Array} color_transform
1324
+ * @return {void}
1325
+ * @method
1326
+ * @private
1327
+ */
1328
+ _$draw(context, matrix, color_transform) {
1329
+ if (!this._$visible || this._$textAreaActive) {
1330
+ return;
1331
+ }
1332
+ if (!this._$background && !this._$border && !this.text) {
1333
+ return;
1334
+ }
1335
+ let multiColor = color_transform;
1336
+ const rawColor = this._$transform._$rawColorTransform();
1337
+ if (rawColor[0] !== 1 || rawColor[1] !== 1
1338
+ || rawColor[2] !== 1 || rawColor[3] !== 1
1339
+ || rawColor[4] !== 0 || rawColor[5] !== 0
1340
+ || rawColor[6] !== 0 || rawColor[7] !== 0) {
1341
+ multiColor = $multiplicationColor(color_transform, rawColor);
1342
+ }
1343
+ const alpha = $clamp(multiColor[3] + multiColor[7] / 255, 0, 1);
1344
+ if (!alpha) {
1345
+ return;
1346
+ }
1347
+ let multiMatrix = matrix;
1348
+ const rawMatrix = this._$transform._$rawMatrix();
1349
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
1350
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
1351
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
1352
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1353
+ }
1354
+ const baseBounds = this._$getBounds(null);
1355
+ baseBounds.xMin -= this._$thickness;
1356
+ baseBounds.xMax += this._$thickness;
1357
+ baseBounds.yMin -= this._$thickness;
1358
+ baseBounds.yMax += this._$thickness;
1359
+ const bounds = $boundsMatrix(baseBounds, multiMatrix);
1360
+ const xMax = +bounds.xMax;
1361
+ const xMin = +bounds.xMin;
1362
+ const yMax = +bounds.yMax;
1363
+ const yMin = +bounds.yMin;
1364
+ $poolBoundsObject(bounds);
1365
+ const width = $Math.ceil($Math.abs(xMax - xMin));
1366
+ const height = $Math.ceil($Math.abs(yMax - yMin));
1367
+ switch (true) {
1368
+ case width === 0:
1369
+ case height === 0:
1370
+ case width === -$Infinity:
1371
+ case height === -$Infinity:
1372
+ case width === $Infinity:
1373
+ case height === $Infinity:
1374
+ return;
1375
+ default:
1376
+ break;
1377
+ }
1378
+ let xScale = +$Math.sqrt(multiMatrix[0] * multiMatrix[0]
1379
+ + multiMatrix[1] * multiMatrix[1]);
1380
+ if (!$Number.isInteger(xScale)) {
1381
+ const value = xScale.toString();
1382
+ const index = value.indexOf("e");
1383
+ if (index !== -1) {
1384
+ xScale = +value.slice(0, index);
1385
+ }
1386
+ xScale = +xScale.toFixed(4);
1387
+ }
1388
+ let yScale = +$Math.sqrt(multiMatrix[2] * multiMatrix[2]
1389
+ + multiMatrix[3] * multiMatrix[3]);
1390
+ if (!$Number.isInteger(yScale)) {
1391
+ const value = yScale.toString();
1392
+ const index = value.indexOf("e");
1393
+ if (index !== -1) {
1394
+ yScale = +value.slice(0, index);
1395
+ }
1396
+ yScale = +yScale.toFixed(4);
1397
+ }
1398
+ const filters = this._$filters || this.filters;
1399
+ const canApply = filters !== null
1400
+ && filters.length > 0
1401
+ && this._$canApply(filters);
1402
+ let filterBounds = $getBoundsObject(0, width, 0, height);
1403
+ if (canApply && filters) {
1404
+ for (let idx = 0; idx < filters.length; ++idx) {
1405
+ filterBounds = filters[idx]
1406
+ ._$generateFilterRect(filterBounds, xScale, yScale);
1407
+ }
1408
+ }
1409
+ // cache current buffer
1410
+ const manager = context.frameBuffer;
1411
+ const currentAttachment = manager.currentAttachment;
1412
+ if (!currentAttachment
1413
+ || xMin - filterBounds.xMin > currentAttachment.width
1414
+ || yMin - filterBounds.yMin > currentAttachment.height) {
1415
+ $poolBoundsObject(filterBounds);
1416
+ return;
1417
+ }
1418
+ if (0 > xMin + filterBounds.xMax || 0 > yMin + filterBounds.yMax) {
1419
+ $poolBoundsObject(filterBounds);
1420
+ return;
1421
+ }
1422
+ $poolBoundsObject(filterBounds);
1423
+ // texture is small or renew
1424
+ if (this._$isUpdated()) {
1425
+ $cacheStore.removeCache(this._$instanceId);
1426
+ context.cachePosition = null;
1427
+ this._$cacheKeys.length = 0;
1428
+ }
1429
+ if (!this._$cacheKeys.length
1430
+ || this._$cacheParams[0] !== xScale
1431
+ || this._$cacheParams[1] !== yScale
1432
+ || this._$cacheParams[2] !== color_transform[7]) {
1433
+ const keys = $getArray(xScale, yScale);
1434
+ this._$cacheKeys = $cacheStore.generateKeys(this._$instanceId, keys);
1435
+ $poolArray(keys);
1436
+ this._$cacheParams[0] = xScale;
1437
+ this._$cacheParams[1] = yScale;
1438
+ this._$cacheParams[2] = color_transform[7];
1439
+ }
1440
+ const blendMode = this._$blendMode || this.blendMode;
1441
+ context.cachePosition = $cacheStore.get(this._$cacheKeys);
1442
+ if (!context.cachePosition) {
1443
+ // resize
1444
+ const lineWidth = $Math.min(1, $Math.max(xScale, yScale));
1445
+ const width = $Math.ceil($Math.abs(baseBounds.xMax - baseBounds.xMin) * xScale);
1446
+ const height = $Math.ceil($Math.abs(baseBounds.yMax - baseBounds.yMin) * yScale);
1447
+ // new canvas
1448
+ const canvas = $cacheStore.getCanvas();
1449
+ canvas.width = width + lineWidth * 2;
1450
+ canvas.height = height + lineWidth * 2;
1451
+ const ctx = canvas.getContext("2d");
1452
+ if (!ctx) {
1453
+ throw new Error("the context is null.");
1454
+ }
1455
+ // border and background
1456
+ if (this._$background || this._$border) {
1457
+ ctx.beginPath();
1458
+ ctx.moveTo(0, 0);
1459
+ ctx.lineTo(width, 0);
1460
+ ctx.lineTo(width, height);
1461
+ ctx.lineTo(0, height);
1462
+ ctx.lineTo(0, 0);
1463
+ if (this._$background) {
1464
+ const rgb = $intToRGBA(this._$backgroundColor);
1465
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 + multiColor[7], 255)) / 255;
1466
+ ctx.fillStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
1467
+ ctx.fill();
1468
+ }
1469
+ if (this._$border) {
1470
+ const rgb = $intToRGBA(this._$borderColor);
1471
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 + multiColor[7], 255)) / 255;
1472
+ ctx.lineWidth = lineWidth;
1473
+ ctx.strokeStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
1474
+ ctx.stroke();
1475
+ }
1476
+ }
1477
+ // mask start
1478
+ ctx.save();
1479
+ ctx.beginPath();
1480
+ ctx.moveTo(2, 2);
1481
+ ctx.lineTo(width - 2, 2);
1482
+ ctx.lineTo(width - 2, height - 2);
1483
+ ctx.lineTo(2, height - 2);
1484
+ ctx.lineTo(2, 2);
1485
+ ctx.clip();
1486
+ let ty = 2;
1487
+ if (this._$scrollY > 0) {
1488
+ const scaleY = (this.textHeight - this.height) / this.height;
1489
+ ty += -this._$scrollY * scaleY;
1490
+ }
1491
+ let tx = 2;
1492
+ if (this._$scrollX > 0) {
1493
+ const scaleX = (this.textWidth - this.width) / this.width;
1494
+ tx += -this._$scrollX * scaleX;
1495
+ }
1496
+ ctx.setTransform(xScale, 0, 0, yScale, tx * xScale, ty * yScale);
1497
+ ctx.beginPath();
1498
+ this._$doDraw(ctx, multiColor, width / xScale, lineWidth);
1499
+ ctx.restore();
1500
+ const position = manager
1501
+ .createCachePosition(width, height);
1502
+ const texture = manager
1503
+ .createTextureFromCanvas(ctx.canvas);
1504
+ context.drawTextureFromRect(texture, position);
1505
+ // set cache
1506
+ context.cachePosition = position;
1507
+ $cacheStore.set(this._$cacheKeys, position);
1508
+ // destroy cache
1509
+ $cacheStore.destroy(ctx);
1510
+ }
1511
+ let drawFilter = false;
1512
+ let offsetX = 0;
1513
+ let offsetY = 0;
1514
+ if (filters && filters.length
1515
+ && this._$canApply(filters)) {
1516
+ drawFilter = true;
1517
+ const position = this._$drawFilter(context, multiMatrix, filters, width, height);
1518
+ if (position.offsetX) {
1519
+ offsetX = position.offsetX;
1520
+ }
1521
+ if (position.offsetY) {
1522
+ offsetY = position.offsetY;
1523
+ }
1524
+ // update
1525
+ context.cachePosition = position;
1526
+ }
1527
+ const radianX = $Math.atan2(multiMatrix[1], multiMatrix[0]);
1528
+ const radianY = $Math.atan2(-multiMatrix[2], multiMatrix[3]);
1529
+ if (!drawFilter && (radianX || radianY)) {
1530
+ const tx = baseBounds.xMin * xScale;
1531
+ const ty = baseBounds.yMin * yScale;
1532
+ const cosX = $Math.cos(radianX);
1533
+ const sinX = $Math.sin(radianX);
1534
+ const cosY = $Math.cos(radianY);
1535
+ const sinY = $Math.sin(radianY);
1536
+ context.setTransform(cosX, sinX, -sinY, cosY, tx * cosX - ty * sinY + multiMatrix[4], tx * sinX + ty * cosY + multiMatrix[5]);
1537
+ }
1538
+ else {
1539
+ context.setTransform(1, 0, 0, 1, xMin - offsetX, yMin - offsetY);
1540
+ }
1541
+ // draw
1542
+ if (context.cachePosition) {
1543
+ context.globalAlpha = alpha;
1544
+ context.imageSmoothingEnabled = true;
1545
+ context.globalCompositeOperation = blendMode;
1546
+ context.drawInstance(xMin - offsetX, yMin - offsetY, xMax, yMax, color_transform);
1547
+ // cache position clear
1548
+ context.cachePosition = null;
1549
+ }
1550
+ // get cache
1551
+ $poolBoundsObject(baseBounds);
1552
+ // pool
1553
+ if (multiMatrix !== matrix) {
1554
+ $poolFloat32Array6(multiMatrix);
1555
+ }
1556
+ if (multiColor !== color_transform) {
1557
+ $poolFloat32Array8(multiColor);
1558
+ }
1559
+ }
1560
+ /**
1561
+ * @param {CanvasRenderingContext2D} context
1562
+ * @param {Float32Array} color_transform
1563
+ * @param {number} width
1564
+ * @param {number} line_width
1565
+ * @return {void}
1566
+ * @method
1567
+ * @private
1568
+ */
1569
+ _$doDraw(context, color_transform, width, line_width) {
1570
+ // init
1571
+ const textData = this.getTextData();
1572
+ const tw = this.width;
1573
+ let scrollX = 0;
1574
+ if (this._$scrollX > 0) {
1575
+ const scaleX = (this.textWidth - tw) / tw;
1576
+ scrollX = this._$scrollX * scaleX;
1577
+ }
1578
+ const limitWidth = tw + scrollX;
1579
+ const th = this.height;
1580
+ let scrollY = 0;
1581
+ if (this._$scrollY > 0) {
1582
+ const scaleY = (this.textHeight - th) / th;
1583
+ scrollY = this._$scrollY * scaleY;
1584
+ }
1585
+ const limitHeight = th + scrollY;
1586
+ // setup
1587
+ let offsetWidth = 0;
1588
+ let offsetHeight = 0;
1589
+ let offsetAlign = 0;
1590
+ let verticalAlign = 0;
1591
+ let skip = false;
1592
+ for (let idx = 0; idx < textData.textTable.length; ++idx) {
1593
+ const textObject = textData.textTable[idx];
1594
+ if (skip && textObject.mode === "text") {
1595
+ continue;
1596
+ }
1597
+ const textFormat = textObject.textFormat;
1598
+ // check
1599
+ if (this._$autoSize === "none") {
1600
+ if (offsetHeight > limitHeight) {
1601
+ break;
1602
+ }
1603
+ if (textObject.mode === "text") {
1604
+ if (scrollX > offsetWidth + textObject.w
1605
+ || offsetWidth > limitWidth) {
1606
+ offsetWidth += textObject.w;
1607
+ continue;
1608
+ }
1609
+ }
1610
+ }
1611
+ // color setting
1612
+ const rgb = $intToRGBA(textFormat.color || 0);
1613
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 + color_transform[7], 255)) / 255;
1614
+ context.fillStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
1615
+ if (this._$thickness) {
1616
+ const rgb = $intToRGBA(this._$thicknessColor);
1617
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 + color_transform[7], 255)) / 255;
1618
+ context.lineWidth = this._$thickness;
1619
+ context.strokeStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
1620
+ }
1621
+ const line = textObject.line | 0;
1622
+ switch (textObject.mode) {
1623
+ case "break":
1624
+ case "wrap":
1625
+ // reset width
1626
+ offsetWidth = 0;
1627
+ if (line) {
1628
+ offsetHeight += textData.heightTable[line - 1] + 1;
1629
+ }
1630
+ if (scrollY > offsetHeight + textData.heightTable[line]) {
1631
+ skip = true;
1632
+ continue;
1633
+ }
1634
+ verticalAlign = textData.ascentTable[line];
1635
+ offsetAlign = this._$getAlignOffset(textObject, width);
1636
+ skip = false;
1637
+ break;
1638
+ case "text":
1639
+ {
1640
+ context.beginPath();
1641
+ context.font = $generateFontStyle(textFormat.font || "", textFormat.size || 0, !!textFormat.italic, !!textFormat.bold);
1642
+ const x = offsetWidth + offsetAlign;
1643
+ const y = offsetHeight + verticalAlign;
1644
+ if (textFormat.underline) {
1645
+ const rgb = $intToRGBA(textFormat.color || 0);
1646
+ const alpha = $Math.max(0, $Math.min(rgb.A * 255 + color_transform[7], 255)) / 255;
1647
+ context.lineWidth = line_width;
1648
+ context.strokeStyle = `rgba(${rgb.R},${rgb.G},${rgb.B},${alpha})`;
1649
+ context.beginPath();
1650
+ context.moveTo(x, y + 1);
1651
+ context.lineTo(x + textObject.w, y + 1);
1652
+ context.stroke();
1653
+ }
1654
+ if (this._$thickness) {
1655
+ context.strokeText(textObject.text, x, y);
1656
+ }
1657
+ context.fillText(textObject.text, x, y);
1658
+ offsetWidth += textObject.w;
1659
+ }
1660
+ break;
1661
+ // case "image":
1662
+ // if (!obj.loaded) {
1663
+ // continue;
1664
+ // }
1665
+ // context.beginPath();
1666
+ // context.drawImage(obj.image,
1667
+ // obj.hspace, obj.y,
1668
+ // obj.width, obj.height
1669
+ // );
1670
+ // break;
1671
+ }
1672
+ }
1673
+ }
1674
+ /**
1675
+ * @param {CanvasRenderingContext2D} context
1676
+ * @param {Float32Array} matrix
1677
+ * @param {object} options
1678
+ * @return {boolean}
1679
+ * @method
1680
+ * @private
1681
+ */
1682
+ _$mouseHit(context, matrix, options) {
1683
+ if (!this._$visible) {
1684
+ return false;
1685
+ }
1686
+ return this._$hit(context, matrix, options);
1687
+ }
1688
+ /**
1689
+ * @param {CanvasRenderingContext2D} context
1690
+ * @param {Float32Array} matrix
1691
+ * @param {object} options
1692
+ * @return {boolean}
1693
+ * @method
1694
+ * @private
1695
+ */
1696
+ _$hit(context, matrix, options) {
1697
+ let multiMatrix = matrix;
1698
+ const rawMatrix = this._$transform._$rawMatrix();
1699
+ if (rawMatrix[0] !== 1 || rawMatrix[1] !== 0
1700
+ || rawMatrix[2] !== 0 || rawMatrix[3] !== 1
1701
+ || rawMatrix[4] !== 0 || rawMatrix[5] !== 0) {
1702
+ multiMatrix = $multiplicationMatrix(matrix, rawMatrix);
1703
+ }
1704
+ const baseBounds = this._$getBounds(null);
1705
+ const bounds = $boundsMatrix(baseBounds, multiMatrix);
1706
+ const xMax = +bounds.xMax;
1707
+ const xMin = +bounds.xMin;
1708
+ const yMax = +bounds.yMax;
1709
+ const yMin = +bounds.yMin;
1710
+ $poolBoundsObject(bounds);
1711
+ $poolBoundsObject(baseBounds);
1712
+ const width = $Math.ceil($Math.abs(xMax - xMin));
1713
+ const height = $Math.ceil($Math.abs(yMax - yMin));
1714
+ context.setTransform(1, 0, 0, 1, xMin, yMin);
1715
+ context.beginPath();
1716
+ context.moveTo(0, 0);
1717
+ context.lineTo(width, 0);
1718
+ context.lineTo(width, height);
1719
+ context.lineTo(0, height);
1720
+ context.lineTo(0, 0);
1721
+ if (multiMatrix !== matrix) {
1722
+ $poolFloat32Array6(multiMatrix);
1723
+ }
1724
+ return context.isPointInPath(options.x, options.y);
1725
+ }
1726
+ /**
1727
+ * @param {number} scale
1728
+ * @return {void}
1729
+ * @method
1730
+ * @private
1731
+ */
1732
+ _$createTextAreaElement(scale) {
1733
+ // new text area
1734
+ if (!this._$textarea) {
1735
+ this._$textarea = $document.createElement("textarea");
1736
+ this._$textarea.value = this.text;
1737
+ this._$textarea.id = `${$PREFIX}_TextField_${this._$instanceId}`;
1738
+ if (!this._$wordWrap) {
1739
+ this._$textarea.wrap = "off";
1740
+ }
1741
+ const textFormat = this._$defaultTextFormat;
1742
+ // setup
1743
+ let style = "";
1744
+ style += "position: absolute;";
1745
+ style += "outline: 0;";
1746
+ style += `padding: 2px 2px 2px ${$Math.max(3, textFormat.leftMargin || 0)}px;`;
1747
+ style += "margin: 0;";
1748
+ style += "appearance: none;";
1749
+ style += "resize: none;";
1750
+ style += "overflow: hidden;";
1751
+ style += `z-index: ${0x7fffffff};`;
1752
+ style += "vertical-align: top;";
1753
+ this._$textarea.setAttribute("style", style);
1754
+ // add blur event
1755
+ this._$textarea.addEventListener(`${$PREFIX}_blur`, (event) => {
1756
+ // set new text
1757
+ const element = event.target;
1758
+ let value = element.value;
1759
+ if (value && this._$restrict) {
1760
+ let pattern = this._$restrict;
1761
+ if (pattern[0] !== "[") {
1762
+ pattern = "[" + pattern;
1763
+ }
1764
+ if (pattern[pattern.length - 1] !== "]") {
1765
+ pattern += "]";
1766
+ }
1767
+ const found = value.match(new $RegExp(pattern, "gm"));
1768
+ value = found ? found.join("") : "";
1769
+ }
1770
+ const player = $currentPlayer();
1771
+ const div = $document.getElementById(player.contentElementId);
1772
+ if (div) {
1773
+ const element = $document.getElementById(`${$PREFIX}_TextField_${this._$instanceId}`);
1774
+ if (element) {
1775
+ element.remove();
1776
+ }
1777
+ }
1778
+ this.text = value;
1779
+ this._$focus = false;
1780
+ this._$textAreaActive = false;
1781
+ this._$doChanged();
1782
+ $doUpdated();
1783
+ });
1784
+ // input event
1785
+ this._$textarea.addEventListener("input", (event) => {
1786
+ // set new text
1787
+ const element = event.target;
1788
+ const player = $currentPlayer();
1789
+ let value = element.value;
1790
+ // SafariではInputEvent.isComposingがundefined
1791
+ if (this._$restrict && !this._$isComposing && value) {
1792
+ let pattern = this._$restrict;
1793
+ if (pattern[0] !== "[") {
1794
+ pattern = "[" + pattern;
1795
+ }
1796
+ if (pattern[pattern.length - 1] !== "]") {
1797
+ pattern += "]";
1798
+ }
1799
+ const found = value.match(new $RegExp(pattern, "gm"));
1800
+ value = found ? found.join("") : "";
1801
+ }
1802
+ if (!this._$isComposing && this.text !== value) {
1803
+ // update
1804
+ this.text = value;
1805
+ element.value = value;
1806
+ if (this.willTrigger(Next2DEvent.CHANGE)) {
1807
+ this.dispatchEvent(new Next2DEvent(Next2DEvent.CHANGE, true));
1808
+ }
1809
+ // setup
1810
+ // const element = this._$textarea;
1811
+ const matrix = this._$transform.concatenatedMatrix;
1812
+ const bounds = this._$getBounds(null);
1813
+ element.style.left = `${$Math.floor((matrix.tx + bounds.xMin + player.x / player._$scale / $devicePixelRatio) * player._$scale)}px`;
1814
+ element.style.top = `${$Math.floor((matrix.ty + bounds.yMin + player.y / player._$scale / $devicePixelRatio) * player._$scale)}px`;
1815
+ element.style.width = `${$Math.ceil((this.width - 1) * player._$scale)}px`;
1816
+ element.style.height = `${$Math.ceil((this.height - 1) * player._$scale)}px`;
1817
+ }
1818
+ });
1819
+ // IME入力開始時のevent
1820
+ this._$textarea.addEventListener("compositionstart", () => {
1821
+ this._$isComposing = true;
1822
+ });
1823
+ // IME入力確定時のevent
1824
+ this._$textarea.addEventListener("compositionend", (event) => {
1825
+ this._$isComposing = false;
1826
+ const element = event.target;
1827
+ let value = element.value;
1828
+ if (!this._$restrict || !value) {
1829
+ return;
1830
+ }
1831
+ let pattern = this._$restrict;
1832
+ if (pattern[0] !== "[") {
1833
+ pattern = "[" + pattern;
1834
+ }
1835
+ if (pattern[pattern.length - 1] !== "]") {
1836
+ pattern += "]";
1837
+ }
1838
+ const found = value.match(new $RegExp(pattern, "gm"));
1839
+ value = found ? found.join("") : "";
1840
+ // update
1841
+ this.text = value;
1842
+ element.value = value;
1843
+ });
1844
+ // add click event
1845
+ this._$textarea.addEventListener("click", () => {
1846
+ if (this.willTrigger(Next2DMouseEvent.CLICK)) {
1847
+ this.dispatchEvent(new Next2DMouseEvent(Next2DMouseEvent.CLICK));
1848
+ }
1849
+ });
1850
+ // add mousewheel event
1851
+ this._$textarea.addEventListener($MOUSE_WHEEL, (event) => {
1852
+ this.scrollY += event.deltaY;
1853
+ });
1854
+ // add scroll event
1855
+ this._$textarea.addEventListener($SCROLL, (event) => {
1856
+ const element = event.target;
1857
+ this.scrollY = element.scrollTop;
1858
+ });
1859
+ // down event
1860
+ this._$textarea.addEventListener($TOUCH_START, () => {
1861
+ const player = $currentPlayer();
1862
+ player._$state = "down";
1863
+ });
1864
+ // up event
1865
+ this._$textarea.addEventListener($TOUCH_END, () => {
1866
+ const player = $currentPlayer();
1867
+ player._$state = "up";
1868
+ });
1869
+ // down event
1870
+ this._$textarea.addEventListener($MOUSE_DOWN, () => {
1871
+ const player = $currentPlayer();
1872
+ player._$state = "down";
1873
+ });
1874
+ // up event
1875
+ this._$textarea.addEventListener($MOUSE_UP, () => {
1876
+ const player = $currentPlayer();
1877
+ player._$state = "up";
1878
+ });
1879
+ }
1880
+ // change style
1881
+ const tf = this._$defaultTextFormat;
1882
+ const fontSize = tf.size
1883
+ ? $Math.ceil(tf.size * scale * this._$transform.concatenatedMatrix.d)
1884
+ : 0;
1885
+ this._$textarea.style.fontSize = `${fontSize}px`;
1886
+ this._$textarea.style.fontFamily = tf.font || "Times New Roman";
1887
+ this._$textarea.style.lineHeight = `${(fontSize + $Math.max(0, tf.leading || 0)) / fontSize}em`;
1888
+ if (this._$autoSize !== "none") {
1889
+ this._$textarea.style.textAlign = "center";
1890
+ }
1891
+ else {
1892
+ this._$textarea.style.textAlign = tf.align || "none";
1893
+ }
1894
+ this._$textarea.addEventListener("keydown", (event) => {
1895
+ const element = event.target;
1896
+ let value = element.value;
1897
+ // SafariではInputEvent.isComposingがundefined
1898
+ if (this._$restrict && !this._$isComposing && value) {
1899
+ let pattern = this._$restrict;
1900
+ if (pattern[0] !== "[") {
1901
+ pattern = "[" + pattern;
1902
+ }
1903
+ if (pattern[pattern.length - 1] !== "]") {
1904
+ pattern += "]";
1905
+ }
1906
+ const found = value.match(new $RegExp(pattern, "gm"));
1907
+ value = found ? found.join("") : "";
1908
+ }
1909
+ // update
1910
+ if (!this._$isComposing) {
1911
+ this.text = value;
1912
+ element.value = value;
1913
+ }
1914
+ // enter off
1915
+ if (event.code === "Enter" && !this._$multiline) {
1916
+ return false;
1917
+ }
1918
+ });
1919
+ const style = this._$textarea.style;
1920
+ if (this._$border) {
1921
+ style.border = `solid 1px #${this.borderColor.toString(16)}`;
1922
+ }
1923
+ else {
1924
+ style.border = "none";
1925
+ }
1926
+ if (this._$border || this._$background) {
1927
+ style.backgroundColor = `#${this.backgroundColor.toString(16)}`;
1928
+ }
1929
+ else {
1930
+ style.backgroundColor = "transparent";
1931
+ }
1932
+ //reset
1933
+ this._$textarea.maxLength = this._$maxChars ? this._$maxChars : 0x7fffffff;
1934
+ }
1935
+ /**
1936
+ * @return {void}
1937
+ * @method
1938
+ * @private
1939
+ */
1940
+ _$createWorkerInstance() {
1941
+ if (this._$created || !$rendererWorker) {
1942
+ return;
1943
+ }
1944
+ this._$created = true;
1945
+ const bounds = this._$getBounds();
1946
+ const message = {
1947
+ "command": "createTextField",
1948
+ "buffer": new Float32Array(),
1949
+ "instanceId": this._$instanceId,
1950
+ "parentId": this._$parent ? this._$parent._$instanceId : -1,
1951
+ "xMin": bounds.xMin,
1952
+ "yMin": bounds.yMin,
1953
+ "xMax": bounds.xMax,
1954
+ "yMax": bounds.yMax,
1955
+ "limitWidth": this.width,
1956
+ "limitHeight": this.height,
1957
+ "textHeight": this.textHeight,
1958
+ "verticalAlign": this._$verticalAlign,
1959
+ "autoSize": this._$autoSize,
1960
+ "wordWrap": this._$wordWrap,
1961
+ "border": this._$border,
1962
+ "background": this._$background,
1963
+ "thickness": this._$thickness
1964
+ };
1965
+ if (this._$border) {
1966
+ message.borderColor = this._$borderColor;
1967
+ }
1968
+ if (this._$background) {
1969
+ message.backgroundColor = this._$backgroundColor;
1970
+ }
1971
+ if (this._$thickness) {
1972
+ message.thicknessColor = this._$backgroundColor;
1973
+ }
1974
+ if (this._$characterId > -1) {
1975
+ message.characterId = this._$characterId;
1976
+ }
1977
+ if (this._$loaderInfo) {
1978
+ message.loaderInfoId = this._$loaderInfo._$id;
1979
+ }
1980
+ if (this._$scale9Grid) {
1981
+ message.grid = {
1982
+ "x": this._$scale9Grid.x,
1983
+ "y": this._$scale9Grid.y,
1984
+ "w": this._$scale9Grid.width,
1985
+ "h": this._$scale9Grid.height
1986
+ };
1987
+ }
1988
+ $rendererWorker.postMessage(message);
1989
+ }
1990
+ /**
1991
+ * @return {void}
1992
+ * @method
1993
+ * @private
1994
+ */
1995
+ _$postProperty() {
1996
+ if (!$rendererWorker) {
1997
+ return;
1998
+ }
1999
+ const message = this._$createMessage();
2000
+ message.textAreaActive = this._$textAreaActive;
2001
+ const bounds = this._$getBounds(null);
2002
+ message.xMin = bounds.xMin;
2003
+ message.yMin = bounds.yMin;
2004
+ message.xMax = bounds.xMax;
2005
+ message.yMax = bounds.yMax;
2006
+ $poolBoundsObject(bounds);
2007
+ if (this._$isUpdated()) {
2008
+ message.limitWidth = this.width;
2009
+ message.limitHeight = this.height;
2010
+ message.textHeight = this.textHeight;
2011
+ message.verticalAlign = this._$verticalAlign;
2012
+ message.autoSize = this._$autoSize;
2013
+ message.wordWrap = this._$wordWrap;
2014
+ message.border = this._$border;
2015
+ if (this._$border) {
2016
+ message.borderColor = this._$borderColor;
2017
+ }
2018
+ message.background = this._$background;
2019
+ if (this._$background) {
2020
+ message.backgroundColor = this._$backgroundColor;
2021
+ }
2022
+ message.thickness = this._$thickness;
2023
+ if (this._$thickness) {
2024
+ message.thicknessColor = this._$backgroundColor;
2025
+ }
2026
+ }
2027
+ $rendererWorker.postMessage(message);
2028
+ this._$posted = true;
2029
+ this._$updated = false;
2030
+ }
2031
+ }