zrender-nightly 6.0.0-dev.20250718 → 6.0.0-dev.20250720
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/zrender.js +2559 -2576
- package/dist/zrender.js.map +1 -1
- package/dist/zrender.min.js +1 -1
- package/lib/graphic/TSpan.js +3 -18
- package/lib/graphic/Text.js +7 -13
- package/lib/graphic/helper/parseText.d.ts +8 -3
- package/lib/graphic/helper/parseText.js +31 -4
- package/lib/zrender.d.ts +1 -1
- package/lib/zrender.js +1 -1
- package/package.json +1 -1
- package/src/contain/text.ts +4 -1
- package/src/graphic/TSpan.ts +4 -29
- package/src/graphic/Text.ts +42 -30
- package/src/graphic/helper/parseText.ts +64 -5
- package/src/zrender.ts +1 -1
package/lib/graphic/TSpan.js
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
import { __extends } from "tslib";
|
2
2
|
import Displayable from './Displayable.js';
|
3
|
-
import { getBoundingRect } from '../contain/text.js';
|
4
3
|
import { DEFAULT_PATH_STYLE } from './Path.js';
|
5
4
|
import { createObject, defaults } from '../core/util.js';
|
6
5
|
import { DEFAULT_FONT } from '../core/platform.js';
|
6
|
+
import { tSpanCreateBoundingRect, tSpanHasStroke } from './helper/parseText.js';
|
7
7
|
export var DEFAULT_TSPAN_STYLE = defaults({
|
8
8
|
strokeFirst: true,
|
9
9
|
font: DEFAULT_FONT,
|
@@ -19,9 +19,7 @@ var TSpan = (function (_super) {
|
|
19
19
|
return _super !== null && _super.apply(this, arguments) || this;
|
20
20
|
}
|
21
21
|
TSpan.prototype.hasStroke = function () {
|
22
|
-
|
23
|
-
var stroke = style.stroke;
|
24
|
-
return stroke != null && stroke !== 'none' && style.lineWidth > 0;
|
22
|
+
return tSpanHasStroke(this.style);
|
25
23
|
};
|
26
24
|
TSpan.prototype.hasFill = function () {
|
27
25
|
var style = this.style;
|
@@ -35,21 +33,8 @@ var TSpan = (function (_super) {
|
|
35
33
|
this._rect = rect;
|
36
34
|
};
|
37
35
|
TSpan.prototype.getBoundingRect = function () {
|
38
|
-
var style = this.style;
|
39
36
|
if (!this._rect) {
|
40
|
-
|
41
|
-
text != null ? (text += '') : (text = '');
|
42
|
-
var rect = getBoundingRect(text, style.font, style.textAlign, style.textBaseline);
|
43
|
-
rect.x += style.x || 0;
|
44
|
-
rect.y += style.y || 0;
|
45
|
-
if (this.hasStroke()) {
|
46
|
-
var w = style.lineWidth;
|
47
|
-
rect.x -= w / 2;
|
48
|
-
rect.y -= w / 2;
|
49
|
-
rect.width += w;
|
50
|
-
rect.height += w;
|
51
|
-
}
|
52
|
-
this._rect = rect;
|
37
|
+
this._rect = tSpanCreateBoundingRect(this.style);
|
53
38
|
}
|
54
39
|
return this._rect;
|
55
40
|
};
|
package/lib/graphic/Text.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { __extends } from "tslib";
|
2
|
-
import { parseRichText, parsePlainText, calcInnerTextOverflowArea } from './helper/parseText.js';
|
2
|
+
import { parseRichText, parsePlainText, calcInnerTextOverflowArea, tSpanCreateBoundingRect2, } from './helper/parseText.js';
|
3
3
|
import TSpan from './TSpan.js';
|
4
4
|
import { retrieve2, each, normalizeCssArray, trim, retrieve3, extend, keys, defaults } from '../core/util.js';
|
5
5
|
import { adjustTextX, adjustTextY } from '../contain/text.js';
|
@@ -200,7 +200,6 @@ var ZRText = (function (_super) {
|
|
200
200
|
var bgColorDrawn = !!(style.backgroundColor);
|
201
201
|
var outerHeight = contentBlock.outerHeight;
|
202
202
|
var outerWidth = contentBlock.outerWidth;
|
203
|
-
var contentWidth = contentBlock.contentWidth;
|
204
203
|
var textLines = contentBlock.lines;
|
205
204
|
var lineHeight = contentBlock.lineHeight;
|
206
205
|
this.isTruncated = !!contentBlock.isTruncated;
|
@@ -222,6 +221,7 @@ var ZRText = (function (_super) {
|
|
222
221
|
}
|
223
222
|
}
|
224
223
|
var defaultLineWidth = 0;
|
224
|
+
var usingDefaultStroke = false;
|
225
225
|
var useDefaultFill = false;
|
226
226
|
var textFill = getFill('fill' in style
|
227
227
|
? style.fill
|
@@ -230,12 +230,9 @@ var ZRText = (function (_super) {
|
|
230
230
|
? style.stroke
|
231
231
|
: (!bgColorDrawn
|
232
232
|
&& (!defaultStyle.autoStroke || useDefaultFill))
|
233
|
-
? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
|
233
|
+
? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, usingDefaultStroke = true, defaultStyle.stroke)
|
234
234
|
: null);
|
235
235
|
var hasShadow = style.textShadowBlur > 0;
|
236
|
-
var fixedBoundingRect = style.width != null
|
237
|
-
&& (style.overflow === 'truncate' || style.overflow === 'break' || style.overflow === 'breakAll');
|
238
|
-
var calculatedLineHeight = contentBlock.calculatedLineHeight;
|
239
236
|
for (var i = 0; i < textLines.length; i++) {
|
240
237
|
var el = this._getOrCreateChild(TSpan);
|
241
238
|
var subElStyle = el.createStyle();
|
@@ -265,9 +262,7 @@ var ZRText = (function (_super) {
|
|
265
262
|
subElStyle.font = textFont;
|
266
263
|
setSeparateFont(subElStyle, style);
|
267
264
|
textY += lineHeight;
|
268
|
-
|
269
|
-
el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, contentWidth, subElStyle.textAlign), adjustTextY(subElStyle.y, calculatedLineHeight, subElStyle.textBaseline), contentWidth, calculatedLineHeight));
|
270
|
-
}
|
265
|
+
el.setBoundingRect(tSpanCreateBoundingRect2(subElStyle, contentBlock.contentWidth, contentBlock.calculatedLineHeight, usingDefaultStroke ? 0 : null));
|
271
266
|
}
|
272
267
|
};
|
273
268
|
ZRText.prototype._updateRichTexts = function () {
|
@@ -364,6 +359,7 @@ var ZRText = (function (_super) {
|
|
364
359
|
var defaultStyle = this._defaultStyle;
|
365
360
|
var useDefaultFill = false;
|
366
361
|
var defaultLineWidth = 0;
|
362
|
+
var usingDefaultStroke = false;
|
367
363
|
var textFill = getFill('fill' in tokenStyle ? tokenStyle.fill
|
368
364
|
: 'fill' in style ? style.fill
|
369
365
|
: (useDefaultFill = true, defaultStyle.fill));
|
@@ -371,7 +367,7 @@ var ZRText = (function (_super) {
|
|
371
367
|
: 'stroke' in style ? style.stroke
|
372
368
|
: (!bgColorDrawn
|
373
369
|
&& !parentBgColorDrawn
|
374
|
-
&& (!defaultStyle.autoStroke || useDefaultFill)) ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
|
370
|
+
&& (!defaultStyle.autoStroke || useDefaultFill)) ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, usingDefaultStroke = true, defaultStyle.stroke)
|
375
371
|
: null);
|
376
372
|
var hasShadow = tokenStyle.textShadowBlur > 0
|
377
373
|
|| style.textShadowBlur > 0;
|
@@ -398,9 +394,7 @@ var ZRText = (function (_super) {
|
|
398
394
|
if (textFill) {
|
399
395
|
subElStyle.fill = textFill;
|
400
396
|
}
|
401
|
-
|
402
|
-
var textHeight = token.contentHeight;
|
403
|
-
el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, textWidth, subElStyle.textAlign), adjustTextY(subElStyle.y, textHeight, subElStyle.textBaseline), textWidth, textHeight));
|
397
|
+
el.setBoundingRect(tSpanCreateBoundingRect2(subElStyle, token.contentWidth, token.contentHeight, usingDefaultStroke ? 0 : null));
|
404
398
|
};
|
405
399
|
ZRText.prototype._renderBackground = function (style, topStyle, x, y, width, height) {
|
406
400
|
var textBackgroundColor = style.backgroundColor;
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import { TextAlign, TextVerticalAlign, NullUndefined } from '../../core/types';
|
2
|
-
import { DefaultTextStyle, TextStyleProps } from '../Text';
|
2
|
+
import type { DefaultTextStyle, TextStyleProps } from '../Text';
|
3
|
+
import type { TSpanStyleProps } from '../TSpan';
|
4
|
+
import BoundingRect from '../../core/BoundingRect';
|
3
5
|
interface InnerTruncateOption {
|
4
6
|
maxIteration?: number;
|
5
7
|
minChar?: number;
|
@@ -19,7 +21,7 @@ export interface PlainTextContentBlock {
|
|
19
21
|
lines: string[];
|
20
22
|
isTruncated: boolean;
|
21
23
|
}
|
22
|
-
export declare function parsePlainText(
|
24
|
+
export declare function parsePlainText(rawText: unknown, style: Omit<TextStyleProps, 'align' | 'verticalAlign'>, defaultOuterWidth: number | NullUndefined, defaultOuterHeight: number | NullUndefined): PlainTextContentBlock;
|
23
25
|
declare class RichTextToken {
|
24
26
|
styleName: string;
|
25
27
|
text: string;
|
@@ -52,7 +54,7 @@ export declare class RichTextContentBlock {
|
|
52
54
|
lines: RichTextLine[];
|
53
55
|
isTruncated: boolean;
|
54
56
|
}
|
55
|
-
export declare function parseRichText(
|
57
|
+
export declare function parseRichText(rawText: unknown, style: Omit<TextStyleProps, 'align' | 'verticalAlign'>, defaultOuterWidth: number | NullUndefined, defaultOuterHeight: number | NullUndefined, topTextAlign: TextAlign): RichTextContentBlock;
|
56
58
|
export declare function calcInnerTextOverflowArea(out: CalcInnerTextOverflowAreaOut, overflowRect: DefaultTextStyle['overflowRect'], baseX: number, baseY: number, textAlign: TextAlign, textVerticalAlign: TextVerticalAlign): void;
|
57
59
|
export declare type CalcInnerTextOverflowAreaOut = {
|
58
60
|
baseX: number;
|
@@ -60,4 +62,7 @@ export declare type CalcInnerTextOverflowAreaOut = {
|
|
60
62
|
outerWidth: number | NullUndefined;
|
61
63
|
outerHeight: number | NullUndefined;
|
62
64
|
};
|
65
|
+
export declare function tSpanCreateBoundingRect(style: Pick<TSpanStyleProps, 'text' | 'font' | 'x' | 'y' | 'textAlign' | 'textBaseline' | 'lineWidth'>): BoundingRect;
|
66
|
+
export declare function tSpanCreateBoundingRect2(style: Pick<TSpanStyleProps, 'x' | 'y' | 'textAlign' | 'textBaseline' | 'lineWidth'>, contentWidth: number, contentHeight: number, forceLineWidth: number | NullUndefined): BoundingRect;
|
67
|
+
export declare function tSpanHasStroke(style: TSpanStyleProps): boolean;
|
63
68
|
export {};
|
@@ -93,8 +93,8 @@ function estimateLength(text, contentWidth, fontMeasureInfo) {
|
|
93
93
|
}
|
94
94
|
return i;
|
95
95
|
}
|
96
|
-
export function parsePlainText(
|
97
|
-
text
|
96
|
+
export function parsePlainText(rawText, style, defaultOuterWidth, defaultOuterHeight) {
|
97
|
+
var text = formatText(rawText);
|
98
98
|
var overflow = style.overflow;
|
99
99
|
var padding = style.padding;
|
100
100
|
var paddingH = padding ? padding[1] + padding[3] : 0;
|
@@ -195,9 +195,9 @@ var RichTextContentBlock = (function () {
|
|
195
195
|
return RichTextContentBlock;
|
196
196
|
}());
|
197
197
|
export { RichTextContentBlock };
|
198
|
-
export function parseRichText(
|
198
|
+
export function parseRichText(rawText, style, defaultOuterWidth, defaultOuterHeight, topTextAlign) {
|
199
199
|
var contentBlock = new RichTextContentBlock();
|
200
|
-
text
|
200
|
+
var text = formatText(rawText);
|
201
201
|
if (!text) {
|
202
202
|
return contentBlock;
|
203
203
|
}
|
@@ -523,3 +523,30 @@ export function calcInnerTextOverflowArea(out, overflowRect, baseX, baseY, textA
|
|
523
523
|
}
|
524
524
|
var tmpCITCTextRect = new BoundingRect(0, 0, 0, 0);
|
525
525
|
var tmpCITCIntersectRectOpt = { outIntersectRect: {}, clamp: true };
|
526
|
+
function formatText(text) {
|
527
|
+
return text != null ? (text += '') : (text = '');
|
528
|
+
}
|
529
|
+
export function tSpanCreateBoundingRect(style) {
|
530
|
+
var text = formatText(style.text);
|
531
|
+
var font = style.font;
|
532
|
+
var contentWidth = measureWidth(ensureFontMeasureInfo(font), text);
|
533
|
+
var contentHeight = getLineHeight(font);
|
534
|
+
return tSpanCreateBoundingRect2(style, contentWidth, contentHeight, null);
|
535
|
+
}
|
536
|
+
export function tSpanCreateBoundingRect2(style, contentWidth, contentHeight, forceLineWidth) {
|
537
|
+
var rect = new BoundingRect(adjustTextX(style.x || 0, contentWidth, style.textAlign), adjustTextY(style.y || 0, contentHeight, style.textBaseline), contentWidth, contentHeight);
|
538
|
+
var lineWidth = forceLineWidth != null
|
539
|
+
? forceLineWidth
|
540
|
+
: (tSpanHasStroke(style) ? style.lineWidth : 0);
|
541
|
+
if (lineWidth > 0) {
|
542
|
+
rect.x -= lineWidth / 2;
|
543
|
+
rect.y -= lineWidth / 2;
|
544
|
+
rect.width += lineWidth;
|
545
|
+
rect.height += lineWidth;
|
546
|
+
}
|
547
|
+
return rect;
|
548
|
+
}
|
549
|
+
export function tSpanHasStroke(style) {
|
550
|
+
var stroke = style.stroke;
|
551
|
+
return stroke != null && stroke !== 'none' && style.lineWidth > 0;
|
552
|
+
}
|
package/lib/zrender.d.ts
CHANGED
@@ -90,7 +90,7 @@ export declare type ElementSSRData = zrUtil.HashMap<unknown>;
|
|
90
90
|
export declare type ElementSSRDataGetter<T> = (el: Element) => zrUtil.HashMap<T>;
|
91
91
|
export declare function getElementSSRData(el: Element): ElementSSRData;
|
92
92
|
export declare function registerSSRDataGetter<T>(getter: ElementSSRDataGetter<T>): void;
|
93
|
-
export declare const version = "6.0.0-dev.
|
93
|
+
export declare const version = "6.0.0-dev.20250720";
|
94
94
|
export interface ZRenderType extends ZRender {
|
95
95
|
}
|
96
96
|
export {};
|
package/lib/zrender.js
CHANGED
package/package.json
CHANGED
package/src/contain/text.ts
CHANGED
@@ -106,7 +106,7 @@ export function measureWidth(fontMeasureInfo: FontMeasureInfo, text: string): nu
|
|
106
106
|
|
107
107
|
|
108
108
|
/**
|
109
|
-
*
|
109
|
+
* @deprecated See `getBoundingRect`.
|
110
110
|
* Get bounding rect for inner usage(TSpan)
|
111
111
|
* Which not include text newline.
|
112
112
|
*/
|
@@ -128,6 +128,9 @@ export function innerGetBoundingRect(
|
|
128
128
|
}
|
129
129
|
|
130
130
|
/**
|
131
|
+
* @deprecated Use `(new Text(...)).getBoundingRect()` or `(new TSpan(...)).getBoundingRect()` instead.
|
132
|
+
* This method behaves differently from `Text#getBoundingRect()` - e.g., it does not support the overflow
|
133
|
+
* strategy, and only has single line height even if multiple lines.
|
131
134
|
*
|
132
135
|
* Get bounding rect for outer usage. Compatitable with old implementation
|
133
136
|
* Which includes text newline.
|
package/src/graphic/TSpan.ts
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
import Displayable, { DisplayableProps, DisplayableStatePropNames } from './Displayable';
|
2
|
-
import { getBoundingRect } from '../contain/text';
|
3
2
|
import BoundingRect from '../core/BoundingRect';
|
4
3
|
import { PathStyleProps, DEFAULT_PATH_STYLE } from './Path';
|
5
4
|
import { createObject, defaults } from '../core/util';
|
6
|
-
import { FontStyle, FontWeight
|
5
|
+
import { FontStyle, FontWeight } from '../core/types';
|
7
6
|
import { DEFAULT_FONT } from '../core/platform';
|
7
|
+
import { tSpanCreateBoundingRect, tSpanHasStroke } from './helper/parseText';
|
8
8
|
|
9
9
|
export interface TSpanStyleProps extends PathStyleProps {
|
10
10
|
|
@@ -53,9 +53,7 @@ class TSpan extends Displayable<TSpanProps> {
|
|
53
53
|
style: TSpanStyleProps
|
54
54
|
|
55
55
|
hasStroke() {
|
56
|
-
|
57
|
-
const stroke = style.stroke;
|
58
|
-
return stroke != null && stroke !== 'none' && style.lineWidth > 0;
|
56
|
+
return tSpanHasStroke(this.style);
|
59
57
|
}
|
60
58
|
|
61
59
|
hasFill() {
|
@@ -81,31 +79,8 @@ class TSpan extends Displayable<TSpanProps> {
|
|
81
79
|
}
|
82
80
|
|
83
81
|
getBoundingRect(): BoundingRect {
|
84
|
-
const style = this.style;
|
85
|
-
|
86
82
|
if (!this._rect) {
|
87
|
-
|
88
|
-
text != null ? (text += '') : (text = '');
|
89
|
-
|
90
|
-
const rect = getBoundingRect(
|
91
|
-
text,
|
92
|
-
style.font,
|
93
|
-
style.textAlign as TextAlign,
|
94
|
-
style.textBaseline as TextVerticalAlign
|
95
|
-
);
|
96
|
-
|
97
|
-
rect.x += style.x || 0;
|
98
|
-
rect.y += style.y || 0;
|
99
|
-
|
100
|
-
if (this.hasStroke()) {
|
101
|
-
const w = style.lineWidth;
|
102
|
-
rect.x -= w / 2;
|
103
|
-
rect.y -= w / 2;
|
104
|
-
rect.width += w;
|
105
|
-
rect.height += w;
|
106
|
-
}
|
107
|
-
|
108
|
-
this._rect = rect;
|
83
|
+
this._rect = tSpanCreateBoundingRect(this.style);
|
109
84
|
}
|
110
85
|
|
111
86
|
return this._rect;
|
package/src/graphic/Text.ts
CHANGED
@@ -6,7 +6,8 @@ import {
|
|
6
6
|
TextAlign, TextVerticalAlign, ImageLike, Dictionary, MapToType, FontWeight, FontStyle, NullUndefined
|
7
7
|
} from '../core/types';
|
8
8
|
import {
|
9
|
-
parseRichText, parsePlainText, CalcInnerTextOverflowAreaOut, calcInnerTextOverflowArea
|
9
|
+
parseRichText, parsePlainText, CalcInnerTextOverflowAreaOut, calcInnerTextOverflowArea,
|
10
|
+
tSpanCreateBoundingRect2,
|
10
11
|
} from './helper/parseText';
|
11
12
|
import TSpan, { TSpanStyleProps } from './TSpan';
|
12
13
|
import { retrieve2, each, normalizeCssArray, trim, retrieve3, extend, keys, defaults } from '../core/util';
|
@@ -332,7 +333,7 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
|
|
332
333
|
}
|
333
334
|
}
|
334
335
|
|
335
|
-
|
336
|
+
updateTransform() {
|
336
337
|
const innerTransformable = this.innerTransformable;
|
337
338
|
if (innerTransformable) {
|
338
339
|
innerTransformable.updateTransform();
|
@@ -528,7 +529,6 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
|
|
528
529
|
|
529
530
|
const outerHeight = contentBlock.outerHeight;
|
530
531
|
const outerWidth = contentBlock.outerWidth;
|
531
|
-
const contentWidth = contentBlock.contentWidth;
|
532
532
|
|
533
533
|
const textLines = contentBlock.lines;
|
534
534
|
const lineHeight = contentBlock.lineHeight;
|
@@ -544,6 +544,13 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
|
|
544
544
|
const boxY = adjustTextY(baseY, outerHeight, verticalAlign);
|
545
545
|
needDrawBg && this._renderBackground(style, style, boxX, boxY, outerWidth, outerHeight);
|
546
546
|
}
|
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?
|
547
554
|
|
548
555
|
// `textBaseline` is set as 'middle'.
|
549
556
|
textY += lineHeight / 2;
|
@@ -559,6 +566,7 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
|
|
559
566
|
}
|
560
567
|
|
561
568
|
let defaultLineWidth = 0;
|
569
|
+
let usingDefaultStroke = false;
|
562
570
|
let useDefaultFill = false;
|
563
571
|
const textFill = getFill(
|
564
572
|
'fill' in style
|
@@ -580,16 +588,12 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
|
|
580
588
|
// we give the auto lineWidth to display the given stoke color.
|
581
589
|
&& (!defaultStyle.autoStroke || useDefaultFill)
|
582
590
|
)
|
583
|
-
? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
|
591
|
+
? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, usingDefaultStroke = true, defaultStyle.stroke)
|
584
592
|
: null
|
585
593
|
);
|
586
594
|
|
587
595
|
const hasShadow = style.textShadowBlur > 0;
|
588
596
|
|
589
|
-
const fixedBoundingRect = style.width != null
|
590
|
-
&& (style.overflow === 'truncate' || style.overflow === 'break' || style.overflow === 'breakAll');
|
591
|
-
const calculatedLineHeight = contentBlock.calculatedLineHeight;
|
592
|
-
|
593
597
|
for (let i = 0; i < textLines.length; i++) {
|
594
598
|
const el = this._getOrCreateChild(TSpan);
|
595
599
|
// Always create new style.
|
@@ -633,19 +637,27 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
|
|
633
637
|
|
634
638
|
textY += lineHeight;
|
635
639
|
|
636
|
-
if
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
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
|
+
));
|
649
661
|
}
|
650
662
|
}
|
651
663
|
|
@@ -801,6 +813,7 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
|
|
801
813
|
const defaultStyle = this._defaultStyle;
|
802
814
|
let useDefaultFill = false;
|
803
815
|
let defaultLineWidth = 0;
|
816
|
+
let usingDefaultStroke = false;
|
804
817
|
const textFill = getFill(
|
805
818
|
'fill' in tokenStyle ? tokenStyle.fill
|
806
819
|
: 'fill' in style ? style.fill
|
@@ -812,9 +825,9 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
|
|
812
825
|
: (
|
813
826
|
!bgColorDrawn
|
814
827
|
&& !parentBgColorDrawn
|
815
|
-
// See the strategy explained
|
828
|
+
// See the strategy explained `_updatePlainTexts`.
|
816
829
|
&& (!defaultStyle.autoStroke || useDefaultFill)
|
817
|
-
) ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
|
830
|
+
) ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, usingDefaultStroke = true, defaultStyle.stroke)
|
818
831
|
: null
|
819
832
|
);
|
820
833
|
|
@@ -852,14 +865,13 @@ class ZRText extends Displayable<TextProps> implements GroupLike {
|
|
852
865
|
subElStyle.fill = textFill;
|
853
866
|
}
|
854
867
|
|
855
|
-
const textWidth = token.contentWidth;
|
856
|
-
const textHeight = token.contentHeight;
|
857
868
|
// NOTE: Should not call dirtyStyle after setBoundingRect. Or it will be cleared.
|
858
|
-
el.setBoundingRect(
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
869
|
+
el.setBoundingRect(tSpanCreateBoundingRect2(
|
870
|
+
subElStyle,
|
871
|
+
token.contentWidth,
|
872
|
+
token.contentHeight,
|
873
|
+
// See the strategy explained `_updatePlainTexts`.
|
874
|
+
usingDefaultStroke ? 0 : null
|
863
875
|
));
|
864
876
|
}
|
865
877
|
|
@@ -6,7 +6,8 @@ import {
|
|
6
6
|
reduce,
|
7
7
|
} from '../../core/util';
|
8
8
|
import { TextAlign, TextVerticalAlign, ImageLike, Dictionary, NullUndefined } from '../../core/types';
|
9
|
-
import { DefaultTextStyle, TextStyleProps } from '../Text';
|
9
|
+
import type { DefaultTextStyle, TextStyleProps } from '../Text';
|
10
|
+
import type { TSpanStyleProps } from '../TSpan';
|
10
11
|
import {
|
11
12
|
adjustTextX,
|
12
13
|
adjustTextY,
|
@@ -210,12 +211,12 @@ export interface PlainTextContentBlock {
|
|
210
211
|
}
|
211
212
|
|
212
213
|
export function parsePlainText(
|
213
|
-
|
214
|
+
rawText: unknown,
|
214
215
|
style: Omit<TextStyleProps, 'align' | 'verticalAlign'>, // Exclude props in DefaultTextStyle
|
215
216
|
defaultOuterWidth: number | NullUndefined,
|
216
217
|
defaultOuterHeight: number | NullUndefined
|
217
218
|
): PlainTextContentBlock {
|
218
|
-
text
|
219
|
+
const text = formatText(rawText);
|
219
220
|
|
220
221
|
// textPadding has been normalized
|
221
222
|
const overflow = style.overflow;
|
@@ -382,7 +383,7 @@ type WrapInfo = {
|
|
382
383
|
* If styleName is undefined, it is plain text.
|
383
384
|
*/
|
384
385
|
export function parseRichText(
|
385
|
-
|
386
|
+
rawText: unknown,
|
386
387
|
style: Omit<TextStyleProps, 'align' | 'verticalAlign'>, // Exclude props in DefaultTextStyle
|
387
388
|
defaultOuterWidth: number | NullUndefined,
|
388
389
|
defaultOuterHeight: number | NullUndefined,
|
@@ -390,7 +391,7 @@ export function parseRichText(
|
|
390
391
|
): RichTextContentBlock {
|
391
392
|
const contentBlock = new RichTextContentBlock();
|
392
393
|
|
393
|
-
text
|
394
|
+
const text = formatText(rawText);
|
394
395
|
if (!text) {
|
395
396
|
return contentBlock;
|
396
397
|
}
|
@@ -890,3 +891,61 @@ export type CalcInnerTextOverflowAreaOut = {
|
|
890
891
|
outerHeight: number | NullUndefined
|
891
892
|
};
|
892
893
|
|
894
|
+
// For backward compatibility, and possibly loose type.
|
895
|
+
function formatText(text: unknown): string {
|
896
|
+
return text != null ? (text += '') : (text = '');
|
897
|
+
}
|
898
|
+
|
899
|
+
export function tSpanCreateBoundingRect(
|
900
|
+
style: Pick<TSpanStyleProps, 'text' | 'font' | 'x' | 'y' | 'textAlign' | 'textBaseline' | 'lineWidth'>,
|
901
|
+
): BoundingRect {
|
902
|
+
// Should follow the same way as `parsePlainText` to guarantee the consistency of the result.
|
903
|
+
const text = formatText(style.text);
|
904
|
+
const font = style.font;
|
905
|
+
const contentWidth = measureWidth(ensureFontMeasureInfo(font), text);
|
906
|
+
const contentHeight = getLineHeight(font);
|
907
|
+
|
908
|
+
return tSpanCreateBoundingRect2(
|
909
|
+
style,
|
910
|
+
contentWidth,
|
911
|
+
contentHeight,
|
912
|
+
null
|
913
|
+
);
|
914
|
+
}
|
915
|
+
|
916
|
+
export function tSpanCreateBoundingRect2(
|
917
|
+
style: Pick<TSpanStyleProps, 'x' | 'y' | 'textAlign' | 'textBaseline' | 'lineWidth'>,
|
918
|
+
contentWidth: number,
|
919
|
+
contentHeight: number,
|
920
|
+
forceLineWidth: number | NullUndefined,
|
921
|
+
): BoundingRect {
|
922
|
+
const rect = new BoundingRect(
|
923
|
+
adjustTextX(style.x || 0, contentWidth, style.textAlign as TextAlign),
|
924
|
+
adjustTextY(style.y || 0, contentHeight, style.textBaseline as TextVerticalAlign),
|
925
|
+
/**
|
926
|
+
* Text boundary should be the real text width.
|
927
|
+
* Otherwise, there will be extra space in the
|
928
|
+
* bounding rect calculated.
|
929
|
+
*/
|
930
|
+
contentWidth,
|
931
|
+
contentHeight
|
932
|
+
);
|
933
|
+
|
934
|
+
const lineWidth = forceLineWidth != null
|
935
|
+
? forceLineWidth
|
936
|
+
: (tSpanHasStroke(style) ? style.lineWidth : 0);
|
937
|
+
if (lineWidth > 0) {
|
938
|
+
rect.x -= lineWidth / 2;
|
939
|
+
rect.y -= lineWidth / 2;
|
940
|
+
rect.width += lineWidth;
|
941
|
+
rect.height += lineWidth;
|
942
|
+
}
|
943
|
+
|
944
|
+
return rect;
|
945
|
+
}
|
946
|
+
|
947
|
+
export function tSpanHasStroke(style: TSpanStyleProps): boolean {
|
948
|
+
const stroke = style.stroke;
|
949
|
+
return stroke != null && stroke !== 'none' && style.lineWidth > 0;
|
950
|
+
}
|
951
|
+
|
package/src/zrender.ts
CHANGED
@@ -556,7 +556,7 @@ export function registerSSRDataGetter<T>(getter: ElementSSRDataGetter<T>) {
|
|
556
556
|
/**
|
557
557
|
* @type {string}
|
558
558
|
*/
|
559
|
-
export const version = '6.0.0-dev.
|
559
|
+
export const version = '6.0.0-dev.20250720';
|
560
560
|
|
561
561
|
|
562
562
|
export interface ZRenderType extends ZRender {};
|