mh-two-thousand-and-two
2024-03-25 b8c93990f3fa5e50a8aca16bdc9c2758168aa0fd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import Displayable, { DisplayableProps, DisplayableStatePropNames } from './Displayable';
import { getBoundingRect } from '../contain/text';
import BoundingRect from '../core/BoundingRect';
import { PathStyleProps, DEFAULT_PATH_STYLE } from './Path';
import { createObject, defaults } from '../core/util';
import { FontStyle, FontWeight, TextAlign, TextVerticalAlign } from '../core/types';
import { DEFAULT_FONT } from '../core/platform';
 
export interface TSpanStyleProps extends PathStyleProps {
 
    x?: number
    y?: number
 
    // TODO Text is assigned inside zrender
    text?: string
 
    // Final generated font string
    // Used in canvas, and when developers specified it.
    font?: string
 
    // Value for each part of font
    // Used in svg.
    // NOTE: font should always been sync with these 4 properties.
    fontSize?: number
    fontWeight?: FontWeight
    fontStyle?: FontStyle
    fontFamily?: string
 
    textAlign?: CanvasTextAlign
 
    textBaseline?: CanvasTextBaseline
}
 
export const DEFAULT_TSPAN_STYLE: TSpanStyleProps = defaults({
    strokeFirst: true,
    font: DEFAULT_FONT,
    x: 0,
    y: 0,
    textAlign: 'left',
    textBaseline: 'top',
    miterLimit: 2
} as TSpanStyleProps, DEFAULT_PATH_STYLE);
 
 
export interface TSpanProps extends DisplayableProps {
    style?: TSpanStyleProps
}
 
export type TSpanState = Pick<TSpanProps, DisplayableStatePropNames>
 
class TSpan extends Displayable<TSpanProps> {
 
    style: TSpanStyleProps
 
    hasStroke() {
        const style = this.style;
        const stroke = style.stroke;
        return stroke != null && stroke !== 'none' && style.lineWidth > 0;
    }
 
    hasFill() {
        const style = this.style;
        const fill = style.fill;
        return fill != null && fill !== 'none';
    }
 
    /**
     * Create an image style object with default values in it's prototype.
     * @override
     */
    createStyle(obj?: TSpanStyleProps) {
        return createObject(DEFAULT_TSPAN_STYLE, obj);
    }
 
    /**
     * Set bounding rect calculated from Text
     * For reducing time of calculating bounding rect.
     */
    setBoundingRect(rect: BoundingRect) {
        this._rect = rect;
    }
 
    getBoundingRect(): BoundingRect {
        const style = this.style;
 
        if (!this._rect) {
            let text = style.text;
            text != null ? (text += '') : (text = '');
 
            const rect = getBoundingRect(
                text,
                style.font,
                style.textAlign as TextAlign,
                style.textBaseline as TextVerticalAlign
            );
 
            rect.x += style.x || 0;
            rect.y += style.y || 0;
 
            if (this.hasStroke()) {
                const w = style.lineWidth;
                rect.x -= w / 2;
                rect.y -= w / 2;
                rect.width += w;
                rect.height += w;
            }
 
            this._rect = rect;
        }
 
        return this._rect;
    }
 
    protected static initDefaultProps = (function () {
        const tspanProto = TSpan.prototype;
        // TODO Calculate tolerance smarter
        tspanProto.dirtyRectTolerance = 10;
    })()
}
 
TSpan.prototype.type = 'tspan';
 
export default TSpan;