@@ -14,7 +14,7 @@ import { defined, RuntimeError } from './util';
14
14
15
15
export interface TimeSignatureInfo {
16
16
glyph : Glyph ;
17
- line ? : number ;
17
+ line : number ;
18
18
num : boolean ;
19
19
}
20
20
@@ -36,6 +36,11 @@ const assertIsValidTimeSig = (timeSpec: string) => {
36
36
} ) ;
37
37
} ;
38
38
39
+ /**
40
+ * A TimeSignature is a StaveModifier that can make its appropriate Glyphs directly from
41
+ * a provided "timeSpec" such as "4/4", "C|" (cut time), or even something more advanced
42
+ * such as "3/4(6/8)" or "2/4+5/8".
43
+ */
39
44
export class TimeSignature extends StaveModifier {
40
45
static get CATEGORY ( ) : string {
41
46
return Category . TimeSignature ;
@@ -57,10 +62,13 @@ export class TimeSignature extends StaveModifier {
57
62
}
58
63
59
64
point : number ;
60
- bottomLine : number ;
61
- topLine : number ;
65
+ bottomLine : number ; // bottomLine and topLine are used to calculate the position of the
66
+ topLine : number ; // top row of digits in a numeric TimeSignature.
62
67
63
- protected info : TimeSignatureInfo ;
68
+ protected timeSpec : string = '4/4' ;
69
+ protected line : number = 0 ;
70
+ protected glyph ! : Glyph ;
71
+ protected is_numeric : boolean = true ;
64
72
protected validate_args : boolean ;
65
73
66
74
constructor ( timeSpec : string = '4/4' , customPadding = 15 , validate_args = true ) {
@@ -69,17 +77,23 @@ export class TimeSignature extends StaveModifier {
69
77
70
78
const padding = customPadding ;
71
79
80
+ // point must be defined before parsing spec.
72
81
const musicFont = Tables . currentMusicFont ( ) ;
73
82
this . point = musicFont . lookupMetric ( 'digits.point' ) ;
83
+
74
84
const fontLineShift = musicFont . lookupMetric ( 'digits.shiftLine' , 0 ) ;
75
85
this . topLine = 2 + fontLineShift ;
76
86
this . bottomLine = 4 + fontLineShift ;
77
87
this . setPosition ( StaveModifierPosition . BEGIN ) ;
78
- this . info = this . parseTimeSpec ( timeSpec ) ;
79
- this . setWidth ( defined ( this . info . glyph . getMetrics ( ) . width ) ) ;
88
+ this . setTimeSig ( timeSpec ) ;
80
89
this . setPadding ( padding ) ;
81
90
}
82
91
92
+ /**
93
+ * Return TimeSignatureInfo given a string, consisting of line (number),
94
+ * num (boolean: same as TimeSignature.getIsNumeric()), and glyph (a Glyph or
95
+ * TimeSignatureGlyph object).
96
+ */
83
97
parseTimeSpec ( timeSpec : string ) : TimeSignatureInfo {
84
98
if ( timeSpec === 'C' || timeSpec === 'C|' ) {
85
99
const { line, code, point } = TimeSignature . glyphs [ timeSpec ] ;
@@ -97,35 +111,115 @@ export class TimeSignature extends StaveModifier {
97
111
const parts = timeSpec . split ( '/' ) ;
98
112
99
113
return {
114
+ line : 0 ,
100
115
num : true ,
101
116
glyph : this . makeTimeSignatureGlyph ( parts [ 0 ] ?? '' , parts [ 1 ] ?? '' ) ,
102
117
} ;
103
118
}
104
119
105
- makeTimeSignatureGlyph ( topDigits : string , botDigits : string ) : Glyph {
120
+ /**
121
+ * Returns a new TimeSignatureGlyph (a Glyph subclass that knows how to draw both
122
+ * top and bottom digits along with plus signs etc.)
123
+ */
124
+ makeTimeSignatureGlyph ( topDigits : string , botDigits : string ) : TimeSignatureGlyph {
125
+ // note that 'code' is ignored by TimeSignatureGlyph when rendering.
106
126
return new TimeSignatureGlyph ( this , topDigits , botDigits , 'timeSig0' , this . point ) ;
107
127
}
108
128
129
+ /**
130
+ * Returns {line, num (=getIsNumeric), glyph} --
131
+ * but these can also be accessed directly w/ getters and setters.
132
+ */
109
133
getInfo ( ) : TimeSignatureInfo {
110
- return this . info ;
134
+ const { line, is_numeric, glyph } = this ;
135
+ return { line, num : is_numeric , glyph } ;
111
136
}
112
137
138
+ /**
139
+ * Set a new time signature specification without changing customPadding, etc.
140
+ *
141
+ * The getter for this is `getTimeSpec` not `getTimeSig`.
142
+ */
113
143
setTimeSig ( timeSpec : string ) : this {
114
- this . info = this . parseTimeSpec ( timeSpec ) ;
144
+ this . timeSpec = timeSpec ;
145
+ const info = this . parseTimeSpec ( timeSpec ) ;
146
+ this . setGlyph ( info . glyph ) ;
147
+ this . is_numeric = info . num ;
148
+ this . line = info . line ;
115
149
return this ;
116
150
}
117
151
152
+ /**
153
+ * Return the timeSpec (such as '4/4' or 'C|' or even '2/4+3/8') of the TimeSignature
154
+ */
155
+ getTimeSpec ( ) : string {
156
+ return this . timeSpec ;
157
+ }
158
+
159
+ /**
160
+ * Return the staff line that the TimeSignature sits on. Generally 0 for numerator/
161
+ * denominator time signatures such as 3/4 and 2 for cut/common.
162
+ */
163
+ getLine ( ) : number {
164
+ return this . line ;
165
+ }
166
+
167
+ /**
168
+ * Set the line number that the TimeSignature sits on. Half-values are acceptable
169
+ * for spaces, etc. Can be altered, for instance, for signatures that sit above the
170
+ * staff in large orchestral scores.
171
+ */
172
+ setLine ( line : number ) {
173
+ this . line = line ;
174
+ }
175
+
176
+ /**
177
+ * Get the Glyph object used to create the time signature. Numeric time signatures
178
+ * such as 3/8 have a composite Glyph stored as a single Glyph object.
179
+ */
180
+ getGlyph ( ) : Glyph {
181
+ return this . glyph ;
182
+ }
183
+
184
+ /**
185
+ * Set the Glyph object used to draw the time signature, and update the width of the
186
+ * TimeSignature to match. The Glyph must define width in its metrics.
187
+ */
188
+ setGlyph ( glyph : Glyph ) {
189
+ this . glyph = glyph ;
190
+ this . setWidth ( defined ( this . glyph . getMetrics ( ) . width ) ) ;
191
+ }
192
+
193
+ /**
194
+ * Return a boolean on whether this TimeSignature is drawn with one or more numbers
195
+ * (such as 4/4) or not (as in cut time).
196
+ */
197
+ getIsNumeric ( ) : boolean {
198
+ return this . is_numeric ;
199
+ }
200
+
201
+ /**
202
+ * Set whether this TimeSignature is drawn with one or more numbers.
203
+ */
204
+ setIsNumeric ( isNumeric : boolean ) {
205
+ this . is_numeric = isNumeric ;
206
+ }
207
+
208
+ /**
209
+ * Draw the time signature on a Stave using its RenderContext. Both setStave
210
+ * and setContext must already be run.
211
+ */
118
212
draw ( ) : void {
119
213
const stave = this . checkStave ( ) ;
120
214
const ctx = stave . checkContext ( ) ;
121
215
this . setRendered ( ) ;
122
216
123
217
this . applyStyle ( ctx ) ;
124
218
ctx . openGroup ( 'timesignature' , this . getAttribute ( 'id' ) ) ;
125
- this . info . glyph . setStave ( stave ) ;
126
- this . info . glyph . setContext ( ctx ) ;
127
- this . placeGlyphOnLine ( this . info . glyph , stave , this . info . line ) ;
128
- this . info . glyph . renderToStave ( this . x ) ;
219
+ this . glyph . setStave ( stave ) ;
220
+ this . glyph . setContext ( ctx ) ;
221
+ this . placeGlyphOnLine ( this . glyph , stave , this . line ) ;
222
+ this . glyph . renderToStave ( this . x ) ;
129
223
ctx . closeGroup ( ) ;
130
224
this . restoreStyle ( ctx ) ;
131
225
}
0 commit comments