@galacean/effects-plugin-rich-text 2.7.3 → 2.8.0-alpha.0

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.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Description: Galacean Effects player rich text plugin
4
4
  * Author: Ant Group CO., Ltd.
5
5
  * Contributors: 云垣
6
- * Version: v2.7.3
6
+ * Version: v2.8.0-alpha.0
7
7
  */
8
8
 
9
9
  'use strict';
@@ -353,6 +353,119 @@ typeof SuppressedError === "function" ? SuppressedError : function _SuppressedEr
353
353
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
354
354
  };
355
355
 
356
+ var RichTextLayout = /*#__PURE__*/ function() {
357
+ function RichTextLayout(options) {
358
+ this.width = 0;
359
+ this.height = 0;
360
+ var size = options.size, _options_textOverflow = options.textOverflow, textOverflow = _options_textOverflow === void 0 ? EFFECTS.spec.TextOverflow.clip : _options_textOverflow, _options_textVerticalAlign = options.textVerticalAlign, textVerticalAlign = _options_textVerticalAlign === void 0 ? EFFECTS.spec.TextVerticalAlign.middle : _options_textVerticalAlign, _options_textAlign = options.textAlign, textAlign = _options_textAlign === void 0 ? EFFECTS.spec.TextAlignment.left : _options_textAlign, _options_letterSpace = options.letterSpace, letterSpace = _options_letterSpace === void 0 ? 0 : _options_letterSpace, _options_lineHeight = options.lineHeight, lineHeight = _options_lineHeight === void 0 ? 0.571 : _options_lineHeight, _options_wrapEnabled = options.wrapEnabled, wrapEnabled = _options_wrapEnabled === void 0 ? false : _options_wrapEnabled, _options_maxTextWidth = options.maxTextWidth, maxTextWidth = _options_maxTextWidth === void 0 ? 350 : _options_maxTextWidth, _options_maxTextHeight = options.maxTextHeight, maxTextHeight = _options_maxTextHeight === void 0 ? 1000 : _options_maxTextHeight, _options_sizeMode = options.sizeMode, sizeMode = _options_sizeMode === void 0 ? EFFECTS.spec.TextSizeMode.autoWidth : _options_sizeMode, _options_useLegacyRichText = options.// @ts-expect-error 兼容旧版
361
+ useLegacyRichText, useLegacyRichText = _options_useLegacyRichText === void 0 ? false : _options_useLegacyRichText;
362
+ this.letterSpace = letterSpace;
363
+ this.lineHeight = lineHeight * 300;
364
+ this.useLegacyRichText = useLegacyRichText;
365
+ this.overflow = textOverflow;
366
+ this.textVerticalAlign = textVerticalAlign;
367
+ this.textAlign = textAlign;
368
+ this.width = size ? size[0] : 100;
369
+ this.height = size ? size[1] : 100;
370
+ this.wrapEnabled = wrapEnabled;
371
+ this.maxTextWidth = maxTextWidth;
372
+ this.maxTextHeight = maxTextHeight;
373
+ this.sizeMode = sizeMode;
374
+ }
375
+ var _proto = RichTextLayout.prototype;
376
+ _proto.getOffsetY = function getOffsetY(style, lineCount, lineHeight, fontSize, totalLineHeight) {
377
+ var outlineWidth = style.outlineWidth, fontScale = style.fontScale;
378
+ // /3 计算Y轴偏移量,以匹配编辑器行为
379
+ var offsetY = (lineHeight - fontSize) / 3;
380
+ // 计算基础偏移量
381
+ var baseOffset = fontSize + outlineWidth * fontScale;
382
+ var commonCalculation = totalLineHeight !== undefined ? totalLineHeight : lineHeight * (lineCount - 1);
383
+ var offsetResult = 0;
384
+ switch(this.textVerticalAlign){
385
+ case EFFECTS.spec.TextVerticalAlign.top:
386
+ offsetResult = baseOffset + offsetY;
387
+ break;
388
+ case EFFECTS.spec.TextVerticalAlign.middle:
389
+ offsetResult = (this.height * fontScale - commonCalculation + baseOffset) / 2;
390
+ break;
391
+ case EFFECTS.spec.TextVerticalAlign.bottom:
392
+ offsetResult = this.height * fontScale - commonCalculation - offsetY;
393
+ break;
394
+ }
395
+ return offsetResult;
396
+ };
397
+ _proto.getOffsetX = function getOffsetX(style, maxWidth) {
398
+ var offsetX = 0;
399
+ switch(this.textAlign){
400
+ case EFFECTS.spec.TextAlignment.left:
401
+ offsetX = style.outlineWidth * style.fontScale;
402
+ break;
403
+ case EFFECTS.spec.TextAlignment.middle:
404
+ offsetX = (this.width * style.fontScale - maxWidth) / 2;
405
+ break;
406
+ case EFFECTS.spec.TextAlignment.right:
407
+ offsetX = this.width * style.fontScale - maxWidth;
408
+ break;
409
+ }
410
+ return offsetX;
411
+ };
412
+ /**
413
+ * 富文本垂直对齐计算
414
+ * @param style - 字体样式
415
+ * @param lineHeights - 每行高度数组
416
+ * @param fontSize - 字体大小
417
+ * @returns 第一行基线的Y坐标
418
+ */ _proto.getOffsetYRich = function getOffsetYRich(style, lineHeights, fontSize) {
419
+ if (lineHeights.length === 0) {
420
+ // 空文本时返回 0,避免计算异常;后续策略可按需要再调整
421
+ return 0;
422
+ }
423
+ var outlineWidth = style.outlineWidth, fontScale = style.fontScale;
424
+ var total = lineHeights.reduce(function(a, b) {
425
+ return a + b;
426
+ }, 0);
427
+ var offsetY = (lineHeights[0] - fontSize) / 3;
428
+ var baseOffset = fontSize + outlineWidth * fontScale;
429
+ var commonCalculation = total - lineHeights[0];
430
+ var offsetResult = 0;
431
+ switch(this.textVerticalAlign){
432
+ case EFFECTS.spec.TextVerticalAlign.top:
433
+ offsetResult = baseOffset + offsetY;
434
+ break;
435
+ case EFFECTS.spec.TextVerticalAlign.middle:
436
+ offsetResult = (this.height * fontScale - total) / 2 + baseOffset;
437
+ break;
438
+ case EFFECTS.spec.TextVerticalAlign.bottom:
439
+ offsetResult = this.height * fontScale - commonCalculation - offsetY;
440
+ break;
441
+ }
442
+ return offsetResult;
443
+ };
444
+ /**
445
+ * 富文本横向对齐计算
446
+ * @param style - 字体样式
447
+ * @param maxWidth - 文本框最大宽度
448
+ * @param contentW - 文本实际宽度
449
+ * @returns 水平偏移量
450
+ */ _proto.getOffsetXRich = function getOffsetXRich(style, maxWidth, contentW) {
451
+ switch(this.textAlign){
452
+ case EFFECTS.spec.TextAlignment.left:
453
+ return style.outlineWidth;
454
+ case EFFECTS.spec.TextAlignment.middle:
455
+ return (maxWidth - contentW) / 2;
456
+ case EFFECTS.spec.TextAlignment.right:
457
+ return maxWidth - contentW;
458
+ default:
459
+ return 0;
460
+ }
461
+ };
462
+ _proto.setSize = function setSize(width, height) {
463
+ this.width = width;
464
+ this.height = height;
465
+ };
466
+ return RichTextLayout;
467
+ }();
468
+
356
469
  /**
357
470
  * 将颜色名称转换为 RGBA
358
471
  * @param colorName - 颜色名称
@@ -425,31 +538,620 @@ typeof SuppressedError === "function" ? SuppressedError : function _SuppressedEr
425
538
  }
426
539
  }
427
540
 
541
+ /**
542
+ * 富文本换行禁用策略
543
+ * 实现逻辑:仅基于\n换行,无自动换行
544
+ */ var RichWrapDisabledStrategy = /*#__PURE__*/ function() {
545
+ function RichWrapDisabledStrategy() {}
546
+ var _proto = RichWrapDisabledStrategy.prototype;
547
+ _proto.computeLines = function computeLines(processedOptions, context, style, layout, singleLineHeight, fontScale, letterSpace, scaleFactor) {
548
+ var _this = this;
549
+ var lines = [];
550
+ var baselines = [];
551
+ var gapPx = (layout.lineHeight || 0) * fontScale;
552
+ var currentLine = this.createNewLine();
553
+ var maxLineWidth = 0;
554
+ var totalHeight = 0;
555
+ var finishCurrentLine = function() {
556
+ if (currentLine.chars.length === 0) {
557
+ return;
558
+ }
559
+ // 第1行用真实首行高度,其余行用 gapPx
560
+ currentLine.lineHeight = lines.length === 0 ? (currentLine.lineAscent || 0) + (currentLine.lineDescent || 0) : gapPx;
561
+ // 记录本行基线
562
+ var baseline = lines.length === 0 ? 0 : baselines[baselines.length - 1] + gapPx;
563
+ baselines.push(baseline);
564
+ totalHeight += currentLine.lineHeight;
565
+ lines.push(currentLine);
566
+ maxLineWidth = Math.max(maxLineWidth, currentLine.width);
567
+ currentLine = _this.createNewLine();
568
+ };
569
+ processedOptions.forEach(function(options) {
570
+ var text = options.text, isNewLine = options.isNewLine, fontSize = options.fontSize;
571
+ if (isNewLine) {
572
+ // 先结束上一行
573
+ finishCurrentLine();
574
+ }
575
+ // 用当前片段字体(权重/家族)设置测量字体
576
+ var fontStyle = options.fontStyle || style.fontStyle || "normal";
577
+ context.font = fontStyle + " " + (options.fontWeight || style.textWeight) + " 10px " + (options.fontFamily || style.fontFamily);
578
+ // 记录段起始 x
579
+ currentLine.offsetX.push(currentLine.width);
580
+ // 逐字宽度和高度测量(asc/desc 测量)
581
+ var segmentInnerX = 0;
582
+ var charArr = [];
583
+ var lineAscent = 0;
584
+ var lineDescent = 0;
585
+ for(var i = 0; i < text.length; i++){
586
+ var ch = text[i];
587
+ var m = context.measureText(ch);
588
+ var w = m.width;
589
+ var charWidth = (w <= 0 ? 0 : w) * fontSize * scaleFactor * fontScale;
590
+ // 测量 asc/desc 并按目标字号缩放
591
+ var scale = fontSize * fontScale * scaleFactor;
592
+ var asc = m.actualBoundingBoxAscent * scale;
593
+ var desc = m.actualBoundingBoxDescent * scale;
594
+ lineAscent = Math.max(lineAscent, asc);
595
+ lineDescent = Math.max(lineDescent, desc);
596
+ if (i > 0) {
597
+ segmentInnerX += letterSpace; // 先加"前一个字符与当前字符之间"的间距
598
+ }
599
+ charArr.push({
600
+ char: ch,
601
+ x: segmentInnerX
602
+ });
603
+ segmentInnerX += charWidth;
604
+ }
605
+ currentLine.chars.push(charArr);
606
+ currentLine.width += segmentInnerX;
607
+ currentLine.richOptions.push(options);
608
+ // 累计行级 asc/desc
609
+ currentLine.lineAscent = Math.max(currentLine.lineAscent || 0, lineAscent);
610
+ currentLine.lineDescent = Math.max(currentLine.lineDescent || 0, lineDescent);
611
+ });
612
+ // 结束最后一行
613
+ finishCurrentLine();
614
+ // 计算 bbox
615
+ var bboxTop = Infinity;
616
+ var bboxBottom = -Infinity;
617
+ if (lines.length === 0) {
618
+ return {
619
+ lines: lines,
620
+ maxLineWidth: maxLineWidth,
621
+ totalHeight: totalHeight,
622
+ bboxTop: 0,
623
+ bboxBottom: 0,
624
+ bboxHeight: 0
625
+ };
626
+ }
627
+ for(var i = 0; i < lines.length; i++){
628
+ bboxTop = Math.min(bboxTop, baselines[i] - (lines[i].lineAscent || 0));
629
+ bboxBottom = Math.max(bboxBottom, baselines[i] + (lines[i].lineDescent || 0));
630
+ }
631
+ var bboxHeight = bboxBottom - bboxTop;
632
+ return {
633
+ lines: lines,
634
+ maxLineWidth: maxLineWidth,
635
+ totalHeight: totalHeight,
636
+ bboxTop: bboxTop,
637
+ bboxBottom: bboxBottom,
638
+ bboxHeight: bboxHeight
639
+ };
640
+ };
641
+ /**
642
+ * 创建新行
643
+ */ _proto.createNewLine = function createNewLine() {
644
+ return {
645
+ richOptions: [],
646
+ offsetX: [],
647
+ width: 0,
648
+ lineHeight: 0,
649
+ offsetY: 0,
650
+ chars: [],
651
+ lineAscent: 0,
652
+ lineDescent: 0
653
+ };
654
+ };
655
+ return RichWrapDisabledStrategy;
656
+ }();
657
+
658
+ /**
659
+ * 富文本自动换行策略
660
+ * 实现逻辑:基于\n换行及自动换行
661
+ */ var RichWrapEnabledStrategy = /*#__PURE__*/ function() {
662
+ function RichWrapEnabledStrategy() {}
663
+ var _proto = RichWrapEnabledStrategy.prototype;
664
+ _proto.computeLines = function computeLines(processedOptions, context, style, layout, singleLineHeight, fontScale, letterSpace, scaleFactor) {
665
+ var _this = this;
666
+ var lines = [];
667
+ var baselines = [];
668
+ var gapPx = (layout.lineHeight || 0) * fontScale;
669
+ var currentLine = this.createNewLine();
670
+ var maxLineWidth = 0;
671
+ var totalHeight = 0;
672
+ // 切块缓冲变量
673
+ var segStartX = null;
674
+ var segmentInnerX = 0;
675
+ var chunkChars = [];
676
+ var chunkOptions = null; // 跟踪当前切块所属options
677
+ // 结束当前行(含缓冲切块)
678
+ var finishCurrentLine = function() {
679
+ flushChunk();
680
+ if (currentLine.chars.length === 0) {
681
+ return;
682
+ }
683
+ // 第1行用真实首行高度,其余行用 gapPx
684
+ currentLine.lineHeight = lines.length === 0 ? (currentLine.lineAscent || 0) + (currentLine.lineDescent || 0) : gapPx;
685
+ // 记录本行基线
686
+ var baseline = lines.length === 0 ? 0 : baselines[baselines.length - 1] + gapPx;
687
+ baselines.push(baseline);
688
+ totalHeight += currentLine.lineHeight;
689
+ lines.push(currentLine);
690
+ maxLineWidth = Math.max(maxLineWidth, currentLine.width);
691
+ currentLine = _this.createNewLine();
692
+ segStartX = null;
693
+ segmentInnerX = 0;
694
+ chunkChars = [];
695
+ chunkOptions = null;
696
+ };
697
+ // 刷新当前切块
698
+ var flushChunk = function() {
699
+ if (chunkChars.length === 0) {
700
+ return;
701
+ }
702
+ if (segStartX === null) {
703
+ segStartX = currentLine.width;
704
+ }
705
+ currentLine.offsetX.push(segStartX);
706
+ currentLine.chars.push(chunkChars);
707
+ if (chunkOptions) {
708
+ currentLine.richOptions.push(chunkOptions);
709
+ }
710
+ // 重置缓冲
711
+ segStartX = null;
712
+ segmentInnerX = 0;
713
+ chunkChars = [];
714
+ chunkOptions = null;
715
+ };
716
+ processedOptions.forEach(function(options) {
717
+ var text = options.text, isNewLine = options.isNewLine, fontSize = options.fontSize;
718
+ // 设置测量字体(包含fontStyle)
719
+ var fontStyle = options.fontStyle || style.fontStyle || "normal";
720
+ context.font = fontStyle + " " + (options.fontWeight || style.textWeight) + " 10px " + (options.fontFamily || style.fontFamily);
721
+ // 显式换行符优先处理
722
+ if (isNewLine) {
723
+ flushChunk();
724
+ finishCurrentLine();
725
+ }
726
+ // 逐字符处理
727
+ for(var i = 0; i < text.length; i++){
728
+ var ch = text[i];
729
+ // 获取基础宽度并计算实际宽度(动态缩放)
730
+ var m = context.measureText(ch);
731
+ var baseW = m.width;
732
+ var charWidth = (baseW <= 0 ? 0 : baseW) * fontSize * scaleFactor * fontScale;
733
+ // 测量 asc/desc 并按目标字号缩放
734
+ var scale = fontSize * fontScale * scaleFactor;
735
+ var asc = m.actualBoundingBoxAscent * scale;
736
+ var desc = m.actualBoundingBoxDescent * scale;
737
+ // 计算预期宽度(包含字符间距)
738
+ var spacing = chunkChars.length > 0 ? letterSpace : 0;
739
+ var willWidth = currentLine.width + spacing + charWidth;
740
+ // 自动换行判断
741
+ if (willWidth > (layout.maxTextWidth || Infinity)) {
742
+ flushChunk();
743
+ finishCurrentLine();
744
+ }
745
+ // 初始化切块起点和所属options
746
+ if (segStartX === null) {
747
+ segStartX = currentLine.width;
748
+ chunkOptions = options; // 绑定当前切块到options
749
+ }
750
+ // 添加字符间距(非首字符)
751
+ if (chunkChars.length > 0) {
752
+ segmentInnerX += letterSpace;
753
+ currentLine.width += letterSpace;
754
+ }
755
+ // 添加字符到切块(x为切块内相对坐标)
756
+ chunkChars.push({
757
+ char: ch,
758
+ x: segmentInnerX
759
+ });
760
+ // 累计行级 asc/desc
761
+ currentLine.lineAscent = Math.max(currentLine.lineAscent || 0, asc);
762
+ currentLine.lineDescent = Math.max(currentLine.lineDescent || 0, desc);
763
+ // 更新位置和宽度
764
+ segmentInnerX += charWidth;
765
+ currentLine.width += charWidth;
766
+ }
767
+ // 文本段结束,落盘当前切块
768
+ flushChunk();
769
+ });
770
+ // 结束最后一行
771
+ finishCurrentLine();
772
+ // 计算 bbox
773
+ var bboxTop = Infinity;
774
+ var bboxBottom = -Infinity;
775
+ for(var i = 0; i < lines.length; i++){
776
+ bboxTop = Math.min(bboxTop, baselines[i] - (lines[i].lineAscent || 0));
777
+ bboxBottom = Math.max(bboxBottom, baselines[i] + (lines[i].lineDescent || 0));
778
+ }
779
+ var bboxHeight = bboxBottom - bboxTop;
780
+ return {
781
+ lines: lines,
782
+ maxLineWidth: maxLineWidth,
783
+ totalHeight: totalHeight,
784
+ bboxTop: bboxTop,
785
+ bboxBottom: bboxBottom,
786
+ bboxHeight: bboxHeight
787
+ };
788
+ };
789
+ /**
790
+ * 创建新行
791
+ */ _proto.createNewLine = function createNewLine() {
792
+ return {
793
+ richOptions: [],
794
+ offsetX: [],
795
+ width: 0,
796
+ lineHeight: 0,
797
+ offsetY: 0,
798
+ chars: [],
799
+ lineAscent: 0,
800
+ lineDescent: 0
801
+ };
802
+ };
803
+ return RichWrapEnabledStrategy;
804
+ }();
805
+
806
+ /**
807
+ * 富文本 Display 溢出策略
808
+ * 在溢出策略中对所有几何量进行一次性缩放
809
+ */ var RichDisplayOverflowStrategy = /*#__PURE__*/ function() {
810
+ function RichDisplayOverflowStrategy() {}
811
+ var _proto = RichDisplayOverflowStrategy.prototype;
812
+ _proto.apply = function apply(lines, sizeResult, layout, style) {
813
+ // 安全处理除零情况
814
+ var safeDiv = function(a, b) {
815
+ return Math.abs(b) > 1e-5 ? a / b : 1;
816
+ };
817
+ var availableW = Math.max(1, layout.maxTextWidth || sizeResult.canvasWidth);
818
+ var availableH = Math.max(1, layout.maxTextHeight || sizeResult.canvasHeight);
819
+ var _sizeResult_contentWidth;
820
+ var contentW = Math.max(1, (_sizeResult_contentWidth = sizeResult.contentWidth) != null ? _sizeResult_contentWidth : sizeResult.canvasWidth);
821
+ var _sizeResult_bboxHeight;
822
+ var contentH = Math.max(1, (_sizeResult_bboxHeight = sizeResult.bboxHeight) != null ? _sizeResult_bboxHeight : sizeResult.canvasHeight);
823
+ // 只缩小不放大
824
+ var s = Math.min(1, safeDiv(availableW, contentW), safeDiv(availableH, contentH));
825
+ // 浮点精度处理
826
+ if (s > 0.9999) {
827
+ return {
828
+ globalScale: 1
829
+ };
830
+ }
831
+ // 统一缩放所有几何量
832
+ for(var _iterator = _create_for_of_iterator_helper_loose(lines), _step; !(_step = _iterator()).done;){
833
+ var line = _step.value;
834
+ line.width *= s;
835
+ line.lineHeight *= s; // 缩小行距(你的 gap-only 模式行高=gapPx)
836
+ if (line.offsetX) {
837
+ for(var i = 0; i < line.offsetX.length; i++){
838
+ line.offsetX[i] *= s;
839
+ }
840
+ }
841
+ for(var _iterator1 = _create_for_of_iterator_helper_loose(line.chars || []), _step1; !(_step1 = _iterator1()).done;){
842
+ var seg = _step1.value;
843
+ for(var _iterator2 = _create_for_of_iterator_helper_loose(seg), _step2; !(_step2 = _iterator2()).done;){
844
+ var ch = _step2.value;
845
+ ch.x *= s;
846
+ }
847
+ }
848
+ for(var _iterator3 = _create_for_of_iterator_helper_loose(line.richOptions || []), _step3; !(_step3 = _iterator3()).done;){
849
+ var opt = _step3.value;
850
+ opt.fontSize *= s; // 缩小字形
851
+ }
852
+ // 同步缩放 asc/desc
853
+ if (line.lineAscent != null) {
854
+ line.lineAscent *= s;
855
+ }
856
+ if (line.lineDescent != null) {
857
+ line.lineDescent *= s;
858
+ }
859
+ }
860
+ return {
861
+ globalScale: s
862
+ };
863
+ };
864
+ return RichDisplayOverflowStrategy;
865
+ }();
866
+
867
+ /**
868
+ * Clip 溢出策略
869
+ * 超出画布部分自然裁切
870
+ */ var RichClippedOverflowStrategy = /*#__PURE__*/ function() {
871
+ function RichClippedOverflowStrategy() {}
872
+ var _proto = RichClippedOverflowStrategy.prototype;
873
+ _proto.apply = function apply(lines, sizeResult, layout, style) {
874
+ // 不进行任何缩放,直接返回单位缩放系数
875
+ return {
876
+ globalScale: 1
877
+ };
878
+ };
879
+ return RichClippedOverflowStrategy;
880
+ }();
881
+
882
+ /**
883
+ * Visible 溢出策略
884
+ * 允许内容超出画布可见
885
+ */ var RichVisibleOverflowStrategy = /*#__PURE__*/ function() {
886
+ function RichVisibleOverflowStrategy() {}
887
+ var _proto = RichVisibleOverflowStrategy.prototype;
888
+ _proto.apply = function apply(lines, sizeResult, layout, style) {
889
+ // 不进行任何缩放或裁剪
890
+ return {
891
+ globalScale: 1
892
+ };
893
+ };
894
+ return RichVisibleOverflowStrategy;
895
+ }();
896
+
897
+ /**
898
+ * 富文本水平对齐策略
899
+ * 直接使用已缩放的行宽计算偏移量
900
+ */ var RichHorizontalAlignStrategyImpl = /*#__PURE__*/ function() {
901
+ function RichHorizontalAlignStrategyImpl() {}
902
+ var _proto = RichHorizontalAlignStrategyImpl.prototype;
903
+ _proto.getHorizontalOffsets = function getHorizontalOffsets(lines, sizeResult, overflowResult, layout, style) {
904
+ var frameW = layout.maxTextWidth;
905
+ var compX = sizeResult.baselineCompensationX || 0;
906
+ // 统一用 frame 宽做容器
907
+ var baseOffsets = lines.map(function(line) {
908
+ return layout.getOffsetXRich(style, frameW, line.width);
909
+ });
910
+ // 仅 visible 叠加水平补偿,clip/display 不加
911
+ var lineOffsets = layout.overflow === EFFECTS.spec.TextOverflow.visible ? baseOffsets.map(function(x) {
912
+ return x + compX;
913
+ }) : baseOffsets;
914
+ return {
915
+ lineOffsets: lineOffsets
916
+ };
917
+ };
918
+ return RichHorizontalAlignStrategyImpl;
919
+ }();
920
+
921
+ /**
922
+ * 富文本垂直对齐策略
923
+ * 直接使用已缩放的行高
924
+ */ var RichVerticalAlignStrategyImpl = /*#__PURE__*/ function() {
925
+ function RichVerticalAlignStrategyImpl() {}
926
+ var _proto = RichVerticalAlignStrategyImpl.prototype;
927
+ _proto.getVerticalOffsets = function getVerticalOffsets(lines, sizeResult, overflowResult, layout, style, singleLineHeight) {
928
+ var lineHeights = lines.map(function(line) {
929
+ return line.lineHeight;
930
+ });
931
+ var compY = sizeResult.baselineCompensationY || 0;
932
+ var baselineY = 0;
933
+ if (lines.length === 0) {
934
+ return {
935
+ baselineY: 0,
936
+ lineYOffsets: []
937
+ };
938
+ }
939
+ switch(layout.overflow){
940
+ case EFFECTS.spec.TextOverflow.visible:
941
+ {
942
+ // frame-based 计算
943
+ var frameH = layout.maxTextHeight;
944
+ var _sizeResult_bboxTop;
945
+ var bboxTop = (_sizeResult_bboxTop = sizeResult.bboxTop) != null ? _sizeResult_bboxTop : 0;
946
+ var _sizeResult_bboxHeight, _sizeResult_bboxBottom;
947
+ var bboxBottom = (_sizeResult_bboxBottom = sizeResult.bboxBottom) != null ? _sizeResult_bboxBottom : bboxTop + ((_sizeResult_bboxHeight = sizeResult.bboxHeight) != null ? _sizeResult_bboxHeight : 0);
948
+ var _sizeResult_bboxHeight1;
949
+ var bboxHeight = (_sizeResult_bboxHeight1 = sizeResult.bboxHeight) != null ? _sizeResult_bboxHeight1 : bboxBottom - bboxTop;
950
+ // 计算 frame 基线
951
+ var baselineYFrame = 0;
952
+ switch(layout.textVerticalAlign){
953
+ case EFFECTS.spec.TextVerticalAlign.top:
954
+ baselineYFrame = -bboxTop;
955
+ break;
956
+ case EFFECTS.spec.TextVerticalAlign.middle:
957
+ baselineYFrame = (frameH - bboxHeight) / 2 - bboxTop;
958
+ break;
959
+ case EFFECTS.spec.TextVerticalAlign.bottom:
960
+ baselineYFrame = frameH - bboxHeight - bboxTop;
961
+ break;
962
+ }
963
+ baselineY = baselineYFrame + compY; // 关键:叠加"向下移动 E"
964
+ break;
965
+ }
966
+ case EFFECTS.spec.TextOverflow.clip:
967
+ {
968
+ var firstLine = lines[0];
969
+ if (firstLine) {
970
+ var _Math;
971
+ var richSizes = firstLine.richOptions.map(function(o) {
972
+ return o.fontSize;
973
+ });
974
+ var firstMax = (_Math = Math).max.apply(_Math, [].concat(richSizes.length ? richSizes : [
975
+ style.fontSize
976
+ ]));
977
+ var fontSizeForOffset = firstMax * style.fontScale * singleLineHeight;
978
+ baselineY = layout.getOffsetYRich(style, lineHeights, fontSizeForOffset) + compY;
979
+ } else {
980
+ baselineY = layout.getOffsetYRich(style, lineHeights, style.fontSize * style.fontScale) + compY;
981
+ }
982
+ break;
983
+ }
984
+ case EFFECTS.spec.TextOverflow.display:
985
+ {
986
+ // display 垂直对齐改为基于 bbox,而不是 getOffsetYRich
987
+ var frameH1 = layout.maxTextHeight;
988
+ // 用缩放后的行数据重建 baselines 和 bbox
989
+ var baselines = [
990
+ 0
991
+ ];
992
+ for(var i = 1; i < lines.length; i++){
993
+ baselines[i] = baselines[i - 1] + lines[i].lineHeight;
994
+ }
995
+ // 计算 bboxTop / bboxBottom(使用行的测量值 lineAscent/lineDescent)
996
+ var bboxTop1 = Infinity;
997
+ var bboxBottom1 = -Infinity;
998
+ for(var i1 = 0; i1 < lines.length; i1++){
999
+ var _lines_i_lineAscent;
1000
+ var asc = (_lines_i_lineAscent = lines[i1].lineAscent) != null ? _lines_i_lineAscent : 0;
1001
+ var _lines_i_lineDescent;
1002
+ var desc = (_lines_i_lineDescent = lines[i1].lineDescent) != null ? _lines_i_lineDescent : 0;
1003
+ bboxTop1 = Math.min(bboxTop1, baselines[i1] - asc);
1004
+ bboxBottom1 = Math.max(bboxBottom1, baselines[i1] + desc);
1005
+ }
1006
+ var bboxHeight1 = bboxBottom1 - bboxTop1;
1007
+ // 计算 display 模式的基线
1008
+ var baselineDisplayY = 0;
1009
+ switch(layout.textVerticalAlign){
1010
+ case EFFECTS.spec.TextVerticalAlign.top:
1011
+ baselineDisplayY = -bboxTop1;
1012
+ break;
1013
+ case EFFECTS.spec.TextVerticalAlign.middle:
1014
+ baselineDisplayY = (frameH1 - bboxHeight1) / 2 - bboxTop1;
1015
+ break;
1016
+ case EFFECTS.spec.TextVerticalAlign.bottom:
1017
+ baselineDisplayY = frameH1 - bboxHeight1 - bboxTop1;
1018
+ break;
1019
+ }
1020
+ // 后续 lineYOffsets 保持按行高累计
1021
+ var lineYOffsets = [];
1022
+ var currentY = baselineDisplayY;
1023
+ for(var i2 = 0; i2 < lines.length; i2++){
1024
+ lineYOffsets.push(currentY);
1025
+ if (i2 < lines.length - 1) {
1026
+ currentY += lines[i2 + 1].lineHeight;
1027
+ }
1028
+ }
1029
+ return {
1030
+ baselineY: baselineDisplayY,
1031
+ lineYOffsets: lineYOffsets
1032
+ };
1033
+ }
1034
+ }
1035
+ // 下面行偏移保持不变
1036
+ var lineYOffsets1 = [];
1037
+ var currentY1 = baselineY;
1038
+ lines.forEach(function(line, index) {
1039
+ lineYOffsets1.push(currentY1);
1040
+ if (index < lines.length - 1) {
1041
+ currentY1 += lines[index + 1].lineHeight;
1042
+ }
1043
+ });
1044
+ return {
1045
+ baselineY: baselineY,
1046
+ lineYOffsets: lineYOffsets1
1047
+ };
1048
+ };
1049
+ return RichVerticalAlignStrategyImpl;
1050
+ }();
1051
+
1052
+ /**
1053
+ * 富文本策略工厂
1054
+ * 负责创建各种策略实例
1055
+ */ var RichTextStrategyFactory = /*#__PURE__*/ function() {
1056
+ function RichTextStrategyFactory() {}
1057
+ /**
1058
+ * 创建换行策略
1059
+ * 根据wrapEnabled参数决定使用哪种策略
1060
+ */ RichTextStrategyFactory.createWrapStrategy = function createWrapStrategy(wrapEnabled) {
1061
+ if (wrapEnabled) {
1062
+ return new RichWrapEnabledStrategy();
1063
+ } else {
1064
+ return new RichWrapDisabledStrategy();
1065
+ }
1066
+ };
1067
+ /**
1068
+ * 创建溢出策略
1069
+ * 支持三种模式:clip(裁切)、display(行级缩放)、visible(不缩放不裁剪)
1070
+ */ RichTextStrategyFactory.createOverflowStrategy = function createOverflowStrategy(mode) {
1071
+ switch(mode){
1072
+ case EFFECTS.spec.TextOverflow.clip:
1073
+ return new RichClippedOverflowStrategy();
1074
+ case EFFECTS.spec.TextOverflow.display:
1075
+ return new RichDisplayOverflowStrategy();
1076
+ case EFFECTS.spec.TextOverflow.visible:
1077
+ default:
1078
+ return new RichVisibleOverflowStrategy();
1079
+ }
1080
+ };
1081
+ /**
1082
+ * 创建水平对齐策略
1083
+ */ RichTextStrategyFactory.createHorizontalAlignStrategy = function createHorizontalAlignStrategy() {
1084
+ return new RichHorizontalAlignStrategyImpl();
1085
+ };
1086
+ /**
1087
+ * 创建垂直对齐策略
1088
+ */ RichTextStrategyFactory.createVerticalAlignStrategy = function createVerticalAlignStrategy() {
1089
+ return new RichVerticalAlignStrategyImpl();
1090
+ };
1091
+ return RichTextStrategyFactory;
1092
+ }();
1093
+
428
1094
  var seed = 0;
