66 TextAlign , TextVerticalAlign , ImageLike , Dictionary , MapToType , FontWeight , FontStyle , NullUndefined
77} from '../core/types' ;
88import {
9- parseRichText , parsePlainText , CalcInnerTextOverflowAreaOut , calcInnerTextOverflowArea
9+ parseRichText , parsePlainText , CalcInnerTextOverflowAreaOut , calcInnerTextOverflowArea ,
10+ tSpanCreateBoundingRect2 ,
1011} from './helper/parseText' ;
1112import TSpan , { TSpanStyleProps } from './TSpan' ;
1213import { retrieve2 , each , normalizeCssArray , trim , retrieve3 , extend , keys , defaults } from '../core/util' ;
@@ -332,7 +333,7 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
332333 }
333334 }
334335
335- updateTransform ( ) {
336+ updateTransform ( ) {
336337 const innerTransformable = this . innerTransformable ;
337338 if ( innerTransformable ) {
338339 innerTransformable . updateTransform ( ) ;
@@ -528,7 +529,6 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
528529
529530 const outerHeight = contentBlock . outerHeight ;
530531 const outerWidth = contentBlock . outerWidth ;
531- const contentWidth = contentBlock . contentWidth ;
532532
533533 const textLines = contentBlock . lines ;
534534 const lineHeight = contentBlock . lineHeight ;
@@ -544,6 +544,13 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
544544 const boxY = adjustTextY ( baseY , outerHeight , verticalAlign ) ;
545545 needDrawBg && this . _renderBackground ( style , style , boxX , boxY , outerWidth , outerHeight ) ;
546546 }
547+ // PENDING:
548+ // Should text bounding rect contains style.padding, style.width, style.height when NO background
549+ // and border displayed? It depends on how to define "boundingRect". HTML `getBoundingClientRect`
550+ // contains padding in that case. But currently ZRText does not.
551+ // If implement that, an extra invisible Rect may need to be added as the placeholder for the bounding
552+ // rect computation, considering animation of padding. But will it degrade performance for the most
553+ // used plain texts cases?
547554
548555 // `textBaseline` is set as 'middle'.
549556 textY += lineHeight / 2 ;
@@ -559,6 +566,7 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
559566 }
560567
561568 let defaultLineWidth = 0 ;
569+ let usingDefaultStroke = false ;
562570 let useDefaultFill = false ;
563571 const textFill = getFill (
564572 'fill' in style
@@ -580,16 +588,12 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
580588 // we give the auto lineWidth to display the given stoke color.
581589 && ( ! defaultStyle . autoStroke || useDefaultFill )
582590 )
583- ? ( defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH , defaultStyle . stroke )
591+ ? ( defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH , usingDefaultStroke = true , defaultStyle . stroke )
584592 : null
585593 ) ;
586594
587595 const hasShadow = style . textShadowBlur > 0 ;
588596
589- const fixedBoundingRect = style . width != null
590- && ( style . overflow === 'truncate' || style . overflow === 'break' || style . overflow === 'breakAll' ) ;
591- const calculatedLineHeight = contentBlock . calculatedLineHeight ;
592-
593597 for ( let i = 0 ; i < textLines . length ; i ++ ) {
594598 const el = this . _getOrCreateChild ( TSpan ) ;
595599 // Always create new style.
@@ -633,19 +637,27 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
633637
634638 textY += lineHeight ;
635639
636- if ( fixedBoundingRect ) {
637- el . setBoundingRect ( new BoundingRect (
638- adjustTextX ( subElStyle . x , contentWidth , subElStyle . textAlign as TextAlign ) ,
639- adjustTextY ( subElStyle . y , calculatedLineHeight , subElStyle . textBaseline as TextVerticalAlign ) ,
640- /**
641- * Text boundary should be the real text width.
642- * Otherwise, there will be extra space in the
643- * bounding rect calculated.
644- */
645- contentWidth ,
646- calculatedLineHeight
647- ) ) ;
648- }
640+ // Always set tspan bounding rect to guarantee the consistency if users lays out based
641+ // on these bounding rects.
642+ el . setBoundingRect ( tSpanCreateBoundingRect2 (
643+ subElStyle ,
644+ contentBlock . contentWidth ,
645+ contentBlock . calculatedLineHeight ,
646+ // Should text bounding rect includes text stroke width?
647+ // Pros:
648+ // - Intuitively, and by convention, bounding rect of `Path` always includes stroke width.
649+ // Cons:
650+ // - It's unpredictable for users whether "auto stroke" is applied. If stroke width is included
651+ // and multiple texts are laid out based on its bounding rect, the position of texts may vary
652+ // and is unpredictable - especially in limited space (e.g., see echarts pie label cases).
653+ // - "auto stroke" attempts to use the same color as the background to make the border to be
654+ // invisible in most cases, thus it might be more reasonable to be excluded from bounding rect.
655+ // Conclusion:
656+ // - If users specifies style.stroke, it will be included into the bounding rect as normal.
657+ // Otherwise, keep the stroke width as `0` in this case to guarantee consistency of bounding
658+ // rect based layout, regardless of whether "auto stroke" is applied.
659+ usingDefaultStroke ? 0 : null
660+ ) ) ;
649661 }
650662 }
651663
@@ -801,6 +813,7 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
801813 const defaultStyle = this . _defaultStyle ;
802814 let useDefaultFill = false ;
803815 let defaultLineWidth = 0 ;
816+ let usingDefaultStroke = false ;
804817 const textFill = getFill (
805818 'fill' in tokenStyle ? tokenStyle . fill
806819 : 'fill' in style ? style . fill
@@ -812,9 +825,9 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
812825 : (
813826 ! bgColorDrawn
814827 && ! parentBgColorDrawn
815- // See the strategy explained above .
828+ // See the strategy explained `_updatePlainTexts` .
816829 && ( ! defaultStyle . autoStroke || useDefaultFill )
817- ) ? ( defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH , defaultStyle . stroke )
830+ ) ? ( defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH , usingDefaultStroke = true , defaultStyle . stroke )
818831 : null
819832 ) ;
820833
@@ -852,14 +865,13 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
852865 subElStyle . fill = textFill ;
853866 }
854867
855- const textWidth = token . contentWidth ;
856- const textHeight = token . contentHeight ;
857868 // NOTE: Should not call dirtyStyle after setBoundingRect. Or it will be cleared.
858- el . setBoundingRect ( new BoundingRect (
859- adjustTextX ( subElStyle . x , textWidth , subElStyle . textAlign as TextAlign ) ,
860- adjustTextY ( subElStyle . y , textHeight , subElStyle . textBaseline as TextVerticalAlign ) ,
861- textWidth ,
862- textHeight
869+ el . setBoundingRect ( tSpanCreateBoundingRect2 (
870+ subElStyle ,
871+ token . contentWidth ,
872+ token . contentHeight ,
873+ // See the strategy explained `_updatePlainTexts`.
874+ usingDefaultStroke ? 0 : null
863875 ) ) ;
864876 }
865877
0 commit comments