429
- exports.RichTextComponent = /*#__PURE__*/ function(TextComponent) {
430
- _inherits(RichTextComponent, TextComponent);
1095
+ exports.RichTextComponent = /*#__PURE__*/ function(MaskableGraphic) {
1096
+ _inherits(RichTextComponent, MaskableGraphic);
431
1097
  function RichTextComponent(engine) {
432
1098
  var _this;
433
- _this = TextComponent.call(this, engine) || this;
1099
+ _this = MaskableGraphic.call(this, engine) || this;
1100
+ _this.isDirty = true;
1101
+ _this.text = "";
434
1102
  _this.processedTextOptions = [];
435
- // 字体高度的倍数(字体高度上下多出来的部分就是行间距)
436
1103
  _this.singleLineHeight = 1.571;
437
1104
  _this.size = null;
438
- /**
439
- * 获取第一次渲染的 size
440
- */ _this.initialized = false;
441
- /**
442
- * canvas 大小
443
- */ _this.canvasSize = null;
1105
+ _this.initialized = false;
1106
+ _this.canvasSize = null;
1107
+ _this.SCALE_FACTOR = 0.1;
1108
+ _this.ALPHA_FIX_VALUE = 1 / 255;
444
1109
  _this.name = "MRichText" + seed++;
1110
+ _this.initTextBase(engine);
1111
+ // 延迟初始化策略,等到textLayout被赋值后再初始化
1112
+ _this.richWrapStrategy = RichTextStrategyFactory.createWrapStrategy();
1113
+ _this.richOverflowStrategy = RichTextStrategyFactory.createOverflowStrategy(EFFECTS.spec.TextOverflow.display);
1114
+ _this.richHorizontalAlignStrategy = RichTextStrategyFactory.createHorizontalAlignStrategy();
1115
+ _this.richVerticalAlignStrategy = RichTextStrategyFactory.createVerticalAlignStrategy();
445
1116
  return _this;
446
1117
  }
447
1118
  var _proto = RichTextComponent.prototype;
1119
+ _proto.onUpdate = function onUpdate(dt) {
1120
+ MaskableGraphic.prototype.onUpdate.call(this, dt);
1121
+ this.updateTexture();
1122
+ };
1123
+ _proto.onDestroy = function onDestroy() {
1124
+ MaskableGraphic.prototype.onDestroy.call(this);
1125
+ this.disposeTextTexture();
1126
+ };
1127
+ _proto.fromData = function fromData(data) {
1128
+ MaskableGraphic.prototype.fromData.call(this, data);
1129
+ var interaction = data.interaction, options = data.options;
1130
+ this.interaction = interaction;
1131
+ this.textStyle = new EFFECTS.TextStyle(options);
1132
+ this.textLayout = new RichTextLayout(options);
1133
+ this.text = options.text ? options.text.toString() : " ";
1134
+ if (this.textLayout.useLegacyRichText) {
1135
+ this.textLayout.textVerticalAlign = EFFECTS.spec.TextVerticalAlign.middle;
1136
+ }
1137
+ this.updateStrategies();
1138
+ this.renderText(options);
1139
+ // 设置默认颜色(math.Color)
1140
+ this.material.setColor("_Color", new EFFECTS.math.Color(1, 1, 1, 1));
1141
+ };
1142
+ /**
1143
+ * 使用策略结果绘制文本
1144
+ */ _proto.updateStrategies = function updateStrategies() {
1145
+ var layout = this.textLayout;
1146
+ if (layout) {
1147
+ this.richWrapStrategy = RichTextStrategyFactory.createWrapStrategy(layout.wrapEnabled);
1148
+ this.richOverflowStrategy = RichTextStrategyFactory.createOverflowStrategy(layout.overflow);
1149
+ }
1150
+ };
448
1151
  _proto.generateTextProgram = function generateTextProgram(text) {
449
1152
  var _this = this;
450
1153
  this.processedTextOptions = [];
451
1154
  var program = generateProgram(function(text, context) {
452
- // 如果富文本仅包含换行符,则在每个换行符后添加一个空格
453
1155
  if (/^\n+$/.test(text)) {
454
1156
  text = text.replace(/\n/g, "\n ");
455
1157
  }
@@ -480,48 +1182,64 @@ exports.RichTextComponent = /*#__PURE__*/ function(TextComponent) {
480
1182
  });
481
1183
  program(text);
482
1184
  };
1185
+ _proto.updateWithOptions = function updateWithOptions(options) {
1186
+ this.textStyle = new EFFECTS.TextStyle(options);
1187
+ this.textLayout = new RichTextLayout(options);
1188
+ this.text = options.text ? options.text.toString() : " ";
1189
+ // TextLayout 构造函数已经正确处理了 textVerticalAlign,这里不需要再设置
1190
+ if (this.textLayout.useLegacyRichText) {
1191
+ this.textLayout.textVerticalAlign = EFFECTS.spec.TextVerticalAlign.middle;
1192
+ }
1193
+ this.updateStrategies();
1194
+ this.isDirty = true;
1195
+ };
1196
+ _proto.renderText = function renderText(options) {
1197
+ var size = options.size;
1198
+ if (size) {
1199
+ this.canvasSize = new EFFECTS.math.Vector2(size[0], size[1]);
1200
+ }
1201
+ this.updateTexture();
1202
+ };
483
1203
  _proto.updateTexture = function updateTexture(flipY) {
484
1204
  if (flipY === void 0) flipY = true;
485
- if (!this.isDirty || !this.context || !this.canvas) {
1205
+ if (!this.isDirty || !this.context || !this.canvas || !this.textStyle || !this.textLayout) {
486
1206
  return;
487
1207
  }
488
- // 根据 useLegacyRichText 字段来判断使用哪种渲染模式
489
- var useLegacy = this.textLayout.useLegacyRichText === true;
1208
+ var layout = this.textLayout;
1209
+ var useLegacy = layout.useLegacyRichText === true;
490
1210
  this.singleLineHeight = useLegacy ? 1.571 : 1.0;
1211
+ // 根据useLegacyRichText字段来判断使用哪种渲染模式
491
1212
  if (useLegacy) {
492
1213
  this.updateTextureLegacy(flipY);
493
1214
  } else {
494
- this.updateTextureModern(flipY);
1215
+ this.updateTextureWithStrategies(flipY);
495
1216
  }
496
1217
  };
497
- _proto.updateTextureLegacy = function updateTextureLegacy(flipY) {
1218
+ /**
1219
+ * 解析富文本
1220
+ */ _proto.updateTextureLegacy = function updateTextureLegacy(flipY) {
498
1221
  var _this = this;
499
- if (!this.isDirty || !this.context || !this.canvas) {
1222
+ if (!this.isDirty || !this.context || !this.canvas || !this.textStyle) {
500
1223
  return;
501
1224
  }
502
- // 解析富文本
503
1225
  this.generateTextProgram(this.text);
504
- var _this1 = this, textLayout = _this1.textLayout, textStyle = _this1.textStyle;
505
- var overflow = textLayout.overflow, _textLayout_letterSpace = textLayout.letterSpace, letterSpace = _textLayout_letterSpace === void 0 ? 0 : _textLayout_letterSpace;
1226
+ var width = 0, height = 0;
1227
+ var layout = this.textLayout;
1228
+ var textStyle = this.textStyle;
1229
+ var overflow = layout.overflow, _layout_letterSpace = layout.letterSpace, letterSpace = _layout_letterSpace === void 0 ? 0 : _layout_letterSpace;
506
1230
  var context = this.context;
507
- var width = 0;
508
- var height = 0;
509
- context.save();
510
1231
  var charsInfo = [];
511
- var fontHeight = textStyle.fontSize * this.textStyle.fontScale;
1232
+ var fontHeight = textStyle.fontSize * textStyle.fontScale;
512
1233
  var charInfo = {
513
1234
  richOptions: [],
514
1235
  offsetX: [],
515
1236
  width: 0,
516
- // 包括字体和上下行间距的高度
517
1237
  lineHeight: fontHeight * this.singleLineHeight,
518
- // 字体偏移高度(也就是行间距)
519
1238
  offsetY: fontHeight * (this.singleLineHeight - 1) / 2
520
1239
  };
521
1240
  // 遍历解析后的文本选项
522
1241
  this.processedTextOptions.forEach(function(options) {
523
1242
  var text = options.text, isNewLine = options.isNewLine, fontSize = options.fontSize;
524
- // 如果是新行,则将之前行的信息存入 charsInfo 并且初始化新行的 charInfo
525
1243
  if (isNewLine) {
526
1244
  charsInfo.push(charInfo);
527
1245
  width = Math.max(width, charInfo.width);
@@ -532,12 +1250,9 @@ exports.RichTextComponent = /*#__PURE__*/ function(TextComponent) {
532
1250
  lineHeight: fontHeight * _this.singleLineHeight,
533
1251
  offsetY: fontHeight * (_this.singleLineHeight - 1) / 2
534
1252
  };
535
- // 管理行的总高度调整 canvas 尺寸
536
1253
  height += charInfo.lineHeight;
537
1254
  }
538
- // 恢复默认设置
539
1255
  context.font = (options.fontWeight || textStyle.textWeight) + " 10px " + (options.fontFamily || textStyle.fontFamily);
540
- // 计算得到每个字段的宽度 textWidth
541
1256
  var textMetrics = context.measureText(text);
542
1257
  var textWidth = textMetrics.width;
543
1258
  if (textMetrics.actualBoundingBoxLeft !== undefined && textMetrics.actualBoundingBoxRight !== undefined) {
@@ -546,32 +1261,28 @@ exports.RichTextComponent = /*#__PURE__*/ function(TextComponent) {
546
1261
  textWidth = Math.max(textWidth, actualWidth);
547
1262
  }
548
1263
  }
549
- var textHeight = fontSize * _this.singleLineHeight * _this.textStyle.fontScale;
1264
+ var textHeight = fontSize * _this.singleLineHeight * textStyle.fontScale;
550
1265
  if (textHeight > charInfo.lineHeight) {
551
1266
  height += textHeight - charInfo.lineHeight;
552
1267
  charInfo.lineHeight = textHeight;
553
- charInfo.offsetY = fontSize * _this.textStyle.fontScale * (_this.singleLineHeight - 1) / 2;
1268
+ charInfo.offsetY = fontSize * textStyle.fontScale * (_this.singleLineHeight - 1) / 2;
554
1269
  }
555
1270
  charInfo.offsetX.push(charInfo.width);
556
- // 计算字段宽度*富文本字体大小*缩放因子*整体文本大小+每个字符的间距(每个字符间距存疑,因为实际测量的宽度已经包含了间距)
557
- charInfo.width += (textWidth <= 0 ? 0 : textWidth) * fontSize * _this.SCALE_FACTOR * _this.textStyle.fontScale + text.length * letterSpace;
558
- // 将富文本数据存入 charInfo
1271
+ charInfo.width += (textWidth <= 0 ? 0 : textWidth) * fontSize * _this.SCALE_FACTOR * textStyle.fontScale + text.length * letterSpace;
559
1272
  charInfo.richOptions.push(options);
560
1273
  });
561
- // 存储最后一行的字符信息,并且更新最终的宽度和高度用于确定 canvas 尺寸
562
1274
  charsInfo.push(charInfo);
563
1275
  width = Math.max(width, charInfo.width);
564
1276
  height += charInfo.lineHeight;
1277
+ // 存储最后一行的字符信息,并且更新最终的宽度和高度用于确定canvas尺寸
565
1278
  if (width === 0 || height === 0) {
566
1279
  this.isDirty = false;
567
- context.restore();
568
1280
  return;
569
1281
  }
570
1282
  if (this.size === undefined || this.size === null) {
571
1283
  this.size = this.item.transform.size.clone();
572
1284
  }
573
1285
  var _this_size = this.size, _this_size_x = _this_size.x, x = _this_size_x === void 0 ? 1 : _this_size_x, _this_size_y = _this_size.y, y = _this_size_y === void 0 ? 1 : _this_size_y;
574
- // 首次渲染时初始化 canvas 尺寸和组件变换
575
1286
  if (!this.initialized) {
576
1287
  this.canvasSize = !this.canvasSize ? new EFFECTS.math.Vector2(width, height) : this.canvasSize;
577
1288
  var _this_canvasSize = this.canvasSize, canvasWidth = _this_canvasSize.x, canvasHeight = _this_canvasSize.y;
@@ -581,318 +1292,327 @@ exports.RichTextComponent = /*#__PURE__*/ function(TextComponent) {
581
1292
  }
582
1293
  EFFECTS.assertExist(this.canvasSize);
583
1294
  var _this_canvasSize1 = this.canvasSize, canvasWidth1 = _this_canvasSize1.x, canvasHeight1 = _this_canvasSize1.y;
584
- this.textLayout.width = canvasWidth1 / textStyle.fontScale;
585
- this.textLayout.height = canvasHeight1 / textStyle.fontScale;
586
- this.canvas.width = canvasWidth1;
587
- this.canvas.height = canvasHeight1;
588
- context.clearRect(0, 0, canvasWidth1, canvasHeight1);
589
- // fix bug 1/255
590
- context.fillStyle = "rgba(255, 255, 255, " + this.ALPHA_FIX_VALUE + ")";
591
- if (!flipY) {
592
- context.translate(0, canvasHeight1);
593
- context.scale(1, -1);
594
- }
595
- if (charsInfo.length === 0) {
596
- context.restore();
597
- return;
598
- }
599
- var charsLineHeight = textLayout.getOffsetY(textStyle, charsInfo.length, fontHeight * this.singleLineHeight, textStyle.fontSize);
600
- charsInfo.forEach(function(charInfo, index) {
601
- var richOptions = charInfo.richOptions, offsetX = charInfo.offsetX, width = charInfo.width;
602
- var charWidth = width;
603
- var offset = offsetX;
604
- if (overflow === EFFECTS.spec.TextOverflow.display) {
605
- if (width > canvasWidth1) {
606
- var canvasScale = canvasWidth1 / width;
607
- charWidth *= canvasScale;
608
- offset = offsetX.map(function(x) {
609
- return x * canvasScale;
610
- });
611
- }
612
- }
613
- var x = _this.textLayout.getOffsetX(textStyle, charWidth);
614
- if (index > 0) {
615
- charsLineHeight += charInfo.lineHeight - charInfo.offsetY;
1295
+ layout.width = canvasWidth1 / textStyle.fontScale;
1296
+ layout.height = canvasHeight1 / textStyle.fontScale;
1297
+ this.renderToTexture(canvasWidth1, canvasHeight1, flipY, function(context) {
1298
+ if (charsInfo.length === 0) {
1299
+ return;
616
1300
  }
617
- richOptions.forEach(function(options, index) {
618
- var fontScale = textStyle.fontScale, textColor = textStyle.textColor, textFamily = textStyle.fontFamily, textWeight = textStyle.textWeight, richStyle = textStyle.fontStyle;
619
- var text = options.text, fontSize = options.fontSize, _options_fontColor = options.fontColor, fontColor = _options_fontColor === void 0 ? textColor : _options_fontColor, _options_fontFamily = options.fontFamily, fontFamily = _options_fontFamily === void 0 ? textFamily : _options_fontFamily, _options_fontWeight = options.fontWeight, fontWeight = _options_fontWeight === void 0 ? textWeight : _options_fontWeight, _options_fontStyle = options.fontStyle, fontStyle = _options_fontStyle === void 0 ? richStyle : _options_fontStyle;
620
- var textSize = fontSize;
1301
+ var charsLineHeight = layout.getOffsetY(textStyle, charsInfo.length, fontHeight * _this.singleLineHeight, textStyle.fontSize);
1302
+ charsInfo.forEach(function(charInfo, index) {
1303
+ var richOptions = charInfo.richOptions, offsetX = charInfo.offsetX, width = charInfo.width;
1304
+ var charWidth = width;
1305
+ var offset = offsetX;
621
1306
  if (overflow === EFFECTS.spec.TextOverflow.display) {
622
1307
  if (width > canvasWidth1) {
623
- textSize /= width / canvasWidth1;
1308
+ var canvasScale = canvasWidth1 / width;
1309
+ charWidth *= canvasScale;
1310
+ offset = offsetX.map(function(x) {
1311
+ return x * canvasScale;
1312
+ });
624
1313
  }
625
1314
  }
626
- var strOffsetX = offset[index] + x;
627
- context.font = fontStyle + " " + fontWeight + " " + textSize * fontScale + "px " + fontFamily;
628
- context.fillStyle = "rgba(" + fontColor[0] + ", " + fontColor[1] + ", " + fontColor[2] + ", " + fontColor[3] + ")";
629
- context.fillText(text, strOffsetX, charsLineHeight);
1315
+ var x = layout.getOffsetX(textStyle, charWidth);
1316
+ if (index > 0) {
1317
+ charsLineHeight += charInfo.lineHeight - charInfo.offsetY;
1318
+ }
1319
+ richOptions.forEach(function(options, index) {
1320
+ var fontScale = textStyle.fontScale, textColor = textStyle.textColor, textFamily = textStyle.fontFamily, textWeight = textStyle.textWeight, richStyle = textStyle.fontStyle;
1321
+ var text = options.text, fontSize = options.fontSize, _options_fontColor = options.fontColor, fontColor = _options_fontColor === void 0 ? textColor : _options_fontColor, _options_fontFamily = options.fontFamily, fontFamily = _options_fontFamily === void 0 ? textFamily : _options_fontFamily, _options_fontWeight = options.fontWeight, fontWeight = _options_fontWeight === void 0 ? textWeight : _options_fontWeight, _options_fontStyle = options.fontStyle, fontStyle = _options_fontStyle === void 0 ? richStyle : _options_fontStyle;
1322
+ var textSize = fontSize;
1323
+ if (overflow === EFFECTS.spec.TextOverflow.display) {
1324
+ if (width > canvasWidth1) {
1325
+ textSize /= width / canvasWidth1;
1326
+ }
1327
+ }
1328
+ var strOffsetX = offset[index] + x;
1329
+ // fix bug 1/255
1330
+ context.font = fontStyle + " " + fontWeight + " " + textSize * fontScale + "px " + fontFamily;
1331
+ var r = fontColor[0], g = fontColor[1], b = fontColor[2], a = fontColor[3];
1332
+ context.fillStyle = "rgba(" + r + ", " + g + ", " + b + ", " + a + ")";
1333
+ context.fillText(text, strOffsetX, charsLineHeight);
1334
+ });
630
1335
  });
631
- });
632
- // 与 toDataURL() 两种方式都需要像素读取操作
633
- var imageData = context.getImageData(0, 0, this.canvas.width, this.canvas.height);
634
- var texture = EFFECTS.Texture.createWithData(this.engine, {
635
- data: new Uint8Array(imageData.data),
636
- width: imageData.width,
637
- height: imageData.height
638
1336
  }, {
639
- flipY: flipY,
640
- magFilter: EFFECTS.glContext.LINEAR,
641
- minFilter: EFFECTS.glContext.LINEAR,
642
- wrapS: EFFECTS.glContext.CLAMP_TO_EDGE,
643
- wrapT: EFFECTS.glContext.CLAMP_TO_EDGE
1337
+ disposeOld: false
644
1338
  });
645
- this.disposeTextTexture();
646
- this.renderer.texture = texture;
647
- this.material.setTexture("_MainTex", texture);
1339
+ // 与 toDataURL() 两种方式都需要像素读取操作
648
1340
  this.isDirty = false;
649
- context.restore();
650
1341
  };
651
- _proto.updateTextureModern = function updateTextureModern(flipY) {
1342
+ /**
1343
+ * 使用策略管线路径的渲染方法
1344
+ */ _proto.updateTextureWithStrategies = function updateTextureWithStrategies(flipY) {
652
1345
  var _this = this;
653
- var _Math;
654
- var _firstLine_richOptions;
1346
+ if (!this.isDirty || !this.context || !this.canvas) {
1347
+ return;
1348
+ }
655
1349
  // 解析富文本
656
1350
  this.generateTextProgram(this.text);
657
- var _this1 = this, textLayout = _this1.textLayout, textStyle = _this1.textStyle;
658
- var overflow = textLayout.overflow, _textLayout_letterSpace = textLayout.letterSpace, letterSpace = _textLayout_letterSpace === void 0 ? 0 : _textLayout_letterSpace;
1351
+ var layout = this.textLayout;
1352
+ var _layout_letterSpace = layout.letterSpace, letterSpace = _layout_letterSpace === void 0 ? 0 : _layout_letterSpace;
659
1353
  var context = this.context;
660
- var width = 0;
661
- var height = 0;
662
1354
  if (!context) {
663
1355
  return;
664
1356
  }
665
- context.save();
666
- var charsInfo = [];
667
- var fontHeight = textStyle.fontSize * this.textStyle.fontScale;
668
- var charInfo = {
669
- richOptions: [],
670
- offsetX: [],
671
- width: 0,
672
- // 包括字体和上下行间距的高度
673
- lineHeight: fontHeight * this.singleLineHeight + (this.textLayout.lineGap || 0) * this.textStyle.fontScale,
674
- // 字体偏移高度(也就是行间距)
675
- offsetY: (this.textLayout.lineGap || 0) * this.textStyle.fontScale / 2,
676
- chars: []
677
- };
678
- // 遍历解析后的文本选项
679
- this.processedTextOptions.forEach(function(options) {
680
- var text = options.text, isNewLine = options.isNewLine, fontSize = options.fontSize;
681
- // 如果是新行,则结束上一行并开始新行
682
- if (isNewLine) {
683
- // 结束上一行:累加行高并重置charInfo
684
- height += charInfo.lineHeight;
685
- charsInfo.push(charInfo);
686
- width = Math.max(width, charInfo.width);
687
- // 初始化新行
688
- charInfo = {
689
- richOptions: [],
690
- offsetX: [],
691
- width: 0,
692
- lineHeight: fontHeight * _this.singleLineHeight + (_this.textLayout.lineGap || 0) * _this.textStyle.fontScale,
693
- offsetY: (_this.textLayout.lineGap || 0) * _this.textStyle.fontScale / 2,
694
- chars: []
695
- };
696
- }
697
- // 恢复默认设置
698
- context.font = (options.fontWeight || textStyle.textWeight) + " 10px " + (options.fontFamily || textStyle.fontFamily);
699
- var textHeight = fontSize * _this.singleLineHeight * _this.textStyle.fontScale + (_this.textLayout.lineGap || 0) * _this.textStyle.fontScale;
700
- // 更新当前行的最大行高
701
- if (textHeight > charInfo.lineHeight) {
702
- charInfo.lineHeight = textHeight;
703
- charInfo.offsetY = (_this.textLayout.lineGap || 0) * _this.textStyle.fontScale / 2;
704
- }
705
- charInfo.offsetX.push(charInfo.width);
706
- // 逐字计算宽度以实现字符间距
707
- var segmentInnerX = 0;
708
- var charArr = [];
709
- for(var i = 0; i < text.length; i++){
710
- var char = text[i];
711
- var tempcharWidth = context.measureText(char).width;
712
- var charWidth = (tempcharWidth <= 0 ? 0 : tempcharWidth) * fontSize * _this.SCALE_FACTOR * _this.textStyle.fontScale;
713
- charArr.push({
714
- char: char,
715
- x: segmentInnerX,
716
- width: charWidth
717
- });
718
- segmentInnerX += charWidth + letterSpace;
719
- }
720
- charInfo.chars.push(charArr);
721
- charInfo.width += segmentInnerX;
722
- charInfo.richOptions.push(options);
723
- });
724
- // 结束最后一行
725
- height += charInfo.lineHeight;
726
- charsInfo.push(charInfo);
727
- width = Math.max(width, charInfo.width);
728
- if (width === 0 || height === 0) {
1357
+ // 步骤1: 换行策略计算行信息
1358
+ var wrapResult = this.richWrapStrategy.computeLines(this.processedTextOptions, context, this.textStyle, layout, this.singleLineHeight, this.textStyle.fontScale, letterSpace, this.SCALE_FACTOR);
1359
+ if (wrapResult.lines.length === 0 || wrapResult.maxLineWidth === 0 || wrapResult.totalHeight === 0) {
729
1360
  this.isDirty = false;
730
- context.restore();
731
1361
  return;
732
1362
  }
1363
+ // 步骤2: 尺寸处理
1364
+ var sizeResult = this.resolveCanvasSize(wrapResult, layout, this.textStyle, this.singleLineHeight);
1365
+ // 首次渲染时初始化 canvas 尺寸和组件变换
1366
+ this.setCanvasSize(sizeResult);
1367
+ // 步骤3: 溢出策略处理
1368
+ var overflowResult = this.richOverflowStrategy.apply(wrapResult.lines, sizeResult, layout, this.textStyle);
1369
+ // 步骤4: 水平对齐策略
1370
+ var horizontalAlignResult = this.richHorizontalAlignStrategy.getHorizontalOffsets(wrapResult.lines, sizeResult, overflowResult, layout, this.textStyle);
1371
+ // 步骤5: 垂直对齐策略
1372
+ var TextVerticalAlignResult = this.richVerticalAlignStrategy.getVerticalOffsets(wrapResult.lines, sizeResult, overflowResult, layout, this.textStyle, this.singleLineHeight);
1373
+ // 使用 this.canvasSize 统一设置画布尺寸
1374
+ EFFECTS.assertExist(this.canvasSize);
1375
+ var _this_canvasSize = this.canvasSize, canvasWidth = _this_canvasSize.x, canvasHeight = _this_canvasSize.y;
1376
+ layout.width = canvasWidth / this.textStyle.fontScale;
1377
+ layout.height = canvasHeight / this.textStyle.fontScale;
1378
+ this.renderToTexture(canvasWidth, canvasHeight, flipY, function(context) {
1379
+ // 步骤6: 绘制文本
1380
+ _this.drawTextWithStrategies(context, wrapResult.lines, horizontalAlignResult, TextVerticalAlignResult, overflowResult, _this.textStyle);
1381
+ }, {
1382
+ disposeOld: false
1383
+ });
1384
+ this.isDirty = false;
1385
+ };
1386
+ _proto.setCanvasSize = function setCanvasSize(sizeResult) {
1387
+ var _this = this;
733
1388
  if (this.size === undefined || this.size === null) {
734
1389
  this.size = this.item.transform.size.clone();
735
1390
  }
736
1391
  var _this_size = this.size, _this_size_x = _this_size.x, x = _this_size_x === void 0 ? 1 : _this_size_x, _this_size_y = _this_size.y, y = _this_size_y === void 0 ? 1 : _this_size_y;
737
- // 首次渲染时初始化 canvas 尺寸和组件变换
738
- if (!this.initialized) {
739
- this.canvasSize = !this.canvasSize ? new EFFECTS.math.Vector2(width, height) : this.canvasSize;
740
- var _this_canvasSize = this.canvasSize, canvasWidth = _this_canvasSize.x, canvasHeight = _this_canvasSize.y;
741
- this.item.transform.size.set(x * canvasWidth * this.SCALE_FACTOR * this.SCALE_FACTOR, y * canvasHeight * this.SCALE_FACTOR * this.SCALE_FACTOR);
742
- this.size = this.item.transform.size.clone();
743
- this.initialized = true;
744
- }
745
- EFFECTS.assertExist(this.canvasSize);
746
- var _this_canvasSize1 = this.canvasSize, canvasWidth1 = _this_canvasSize1.x, canvasHeight1 = _this_canvasSize1.y;
747
- this.textLayout.width = canvasWidth1 / textStyle.fontScale;
748
- this.textLayout.height = canvasHeight1 / textStyle.fontScale;
749
- this.canvas.width = canvasWidth1;
750
- this.canvas.height = canvasHeight1;
751
- context.clearRect(0, 0, canvasWidth1, canvasHeight1);
752
- // fix bug 1/255
753
- context.fillStyle = "rgba(255, 255, 255, " + this.ALPHA_FIX_VALUE + ")";
754
- if (!flipY) {
755
- context.translate(0, canvasHeight1);
756
- context.scale(1, -1);
757
- }
758
- if (charsInfo.length === 0) {
759
- context.restore();
760
- return;
761
- }
762
- // 行高数组
763
- var lineHeights = charsInfo.map(function(l) {
764
- return l.lineHeight;
765
- });
766
- // 计算第一行基线Y坐标
767
- var firstLine = charsInfo[0];
768
- var _firstLine_richOptions_map;
769
- var firstLineMaxFontSize = (_Math = Math).max.apply(_Math, [].concat((_firstLine_richOptions_map = firstLine == null ? void 0 : (_firstLine_richOptions = firstLine.richOptions) == null ? void 0 : _firstLine_richOptions.map(function(opt) {
770
- return opt.fontSize;
771
- })) != null ? _firstLine_richOptions_map : [
772
- this.textStyle.fontSize
773
- ]));
774
- var fontSizeForOffset = firstLineMaxFontSize * this.textStyle.fontScale * this.singleLineHeight;
775
- var baselineY = textLayout.getOffsetYRich(this.textStyle, lineHeights, fontSizeForOffset);
776
- // 逐行绘制
777
- charsInfo.forEach(function(charInfo, index) {
778
- var richOptions = charInfo.richOptions, offsetX = charInfo.offsetX, width = charInfo.width, chars = charInfo.chars;
779
- var charsArr = chars;
780
- var charWidth = width;
781
- var offset = offsetX;
782
- if (overflow === EFFECTS.spec.TextOverflow.display) {
783
- if (width > canvasWidth1) {
784
- var canvasScale = canvasWidth1 / width;
785
- charWidth *= canvasScale;
786
- offset = offsetX.map(function(x) {
787
- return x * canvasScale;
788
- });
789
- charsArr.forEach(function(charArr) {
790
- charArr.forEach(function(charDetail) {
791
- charDetail.x *= canvasScale;
792
- charDetail.width *= canvasScale;
793
- });
1392
+ var layout = this.textLayout;
1393
+ switch(layout.overflow){
1394
+ case EFFECTS.spec.TextOverflow.visible:
1395
+ {
1396
+ var _Math;
1397
+ var frameW = layout.maxTextWidth;
1398
+ var frameH = layout.maxTextHeight;
1399
+ var _sizeResult_bboxTop;
1400
+ var bboxTop = (_sizeResult_bboxTop = sizeResult.bboxTop) != null ? _sizeResult_bboxTop : 0;
1401
+ var _sizeResult_bboxHeight, _sizeResult_bboxBottom;
1402
+ var bboxBottom = (_sizeResult_bboxBottom = sizeResult.bboxBottom) != null ? _sizeResult_bboxBottom : bboxTop + ((_sizeResult_bboxHeight = sizeResult.bboxHeight) != null ? _sizeResult_bboxHeight : 0);
1403
+ var _sizeResult_bboxHeight1;
1404
+ var bboxHeight = (_sizeResult_bboxHeight1 = sizeResult.bboxHeight) != null ? _sizeResult_bboxHeight1 : bboxBottom - bboxTop;
1405
+ // 计算 frame 基线
1406
+ var baselineYFrame = 0;
1407
+ switch(layout.textVerticalAlign){
1408
+ case EFFECTS.spec.TextVerticalAlign.top:
1409
+ baselineYFrame = -bboxTop;
1410
+ break;
1411
+ case EFFECTS.spec.TextVerticalAlign.middle:
1412
+ baselineYFrame = (frameH - bboxHeight) / 2 - bboxTop;
1413
+ break;
1414
+ case EFFECTS.spec.TextVerticalAlign.bottom:
1415
+ baselineYFrame = frameH - bboxHeight - bboxTop;
1416
+ break;
1417
+ }
1418
+ // 上下溢出检测
1419
+ var contentTopInFrame = baselineYFrame + bboxTop;
1420
+ var contentBottomInFrame = baselineYFrame + bboxBottom;
1421
+ var overflowTop = Math.max(0, -contentTopInFrame);
1422
+ var overflowBottom = Math.max(0, contentBottomInFrame - frameH);
1423
+ // 垂直扩张
1424
+ var expandTop = overflowTop;
1425
+ var expandBottom = overflowBottom;
1426
+ switch(layout.textVerticalAlign){
1427
+ case EFFECTS.spec.TextVerticalAlign.top:
1428
+ {
1429
+ var E = overflowBottom;
1430
+ expandTop = E;
1431
+ expandBottom = E;
1432
+ break;
1433
+ }
1434
+ case EFFECTS.spec.TextVerticalAlign.bottom:
1435
+ {
1436
+ var E1 = overflowTop;
1437
+ expandTop = E1;
1438
+ expandBottom = E1;
1439
+ break;
1440
+ }
1441
+ case EFFECTS.spec.TextVerticalAlign.middle:
1442
+ {
1443
+ // 保持非对称:上扩 overflowTop,下扩 overflowBottom
1444
+ expandTop = overflowTop;
1445
+ expandBottom = overflowBottom;
1446
+ break;
1447
+ }
1448
+ }
1449
+ // 位移补偿:始终使用 expandTop
1450
+ var compY = expandTop;
1451
+ // 水平扩张
1452
+ var lines = sizeResult.lines || [];
1453
+ var xOffsetsFrame = lines.map(function(line) {
1454
+ return layout.getOffsetXRich(_this.textStyle, frameW, line.width);
794
1455
  });
1456
+ var leftMost = xOffsetsFrame.length > 0 ? (_Math = Math).min.apply(_Math, [].concat(xOffsetsFrame)) : 0;
1457
+ var ex = Math.max(0, -leftMost);
1458
+ var expandLeft = ex;
1459
+ var expandRight = ex;
1460
+ var finalW = frameW + expandLeft + expandRight;
1461
+ var finalH = frameH + expandTop + expandBottom;
1462
+ // 记录补偿,供垂直对齐策略叠加
1463
+ sizeResult.baselineCompensationX = expandLeft;
1464
+ sizeResult.baselineCompensationY = compY;
1465
+ sizeResult.canvasWidth = finalW;
1466
+ sizeResult.canvasHeight = finalH;
1467
+ this.canvasSize = new EFFECTS.math.Vector2(finalW, finalH);
1468
+ var _this_size1;
1469
+ var _ref = (_this_size1 = this.size) != null ? _this_size1 : this.item.transform.size, _ref_x = _ref.x, x1 = _ref_x === void 0 ? 1 : _ref_x, _ref_y = _ref.y, y1 = _ref_y === void 0 ? 1 : _ref_y;
1470
+ this.item.transform.size.set(x1 * finalW * this.SCALE_FACTOR * this.SCALE_FACTOR, y1 * finalH * this.SCALE_FACTOR * this.SCALE_FACTOR);
1471
+ this.size = this.item.transform.size.clone();
1472
+ this.initialized = true;
1473
+ break;
795
1474
  }
796
- }
797
- var x = _this.textLayout.getOffsetX(textStyle, charWidth);
1475
+ case EFFECTS.spec.TextOverflow.clip:
1476
+ {
1477
+ var frameW1 = layout.maxTextWidth;
1478
+ var frameH1 = layout.maxTextHeight;
1479
+ // 直接使用 frame 尺寸作为画布尺寸
1480
+ sizeResult.canvasWidth = frameW1;
1481
+ sizeResult.canvasHeight = frameH1;
1482
+ // clip 模式不需要任何补偿
1483
+ sizeResult.baselineCompensationX = 0;
1484
+ sizeResult.baselineCompensationY = 0;
1485
+ // 设置 canvas 和节点变换
1486
+ this.canvasSize = new EFFECTS.math.Vector2(frameW1, frameH1);
1487
+ // 把 layout 的尺寸更新为 frame 尺寸
1488
+ layout.width = frameW1 / this.textStyle.fontScale;
1489
+ layout.height = frameH1 / this.textStyle.fontScale;
1490
+ var _this_size2;
1491
+ var _ref1 = (_this_size2 = this.size) != null ? _this_size2 : this.item.transform.size, _ref_x1 = _ref1.x, x2 = _ref_x1 === void 0 ? 1 : _ref_x1, _ref_y1 = _ref1.y, y2 = _ref_y1 === void 0 ? 1 : _ref_y1;
1492
+ this.item.transform.size.set(x2 * frameW1 * this.SCALE_FACTOR * this.SCALE_FACTOR, y2 * frameH1 * this.SCALE_FACTOR * this.SCALE_FACTOR);
1493
+ this.size = this.item.transform.size.clone();
1494
+ this.initialized = true;
1495
+ break;
1496
+ }
1497
+ case EFFECTS.spec.TextOverflow.display:
1498
+ {
1499
+ if (!this.initialized) {
1500
+ this.canvasSize = new EFFECTS.math.Vector2(layout.maxTextWidth, layout.maxTextHeight);
1501
+ this.item.transform.size.set(x * this.canvasSize.x * this.SCALE_FACTOR * this.SCALE_FACTOR, y * this.canvasSize.y * this.SCALE_FACTOR * this.SCALE_FACTOR);
1502
+ this.size = this.item.transform.size.clone();
1503
+ this.initialized = true;
1504
+ }
1505
+ break;
1506
+ }
1507
+ }
1508
+ };
1509
+ /**
1510
+ * 尺寸处理
1511
+ */ _proto.resolveCanvasSize = function resolveCanvasSize(wrapResult, layout, style, singleLineHeight) {
1512
+ var canvasWidth = Math.max(1, wrapResult.maxLineWidth || 0);
1513
+ var canvasHeight = Math.max(1, wrapResult.totalHeight || 0); // stepTotalHeight
1514
+ layout.width = canvasWidth / style.fontScale;
1515
+ layout.height = canvasHeight / style.fontScale;
1516
+ return {
1517
+ canvasWidth: canvasWidth,
1518
+ canvasHeight: canvasHeight,
1519
+ contentWidth: wrapResult.maxLineWidth,
1520
+ bboxTop: wrapResult.bboxTop,
1521
+ bboxBottom: wrapResult.bboxBottom,
1522
+ bboxHeight: wrapResult.bboxHeight,
1523
+ // 为 visible 模式的画布尺寸计算保留行信息
1524
+ lines: wrapResult.lines
1525
+ };
1526
+ };
1527
+ /**
1528
+ * 使用策略结果绘制文本
1529
+ */ _proto.drawTextWithStrategies = function drawTextWithStrategies(context, lines, horizontalAlignResult, TextVerticalAlignResult, overflowResult, textStyle) {
1530
+ var currentBaselineY = TextVerticalAlignResult.baselineY;
1531
+ var lineOffsets = horizontalAlignResult.lineOffsets;
1532
+ lines.forEach(function(line, index) {
1533
+ var richOptions = line.richOptions, chars = line.chars;
1534
+ var xOffset = lineOffsets[index];
1535
+ var yOffset = currentBaselineY;
798
1536
  richOptions.forEach(function(options, segIndex) {
799
1537
  var fontScale = textStyle.fontScale, textColor = textStyle.textColor, textFamily = textStyle.fontFamily, textWeight = textStyle.textWeight, richStyle = textStyle.fontStyle;
800
1538
  var fontSize = options.fontSize, _options_fontColor = options.fontColor, fontColor = _options_fontColor === void 0 ? textColor : _options_fontColor, _options_fontFamily = options.fontFamily, fontFamily = _options_fontFamily === void 0 ? textFamily : _options_fontFamily, _options_fontWeight = options.fontWeight, fontWeight = _options_fontWeight === void 0 ? textWeight : _options_fontWeight, _options_fontStyle = options.fontStyle, fontStyle = _options_fontStyle === void 0 ? richStyle : _options_fontStyle;
1539
+ // 直接使用原始字体大小(已在行数据中预缩放)
801
1540
  var textSize = fontSize;
802
- if (overflow === EFFECTS.spec.TextOverflow.display && width > canvasWidth1) {
803
- textSize /= width / canvasWidth1;
804
- }
805
- var strOffsetX = offset[segIndex] + x;
806
1541
  context.font = fontStyle + " " + fontWeight + " " + textSize * fontScale + "px " + fontFamily;
807
- context.fillStyle = "rgba(" + fontColor[0] + ", " + fontColor[1] + ", " + fontColor[2] + ", " + fontColor[3] + ")";
1542
+ var r = fontColor[0], g = fontColor[1], b = fontColor[2], a = fontColor[3];
1543
+ context.fillStyle = "rgba(" + r + ", " + g + ", " + b + ", " + a + ")";
808
1544
  // 逐字绘制
809
- var charArr = charInfo.chars[segIndex];
1545
+ var segStartX = line.offsetX && line.offsetX[segIndex] ? line.offsetX[segIndex] : 0;
1546
+ var charArr = chars[segIndex];
810
1547
  charArr.forEach(function(charDetail) {
811
- context.fillText(charDetail.char, strOffsetX + charDetail.x, baselineY);
1548
+ // 直接使用缩放后的字符位置
1549
+ context.fillText(charDetail.char, xOffset + segStartX + charDetail.x, yOffset);
812
1550
  });
813
1551
  });
814
1552
  // 推进到下一行
815
- if (index < charsInfo.length - 1) {
816
- baselineY += lineHeights[index + 1];
1553
+ if (index < lines.length - 1) {
1554
+ currentBaselineY += lines[index + 1].lineHeight;
817
1555
  }
818
1556
  });
819
- var imageData = context.getImageData(0, 0, this.canvas.width, this.canvas.height);
820
- var texture = EFFECTS.Texture.createWithData(this.engine, {
821
- data: new Uint8Array(imageData.data),
822
- width: imageData.width,
823
- height: imageData.height
824
- }, {
825
- flipY: flipY,
826
- magFilter: EFFECTS.glContext.LINEAR,
827
- minFilter: EFFECTS.glContext.LINEAR,
828
- wrapS: EFFECTS.glContext.CLAMP_TO_EDGE,
829
- wrapT: EFFECTS.glContext.CLAMP_TO_EDGE
830
- });
831
- this.renderer.texture = texture;
832
- this.material.setTexture("_MainTex", texture);
833
- this.isDirty = false;
834
- context.restore();
1557
+ };
1558
+ _proto.unsupported = function unsupported(name) {
1559
+ throw new Error("RichTextComponent does not support " + name + " at runtime.");
835
1560
  };
836
1561
  /**
837
1562
  * 该方法富文本组件不支持
838
1563
  * @param value - 水平偏移距离
839
1564
  * @returns
840
1565
  */ _proto.setShadowOffsetY = function setShadowOffsetY(value) {
841
- throw new Error("Method not implemented.");
1566
+ this.unsupported("setShadowOffsetY");
842
1567
  };
843
1568
  /**
844
1569
  * 该方法富文本组件不支持
845
1570
  * @param value - 模糊程度
846
1571
  */ _proto.setShadowBlur = function setShadowBlur(value) {
847
- throw new Error("Method not implemented.");
1572
+ this.unsupported("setShadowBlur");
848
1573
  };
849
1574
  /**
850
1575
  * 该方法富文本组件不支持
851
1576
  * @param value - 水平偏移距离
852
1577
  */ _proto.setShadowOffsetX = function setShadowOffsetX(value) {
853
- throw new Error("Method not implemented.");
1578
+ this.unsupported("setShadowOffsetX");
854
1579
  };
855
1580
  /**
856
1581
  * 该方法富文本组件不支持
857
1582
  * @param value - 阴影颜色
858
1583
  */ _proto.setShadowColor = function setShadowColor(value) {
859
- throw new Error("Method not implemented.");
1584
+ this.unsupported("setShadowColor");
860
1585
  };
861
1586
  /**
862
1587
  * 该方法富文本组件不支持
863
1588
  * @param value - 外描边宽度
864
1589
  * @returns
865
1590
  */ _proto.setOutlineWidth = function setOutlineWidth(value) {
866
- throw new Error("Method not implemented.");
1591
+ this.unsupported("setOutlineWidth");
867
1592
  };
868
1593
  /**
869
1594
  * 该方法富文本组件不支持
870
1595
  * @param value - 是否自动设置宽度
871
1596
  */ _proto.setAutoWidth = function setAutoWidth(value) {
872
- throw new Error("Method not implemented.");
873
- };
874
- _proto.updateWithOptions = function updateWithOptions(options) {
875
- this.textStyle = new EFFECTS.TextStyle(options);
876
- this.textLayout = new EFFECTS.TextLayout(options);
877
- this.textLayout.textBaseline = options.textBaseline || EFFECTS.spec.TextBaseline.middle;
878
- this.text = options.text ? options.text.toString() : " ";
1597
+ this.unsupported("setAutoWidth");
879
1598
  };
880
- _proto.renderText = function renderText(options) {
881
- var size = options.size;
882
- if (size) {
883
- this.canvasSize = new EFFECTS.math.Vector2(size[0], size[1]);
884
- }
885
- this.updateTexture();
1599
+ /**
1600
+ * 该方法富文本组件不支持
1601
+ */ _proto.setFontSize = function setFontSize(value) {
1602
+ this.unsupported("setFontSize");
886
1603
  };
887
1604
  return RichTextComponent;
888
- }(EFFECTS.TextComponent);
1605
+ }(EFFECTS.MaskableGraphic);
889
1606
  exports.RichTextComponent = __decorate([
890
1607
  EFFECTS.effectsClass(EFFECTS.spec.DataType.RichTextComponent)
891
1608
  ], exports.RichTextComponent);
1609
+ EFFECTS.applyMixins(exports.RichTextComponent, [
1610
+ EFFECTS.TextComponentBase
1611
+ ]);
892
1612
 
893
1613
  /**
894
1614
  * 插件版本号
895
- */ var version = "2.7.3";
1615
+ */ var version = "2.8.0-alpha.0";
896
1616
  EFFECTS.registerPlugin("rich-text", RichTextLoader, EFFECTS.VFXItem);
897
1617
  EFFECTS.logger.info("Plugin rich text version: " + version + ".");
898
1618
  if (version !== EFFECTS__namespace.version) {