@coderline/alphatab 1.8.0-alpha.1637 → 1.8.0-alpha.1639
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/alphaTab.core.min.mjs +2 -2
- package/dist/alphaTab.core.mjs +794 -732
- package/dist/alphaTab.js +794 -732
- package/dist/alphaTab.min.js +2 -2
- package/dist/alphaTab.min.mjs +1 -1
- package/dist/alphaTab.mjs +1 -1
- package/dist/alphaTab.worker.min.mjs +1 -1
- package/dist/alphaTab.worker.mjs +1 -1
- package/dist/alphaTab.worklet.min.mjs +1 -1
- package/dist/alphaTab.worklet.mjs +1 -1
- package/package.json +3 -3
package/dist/alphaTab.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* alphaTab v1.8.0-alpha.
|
|
2
|
+
* alphaTab v1.8.0-alpha.1639 (develop, build 1639)
|
|
3
3
|
*
|
|
4
4
|
* Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
5
|
*
|
|
@@ -209,9 +209,9 @@
|
|
|
209
209
|
* @internal
|
|
210
210
|
*/
|
|
211
211
|
class VersionInfo {
|
|
212
|
-
static version = '1.8.0-alpha.
|
|
213
|
-
static date = '2025-12-
|
|
214
|
-
static commit = '
|
|
212
|
+
static version = '1.8.0-alpha.1639';
|
|
213
|
+
static date = '2025-12-09T02:16:01.440Z';
|
|
214
|
+
static commit = 'af86866e4f9d89a3ccc34006d01473a549dbbe7f';
|
|
215
215
|
static print(print) {
|
|
216
216
|
print(`alphaTab ${VersionInfo.version}`);
|
|
217
217
|
print(`commit: ${VersionInfo.commit}`);
|
|
@@ -56670,12 +56670,12 @@
|
|
|
56670
56670
|
this.endPosition = endPosition;
|
|
56671
56671
|
}
|
|
56672
56672
|
get isLinkedWithPrevious() {
|
|
56673
|
-
return !!this.previousGlyph && this.previousGlyph.renderer.staff
|
|
56673
|
+
return !!this.previousGlyph && this.previousGlyph.renderer.staff?.system === this.renderer.staff.system;
|
|
56674
56674
|
}
|
|
56675
56675
|
get isLinkedWithNext() {
|
|
56676
56676
|
return (!!this.nextGlyph &&
|
|
56677
56677
|
this.nextGlyph.renderer.isFinalized &&
|
|
56678
|
-
this.nextGlyph.renderer.staff
|
|
56678
|
+
this.nextGlyph.renderer.staff?.system === this.renderer.staff.system);
|
|
56679
56679
|
}
|
|
56680
56680
|
paint(cx, cy, canvas) {
|
|
56681
56681
|
// if we are linked with the previous, the first glyph of the group will also render this one.
|
|
@@ -59063,6 +59063,437 @@
|
|
|
59063
59063
|
}
|
|
59064
59064
|
}
|
|
59065
59065
|
|
|
59066
|
+
/**
|
|
59067
|
+
* @internal
|
|
59068
|
+
*/
|
|
59069
|
+
class TieGlyph extends Glyph {
|
|
59070
|
+
tieDirection = BeamDirection.Up;
|
|
59071
|
+
slurEffectId;
|
|
59072
|
+
isForEnd;
|
|
59073
|
+
constructor(slurEffectId, forEnd) {
|
|
59074
|
+
super(0, 0);
|
|
59075
|
+
this.slurEffectId = slurEffectId;
|
|
59076
|
+
this.isForEnd = forEnd;
|
|
59077
|
+
}
|
|
59078
|
+
_startX = 0;
|
|
59079
|
+
_startY = 0;
|
|
59080
|
+
_endX = 0;
|
|
59081
|
+
_endY = 0;
|
|
59082
|
+
_tieHeight = 0;
|
|
59083
|
+
_boundingBox;
|
|
59084
|
+
_shouldPaint = false;
|
|
59085
|
+
get checkForOverflow() {
|
|
59086
|
+
return this._shouldPaint && this._boundingBox !== undefined;
|
|
59087
|
+
}
|
|
59088
|
+
getBoundingBoxTop() {
|
|
59089
|
+
if (this._boundingBox) {
|
|
59090
|
+
return this._boundingBox.y;
|
|
59091
|
+
}
|
|
59092
|
+
return this._startY;
|
|
59093
|
+
}
|
|
59094
|
+
getBoundingBoxBottom() {
|
|
59095
|
+
if (this._boundingBox) {
|
|
59096
|
+
return this._boundingBox.y + this._boundingBox.h;
|
|
59097
|
+
}
|
|
59098
|
+
return this._startY;
|
|
59099
|
+
}
|
|
59100
|
+
doLayout() {
|
|
59101
|
+
this.width = 0;
|
|
59102
|
+
const startNoteRenderer = this.lookupStartBeatRenderer();
|
|
59103
|
+
const endNoteRenderer = this.lookupEndBeatRenderer();
|
|
59104
|
+
this._startX = 0;
|
|
59105
|
+
this._endX = 0;
|
|
59106
|
+
this._startY = 0;
|
|
59107
|
+
this._endY = 0;
|
|
59108
|
+
this.height = 0;
|
|
59109
|
+
// if we are on the tie start, we check if we
|
|
59110
|
+
// either can draw till the end note, or we just can draw till the bar end
|
|
59111
|
+
this.tieDirection = this.calculateTieDirection();
|
|
59112
|
+
const forEnd = this.isForEnd;
|
|
59113
|
+
this._shouldPaint = false;
|
|
59114
|
+
if (!forEnd) {
|
|
59115
|
+
if (startNoteRenderer !== endNoteRenderer) {
|
|
59116
|
+
this._startX = this.calculateStartX();
|
|
59117
|
+
this._startY = this.calculateStartY();
|
|
59118
|
+
if (!endNoteRenderer || startNoteRenderer.staff !== endNoteRenderer.staff) {
|
|
59119
|
+
const lastRendererInStaff = startNoteRenderer.staff.barRenderers[startNoteRenderer.staff.barRenderers.length - 1];
|
|
59120
|
+
this._endX = lastRendererInStaff.x + lastRendererInStaff.width;
|
|
59121
|
+
this._endY = this._startY;
|
|
59122
|
+
startNoteRenderer.scoreRenderer.layout.slurRegistry.startMultiSystemSlur(this);
|
|
59123
|
+
}
|
|
59124
|
+
else {
|
|
59125
|
+
this._endX = this.calculateEndX();
|
|
59126
|
+
this._endY = this.caclculateEndY();
|
|
59127
|
+
}
|
|
59128
|
+
}
|
|
59129
|
+
else {
|
|
59130
|
+
this._shouldPaint = true;
|
|
59131
|
+
this._startX = this.calculateStartX();
|
|
59132
|
+
this._endX = this.calculateEndX();
|
|
59133
|
+
this._startY = this.calculateStartY();
|
|
59134
|
+
this._endY = this.caclculateEndY();
|
|
59135
|
+
}
|
|
59136
|
+
this._shouldPaint = true;
|
|
59137
|
+
}
|
|
59138
|
+
else if (startNoteRenderer.staff !== endNoteRenderer.staff) {
|
|
59139
|
+
const firstRendererInStaff = startNoteRenderer.staff.barRenderers[0];
|
|
59140
|
+
this._startX = firstRendererInStaff.x;
|
|
59141
|
+
this._endX = this.calculateEndX();
|
|
59142
|
+
const startGlyph = startNoteRenderer.scoreRenderer.layout.slurRegistry.completeMultiSystemSlur(this);
|
|
59143
|
+
if (startGlyph) {
|
|
59144
|
+
this._startY = startGlyph.calculateMultiSystemSlurY(endNoteRenderer);
|
|
59145
|
+
}
|
|
59146
|
+
else {
|
|
59147
|
+
this._startY = this.caclculateEndY();
|
|
59148
|
+
}
|
|
59149
|
+
this._endY = this.caclculateEndY();
|
|
59150
|
+
this._shouldPaint = startNoteRenderer.staff !== endNoteRenderer.staff;
|
|
59151
|
+
}
|
|
59152
|
+
this._boundingBox = undefined;
|
|
59153
|
+
this.y = Math.min(this._startY, this._endY);
|
|
59154
|
+
if (this.shouldDrawBendSlur()) {
|
|
59155
|
+
this._tieHeight = 0; // TODO: Bend slur height to be considered?
|
|
59156
|
+
}
|
|
59157
|
+
else {
|
|
59158
|
+
this._tieHeight = this.getTieHeight(this._startX, this._startY, this._endX, this._endY);
|
|
59159
|
+
const tieBoundingBox = TieGlyph.calculateActualTieHeight(1, this._startX, this._startY, this._endX, this._endY, this.tieDirection === BeamDirection.Down, this._tieHeight, this.renderer.smuflMetrics.tieMidpointThickness);
|
|
59160
|
+
this._boundingBox = tieBoundingBox;
|
|
59161
|
+
this.height = tieBoundingBox.h;
|
|
59162
|
+
if (this.tieDirection === BeamDirection.Up) {
|
|
59163
|
+
// the tie might go above `this.y` due to its shape
|
|
59164
|
+
// here we calculate how much this is so we can consider the
|
|
59165
|
+
// respective overflow
|
|
59166
|
+
const overlap = this.y - tieBoundingBox.y;
|
|
59167
|
+
if (overlap > 0) {
|
|
59168
|
+
this.y -= overlap;
|
|
59169
|
+
}
|
|
59170
|
+
}
|
|
59171
|
+
}
|
|
59172
|
+
}
|
|
59173
|
+
paint(cx, cy, canvas) {
|
|
59174
|
+
if (!this._shouldPaint) {
|
|
59175
|
+
return;
|
|
59176
|
+
}
|
|
59177
|
+
if (this.shouldDrawBendSlur()) {
|
|
59178
|
+
TieGlyph.drawBendSlur(canvas, cx + this._startX, cy + this._startY, cx + this._endX, cy + this._endY, this.tieDirection === BeamDirection.Down, 1, this.renderer.smuflMetrics.tieHeight);
|
|
59179
|
+
}
|
|
59180
|
+
else {
|
|
59181
|
+
TieGlyph.paintTie(canvas, 1, cx + this._startX, cy + this._startY, cx + this._endX, cy + this._endY, this.tieDirection === BeamDirection.Down, this._tieHeight, this.renderer.smuflMetrics.tieMidpointThickness);
|
|
59182
|
+
}
|
|
59183
|
+
}
|
|
59184
|
+
getTieHeight(_startX, _startY, _endX, _endY) {
|
|
59185
|
+
return this.renderer.smuflMetrics.tieHeight;
|
|
59186
|
+
}
|
|
59187
|
+
calculateMultiSystemSlurY(renderer) {
|
|
59188
|
+
const startRenderer = this.lookupStartBeatRenderer();
|
|
59189
|
+
const startY = this.calculateStartY();
|
|
59190
|
+
const relY = startY - startRenderer.y;
|
|
59191
|
+
return renderer.y + relY;
|
|
59192
|
+
}
|
|
59193
|
+
shouldCreateMultiSystemSlur(renderer) {
|
|
59194
|
+
const endStaff = this.lookupEndBeatRenderer()?.staff;
|
|
59195
|
+
if (!endStaff) {
|
|
59196
|
+
return true;
|
|
59197
|
+
}
|
|
59198
|
+
return renderer.staff.system.index < endStaff.system.index;
|
|
59199
|
+
}
|
|
59200
|
+
static calculateActualTieHeight(scale, x1, y1, x2, y2, down, offset, size) {
|
|
59201
|
+
const cp = TieGlyph._computeBezierControlPoints(scale, x1, y1, x2, y2, down, offset, size);
|
|
59202
|
+
if (cp.length === 0) {
|
|
59203
|
+
return new Bounds(x1, y1, x2 - x1, y2 - y1);
|
|
59204
|
+
}
|
|
59205
|
+
// For a musical tie/slur, the extrema occur predictably near the midpoint
|
|
59206
|
+
// Evaluate at midpoint (t=0.5) and check endpoints
|
|
59207
|
+
const p0x = cp[0];
|
|
59208
|
+
const p0y = cp[1];
|
|
59209
|
+
const c1x = cp[2];
|
|
59210
|
+
const c1y = cp[3];
|
|
59211
|
+
const c2x = cp[4];
|
|
59212
|
+
const c2y = cp[5];
|
|
59213
|
+
const p1x = cp[6];
|
|
59214
|
+
const p1y = cp[7];
|
|
59215
|
+
// Evaluate at t=0.5 for midpoint
|
|
59216
|
+
const midX = 0.125 * p0x + 0.375 * c1x + 0.375 * c2x + 0.125 * p1x;
|
|
59217
|
+
const midY = 0.125 * p0y + 0.375 * c1y + 0.375 * c2y + 0.125 * p1y;
|
|
59218
|
+
// Bounds are simply min/max of start, end, and midpoint
|
|
59219
|
+
const xMin = Math.min(p0x, p1x, midX);
|
|
59220
|
+
const xMax = Math.max(p0x, p1x, midX);
|
|
59221
|
+
let yMin = Math.min(p0y, p1y, midY);
|
|
59222
|
+
let yMax = Math.max(p0y, p1y, midY);
|
|
59223
|
+
// Account for thickness of the tie/slur
|
|
59224
|
+
if (down) {
|
|
59225
|
+
yMax += size;
|
|
59226
|
+
}
|
|
59227
|
+
else {
|
|
59228
|
+
yMin -= size;
|
|
59229
|
+
}
|
|
59230
|
+
const b = new Bounds();
|
|
59231
|
+
b.x = xMin;
|
|
59232
|
+
b.y = yMin;
|
|
59233
|
+
b.w = xMax - xMin;
|
|
59234
|
+
b.h = yMax - yMin;
|
|
59235
|
+
return b;
|
|
59236
|
+
}
|
|
59237
|
+
static _computeBezierControlPoints(scale, x1, y1, x2, y2, down, offset, size) {
|
|
59238
|
+
if (x1 === x2 && y1 === y2) {
|
|
59239
|
+
return [];
|
|
59240
|
+
}
|
|
59241
|
+
// ensure endX > startX
|
|
59242
|
+
if (x2 < x1) {
|
|
59243
|
+
let t = x1;
|
|
59244
|
+
x1 = x2;
|
|
59245
|
+
x2 = t;
|
|
59246
|
+
t = y1;
|
|
59247
|
+
y1 = y2;
|
|
59248
|
+
y2 = t;
|
|
59249
|
+
}
|
|
59250
|
+
//
|
|
59251
|
+
// calculate control points
|
|
59252
|
+
//
|
|
59253
|
+
offset *= scale;
|
|
59254
|
+
size *= scale;
|
|
59255
|
+
if (down) {
|
|
59256
|
+
offset *= -1;
|
|
59257
|
+
size *= -1;
|
|
59258
|
+
}
|
|
59259
|
+
if (scale >= 1) {
|
|
59260
|
+
size *= 1.2;
|
|
59261
|
+
}
|
|
59262
|
+
// calculate control points on horizontal axis then rotate:
|
|
59263
|
+
/*
|
|
59264
|
+
cp1x/cpy1 cp2x/cpy2
|
|
59265
|
+
*----------------*
|
|
59266
|
+
/ \
|
|
59267
|
+
/ \
|
|
59268
|
+
x1/y1 * * x2/y2
|
|
59269
|
+
|
|
59270
|
+
cp3 and cp4 are simply with lower height
|
|
59271
|
+
*/
|
|
59272
|
+
const dY = y2 - y1;
|
|
59273
|
+
const dX = x2 - x1;
|
|
59274
|
+
const length = Math.sqrt(dX * dX + dY * dY);
|
|
59275
|
+
let cp1x = x1 + length * 0.25;
|
|
59276
|
+
let cp1y = y1 - offset;
|
|
59277
|
+
let cp2x = x1 + length * 0.75;
|
|
59278
|
+
let cp2y = y1 - offset;
|
|
59279
|
+
let cp3x = x1 + length * 0.75;
|
|
59280
|
+
let cp3y = y1 - offset - size;
|
|
59281
|
+
let cp4x = x1 + length * 0.25;
|
|
59282
|
+
let cp4y = y1 - offset - size;
|
|
59283
|
+
const angle = Math.atan2(dY, dX);
|
|
59284
|
+
[cp1x, cp1y] = TieGlyph._rotate(cp1x, cp1y, x1, y1, angle);
|
|
59285
|
+
[cp2x, cp2y] = TieGlyph._rotate(cp2x, cp2y, x1, y1, angle);
|
|
59286
|
+
[cp3x, cp3y] = TieGlyph._rotate(cp3x, cp3y, x1, y1, angle);
|
|
59287
|
+
[cp4x, cp4y] = TieGlyph._rotate(cp4x, cp4y, x1, y1, angle);
|
|
59288
|
+
return [x1, y1, cp1x, cp1y, cp2x, cp2y, x2, y2, cp3x, cp3y, cp4x, cp4y, x1, y1];
|
|
59289
|
+
}
|
|
59290
|
+
static _rotate(x, y, rotateX, rotateY, angle) {
|
|
59291
|
+
const dx = x - rotateX;
|
|
59292
|
+
const dy = y - rotateY;
|
|
59293
|
+
const rx = dx * Math.cos(angle) - dy * Math.sin(angle);
|
|
59294
|
+
const ry = dx * Math.sin(angle) + dy * Math.cos(angle);
|
|
59295
|
+
return [rotateX + rx, rotateY + ry];
|
|
59296
|
+
}
|
|
59297
|
+
static paintTie(canvas, scale, x1, y1, x2, y2, down /*= false*/, offset /*= 22*/, size /*= 4*/) {
|
|
59298
|
+
const cps = TieGlyph._computeBezierControlPoints(scale, x1, y1, x2, y2, down, offset, size);
|
|
59299
|
+
canvas.beginPath();
|
|
59300
|
+
canvas.moveTo(cps[0], cps[1]);
|
|
59301
|
+
canvas.bezierCurveTo(cps[2], cps[3], cps[4], cps[5], cps[6], cps[7]);
|
|
59302
|
+
canvas.bezierCurveTo(cps[8], cps[9], cps[10], cps[11], cps[12], cps[13]);
|
|
59303
|
+
canvas.closePath();
|
|
59304
|
+
canvas.fill();
|
|
59305
|
+
}
|
|
59306
|
+
static calculateBendSlurTopY(x1, y1, x2, y2, down, scale, bendSlurHeight) {
|
|
59307
|
+
let normalVectorX = y2 - y1;
|
|
59308
|
+
let normalVectorY = x2 - x1;
|
|
59309
|
+
const length = Math.sqrt(normalVectorX * normalVectorX + normalVectorY * normalVectorY);
|
|
59310
|
+
if (down) {
|
|
59311
|
+
normalVectorX *= -1;
|
|
59312
|
+
}
|
|
59313
|
+
else {
|
|
59314
|
+
normalVectorY *= -1;
|
|
59315
|
+
}
|
|
59316
|
+
// make to unit vector
|
|
59317
|
+
normalVectorX /= length;
|
|
59318
|
+
normalVectorY /= length;
|
|
59319
|
+
let offset = bendSlurHeight * scale;
|
|
59320
|
+
if (x2 - x1 < 20) {
|
|
59321
|
+
offset /= 2;
|
|
59322
|
+
}
|
|
59323
|
+
const centerY = (y2 + y1) / 2;
|
|
59324
|
+
const cp1Y = centerY + offset * normalVectorY;
|
|
59325
|
+
return cp1Y;
|
|
59326
|
+
}
|
|
59327
|
+
static drawBendSlur(canvas, x1, y1, x2, y2, down, scale, bendSlurHeight, slurText) {
|
|
59328
|
+
let normalVectorX = y2 - y1;
|
|
59329
|
+
let normalVectorY = x2 - x1;
|
|
59330
|
+
const length = Math.sqrt(normalVectorX * normalVectorX + normalVectorY * normalVectorY);
|
|
59331
|
+
if (down) {
|
|
59332
|
+
normalVectorX *= -1;
|
|
59333
|
+
}
|
|
59334
|
+
else {
|
|
59335
|
+
normalVectorY *= -1;
|
|
59336
|
+
}
|
|
59337
|
+
// make to unit vector
|
|
59338
|
+
normalVectorX /= length;
|
|
59339
|
+
normalVectorY /= length;
|
|
59340
|
+
// center of connection
|
|
59341
|
+
// TODO: should be 1/3
|
|
59342
|
+
const centerX = (x2 + x1) / 2;
|
|
59343
|
+
const centerY = (y2 + y1) / 2;
|
|
59344
|
+
let offset = bendSlurHeight * scale;
|
|
59345
|
+
if (x2 - x1 < 20) {
|
|
59346
|
+
offset /= 2;
|
|
59347
|
+
}
|
|
59348
|
+
const cp1X = centerX + offset * normalVectorX;
|
|
59349
|
+
const cp1Y = centerY + offset * normalVectorY;
|
|
59350
|
+
canvas.beginPath();
|
|
59351
|
+
canvas.moveTo(x1, y1);
|
|
59352
|
+
canvas.lineTo(cp1X, cp1Y);
|
|
59353
|
+
canvas.lineTo(x2, y2);
|
|
59354
|
+
canvas.stroke();
|
|
59355
|
+
if (slurText) {
|
|
59356
|
+
const w = canvas.measureText(slurText).width;
|
|
59357
|
+
const textOffset = down ? 0 : -canvas.font.size;
|
|
59358
|
+
canvas.fillText(slurText, cp1X - w / 2, cp1Y + textOffset);
|
|
59359
|
+
}
|
|
59360
|
+
}
|
|
59361
|
+
}
|
|
59362
|
+
/**
|
|
59363
|
+
* A common tie implementation using note details for positioning
|
|
59364
|
+
* @internal
|
|
59365
|
+
*/
|
|
59366
|
+
class NoteTieGlyph extends TieGlyph {
|
|
59367
|
+
startNote;
|
|
59368
|
+
endNote;
|
|
59369
|
+
startNoteRenderer = null;
|
|
59370
|
+
endNoteRenderer = null;
|
|
59371
|
+
constructor(slurEffectId, startNote, endNote, forEnd) {
|
|
59372
|
+
super(slurEffectId, forEnd);
|
|
59373
|
+
this.startNote = startNote;
|
|
59374
|
+
this.endNote = endNote;
|
|
59375
|
+
}
|
|
59376
|
+
get isLeftHandTap() {
|
|
59377
|
+
return this.startNote === this.endNote;
|
|
59378
|
+
}
|
|
59379
|
+
getTieHeight(startX, startY, endX, endY) {
|
|
59380
|
+
if (this.isLeftHandTap) {
|
|
59381
|
+
return this.renderer.smuflMetrics.tieHeight;
|
|
59382
|
+
}
|
|
59383
|
+
return super.getTieHeight(startX, startY, endX, endY);
|
|
59384
|
+
}
|
|
59385
|
+
calculateTieDirection() {
|
|
59386
|
+
// invert direction (if stems go up, ties go down to not cross them)
|
|
59387
|
+
switch (this.lookupStartBeatRenderer().getBeatDirection(this.startNote.beat)) {
|
|
59388
|
+
case BeamDirection.Up:
|
|
59389
|
+
return BeamDirection.Down;
|
|
59390
|
+
default:
|
|
59391
|
+
return BeamDirection.Up;
|
|
59392
|
+
}
|
|
59393
|
+
}
|
|
59394
|
+
calculateStartX() {
|
|
59395
|
+
const startNoteRenderer = this.lookupStartBeatRenderer();
|
|
59396
|
+
if (this.isLeftHandTap) {
|
|
59397
|
+
return this.calculateEndX() - startNoteRenderer.smuflMetrics.leftHandTabTieWidth;
|
|
59398
|
+
}
|
|
59399
|
+
return startNoteRenderer.x + startNoteRenderer.getNoteX(this.startNote, this.getStartNotePosition());
|
|
59400
|
+
}
|
|
59401
|
+
getStartNotePosition() {
|
|
59402
|
+
return NoteXPosition.Center;
|
|
59403
|
+
}
|
|
59404
|
+
calculateStartY() {
|
|
59405
|
+
const startNoteRenderer = this.lookupStartBeatRenderer();
|
|
59406
|
+
if (this.isLeftHandTap) {
|
|
59407
|
+
return startNoteRenderer.y + startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Center);
|
|
59408
|
+
}
|
|
59409
|
+
switch (this.tieDirection) {
|
|
59410
|
+
case BeamDirection.Up:
|
|
59411
|
+
return startNoteRenderer.y + startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Top);
|
|
59412
|
+
default:
|
|
59413
|
+
return startNoteRenderer.y + startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Bottom);
|
|
59414
|
+
}
|
|
59415
|
+
}
|
|
59416
|
+
calculateEndX() {
|
|
59417
|
+
const endNoteRenderer = this.lookupEndBeatRenderer();
|
|
59418
|
+
if (!endNoteRenderer) {
|
|
59419
|
+
return this.calculateStartY() + this.renderer.smuflMetrics.leftHandTabTieWidth;
|
|
59420
|
+
}
|
|
59421
|
+
if (this.isLeftHandTap) {
|
|
59422
|
+
return endNoteRenderer.x + endNoteRenderer.getNoteX(this.endNote, NoteXPosition.Left);
|
|
59423
|
+
}
|
|
59424
|
+
return endNoteRenderer.x + endNoteRenderer.getNoteX(this.endNote, NoteXPosition.Center);
|
|
59425
|
+
}
|
|
59426
|
+
getEndNotePosition() {
|
|
59427
|
+
return NoteXPosition.Center;
|
|
59428
|
+
}
|
|
59429
|
+
caclculateEndY() {
|
|
59430
|
+
const endNoteRenderer = this.lookupEndBeatRenderer();
|
|
59431
|
+
if (!endNoteRenderer) {
|
|
59432
|
+
return this.calculateStartY();
|
|
59433
|
+
}
|
|
59434
|
+
if (this.isLeftHandTap) {
|
|
59435
|
+
return endNoteRenderer.y + endNoteRenderer.getNoteY(this.endNote, NoteYPosition.Center);
|
|
59436
|
+
}
|
|
59437
|
+
switch (this.tieDirection) {
|
|
59438
|
+
case BeamDirection.Up:
|
|
59439
|
+
return endNoteRenderer.y + endNoteRenderer.getNoteY(this.endNote, NoteYPosition.Top);
|
|
59440
|
+
default:
|
|
59441
|
+
return endNoteRenderer.y + endNoteRenderer.getNoteY(this.endNote, NoteYPosition.Bottom);
|
|
59442
|
+
}
|
|
59443
|
+
}
|
|
59444
|
+
lookupEndBeatRenderer() {
|
|
59445
|
+
if (!this.endNoteRenderer) {
|
|
59446
|
+
this.endNoteRenderer = this.renderer.scoreRenderer.layout.getRendererForBar(this.renderer.staff.staffId, this.endNote.beat.voice.bar);
|
|
59447
|
+
}
|
|
59448
|
+
return this.endNoteRenderer;
|
|
59449
|
+
}
|
|
59450
|
+
lookupStartBeatRenderer() {
|
|
59451
|
+
if (!this.startNoteRenderer) {
|
|
59452
|
+
this.startNoteRenderer = this.renderer.scoreRenderer.layout.getRendererForBar(this.renderer.staff.staffId, this.startNote.beat.voice.bar);
|
|
59453
|
+
}
|
|
59454
|
+
return this.startNoteRenderer;
|
|
59455
|
+
}
|
|
59456
|
+
shouldDrawBendSlur() {
|
|
59457
|
+
return false;
|
|
59458
|
+
}
|
|
59459
|
+
}
|
|
59460
|
+
/**
|
|
59461
|
+
* A tie glyph for continued multi-system ties/slurs
|
|
59462
|
+
* @internal
|
|
59463
|
+
*/
|
|
59464
|
+
class ContinuationTieGlyph extends TieGlyph {
|
|
59465
|
+
_startTie;
|
|
59466
|
+
constructor(startTie) {
|
|
59467
|
+
super(startTie.slurEffectId, false);
|
|
59468
|
+
this._startTie = startTie;
|
|
59469
|
+
}
|
|
59470
|
+
lookupStartBeatRenderer() {
|
|
59471
|
+
return this.renderer;
|
|
59472
|
+
}
|
|
59473
|
+
lookupEndBeatRenderer() {
|
|
59474
|
+
return this.renderer;
|
|
59475
|
+
}
|
|
59476
|
+
shouldDrawBendSlur() {
|
|
59477
|
+
return false;
|
|
59478
|
+
}
|
|
59479
|
+
calculateTieDirection() {
|
|
59480
|
+
return this._startTie.tieDirection;
|
|
59481
|
+
}
|
|
59482
|
+
calculateStartY() {
|
|
59483
|
+
return this._startTie.calculateMultiSystemSlurY(this.renderer);
|
|
59484
|
+
}
|
|
59485
|
+
caclculateEndY() {
|
|
59486
|
+
return this.calculateStartY();
|
|
59487
|
+
}
|
|
59488
|
+
calculateStartX() {
|
|
59489
|
+
return this.renderer.staff.barRenderers[0].x;
|
|
59490
|
+
}
|
|
59491
|
+
calculateEndX() {
|
|
59492
|
+
const last = this.renderer.staff.barRenderers[this.renderer.staff.barRenderers.length - 1];
|
|
59493
|
+
return last.x + last.width;
|
|
59494
|
+
}
|
|
59495
|
+
}
|
|
59496
|
+
|
|
59066
59497
|
/**
|
|
59067
59498
|
* This glyph acts as container for handling
|
|
59068
59499
|
* multiple voice rendering
|
|
@@ -59533,6 +59964,63 @@
|
|
|
59533
59964
|
}
|
|
59534
59965
|
}
|
|
59535
59966
|
|
|
59967
|
+
/**
|
|
59968
|
+
* This registry keeps track of which slurs and ties were started and needs completion.
|
|
59969
|
+
* Slurs might span multiple systems, and in such cases we need to create additional
|
|
59970
|
+
* slur/ties in the intermediate and end system.
|
|
59971
|
+
*
|
|
59972
|
+
* @internal
|
|
59973
|
+
*
|
|
59974
|
+
*/
|
|
59975
|
+
class SlurRegistry {
|
|
59976
|
+
_staffLookup = new Map();
|
|
59977
|
+
clear() {
|
|
59978
|
+
this._staffLookup.clear();
|
|
59979
|
+
}
|
|
59980
|
+
startMultiSystemSlur(startGlyph) {
|
|
59981
|
+
const staffId = SlurRegistry._staffId(startGlyph.renderer.staff);
|
|
59982
|
+
let container;
|
|
59983
|
+
if (!this._staffLookup.has(staffId)) {
|
|
59984
|
+
container = {
|
|
59985
|
+
startedSlurs: new Map()
|
|
59986
|
+
};
|
|
59987
|
+
this._staffLookup.set(staffId, container);
|
|
59988
|
+
}
|
|
59989
|
+
else {
|
|
59990
|
+
container = this._staffLookup.get(staffId);
|
|
59991
|
+
}
|
|
59992
|
+
container.startedSlurs.set(startGlyph.slurEffectId, { startGlyph });
|
|
59993
|
+
}
|
|
59994
|
+
static _staffId(staff) {
|
|
59995
|
+
return `${staff.modelStaff.index}.${staff.modelStaff.track.index}.${staff.staffId}`;
|
|
59996
|
+
}
|
|
59997
|
+
completeMultiSystemSlur(endGlyph) {
|
|
59998
|
+
const staffId = SlurRegistry._staffId(endGlyph.renderer.staff);
|
|
59999
|
+
if (!this._staffLookup.has(staffId)) {
|
|
60000
|
+
return undefined;
|
|
60001
|
+
}
|
|
60002
|
+
const container = this._staffLookup.get(staffId);
|
|
60003
|
+
if (container.startedSlurs.has(endGlyph.slurEffectId)) {
|
|
60004
|
+
const info = container.startedSlurs.get(endGlyph.slurEffectId);
|
|
60005
|
+
info.endGlyph = endGlyph;
|
|
60006
|
+
return info.startGlyph;
|
|
60007
|
+
}
|
|
60008
|
+
return undefined;
|
|
60009
|
+
}
|
|
60010
|
+
*getAllContinuations(renderer) {
|
|
60011
|
+
const staffId = SlurRegistry._staffId(renderer.staff);
|
|
60012
|
+
if (!this._staffLookup.has(staffId) || renderer.index > 0) {
|
|
60013
|
+
return;
|
|
60014
|
+
}
|
|
60015
|
+
const container = this._staffLookup.get(staffId);
|
|
60016
|
+
for (const g of container.startedSlurs.values()) {
|
|
60017
|
+
if (g.startGlyph.shouldCreateMultiSystemSlur(renderer)) {
|
|
60018
|
+
yield g.startGlyph;
|
|
60019
|
+
}
|
|
60020
|
+
}
|
|
60021
|
+
}
|
|
60022
|
+
}
|
|
60023
|
+
|
|
59536
60024
|
/**
|
|
59537
60025
|
* A Staff represents a single line within a StaffSystem.
|
|
59538
60026
|
* It stores BarRenderer instances created from a given factory.
|
|
@@ -59654,7 +60142,6 @@
|
|
|
59654
60142
|
this._sharedLayoutData = new Map();
|
|
59655
60143
|
const lastBar = this.barRenderers[this.barRenderers.length - 1];
|
|
59656
60144
|
this.barRenderers.splice(this.barRenderers.length - 1, 1);
|
|
59657
|
-
this.system.layout.unregisterBarRenderer(this.staffId, lastBar);
|
|
59658
60145
|
this.topOverflow = 0;
|
|
59659
60146
|
this.bottomOverflow = 0;
|
|
59660
60147
|
for (const r of this.barRenderers) {
|
|
@@ -59747,23 +60234,23 @@
|
|
|
59747
60234
|
// changes in the overflows
|
|
59748
60235
|
let needsSecondPass = false;
|
|
59749
60236
|
let topOverflow = this.topOverflow;
|
|
59750
|
-
for (
|
|
59751
|
-
this.
|
|
59752
|
-
if (
|
|
60237
|
+
for (const renderer of this.barRenderers) {
|
|
60238
|
+
renderer.registerMultiSystemSlurs(this.system.layout.slurRegistry.getAllContinuations(renderer));
|
|
60239
|
+
if (renderer.finalizeRenderer()) {
|
|
59753
60240
|
needsSecondPass = true;
|
|
59754
60241
|
}
|
|
59755
|
-
this.height = Math.max(this.height,
|
|
60242
|
+
this.height = Math.max(this.height, renderer.height);
|
|
59756
60243
|
}
|
|
59757
60244
|
// 2nd pass: move renderers to correct position respecting the new overflows
|
|
59758
60245
|
if (needsSecondPass) {
|
|
59759
60246
|
topOverflow = this.topOverflow;
|
|
59760
60247
|
// shift all the renderers to the new position to match required spacing
|
|
59761
|
-
for (
|
|
59762
|
-
|
|
60248
|
+
for (const renderer of this.barRenderers) {
|
|
60249
|
+
renderer.y = this.topPadding + topOverflow;
|
|
59763
60250
|
}
|
|
59764
60251
|
// finalize again (to align ties)
|
|
59765
|
-
for (
|
|
59766
|
-
|
|
60252
|
+
for (const renderer of this.barRenderers) {
|
|
60253
|
+
renderer.finalizeRenderer();
|
|
59767
60254
|
}
|
|
59768
60255
|
}
|
|
59769
60256
|
if (this.height > 0) {
|
|
@@ -60369,6 +60856,7 @@
|
|
|
60369
60856
|
if (newBarDisplayScale > barDisplayScale) {
|
|
60370
60857
|
barDisplayScale = newBarDisplayScale;
|
|
60371
60858
|
}
|
|
60859
|
+
lastBar.afterReverted();
|
|
60372
60860
|
}
|
|
60373
60861
|
this.width -= width;
|
|
60374
60862
|
this.computedWidth -= width;
|
|
@@ -60888,12 +61376,16 @@
|
|
|
60888
61376
|
constructor(renderer) {
|
|
60889
61377
|
this.renderer = renderer;
|
|
60890
61378
|
}
|
|
61379
|
+
slurRegistry = new SlurRegistry();
|
|
60891
61380
|
resize() {
|
|
60892
61381
|
this._lazyPartials.clear();
|
|
61382
|
+
this.slurRegistry.clear();
|
|
60893
61383
|
this.doResize();
|
|
60894
61384
|
}
|
|
60895
61385
|
layoutAndRender() {
|
|
60896
61386
|
this._lazyPartials.clear();
|
|
61387
|
+
this.slurRegistry.clear();
|
|
61388
|
+
this._barRendererLookup.clear();
|
|
60897
61389
|
this.profile = Environment.staveProfiles.get(this.renderer.settings.display.staveProfile);
|
|
60898
61390
|
const score = this.renderer.score;
|
|
60899
61391
|
this.firstBarIndex = ModelUtils.computeFirstDisplayedBarIndex(score, this.renderer.settings);
|
|
@@ -61162,17 +61654,6 @@
|
|
|
61162
61654
|
}
|
|
61163
61655
|
}
|
|
61164
61656
|
}
|
|
61165
|
-
unregisterBarRenderer(key, renderer) {
|
|
61166
|
-
if (this._barRendererLookup.has(key)) {
|
|
61167
|
-
const lookup = this._barRendererLookup.get(key);
|
|
61168
|
-
lookup.delete(renderer.bar.id);
|
|
61169
|
-
if (renderer.additionalMultiRestBars) {
|
|
61170
|
-
for (const b of renderer.additionalMultiRestBars) {
|
|
61171
|
-
lookup.delete(b.id);
|
|
61172
|
-
}
|
|
61173
|
-
}
|
|
61174
|
-
}
|
|
61175
|
-
}
|
|
61176
61657
|
getRendererForBar(key, bar) {
|
|
61177
61658
|
const barRendererId = bar.id;
|
|
61178
61659
|
if (this._barRendererLookup.has(key) && this._barRendererLookup.get(key).has(barRendererId)) {
|
|
@@ -62161,6 +62642,7 @@
|
|
|
62161
62642
|
_voiceContainers = new Map();
|
|
62162
62643
|
_postBeatGlyphs = new LeftToRightLayoutingGlyphGroup();
|
|
62163
62644
|
_ties = [];
|
|
62645
|
+
_multiSystemSlurs;
|
|
62164
62646
|
topEffects;
|
|
62165
62647
|
bottomEffects;
|
|
62166
62648
|
get nextRenderer() {
|
|
@@ -62313,6 +62795,11 @@
|
|
|
62313
62795
|
}
|
|
62314
62796
|
}
|
|
62315
62797
|
_appliedLayoutingInfo = 0;
|
|
62798
|
+
afterReverted() {
|
|
62799
|
+
this.staff = undefined;
|
|
62800
|
+
this.registerMultiSystemSlurs(undefined);
|
|
62801
|
+
this.isFinalized = false;
|
|
62802
|
+
}
|
|
62316
62803
|
afterStaffBarReverted() {
|
|
62317
62804
|
this.topEffects.afterStaffBarReverted();
|
|
62318
62805
|
this.bottomEffects.afterStaffBarReverted();
|
|
@@ -62358,13 +62845,26 @@
|
|
|
62358
62845
|
return true;
|
|
62359
62846
|
}
|
|
62360
62847
|
isFinalized = false;
|
|
62361
|
-
|
|
62362
|
-
|
|
62848
|
+
registerMultiSystemSlurs(startedTies) {
|
|
62849
|
+
if (!startedTies) {
|
|
62850
|
+
this._multiSystemSlurs = undefined;
|
|
62851
|
+
return;
|
|
62852
|
+
}
|
|
62853
|
+
let ties = undefined;
|
|
62854
|
+
for (const g of startedTies) {
|
|
62855
|
+
const continuation = new ContinuationTieGlyph(g);
|
|
62856
|
+
continuation.renderer = this;
|
|
62857
|
+
continuation.tieDirection = g.tieDirection;
|
|
62858
|
+
if (!ties) {
|
|
62859
|
+
ties = [];
|
|
62860
|
+
}
|
|
62861
|
+
ties.push(continuation);
|
|
62862
|
+
}
|
|
62863
|
+
this._multiSystemSlurs = ties;
|
|
62864
|
+
}
|
|
62865
|
+
_finalizeTies(ties, barTop, barBottom) {
|
|
62363
62866
|
let didChangeOverflows = false;
|
|
62364
|
-
|
|
62365
|
-
const barTop = this.y;
|
|
62366
|
-
const barBottom = this.y + this.height;
|
|
62367
|
-
for (const t of this._ties) {
|
|
62867
|
+
for (const t of ties) {
|
|
62368
62868
|
const tie = t;
|
|
62369
62869
|
tie.doLayout();
|
|
62370
62870
|
if (t.checkForOverflow) {
|
|
@@ -62385,6 +62885,21 @@
|
|
|
62385
62885
|
}
|
|
62386
62886
|
}
|
|
62387
62887
|
}
|
|
62888
|
+
return didChangeOverflows;
|
|
62889
|
+
}
|
|
62890
|
+
finalizeRenderer() {
|
|
62891
|
+
this.isFinalized = true;
|
|
62892
|
+
let didChangeOverflows = false;
|
|
62893
|
+
// allow spacing to be used for tie overflows
|
|
62894
|
+
const barTop = this.y;
|
|
62895
|
+
const barBottom = this.y + this.height;
|
|
62896
|
+
if (this._finalizeTies(this._ties, barTop, barBottom)) {
|
|
62897
|
+
didChangeOverflows = true;
|
|
62898
|
+
}
|
|
62899
|
+
const multiSystemSlurs = this._multiSystemSlurs;
|
|
62900
|
+
if (multiSystemSlurs && this._finalizeTies(multiSystemSlurs, barTop, barBottom)) {
|
|
62901
|
+
didChangeOverflows = true;
|
|
62902
|
+
}
|
|
62388
62903
|
const topHeightChanged = this.topEffects.finalizeEffects();
|
|
62389
62904
|
const bottomHeightChanged = this.bottomEffects.finalizeEffects();
|
|
62390
62905
|
if (topHeightChanged || bottomHeightChanged) {
|
|
@@ -62565,6 +63080,16 @@
|
|
|
62565
63080
|
}
|
|
62566
63081
|
canvas.color = this.resources.mainGlyphColor;
|
|
62567
63082
|
this._postBeatGlyphs.paint(cx + this.x, cy + this.y, canvas);
|
|
63083
|
+
this._paintMultiSystemSlurs(cx, cy, canvas);
|
|
63084
|
+
}
|
|
63085
|
+
_paintMultiSystemSlurs(cx, cy, canvas) {
|
|
63086
|
+
const multiSystemSlurs = this._multiSystemSlurs;
|
|
63087
|
+
if (!multiSystemSlurs) {
|
|
63088
|
+
return;
|
|
63089
|
+
}
|
|
63090
|
+
for (const slur of multiSystemSlurs) {
|
|
63091
|
+
slur.paint(cx, cy, canvas);
|
|
63092
|
+
}
|
|
62568
63093
|
}
|
|
62569
63094
|
paintBackground(cx, cy, canvas) {
|
|
62570
63095
|
this.layoutingInfo.paint(cx + this.x + this._preBeatGlyphs.x + this._preBeatGlyphs.width, cy + this.y + this.height, canvas);
|
|
@@ -64643,6 +65168,13 @@
|
|
|
64643
65168
|
}
|
|
64644
65169
|
}
|
|
64645
65170
|
else {
|
|
65171
|
+
// clear out staves during re-layout, this info is outdated during
|
|
65172
|
+
// re-layout of the bars
|
|
65173
|
+
for (const r of this._allMasterBarRenderers) {
|
|
65174
|
+
for (const b of r.renderers) {
|
|
65175
|
+
b.afterReverted();
|
|
65176
|
+
}
|
|
65177
|
+
}
|
|
64646
65178
|
this._systems = [];
|
|
64647
65179
|
let currentIndex = 0;
|
|
64648
65180
|
const maxWidth = this._maxWidth;
|
|
@@ -65104,7 +65636,7 @@
|
|
|
65104
65636
|
// as during layout things are still moving
|
|
65105
65637
|
let actualLineHeight = this.height;
|
|
65106
65638
|
const thisStaff = renderer.staff;
|
|
65107
|
-
const allStaves =
|
|
65639
|
+
const allStaves = thisStaff.system.allStaves;
|
|
65108
65640
|
let isExtended = false;
|
|
65109
65641
|
if (this._extendToNextStaff && thisStaff.index < allStaves.length - 1) {
|
|
65110
65642
|
const nextStaff = allStaves[thisStaff.index + 1];
|
|
@@ -65286,7 +65818,7 @@
|
|
|
65286
65818
|
}
|
|
65287
65819
|
// during system fitting it can happen that we have fraction widths
|
|
65288
65820
|
// but to have lines until the full end-pixel we round up.
|
|
65289
|
-
// this way we avoid holes,
|
|
65821
|
+
// this way we avoid holes,
|
|
65290
65822
|
const lineWidth = this.width;
|
|
65291
65823
|
// we want the lines to be exactly virtually aligned with the respective Y-position
|
|
65292
65824
|
// for note heads to align correctly
|
|
@@ -66052,375 +66584,23 @@
|
|
|
66052
66584
|
/**
|
|
66053
66585
|
* @internal
|
|
66054
66586
|
*/
|
|
66055
|
-
class
|
|
66056
|
-
startBeat;
|
|
66057
|
-
endBeat;
|
|
66058
|
-
yOffset = 0;
|
|
66059
|
-
forEnd;
|
|
66060
|
-
startNoteRenderer = null;
|
|
66061
|
-
endNoteRenderer = null;
|
|
66062
|
-
tieDirection = BeamDirection.Up;
|
|
66063
|
-
constructor(startBeat, endBeat, forEnd) {
|
|
66064
|
-
super(0, 0);
|
|
66065
|
-
this.startBeat = startBeat;
|
|
66066
|
-
this.endBeat = endBeat;
|
|
66067
|
-
this.forEnd = forEnd;
|
|
66068
|
-
}
|
|
66069
|
-
_startX = 0;
|
|
66070
|
-
_startY = 0;
|
|
66071
|
-
_endX = 0;
|
|
66072
|
-
_endY = 0;
|
|
66073
|
-
_tieHeight = 0;
|
|
66074
|
-
_shouldDraw = false;
|
|
66075
|
-
_boundingBox;
|
|
66076
|
-
get checkForOverflow() {
|
|
66077
|
-
return this._boundingBox !== undefined;
|
|
66078
|
-
}
|
|
66079
|
-
getBoundingBoxTop() {
|
|
66080
|
-
if (this._boundingBox) {
|
|
66081
|
-
return this._boundingBox.y;
|
|
66082
|
-
}
|
|
66083
|
-
return this._startY;
|
|
66084
|
-
}
|
|
66085
|
-
getBoundingBoxBottom() {
|
|
66086
|
-
if (this._boundingBox) {
|
|
66087
|
-
return this._boundingBox.y + this._boundingBox.h;
|
|
66088
|
-
}
|
|
66089
|
-
return this._startY;
|
|
66090
|
-
}
|
|
66091
|
-
doLayout() {
|
|
66092
|
-
this.width = 0;
|
|
66093
|
-
// TODO fix nullability of start/end beat,
|
|
66094
|
-
if (!this.endBeat) {
|
|
66095
|
-
this._shouldDraw = false;
|
|
66096
|
-
return;
|
|
66097
|
-
}
|
|
66098
|
-
const startNoteRenderer = this.renderer.scoreRenderer.layout.getRendererForBar(this.renderer.staff.staffId, this.startBeat.voice.bar);
|
|
66099
|
-
this.startNoteRenderer = startNoteRenderer;
|
|
66100
|
-
const endNoteRenderer = this.renderer.scoreRenderer.layout.getRendererForBar(this.renderer.staff.staffId, this.endBeat.voice.bar);
|
|
66101
|
-
this.endNoteRenderer = endNoteRenderer;
|
|
66102
|
-
this._startX = 0;
|
|
66103
|
-
this._endX = 0;
|
|
66104
|
-
this._startY = 0;
|
|
66105
|
-
this._endY = 0;
|
|
66106
|
-
this.height = 0;
|
|
66107
|
-
this._shouldDraw = false;
|
|
66108
|
-
// if we are on the tie start, we check if we
|
|
66109
|
-
// either can draw till the end note, or we just can draw till the bar end
|
|
66110
|
-
this.tieDirection = !startNoteRenderer
|
|
66111
|
-
? this.getBeamDirection(this.endBeat, endNoteRenderer)
|
|
66112
|
-
: this.getBeamDirection(this.startBeat, startNoteRenderer);
|
|
66113
|
-
if (!this.forEnd && startNoteRenderer) {
|
|
66114
|
-
// line break or bar break
|
|
66115
|
-
if (startNoteRenderer !== endNoteRenderer) {
|
|
66116
|
-
this._startX = startNoteRenderer.x + this.getStartX();
|
|
66117
|
-
this._startY = startNoteRenderer.y + this.getStartY() + this.yOffset;
|
|
66118
|
-
// line break: to bar end
|
|
66119
|
-
if (!endNoteRenderer || startNoteRenderer.staff !== endNoteRenderer.staff) {
|
|
66120
|
-
this._endX = startNoteRenderer.x + startNoteRenderer.width;
|
|
66121
|
-
this._endY = this._startY;
|
|
66122
|
-
}
|
|
66123
|
-
else {
|
|
66124
|
-
this._endX = endNoteRenderer.x + this.getEndX();
|
|
66125
|
-
this._endY = endNoteRenderer.y + this.getEndY() + this.yOffset;
|
|
66126
|
-
}
|
|
66127
|
-
}
|
|
66128
|
-
else {
|
|
66129
|
-
this._startX = startNoteRenderer.x + this.getStartX();
|
|
66130
|
-
this._endX = endNoteRenderer.x + this.getEndX();
|
|
66131
|
-
this._startY = startNoteRenderer.y + this.getStartY() + this.yOffset;
|
|
66132
|
-
this._endY = endNoteRenderer.y + this.getEndY() + this.yOffset;
|
|
66133
|
-
}
|
|
66134
|
-
this._shouldDraw = true;
|
|
66135
|
-
}
|
|
66136
|
-
else if (!startNoteRenderer || startNoteRenderer.staff !== endNoteRenderer.staff) {
|
|
66137
|
-
this._startX = endNoteRenderer.x;
|
|
66138
|
-
this._endX = endNoteRenderer.x + this.getEndX();
|
|
66139
|
-
this._startY = endNoteRenderer.y + this.getEndY() + this.yOffset;
|
|
66140
|
-
this._endY = this._startY;
|
|
66141
|
-
this._shouldDraw = true;
|
|
66142
|
-
}
|
|
66143
|
-
this._boundingBox = undefined;
|
|
66144
|
-
if (this._shouldDraw) {
|
|
66145
|
-
this.y = Math.min(this._startY, this._endY);
|
|
66146
|
-
if (this.shouldDrawBendSlur()) {
|
|
66147
|
-
this._tieHeight = 0; // TODO: Bend slur height to be considered?
|
|
66148
|
-
}
|
|
66149
|
-
else {
|
|
66150
|
-
this._tieHeight = this.getTieHeight(this._startX, this._startY, this._endX, this._endY);
|
|
66151
|
-
const tieBoundingBox = TieGlyph.calculateActualTieHeight(1, this._startX, this._startY, this._endX, this._endY, this.tieDirection === BeamDirection.Down, this._tieHeight, this.renderer.smuflMetrics.tieMidpointThickness);
|
|
66152
|
-
this._boundingBox = tieBoundingBox;
|
|
66153
|
-
this.height = tieBoundingBox.h;
|
|
66154
|
-
if (this.tieDirection === BeamDirection.Up) {
|
|
66155
|
-
// the tie might go above `this.y` due to its shape
|
|
66156
|
-
// here we calculate how much this is so we can consider the
|
|
66157
|
-
// respective overflow
|
|
66158
|
-
const overlap = this.y - tieBoundingBox.y;
|
|
66159
|
-
if (overlap > 0) {
|
|
66160
|
-
this.y -= overlap;
|
|
66161
|
-
}
|
|
66162
|
-
}
|
|
66163
|
-
}
|
|
66164
|
-
}
|
|
66165
|
-
}
|
|
66166
|
-
paint(cx, cy, canvas) {
|
|
66167
|
-
if (this._shouldDraw) {
|
|
66168
|
-
if (this.shouldDrawBendSlur()) {
|
|
66169
|
-
TieGlyph.drawBendSlur(canvas, cx + this._startX, cy + this._startY, cx + this._endX, cy + this._endY, this.tieDirection === BeamDirection.Down, 1, this.renderer.smuflMetrics.tieHeight);
|
|
66170
|
-
}
|
|
66171
|
-
else {
|
|
66172
|
-
TieGlyph.paintTie(canvas, 1, cx + this._startX, cy + this._startY, cx + this._endX, cy + this._endY, this.tieDirection === BeamDirection.Down, this._tieHeight, this.renderer.smuflMetrics.tieMidpointThickness);
|
|
66173
|
-
}
|
|
66174
|
-
}
|
|
66175
|
-
}
|
|
66176
|
-
shouldDrawBendSlur() {
|
|
66177
|
-
return false;
|
|
66178
|
-
}
|
|
66179
|
-
getTieHeight(_startX, _startY, _endX, _endY) {
|
|
66180
|
-
return this.renderer.smuflMetrics.tieHeight;
|
|
66181
|
-
}
|
|
66182
|
-
getBeamDirection(_beat, _noteRenderer) {
|
|
66183
|
-
return BeamDirection.Down;
|
|
66184
|
-
}
|
|
66185
|
-
getStartY() {
|
|
66186
|
-
return 0;
|
|
66187
|
-
}
|
|
66188
|
-
getEndY() {
|
|
66189
|
-
return 0;
|
|
66190
|
-
}
|
|
66191
|
-
getStartX() {
|
|
66192
|
-
return 0;
|
|
66193
|
-
}
|
|
66194
|
-
getEndX() {
|
|
66195
|
-
return 0;
|
|
66196
|
-
}
|
|
66197
|
-
static calculateActualTieHeight(scale, x1, y1, x2, y2, down, offset, size) {
|
|
66198
|
-
const cp = TieGlyph._computeBezierControlPoints(scale, x1, y1, x2, y2, down, offset, size);
|
|
66199
|
-
// For a musical tie/slur, the extrema occur predictably near the midpoint
|
|
66200
|
-
// Evaluate at midpoint (t=0.5) and check endpoints
|
|
66201
|
-
const p0x = cp[0];
|
|
66202
|
-
const p0y = cp[1];
|
|
66203
|
-
const c1x = cp[2];
|
|
66204
|
-
const c1y = cp[3];
|
|
66205
|
-
const c2x = cp[4];
|
|
66206
|
-
const c2y = cp[5];
|
|
66207
|
-
const p1x = cp[6];
|
|
66208
|
-
const p1y = cp[7];
|
|
66209
|
-
// Evaluate at t=0.5 for midpoint
|
|
66210
|
-
const midX = 0.125 * p0x + 0.375 * c1x + 0.375 * c2x + 0.125 * p1x;
|
|
66211
|
-
const midY = 0.125 * p0y + 0.375 * c1y + 0.375 * c2y + 0.125 * p1y;
|
|
66212
|
-
// Bounds are simply min/max of start, end, and midpoint
|
|
66213
|
-
const xMin = Math.min(p0x, p1x, midX);
|
|
66214
|
-
const xMax = Math.max(p0x, p1x, midX);
|
|
66215
|
-
let yMin = Math.min(p0y, p1y, midY);
|
|
66216
|
-
let yMax = Math.max(p0y, p1y, midY);
|
|
66217
|
-
// Account for thickness of the tie/slur
|
|
66218
|
-
if (down) {
|
|
66219
|
-
yMax += size;
|
|
66220
|
-
}
|
|
66221
|
-
else {
|
|
66222
|
-
yMin -= size;
|
|
66223
|
-
}
|
|
66224
|
-
const b = new Bounds();
|
|
66225
|
-
b.x = xMin;
|
|
66226
|
-
b.y = yMin;
|
|
66227
|
-
b.w = xMax - xMin;
|
|
66228
|
-
b.h = yMax - yMin;
|
|
66229
|
-
return b;
|
|
66230
|
-
}
|
|
66231
|
-
static _computeBezierControlPoints(scale, x1, y1, x2, y2, down, offset, size) {
|
|
66232
|
-
if (x1 === x2 && y1 === y2) {
|
|
66233
|
-
return [];
|
|
66234
|
-
}
|
|
66235
|
-
// ensure endX > startX
|
|
66236
|
-
if (x2 < x1) {
|
|
66237
|
-
let t = x1;
|
|
66238
|
-
x1 = x2;
|
|
66239
|
-
x2 = t;
|
|
66240
|
-
t = y1;
|
|
66241
|
-
y1 = y2;
|
|
66242
|
-
y2 = t;
|
|
66243
|
-
}
|
|
66244
|
-
//
|
|
66245
|
-
// calculate control points
|
|
66246
|
-
//
|
|
66247
|
-
offset *= scale;
|
|
66248
|
-
size *= scale;
|
|
66249
|
-
if (down) {
|
|
66250
|
-
offset *= -1;
|
|
66251
|
-
size *= -1;
|
|
66252
|
-
}
|
|
66253
|
-
if (scale >= 1) {
|
|
66254
|
-
size *= 1.2;
|
|
66255
|
-
}
|
|
66256
|
-
// calculate control points on horizontal axis then rotate:
|
|
66257
|
-
/*
|
|
66258
|
-
cp1x/cpy1 cp2x/cpy2
|
|
66259
|
-
*----------------*
|
|
66260
|
-
/ \
|
|
66261
|
-
/ \
|
|
66262
|
-
x1/y1 * * x2/y2
|
|
66263
|
-
|
|
66264
|
-
cp3 and cp4 are simply with lower height
|
|
66265
|
-
*/
|
|
66266
|
-
const dY = y2 - y1;
|
|
66267
|
-
const dX = x2 - x1;
|
|
66268
|
-
const length = Math.sqrt(dX * dX + dY * dY);
|
|
66269
|
-
let cp1x = x1 + length * 0.25;
|
|
66270
|
-
let cp1y = y1 - offset;
|
|
66271
|
-
let cp2x = x1 + length * 0.75;
|
|
66272
|
-
let cp2y = y1 - offset;
|
|
66273
|
-
let cp3x = x1 + length * 0.75;
|
|
66274
|
-
let cp3y = y1 - offset - size;
|
|
66275
|
-
let cp4x = x1 + length * 0.25;
|
|
66276
|
-
let cp4y = y1 - offset - size;
|
|
66277
|
-
const angle = Math.atan2(dY, dX);
|
|
66278
|
-
[cp1x, cp1y] = TieGlyph._rotate(cp1x, cp1y, x1, y1, angle);
|
|
66279
|
-
[cp2x, cp2y] = TieGlyph._rotate(cp2x, cp2y, x1, y1, angle);
|
|
66280
|
-
[cp3x, cp3y] = TieGlyph._rotate(cp3x, cp3y, x1, y1, angle);
|
|
66281
|
-
[cp4x, cp4y] = TieGlyph._rotate(cp4x, cp4y, x1, y1, angle);
|
|
66282
|
-
return [x1, y1, cp1x, cp1y, cp2x, cp2y, x2, y2, cp3x, cp3y, cp4x, cp4y, x1, y1];
|
|
66283
|
-
}
|
|
66284
|
-
static _rotate(x, y, rotateX, rotateY, angle) {
|
|
66285
|
-
const dx = x - rotateX;
|
|
66286
|
-
const dy = y - rotateY;
|
|
66287
|
-
const rx = dx * Math.cos(angle) - dy * Math.sin(angle);
|
|
66288
|
-
const ry = dx * Math.sin(angle) + dy * Math.cos(angle);
|
|
66289
|
-
return [rotateX + rx, rotateY + ry];
|
|
66290
|
-
}
|
|
66291
|
-
static paintTie(canvas, scale, x1, y1, x2, y2, down /*= false*/, offset /*= 22*/, size /*= 4*/) {
|
|
66292
|
-
const cps = TieGlyph._computeBezierControlPoints(scale, x1, y1, x2, y2, down, offset, size);
|
|
66293
|
-
canvas.beginPath();
|
|
66294
|
-
canvas.moveTo(cps[0], cps[1]);
|
|
66295
|
-
canvas.bezierCurveTo(cps[2], cps[3], cps[4], cps[5], cps[6], cps[7]);
|
|
66296
|
-
canvas.bezierCurveTo(cps[8], cps[9], cps[10], cps[11], cps[12], cps[13]);
|
|
66297
|
-
canvas.closePath();
|
|
66298
|
-
canvas.fill();
|
|
66299
|
-
}
|
|
66300
|
-
static calculateBendSlurTopY(x1, y1, x2, y2, down, scale, bendSlurHeight) {
|
|
66301
|
-
let normalVectorX = y2 - y1;
|
|
66302
|
-
let normalVectorY = x2 - x1;
|
|
66303
|
-
const length = Math.sqrt(normalVectorX * normalVectorX + normalVectorY * normalVectorY);
|
|
66304
|
-
if (down) {
|
|
66305
|
-
normalVectorX *= -1;
|
|
66306
|
-
}
|
|
66307
|
-
else {
|
|
66308
|
-
normalVectorY *= -1;
|
|
66309
|
-
}
|
|
66310
|
-
// make to unit vector
|
|
66311
|
-
normalVectorX /= length;
|
|
66312
|
-
normalVectorY /= length;
|
|
66313
|
-
let offset = bendSlurHeight * scale;
|
|
66314
|
-
if (x2 - x1 < 20) {
|
|
66315
|
-
offset /= 2;
|
|
66316
|
-
}
|
|
66317
|
-
const centerY = (y2 + y1) / 2;
|
|
66318
|
-
const cp1Y = centerY + offset * normalVectorY;
|
|
66319
|
-
return cp1Y;
|
|
66320
|
-
}
|
|
66321
|
-
static drawBendSlur(canvas, x1, y1, x2, y2, down, scale, bendSlurHeight, slurText) {
|
|
66322
|
-
let normalVectorX = y2 - y1;
|
|
66323
|
-
let normalVectorY = x2 - x1;
|
|
66324
|
-
const length = Math.sqrt(normalVectorX * normalVectorX + normalVectorY * normalVectorY);
|
|
66325
|
-
if (down) {
|
|
66326
|
-
normalVectorX *= -1;
|
|
66327
|
-
}
|
|
66328
|
-
else {
|
|
66329
|
-
normalVectorY *= -1;
|
|
66330
|
-
}
|
|
66331
|
-
// make to unit vector
|
|
66332
|
-
normalVectorX /= length;
|
|
66333
|
-
normalVectorY /= length;
|
|
66334
|
-
// center of connection
|
|
66335
|
-
// TODO: should be 1/3
|
|
66336
|
-
const centerX = (x2 + x1) / 2;
|
|
66337
|
-
const centerY = (y2 + y1) / 2;
|
|
66338
|
-
let offset = bendSlurHeight * scale;
|
|
66339
|
-
if (x2 - x1 < 20) {
|
|
66340
|
-
offset /= 2;
|
|
66341
|
-
}
|
|
66342
|
-
const cp1X = centerX + offset * normalVectorX;
|
|
66343
|
-
const cp1Y = centerY + offset * normalVectorY;
|
|
66344
|
-
canvas.beginPath();
|
|
66345
|
-
canvas.moveTo(x1, y1);
|
|
66346
|
-
canvas.lineTo(cp1X, cp1Y);
|
|
66347
|
-
canvas.lineTo(x2, y2);
|
|
66348
|
-
canvas.stroke();
|
|
66349
|
-
if (slurText) {
|
|
66350
|
-
const w = canvas.measureText(slurText).width;
|
|
66351
|
-
const textOffset = down ? 0 : -canvas.font.size;
|
|
66352
|
-
canvas.fillText(slurText, cp1X - w / 2, cp1Y + textOffset);
|
|
66353
|
-
}
|
|
66354
|
-
}
|
|
66355
|
-
}
|
|
66356
|
-
|
|
66357
|
-
/**
|
|
66358
|
-
* @internal
|
|
66359
|
-
*/
|
|
66360
|
-
class NumberedTieGlyph extends TieGlyph {
|
|
66361
|
-
startNote;
|
|
66362
|
-
endNote;
|
|
66363
|
-
constructor(startNote, endNote, forEnd = false) {
|
|
66364
|
-
super(!startNote ? null : startNote.beat, !endNote ? null : endNote.beat, forEnd);
|
|
66365
|
-
this.startNote = startNote;
|
|
66366
|
-
this.endNote = endNote;
|
|
66367
|
-
}
|
|
66368
|
-
get _isLeftHandTap() {
|
|
66369
|
-
return this.startNote === this.endNote;
|
|
66370
|
-
}
|
|
66587
|
+
class NumberedTieGlyph extends NoteTieGlyph {
|
|
66371
66588
|
shouldDrawBendSlur() {
|
|
66372
66589
|
return (this.renderer.settings.notation.extendBendArrowsOnTiedNotes &&
|
|
66373
66590
|
!!this.startNote.bendOrigin &&
|
|
66374
66591
|
this.startNote.isTieOrigin);
|
|
66375
66592
|
}
|
|
66376
|
-
|
|
66377
|
-
super.doLayout();
|
|
66378
|
-
}
|
|
66379
|
-
getBeamDirection(_beat, _noteRenderer) {
|
|
66593
|
+
calculateTieDirection() {
|
|
66380
66594
|
return BeamDirection.Up;
|
|
66381
66595
|
}
|
|
66382
|
-
getStartY() {
|
|
66383
|
-
return this.startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Top);
|
|
66384
|
-
}
|
|
66385
|
-
getEndY() {
|
|
66386
|
-
return this.getStartY();
|
|
66387
|
-
}
|
|
66388
|
-
getStartX() {
|
|
66389
|
-
if (this._isLeftHandTap) {
|
|
66390
|
-
return this.getEndX() - this.startNoteRenderer.smuflMetrics.leftHandTabTieWidth;
|
|
66391
|
-
}
|
|
66392
|
-
return this.startNoteRenderer.getNoteX(this.startNote, NoteXPosition.Center);
|
|
66393
|
-
}
|
|
66394
|
-
getEndX() {
|
|
66395
|
-
if (this._isLeftHandTap) {
|
|
66396
|
-
return this.endNoteRenderer.getNoteX(this.endNote, NoteXPosition.Left);
|
|
66397
|
-
}
|
|
66398
|
-
return this.endNoteRenderer.getNoteX(this.endNote, NoteXPosition.Center);
|
|
66399
|
-
}
|
|
66400
66596
|
}
|
|
66401
66597
|
|
|
66402
66598
|
/**
|
|
66403
66599
|
* @internal
|
|
66404
66600
|
*/
|
|
66405
|
-
class TabTieGlyph extends
|
|
66406
|
-
|
|
66407
|
-
|
|
66408
|
-
constructor(startNote, endNote, forEnd = false) {
|
|
66409
|
-
super(startNote.beat, endNote.beat, forEnd);
|
|
66410
|
-
this.startNote = startNote;
|
|
66411
|
-
this.endNote = endNote;
|
|
66412
|
-
}
|
|
66413
|
-
get _isLeftHandTap() {
|
|
66414
|
-
return this.startNote === this.endNote;
|
|
66415
|
-
}
|
|
66416
|
-
getTieHeight(startX, startY, endX, endY) {
|
|
66417
|
-
if (this._isLeftHandTap) {
|
|
66418
|
-
return this.startNoteRenderer.smuflMetrics.tieHeight;
|
|
66419
|
-
}
|
|
66420
|
-
return super.getTieHeight(startX, startY, endX, endY);
|
|
66421
|
-
}
|
|
66422
|
-
getBeamDirection(_beat, _noteRenderer) {
|
|
66423
|
-
if (this._isLeftHandTap) {
|
|
66601
|
+
class TabTieGlyph extends NoteTieGlyph {
|
|
66602
|
+
calculateTieDirection() {
|
|
66603
|
+
if (this.isLeftHandTap) {
|
|
66424
66604
|
return BeamDirection.Up;
|
|
66425
66605
|
}
|
|
66426
66606
|
return TabTieGlyph.getBeamDirectionForNote(this.startNote);
|
|
@@ -66428,54 +66608,25 @@
|
|
|
66428
66608
|
static getBeamDirectionForNote(note) {
|
|
66429
66609
|
return note.string > 3 ? BeamDirection.Up : BeamDirection.Down;
|
|
66430
66610
|
}
|
|
66431
|
-
getStartY() {
|
|
66432
|
-
if (this._isLeftHandTap) {
|
|
66433
|
-
return this.startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Center);
|
|
66434
|
-
}
|
|
66435
|
-
if (this.tieDirection === BeamDirection.Up) {
|
|
66436
|
-
return this.startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Top);
|
|
66437
|
-
}
|
|
66438
|
-
return this.startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Bottom);
|
|
66439
|
-
}
|
|
66440
|
-
getEndY() {
|
|
66441
|
-
return this.getStartY();
|
|
66442
|
-
}
|
|
66443
|
-
getStartX() {
|
|
66444
|
-
if (this._isLeftHandTap) {
|
|
66445
|
-
return this.getEndX() - this.renderer.smuflMetrics.leftHandTabTieWidth;
|
|
66446
|
-
}
|
|
66447
|
-
return this.startNoteRenderer.getNoteX(this.startNote, NoteXPosition.Center);
|
|
66448
|
-
}
|
|
66449
|
-
getEndX() {
|
|
66450
|
-
if (this._isLeftHandTap) {
|
|
66451
|
-
return this.endNoteRenderer.getNoteX(this.endNote, NoteXPosition.Left);
|
|
66452
|
-
}
|
|
66453
|
-
return this.endNoteRenderer.getNoteX(this.endNote, NoteXPosition.Center);
|
|
66454
|
-
}
|
|
66455
66611
|
}
|
|
66456
66612
|
|
|
66457
66613
|
/**
|
|
66458
66614
|
* @internal
|
|
66459
66615
|
*/
|
|
66460
|
-
class
|
|
66461
|
-
_direction;
|
|
66616
|
+
class TabSlurGlyph extends TabTieGlyph {
|
|
66462
66617
|
_forSlide;
|
|
66463
|
-
constructor(startNote, endNote, forSlide, forEnd
|
|
66464
|
-
super(startNote, endNote, forEnd);
|
|
66465
|
-
this._direction = BeamDirection.Up;
|
|
66618
|
+
constructor(slurEffectId, startNote, endNote, forSlide, forEnd) {
|
|
66619
|
+
super(slurEffectId, startNote, endNote, forEnd);
|
|
66466
66620
|
this._forSlide = forSlide;
|
|
66467
66621
|
}
|
|
66468
66622
|
getTieHeight(startX, _startY, endX, _endY) {
|
|
66469
|
-
return Math.log(endX - startX + 1) * this.renderer.settings.notation.slurHeight / 2;
|
|
66623
|
+
return (Math.log(endX - startX + 1) * this.renderer.settings.notation.slurHeight) / 2;
|
|
66470
66624
|
}
|
|
66471
66625
|
tryExpand(startNote, endNote, forSlide, forEnd) {
|
|
66472
66626
|
// same type required
|
|
66473
66627
|
if (this._forSlide !== forSlide) {
|
|
66474
66628
|
return false;
|
|
66475
66629
|
}
|
|
66476
|
-
if (this.forEnd !== forEnd) {
|
|
66477
|
-
return false;
|
|
66478
|
-
}
|
|
66479
66630
|
// same start and endbeat
|
|
66480
66631
|
if (this.startNote.beat.id !== startNote.beat.id) {
|
|
66481
66632
|
return false;
|
|
@@ -66483,41 +66634,43 @@
|
|
|
66483
66634
|
if (this.endNote.beat.id !== endNote.beat.id) {
|
|
66484
66635
|
return false;
|
|
66485
66636
|
}
|
|
66637
|
+
const isForEnd = this.renderer === this.lookupEndBeatRenderer();
|
|
66638
|
+
if (isForEnd !== forEnd) {
|
|
66639
|
+
return false;
|
|
66640
|
+
}
|
|
66641
|
+
// same draw direction
|
|
66642
|
+
if (this.tieDirection !== TabTieGlyph.getBeamDirectionForNote(startNote)) {
|
|
66643
|
+
return false;
|
|
66644
|
+
}
|
|
66486
66645
|
// if we can expand, expand in correct direction
|
|
66487
|
-
switch (this.
|
|
66646
|
+
switch (this.tieDirection) {
|
|
66488
66647
|
case BeamDirection.Up:
|
|
66489
66648
|
if (startNote.realValue > this.startNote.realValue) {
|
|
66490
66649
|
this.startNote = startNote;
|
|
66491
|
-
this.startBeat = startNote.beat;
|
|
66492
66650
|
}
|
|
66493
66651
|
if (endNote.realValue > this.endNote.realValue) {
|
|
66494
66652
|
this.endNote = endNote;
|
|
66495
|
-
this.endBeat = endNote.beat;
|
|
66496
66653
|
}
|
|
66497
66654
|
break;
|
|
66498
66655
|
case BeamDirection.Down:
|
|
66499
66656
|
if (startNote.realValue < this.startNote.realValue) {
|
|
66500
66657
|
this.startNote = startNote;
|
|
66501
|
-
this.startBeat = startNote.beat;
|
|
66502
66658
|
}
|
|
66503
66659
|
if (endNote.realValue < this.endNote.realValue) {
|
|
66504
66660
|
this.endNote = endNote;
|
|
66505
|
-
this.endBeat = endNote.beat;
|
|
66506
66661
|
}
|
|
66507
66662
|
break;
|
|
66508
66663
|
}
|
|
66509
66664
|
return true;
|
|
66510
66665
|
}
|
|
66511
|
-
|
|
66512
|
-
|
|
66513
|
-
|
|
66514
|
-
|
|
66515
|
-
|
|
66516
|
-
|
|
66517
|
-
|
|
66518
|
-
|
|
66519
|
-
super.paint(cx, cy, canvas);
|
|
66520
|
-
}
|
|
66666
|
+
}
|
|
66667
|
+
|
|
66668
|
+
/**
|
|
66669
|
+
* @internal
|
|
66670
|
+
*/
|
|
66671
|
+
class NumberedSlurGlyph extends TabSlurGlyph {
|
|
66672
|
+
calculateTieDirection() {
|
|
66673
|
+
return BeamDirection.Up;
|
|
66521
66674
|
}
|
|
66522
66675
|
}
|
|
66523
66676
|
|
|
@@ -66525,23 +66678,31 @@
|
|
|
66525
66678
|
* @internal
|
|
66526
66679
|
*/
|
|
66527
66680
|
class NumberedBeatContainerGlyph extends BeatContainerGlyph {
|
|
66681
|
+
_slurs = new Map();
|
|
66528
66682
|
_effectSlurs = [];
|
|
66683
|
+
doLayout() {
|
|
66684
|
+
this._slurs.clear();
|
|
66685
|
+
this._effectSlurs = [];
|
|
66686
|
+
super.doLayout();
|
|
66687
|
+
}
|
|
66529
66688
|
createTies(n) {
|
|
66530
66689
|
// create a tie if any effect requires it
|
|
66531
66690
|
if (!n.isVisible) {
|
|
66532
66691
|
return;
|
|
66533
66692
|
}
|
|
66534
|
-
if (n.isTieOrigin && n.tieDestination.isVisible) {
|
|
66535
|
-
const tie = new NumberedTieGlyph(n, n.tieDestination, false);
|
|
66693
|
+
if (n.isTieOrigin && n.tieDestination.isVisible && !this._slurs.has('numbered.tie')) {
|
|
66694
|
+
const tie = new NumberedTieGlyph(`numbered.tie.${n.beat.id}`, n, n.tieDestination, false);
|
|
66536
66695
|
this.addTie(tie);
|
|
66696
|
+
this._slurs.set(tie.slurEffectId, tie);
|
|
66537
66697
|
}
|
|
66538
66698
|
if (n.isTieDestination) {
|
|
66539
|
-
const tie = new NumberedTieGlyph(n.tieOrigin, n, true);
|
|
66699
|
+
const tie = new NumberedTieGlyph(`numbered.tie.${n.tieOrigin.beat.id}`, n.tieOrigin, n, true);
|
|
66540
66700
|
this.addTie(tie);
|
|
66541
66701
|
}
|
|
66542
|
-
if (n.isLeftHandTapped && !n.isHammerPullDestination) {
|
|
66543
|
-
const tapSlur = new NumberedTieGlyph(n, n, false);
|
|
66702
|
+
if (n.isLeftHandTapped && !n.isHammerPullDestination && !this._slurs.has(`numbered.tie.leftHandTap.${n.beat.id}`)) {
|
|
66703
|
+
const tapSlur = new NumberedTieGlyph(`numbered.tie.leftHandTap.${n.beat.id}`, n, n, false);
|
|
66544
66704
|
this.addTie(tapSlur);
|
|
66705
|
+
this._slurs.set(tapSlur.slurEffectId, tapSlur);
|
|
66545
66706
|
}
|
|
66546
66707
|
// start effect slur on first beat
|
|
66547
66708
|
if (n.isEffectSlurOrigin && n.effectSlurDestination) {
|
|
@@ -66553,9 +66714,11 @@
|
|
|
66553
66714
|
}
|
|
66554
66715
|
}
|
|
66555
66716
|
if (!expanded) {
|
|
66556
|
-
const effectSlur = new NumberedSlurGlyph(n, n.effectSlurDestination, false, false);
|
|
66717
|
+
const effectSlur = new NumberedSlurGlyph(`numbered.slur.effect`, n, n.effectSlurDestination, false, false);
|
|
66557
66718
|
this._effectSlurs.push(effectSlur);
|
|
66558
66719
|
this.addTie(effectSlur);
|
|
66720
|
+
this._slurs.set(effectSlur.slurEffectId, effectSlur);
|
|
66721
|
+
this._slurs.set('numbered.slur.effect', effectSlur);
|
|
66559
66722
|
}
|
|
66560
66723
|
}
|
|
66561
66724
|
// end effect slur on last beat
|
|
@@ -66568,9 +66731,11 @@
|
|
|
66568
66731
|
}
|
|
66569
66732
|
}
|
|
66570
66733
|
if (!expanded) {
|
|
66571
|
-
const effectSlur = new NumberedSlurGlyph(n.effectSlurOrigin, n, false, true);
|
|
66734
|
+
const effectSlur = new NumberedSlurGlyph(`numbered.slur.effect`, n.effectSlurOrigin, n, false, true);
|
|
66572
66735
|
this._effectSlurs.push(effectSlur);
|
|
66573
66736
|
this.addTie(effectSlur);
|
|
66737
|
+
this._slurs.set(effectSlur.slurEffectId, effectSlur);
|
|
66738
|
+
this._slurs.set('numbered.slur.effect', effectSlur);
|
|
66574
66739
|
}
|
|
66575
66740
|
}
|
|
66576
66741
|
}
|
|
@@ -66963,10 +67128,11 @@
|
|
|
66963
67128
|
if (sr.shortestDuration < this.container.beat.duration) {
|
|
66964
67129
|
sr.shortestDuration = this.container.beat.duration;
|
|
66965
67130
|
}
|
|
66966
|
-
const glyphY = sr.getLineY(sr.getNoteLine());
|
|
66967
67131
|
if (!this.container.beat.isEmpty) {
|
|
67132
|
+
const glyphY = sr.getLineY(0);
|
|
66968
67133
|
let numberWithinOctave = '0';
|
|
66969
67134
|
if (this.container.beat.notes.length > 0) {
|
|
67135
|
+
const note = this.container.beat.notes[0];
|
|
66970
67136
|
const kst = this.renderer.bar.keySignatureType;
|
|
66971
67137
|
const ks = this.renderer.bar.keySignature;
|
|
66972
67138
|
const ksi = ks + 7;
|
|
@@ -66974,7 +67140,6 @@
|
|
|
66974
67140
|
? NumberedBeatGlyph.minorKeySignatureOneValues
|
|
66975
67141
|
: NumberedBeatGlyph.majorKeySignatureOneValues;
|
|
66976
67142
|
const oneNoteValue = oneNoteValues[ksi];
|
|
66977
|
-
const note = this.container.beat.notes[0];
|
|
66978
67143
|
if (note.isDead) {
|
|
66979
67144
|
numberWithinOctave = 'X';
|
|
66980
67145
|
}
|
|
@@ -67021,7 +67186,7 @@
|
|
|
67021
67186
|
// Note dots
|
|
67022
67187
|
if (this.container.beat.dots > 0 && this.container.beat.duration >= Duration.Quarter) {
|
|
67023
67188
|
for (let i = 0; i < this.container.beat.dots; i++) {
|
|
67024
|
-
const dot = new AugmentationDotGlyph(0,
|
|
67189
|
+
const dot = new AugmentationDotGlyph(0, glyphY);
|
|
67025
67190
|
dot.renderer = this.renderer;
|
|
67026
67191
|
this.addEffect(dot);
|
|
67027
67192
|
}
|
|
@@ -67049,7 +67214,7 @@
|
|
|
67049
67214
|
numberOfQuarterNotes += numberOfAddedQuarters;
|
|
67050
67215
|
}
|
|
67051
67216
|
for (let i = 0; i < numberOfQuarterNotes - 1; i++) {
|
|
67052
|
-
const dash = new NumberedDashGlyph(0,
|
|
67217
|
+
const dash = new NumberedDashGlyph(0, glyphY, this.container.beat);
|
|
67053
67218
|
dash.renderer = this.renderer;
|
|
67054
67219
|
this.addNormal(dash);
|
|
67055
67220
|
}
|
|
@@ -67519,7 +67684,7 @@
|
|
|
67519
67684
|
}
|
|
67520
67685
|
}
|
|
67521
67686
|
}
|
|
67522
|
-
getNoteLine() {
|
|
67687
|
+
getNoteLine(_note) {
|
|
67523
67688
|
return 0;
|
|
67524
67689
|
}
|
|
67525
67690
|
get tupletOffset() {
|
|
@@ -69734,87 +69899,128 @@
|
|
|
69734
69899
|
* @internal
|
|
69735
69900
|
*/
|
|
69736
69901
|
class ScoreLegatoGlyph extends TieGlyph {
|
|
69737
|
-
|
|
69738
|
-
|
|
69902
|
+
startBeat;
|
|
69903
|
+
endBeat;
|
|
69904
|
+
startBeatRenderer = null;
|
|
69905
|
+
endBeatRenderer = null;
|
|
69906
|
+
constructor(slurEffectId, startBeat, endBeat, forEnd) {
|
|
69907
|
+
super(slurEffectId, forEnd);
|
|
69908
|
+
this.startBeat = startBeat;
|
|
69909
|
+
this.endBeat = endBeat;
|
|
69739
69910
|
}
|
|
69740
69911
|
doLayout() {
|
|
69741
69912
|
super.doLayout();
|
|
69742
69913
|
}
|
|
69743
|
-
|
|
69744
|
-
if (
|
|
69914
|
+
lookupStartBeatRenderer() {
|
|
69915
|
+
if (!this.startBeatRenderer) {
|
|
69916
|
+
this.startBeatRenderer = this.renderer.scoreRenderer.layout.getRendererForBar(this.renderer.staff.staffId, this.startBeat.voice.bar);
|
|
69917
|
+
}
|
|
69918
|
+
return this.startBeatRenderer;
|
|
69919
|
+
}
|
|
69920
|
+
lookupEndBeatRenderer() {
|
|
69921
|
+
if (!this.endBeatRenderer) {
|
|
69922
|
+
this.endBeatRenderer = this.renderer.scoreRenderer.layout.getRendererForBar(this.renderer.staff.staffId, this.endBeat.voice.bar);
|
|
69923
|
+
}
|
|
69924
|
+
return this.endBeatRenderer;
|
|
69925
|
+
}
|
|
69926
|
+
shouldDrawBendSlur() {
|
|
69927
|
+
return false;
|
|
69928
|
+
}
|
|
69929
|
+
calculateTieDirection() {
|
|
69930
|
+
if (this.startBeat.isRest) {
|
|
69745
69931
|
return BeamDirection.Up;
|
|
69746
69932
|
}
|
|
69747
69933
|
// invert direction (if stems go up, ties go down to not cross them)
|
|
69748
|
-
switch (
|
|
69934
|
+
switch (this.lookupStartBeatRenderer().getBeatDirection(this.startBeat)) {
|
|
69749
69935
|
case BeamDirection.Up:
|
|
69750
69936
|
return BeamDirection.Down;
|
|
69751
69937
|
default:
|
|
69752
69938
|
return BeamDirection.Up;
|
|
69753
69939
|
}
|
|
69754
69940
|
}
|
|
69755
|
-
|
|
69941
|
+
calculateStartX() {
|
|
69942
|
+
const startBeatRenderer = this.lookupStartBeatRenderer();
|
|
69943
|
+
return startBeatRenderer.x + startBeatRenderer.getBeatX(this.startBeat, BeatXPosition.MiddleNotes);
|
|
69944
|
+
}
|
|
69945
|
+
calculateStartY() {
|
|
69946
|
+
const startBeatRenderer = this.lookupStartBeatRenderer();
|
|
69756
69947
|
if (this.startBeat.isRest) {
|
|
69757
|
-
|
|
69758
|
-
|
|
69948
|
+
switch (this.tieDirection) {
|
|
69949
|
+
case BeamDirection.Up:
|
|
69950
|
+
return (startBeatRenderer.y +
|
|
69951
|
+
startBeatRenderer.getBeatContainer(this.startBeat).onNotes.getBoundingBoxTop());
|
|
69952
|
+
default:
|
|
69953
|
+
return (startBeatRenderer.y +
|
|
69954
|
+
startBeatRenderer.getBeatContainer(this.startBeat).onNotes.getBoundingBoxBottom());
|
|
69955
|
+
}
|
|
69759
69956
|
}
|
|
69760
69957
|
switch (this.tieDirection) {
|
|
69761
69958
|
case BeamDirection.Up:
|
|
69762
69959
|
// below lowest note
|
|
69763
|
-
return
|
|
69960
|
+
return startBeatRenderer.y + startBeatRenderer.getNoteY(this.startBeat.maxNote, NoteYPosition.Top);
|
|
69764
69961
|
default:
|
|
69765
|
-
return
|
|
69962
|
+
return startBeatRenderer.y + startBeatRenderer.getNoteY(this.startBeat.minNote, NoteYPosition.Bottom);
|
|
69963
|
+
}
|
|
69964
|
+
}
|
|
69965
|
+
calculateEndX() {
|
|
69966
|
+
const endBeatRenderer = this.lookupEndBeatRenderer();
|
|
69967
|
+
if (!endBeatRenderer) {
|
|
69968
|
+
return this.calculateStartX() + this.renderer.smuflMetrics.leftHandTabTieWidth;
|
|
69766
69969
|
}
|
|
69970
|
+
const endBeamDirection = endBeatRenderer.getBeatDirection(this.endBeat);
|
|
69971
|
+
return (endBeatRenderer.x +
|
|
69972
|
+
endBeatRenderer.getBeatX(this.endBeat, this.endBeat.duration > Duration.Whole && endBeamDirection === this.tieDirection
|
|
69973
|
+
? BeatXPosition.Stem
|
|
69974
|
+
: BeatXPosition.MiddleNotes));
|
|
69767
69975
|
}
|
|
69768
|
-
|
|
69769
|
-
const
|
|
69976
|
+
caclculateEndY() {
|
|
69977
|
+
const endBeatRenderer = this.lookupEndBeatRenderer();
|
|
69978
|
+
if (!endBeatRenderer) {
|
|
69979
|
+
return this.calculateStartY();
|
|
69980
|
+
}
|
|
69770
69981
|
if (this.endBeat.isRest) {
|
|
69771
69982
|
switch (this.tieDirection) {
|
|
69772
69983
|
case BeamDirection.Up:
|
|
69773
|
-
return
|
|
69984
|
+
return (endBeatRenderer.y + endBeatRenderer.getBeatContainer(this.endBeat).onNotes.getBoundingBoxTop());
|
|
69774
69985
|
default:
|
|
69775
|
-
return
|
|
69986
|
+
return (endBeatRenderer.y +
|
|
69987
|
+
endBeatRenderer.getBeatContainer(this.endBeat).onNotes.getBoundingBoxBottom());
|
|
69776
69988
|
}
|
|
69777
69989
|
}
|
|
69778
|
-
const startBeamDirection = this.
|
|
69779
|
-
const endBeamDirection =
|
|
69990
|
+
const startBeamDirection = this.lookupStartBeatRenderer().getBeatDirection(this.startBeat);
|
|
69991
|
+
const endBeamDirection = endBeatRenderer.getBeatDirection(this.endBeat);
|
|
69780
69992
|
if (startBeamDirection !== endBeamDirection && this.startBeat.graceType === GraceType.None) {
|
|
69781
69993
|
if (endBeamDirection === this.tieDirection) {
|
|
69782
69994
|
switch (this.tieDirection) {
|
|
69783
69995
|
case BeamDirection.Up:
|
|
69784
69996
|
// stem upper end
|
|
69785
|
-
return
|
|
69997
|
+
return (endBeatRenderer.y +
|
|
69998
|
+
endBeatRenderer.getNoteY(this.endBeat.maxNote, NoteYPosition.TopWithStem));
|
|
69786
69999
|
default:
|
|
69787
70000
|
// stem lower end
|
|
69788
|
-
return
|
|
70001
|
+
return (endBeatRenderer.y +
|
|
70002
|
+
endBeatRenderer.getNoteY(this.endBeat.minNote, NoteYPosition.BottomWithStem));
|
|
69789
70003
|
}
|
|
69790
70004
|
}
|
|
69791
70005
|
switch (this.tieDirection) {
|
|
69792
70006
|
case BeamDirection.Up:
|
|
69793
70007
|
// stem upper end
|
|
69794
|
-
return
|
|
70008
|
+
return (endBeatRenderer.y +
|
|
70009
|
+
endBeatRenderer.getNoteY(this.endBeat.maxNote, NoteYPosition.BottomWithStem));
|
|
69795
70010
|
default:
|
|
69796
70011
|
// stem lower end
|
|
69797
|
-
return
|
|
70012
|
+
return (endBeatRenderer.y + endBeatRenderer.getNoteY(this.endBeat.minNote, NoteYPosition.TopWithStem));
|
|
69798
70013
|
}
|
|
69799
70014
|
}
|
|
69800
70015
|
switch (this.tieDirection) {
|
|
69801
70016
|
case BeamDirection.Up:
|
|
69802
70017
|
// below lowest note
|
|
69803
|
-
return
|
|
70018
|
+
return endBeatRenderer.y + endBeatRenderer.getNoteY(this.endBeat.maxNote, NoteYPosition.Top);
|
|
69804
70019
|
default:
|
|
69805
70020
|
// above highest note
|
|
69806
|
-
return
|
|
70021
|
+
return endBeatRenderer.y + endBeatRenderer.getNoteY(this.endBeat.minNote, NoteYPosition.Bottom);
|
|
69807
70022
|
}
|
|
69808
70023
|
}
|
|
69809
|
-
getStartX() {
|
|
69810
|
-
return this.startNoteRenderer.getBeatX(this.startBeat, BeatXPosition.MiddleNotes);
|
|
69811
|
-
}
|
|
69812
|
-
getEndX() {
|
|
69813
|
-
const endBeamDirection = this.endNoteRenderer.getBeatDirection(this.endBeat);
|
|
69814
|
-
return this.endNoteRenderer.getBeatX(this.endBeat, this.endBeat.duration > Duration.Whole && endBeamDirection === this.tieDirection
|
|
69815
|
-
? BeatXPosition.Stem
|
|
69816
|
-
: BeatXPosition.MiddleNotes);
|
|
69817
|
-
}
|
|
69818
70024
|
}
|
|
69819
70025
|
|
|
69820
70026
|
/**
|
|
@@ -70014,142 +70220,106 @@
|
|
|
70014
70220
|
/**
|
|
70015
70221
|
* @internal
|
|
70016
70222
|
*/
|
|
70017
|
-
class
|
|
70018
|
-
|
|
70019
|
-
|
|
70020
|
-
|
|
70021
|
-
|
|
70022
|
-
|
|
70023
|
-
|
|
70223
|
+
class ScoreTieGlyph extends NoteTieGlyph {
|
|
70224
|
+
shouldDrawBendSlur() {
|
|
70225
|
+
return (this.renderer.settings.notation.extendBendArrowsOnTiedNotes &&
|
|
70226
|
+
!!this.startNote.bendOrigin &&
|
|
70227
|
+
this.startNote.isTieOrigin);
|
|
70228
|
+
}
|
|
70229
|
+
calculateStartX() {
|
|
70230
|
+
if (this.isLeftHandTap) {
|
|
70231
|
+
return this.calculateEndX() - this.renderer.smuflMetrics.leftHandTabTieWidth;
|
|
70232
|
+
}
|
|
70233
|
+
return this.renderer.x + this.renderer.getBeatX(this.startNote.beat, BeatXPosition.PostNotes);
|
|
70234
|
+
}
|
|
70235
|
+
calculateEndX() {
|
|
70236
|
+
const endNoteRenderer = this.lookupEndBeatRenderer();
|
|
70237
|
+
if (!endNoteRenderer) {
|
|
70238
|
+
return this.calculateStartX() + this.renderer.smuflMetrics.leftHandTabTieWidth;
|
|
70239
|
+
}
|
|
70240
|
+
if (this.isLeftHandTap) {
|
|
70241
|
+
return endNoteRenderer.x + endNoteRenderer.getNoteX(this.endNote, NoteXPosition.Left);
|
|
70242
|
+
}
|
|
70243
|
+
return endNoteRenderer.x + endNoteRenderer.getBeatX(this.endNote.beat, BeatXPosition.PreNotes);
|
|
70024
70244
|
}
|
|
70245
|
+
}
|
|
70246
|
+
|
|
70247
|
+
/**
|
|
70248
|
+
* @internal
|
|
70249
|
+
*/
|
|
70250
|
+
class ScoreSlurGlyph extends ScoreTieGlyph {
|
|
70025
70251
|
getTieHeight(startX, _startY, endX, _endY) {
|
|
70026
|
-
return Math.log2(endX - startX + 1) * this.renderer.settings.notation.slurHeight / 2;
|
|
70252
|
+
return (Math.log2(endX - startX + 1) * this.renderer.settings.notation.slurHeight) / 2;
|
|
70027
70253
|
}
|
|
70028
|
-
|
|
70254
|
+
calculateStartX() {
|
|
70255
|
+
return (this.renderer.x +
|
|
70256
|
+
(this._isStartCentered()
|
|
70257
|
+
? this.renderer.getBeatX(this.startNote.beat, BeatXPosition.MiddleNotes)
|
|
70258
|
+
: this.renderer.getNoteX(this.startNote, NoteXPosition.Right)));
|
|
70259
|
+
}
|
|
70260
|
+
calculateStartY() {
|
|
70029
70261
|
if (this._isStartCentered()) {
|
|
70030
70262
|
switch (this.tieDirection) {
|
|
70031
70263
|
case BeamDirection.Up:
|
|
70032
|
-
|
|
70033
|
-
return this.startNoteRenderer.getNoteY(this._startNote, NoteYPosition.Top);
|
|
70264
|
+
return this.renderer.y + this.renderer.getNoteY(this.startNote, NoteYPosition.Top);
|
|
70034
70265
|
default:
|
|
70035
|
-
return this.
|
|
70266
|
+
return this.renderer.y + this.renderer.getNoteY(this.startNote, NoteYPosition.Bottom);
|
|
70267
|
+
}
|
|
70268
|
+
}
|
|
70269
|
+
return this.renderer.y + this.renderer.getNoteY(this.startNote, NoteYPosition.Center);
|
|
70270
|
+
}
|
|
70271
|
+
calculateEndX() {
|
|
70272
|
+
const endNoteRenderer = this.lookupEndBeatRenderer();
|
|
70273
|
+
if (!endNoteRenderer) {
|
|
70274
|
+
return this.calculateStartX() + this.renderer.smuflMetrics.leftHandTabTieWidth;
|
|
70275
|
+
}
|
|
70276
|
+
if (this._isEndCentered()) {
|
|
70277
|
+
if (this._isEndOnStem()) {
|
|
70278
|
+
return endNoteRenderer.x + endNoteRenderer.getBeatX(this.endNote.beat, BeatXPosition.Stem);
|
|
70036
70279
|
}
|
|
70280
|
+
return endNoteRenderer.x + endNoteRenderer.getNoteX(this.endNote, NoteXPosition.Center);
|
|
70037
70281
|
}
|
|
70038
|
-
return
|
|
70282
|
+
return endNoteRenderer.x + endNoteRenderer.getBeatX(this.endNote.beat, BeatXPosition.PreNotes);
|
|
70039
70283
|
}
|
|
70040
|
-
|
|
70284
|
+
caclculateEndY() {
|
|
70285
|
+
const endNoteRenderer = this.lookupEndBeatRenderer();
|
|
70286
|
+
if (!endNoteRenderer) {
|
|
70287
|
+
return this.calculateStartY();
|
|
70288
|
+
}
|
|
70041
70289
|
if (this._isEndCentered()) {
|
|
70042
70290
|
if (this._isEndOnStem()) {
|
|
70043
70291
|
switch (this.tieDirection) {
|
|
70044
70292
|
case BeamDirection.Up:
|
|
70045
|
-
return
|
|
70293
|
+
return endNoteRenderer.y + endNoteRenderer.getNoteY(this.endNote, NoteYPosition.TopWithStem);
|
|
70046
70294
|
default:
|
|
70047
|
-
return
|
|
70295
|
+
return endNoteRenderer.y + endNoteRenderer.getNoteY(this.endNote, NoteYPosition.BottomWithStem);
|
|
70048
70296
|
}
|
|
70049
70297
|
}
|
|
70050
70298
|
switch (this.tieDirection) {
|
|
70051
70299
|
case BeamDirection.Up:
|
|
70052
|
-
return
|
|
70300
|
+
return endNoteRenderer.y + endNoteRenderer.getNoteY(this.endNote, NoteYPosition.Top);
|
|
70053
70301
|
default:
|
|
70054
|
-
return
|
|
70302
|
+
return endNoteRenderer.y + endNoteRenderer.getNoteY(this.endNote, NoteYPosition.Bottom);
|
|
70055
70303
|
}
|
|
70056
70304
|
}
|
|
70057
|
-
return
|
|
70305
|
+
return endNoteRenderer.y + endNoteRenderer.getNoteY(this.endNote, NoteYPosition.Center);
|
|
70058
70306
|
}
|
|
70059
70307
|
_isStartCentered() {
|
|
70060
|
-
return ((this.
|
|
70061
|
-
(this.
|
|
70308
|
+
return ((this.startNote === this.startNote.beat.maxNote && this.tieDirection === BeamDirection.Up) ||
|
|
70309
|
+
(this.startNote === this.startNote.beat.minNote && this.tieDirection === BeamDirection.Down));
|
|
70062
70310
|
}
|
|
70063
70311
|
_isEndCentered() {
|
|
70064
|
-
return (this.
|
|
70065
|
-
((this.
|
|
70066
|
-
(this.
|
|
70312
|
+
return (this.startNote.beat.graceType === GraceType.None &&
|
|
70313
|
+
((this.endNote === this.endNote.beat.maxNote && this.tieDirection === BeamDirection.Up) ||
|
|
70314
|
+
(this.endNote === this.endNote.beat.minNote && this.tieDirection === BeamDirection.Down)));
|
|
70067
70315
|
}
|
|
70068
70316
|
_isEndOnStem() {
|
|
70069
|
-
const
|
|
70070
|
-
const
|
|
70071
|
-
const endBeamDirection =
|
|
70072
|
-
|
|
70073
|
-
|
|
70074
|
-
|
|
70075
|
-
return this._isStartCentered()
|
|
70076
|
-
? this.startNoteRenderer.getBeatX(this._startNote.beat, BeatXPosition.MiddleNotes)
|
|
70077
|
-
: this.startNoteRenderer.getNoteX(this._startNote, NoteXPosition.Right);
|
|
70078
|
-
}
|
|
70079
|
-
getEndX() {
|
|
70080
|
-
if (this._isEndCentered()) {
|
|
70081
|
-
if (this._isEndOnStem()) {
|
|
70082
|
-
return this.endNoteRenderer.getBeatX(this._endNote.beat, BeatXPosition.Stem);
|
|
70083
|
-
}
|
|
70084
|
-
return this.endNoteRenderer.getNoteX(this._endNote, NoteXPosition.Center);
|
|
70085
|
-
}
|
|
70086
|
-
return this.endNoteRenderer.getBeatX(this._endNote.beat, BeatXPosition.PreNotes);
|
|
70087
|
-
}
|
|
70088
|
-
}
|
|
70089
|
-
|
|
70090
|
-
/**
|
|
70091
|
-
* @internal
|
|
70092
|
-
*/
|
|
70093
|
-
class ScoreTieGlyph extends TieGlyph {
|
|
70094
|
-
startNote;
|
|
70095
|
-
endNote;
|
|
70096
|
-
constructor(startNote, endNote, forEnd = false) {
|
|
70097
|
-
super(!startNote ? null : startNote.beat, !endNote ? null : endNote.beat, forEnd);
|
|
70098
|
-
this.startNote = startNote;
|
|
70099
|
-
this.endNote = endNote;
|
|
70100
|
-
}
|
|
70101
|
-
shouldDrawBendSlur() {
|
|
70102
|
-
return (this.renderer.settings.notation.extendBendArrowsOnTiedNotes &&
|
|
70103
|
-
!!this.startNote.bendOrigin &&
|
|
70104
|
-
this.startNote.isTieOrigin);
|
|
70105
|
-
}
|
|
70106
|
-
doLayout() {
|
|
70107
|
-
super.doLayout();
|
|
70108
|
-
}
|
|
70109
|
-
getBeamDirection(beat, noteRenderer) {
|
|
70110
|
-
// invert direction (if stems go up, ties go down to not cross them)
|
|
70111
|
-
switch (noteRenderer.getBeatDirection(beat)) {
|
|
70112
|
-
case BeamDirection.Up:
|
|
70113
|
-
return BeamDirection.Down;
|
|
70114
|
-
default:
|
|
70115
|
-
return BeamDirection.Up;
|
|
70116
|
-
}
|
|
70117
|
-
}
|
|
70118
|
-
getStartY() {
|
|
70119
|
-
if (this.startBeat.isRest) {
|
|
70120
|
-
// below all lines
|
|
70121
|
-
return this.startNoteRenderer.getScoreY(9);
|
|
70122
|
-
}
|
|
70123
|
-
switch (this.tieDirection) {
|
|
70124
|
-
case BeamDirection.Up:
|
|
70125
|
-
// below lowest note
|
|
70126
|
-
return this.startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Top);
|
|
70127
|
-
default:
|
|
70128
|
-
return this.startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Bottom);
|
|
70129
|
-
}
|
|
70130
|
-
}
|
|
70131
|
-
getEndY() {
|
|
70132
|
-
const endNoteScoreRenderer = this.endNoteRenderer;
|
|
70133
|
-
if (this.endBeat.isRest) {
|
|
70134
|
-
switch (this.tieDirection) {
|
|
70135
|
-
case BeamDirection.Up:
|
|
70136
|
-
return endNoteScoreRenderer.getScoreY(9);
|
|
70137
|
-
default:
|
|
70138
|
-
return endNoteScoreRenderer.getScoreY(0);
|
|
70139
|
-
}
|
|
70140
|
-
}
|
|
70141
|
-
switch (this.tieDirection) {
|
|
70142
|
-
case BeamDirection.Up:
|
|
70143
|
-
return endNoteScoreRenderer.getNoteY(this.endNote, NoteYPosition.Top);
|
|
70144
|
-
default:
|
|
70145
|
-
return endNoteScoreRenderer.getNoteY(this.endNote, NoteYPosition.Bottom);
|
|
70146
|
-
}
|
|
70147
|
-
}
|
|
70148
|
-
getStartX() {
|
|
70149
|
-
return this.startNoteRenderer.getBeatX(this.startNote.beat, BeatXPosition.PostNotes);
|
|
70150
|
-
}
|
|
70151
|
-
getEndX() {
|
|
70152
|
-
return this.endNoteRenderer.getBeatX(this.endNote.beat, BeatXPosition.PreNotes);
|
|
70317
|
+
const startBeamDirection = this.lookupStartBeatRenderer().getBeatDirection(this.startNote.beat);
|
|
70318
|
+
const endBeatRenderer = this.lookupEndBeatRenderer();
|
|
70319
|
+
const endBeamDirection = endBeatRenderer
|
|
70320
|
+
? endBeatRenderer.getBeatDirection(this.endNote.beat)
|
|
70321
|
+
: startBeamDirection;
|
|
70322
|
+
return startBeamDirection !== endBeamDirection && this.startNote.beat.graceType === GraceType.None;
|
|
70153
70323
|
}
|
|
70154
70324
|
}
|
|
70155
70325
|
|
|
@@ -70199,12 +70369,11 @@
|
|
|
70199
70369
|
n.beat.graceType !== GraceType.BendGrace &&
|
|
70200
70370
|
n.tieDestination &&
|
|
70201
70371
|
n.tieDestination.isVisible) {
|
|
70202
|
-
|
|
70203
|
-
const tie = new ScoreTieGlyph(n, n.tieDestination, false);
|
|
70372
|
+
const tie = new ScoreTieGlyph(`score.tie.${n.id}`, n, n.tieDestination, false);
|
|
70204
70373
|
this.addTie(tie);
|
|
70205
70374
|
}
|
|
70206
70375
|
if (n.isTieDestination && !n.tieOrigin.hasBend && !n.beat.hasWhammyBar) {
|
|
70207
|
-
const tie = new ScoreTieGlyph(n.tieOrigin, n, true);
|
|
70376
|
+
const tie = new ScoreTieGlyph(`score.tie.${n.tieOrigin.id}`, n.tieOrigin, n, true);
|
|
70208
70377
|
this.addTie(tie);
|
|
70209
70378
|
}
|
|
70210
70379
|
// TODO: depending on the type we have other positioning
|
|
@@ -70214,17 +70383,16 @@
|
|
|
70214
70383
|
this.addTie(l);
|
|
70215
70384
|
}
|
|
70216
70385
|
if (n.isSlurOrigin && n.slurDestination && n.slurDestination.isVisible) {
|
|
70217
|
-
|
|
70218
|
-
const tie = new ScoreSlurGlyph(n, n.slurDestination, false);
|
|
70386
|
+
const tie = new ScoreSlurGlyph(`score.slur.${n.id}`, n, n.slurDestination, false);
|
|
70219
70387
|
this.addTie(tie);
|
|
70220
70388
|
}
|
|
70221
70389
|
if (n.isSlurDestination) {
|
|
70222
|
-
const tie = new ScoreSlurGlyph(n.slurOrigin, n, true);
|
|
70390
|
+
const tie = new ScoreSlurGlyph(`score.slur.${n.slurOrigin.id}`, n.slurOrigin, n, true);
|
|
70223
70391
|
this.addTie(tie);
|
|
70224
70392
|
}
|
|
70225
70393
|
// start effect slur on first beat
|
|
70226
70394
|
if (!this._effectSlur && n.isEffectSlurOrigin && n.effectSlurDestination) {
|
|
70227
|
-
const effectSlur = new ScoreSlurGlyph(n, n.effectSlurDestination, false);
|
|
70395
|
+
const effectSlur = new ScoreSlurGlyph(`score.slur.effect.${n.beat.id}`, n, n.effectSlurDestination, false);
|
|
70228
70396
|
this._effectSlur = effectSlur;
|
|
70229
70397
|
this.addTie(effectSlur);
|
|
70230
70398
|
}
|
|
@@ -70233,7 +70401,7 @@
|
|
|
70233
70401
|
const direction = this.onNotes.beamingHelper.direction;
|
|
70234
70402
|
const startNote = direction === BeamDirection.Up ? n.beat.effectSlurOrigin.minNote : n.beat.effectSlurOrigin.maxNote;
|
|
70235
70403
|
const endNote = direction === BeamDirection.Up ? n.beat.minNote : n.beat.maxNote;
|
|
70236
|
-
const effectEndSlur = new ScoreSlurGlyph(startNote, endNote, true);
|
|
70404
|
+
const effectEndSlur = new ScoreSlurGlyph(`score.slur.effect.${startNote.beat.id}`, startNote, endNote, true);
|
|
70237
70405
|
this._effectEndSlur = effectEndSlur;
|
|
70238
70406
|
this.addTie(effectEndSlur);
|
|
70239
70407
|
}
|
|
@@ -70255,7 +70423,7 @@
|
|
|
70255
70423
|
while (destination.nextBeat && destination.nextBeat.isLegatoDestination) {
|
|
70256
70424
|
destination = destination.nextBeat;
|
|
70257
70425
|
}
|
|
70258
|
-
this.addTie(new ScoreLegatoGlyph(this.beat, destination, false));
|
|
70426
|
+
this.addTie(new ScoreLegatoGlyph(`score.legato.${this.beat.id}`, this.beat, destination, false));
|
|
70259
70427
|
}
|
|
70260
70428
|
}
|
|
70261
70429
|
else if (this.beat.isLegatoDestination) {
|
|
@@ -70265,7 +70433,7 @@
|
|
|
70265
70433
|
while (origin.previousBeat && origin.previousBeat.isLegatoOrigin) {
|
|
70266
70434
|
origin = origin.previousBeat;
|
|
70267
70435
|
}
|
|
70268
|
-
this.addTie(new ScoreLegatoGlyph(origin, this.beat, true));
|
|
70436
|
+
this.addTie(new ScoreLegatoGlyph(`score.legato.${origin.id}`, origin, this.beat, true));
|
|
70269
70437
|
}
|
|
70270
70438
|
}
|
|
70271
70439
|
}
|
|
@@ -70645,6 +70813,9 @@
|
|
|
70645
70813
|
this.addBeatGlyph(container);
|
|
70646
70814
|
}
|
|
70647
70815
|
}
|
|
70816
|
+
getNoteLine(note) {
|
|
70817
|
+
return this.accidentalHelper.getNoteSteps(note) / 2;
|
|
70818
|
+
}
|
|
70648
70819
|
getNoteSteps(n) {
|
|
70649
70820
|
return this.accidentalHelper.getNoteSteps(n);
|
|
70650
70821
|
}
|
|
@@ -70701,43 +70872,15 @@
|
|
|
70701
70872
|
/**
|
|
70702
70873
|
* @internal
|
|
70703
70874
|
*/
|
|
70704
|
-
class SlashTieGlyph extends
|
|
70705
|
-
|
|
70706
|
-
endNote;
|
|
70707
|
-
constructor(startNote, endNote, forEnd = false) {
|
|
70708
|
-
super(startNote.beat, endNote.beat, forEnd);
|
|
70709
|
-
this.startNote = startNote;
|
|
70710
|
-
this.endNote = endNote;
|
|
70711
|
-
}
|
|
70712
|
-
get _isLeftHandTap() {
|
|
70713
|
-
return this.startNote === this.endNote;
|
|
70714
|
-
}
|
|
70715
|
-
getTieHeight(startX, startY, endX, endY) {
|
|
70716
|
-
if (this._isLeftHandTap) {
|
|
70717
|
-
return this.startNoteRenderer.smuflMetrics.tieHeight;
|
|
70718
|
-
}
|
|
70719
|
-
return super.getTieHeight(startX, startY, endX, endY);
|
|
70720
|
-
}
|
|
70721
|
-
getBeamDirection(_beat, _noteRenderer) {
|
|
70875
|
+
class SlashTieGlyph extends NoteTieGlyph {
|
|
70876
|
+
calculateTieDirection() {
|
|
70722
70877
|
return BeamDirection.Down;
|
|
70723
70878
|
}
|
|
70724
|
-
|
|
70725
|
-
return
|
|
70726
|
-
}
|
|
70727
|
-
getStartY() {
|
|
70728
|
-
return this.startNoteRenderer.getNoteY(this.startNote, NoteYPosition.Center);
|
|
70729
|
-
}
|
|
70730
|
-
getEndY() {
|
|
70731
|
-
return this.getStartY();
|
|
70732
|
-
}
|
|
70733
|
-
getStartX() {
|
|
70734
|
-
if (this._isLeftHandTap) {
|
|
70735
|
-
return this.getEndX() - this.renderer.smuflMetrics.leftHandTabTieWidth;
|
|
70736
|
-
}
|
|
70737
|
-
return this.startNoteRenderer.getNoteX(this.startNote, NoteXPosition.Right);
|
|
70879
|
+
getStartNotePosition() {
|
|
70880
|
+
return NoteXPosition.Right;
|
|
70738
70881
|
}
|
|
70739
|
-
|
|
70740
|
-
return
|
|
70882
|
+
getEndNotePosition() {
|
|
70883
|
+
return NoteXPosition.Left;
|
|
70741
70884
|
}
|
|
70742
70885
|
}
|
|
70743
70886
|
|
|
@@ -70752,12 +70895,12 @@
|
|
|
70752
70895
|
return;
|
|
70753
70896
|
}
|
|
70754
70897
|
if (!this._tiedNoteTie && n.isTieOrigin && n.tieDestination.isVisible) {
|
|
70755
|
-
const tie = new SlashTieGlyph(n, n.tieDestination, false);
|
|
70898
|
+
const tie = new SlashTieGlyph('slash.tie', n, n.tieDestination, false);
|
|
70756
70899
|
this._tiedNoteTie = tie;
|
|
70757
70900
|
this.addTie(tie);
|
|
70758
70901
|
}
|
|
70759
70902
|
if (!this._tiedNoteTie && n.isTieDestination) {
|
|
70760
|
-
const tie = new SlashTieGlyph(n.tieOrigin, n, true);
|
|
70903
|
+
const tie = new SlashTieGlyph('slash.tie', n.tieOrigin, n, true);
|
|
70761
70904
|
this._tiedNoteTie = tie;
|
|
70762
70905
|
this.addTie(tie);
|
|
70763
70906
|
}
|
|
@@ -70884,8 +71027,7 @@
|
|
|
70884
71027
|
doLayout() {
|
|
70885
71028
|
// create glyphs
|
|
70886
71029
|
const sr = this.renderer;
|
|
70887
|
-
const
|
|
70888
|
-
const glyphY = sr.getLineY(line);
|
|
71030
|
+
const glyphY = sr.getLineY(0);
|
|
70889
71031
|
if (this.container.beat.deadSlapped) {
|
|
70890
71032
|
const deadSlapped = new DeadSlappedBeatGlyph();
|
|
70891
71033
|
deadSlapped.renderer = this.renderer;
|
|
@@ -70918,7 +71060,7 @@
|
|
|
70918
71060
|
//
|
|
70919
71061
|
if (this.container.beat.dots > 0) {
|
|
70920
71062
|
for (let i = 0; i < this.container.beat.dots; i++) {
|
|
70921
|
-
this.addEffect(new AugmentationDotGlyph(0,
|
|
71063
|
+
this.addEffect(new AugmentationDotGlyph(0, glyphY - sr.getLineHeight(0.5)));
|
|
70922
71064
|
}
|
|
70923
71065
|
}
|
|
70924
71066
|
super.doLayout();
|
|
@@ -71000,7 +71142,7 @@
|
|
|
71000
71142
|
this.registerOverflowTop(this.tupletSize);
|
|
71001
71143
|
}
|
|
71002
71144
|
}
|
|
71003
|
-
getNoteLine() {
|
|
71145
|
+
getNoteLine(_note) {
|
|
71004
71146
|
return 0;
|
|
71005
71147
|
}
|
|
71006
71148
|
getFlagTopY(beat, _direction) {
|
|
@@ -71337,77 +71479,6 @@
|
|
|
71337
71479
|
}
|
|
71338
71480
|
}
|
|
71339
71481
|
|
|
71340
|
-
/**
|
|
71341
|
-
* @internal
|
|
71342
|
-
*/
|
|
71343
|
-
class TabSlurGlyph extends TabTieGlyph {
|
|
71344
|
-
_direction;
|
|
71345
|
-
_forSlide;
|
|
71346
|
-
constructor(startNote, endNote, forSlide, forEnd = false) {
|
|
71347
|
-
super(startNote, endNote, forEnd);
|
|
71348
|
-
this._direction = TabTieGlyph.getBeamDirectionForNote(startNote);
|
|
71349
|
-
this._forSlide = forSlide;
|
|
71350
|
-
}
|
|
71351
|
-
getTieHeight(startX, _startY, endX, _endY) {
|
|
71352
|
-
return Math.log(endX - startX + 1) * this.renderer.settings.notation.slurHeight / 2;
|
|
71353
|
-
}
|
|
71354
|
-
tryExpand(startNote, endNote, forSlide, forEnd) {
|
|
71355
|
-
// same type required
|
|
71356
|
-
if (this._forSlide !== forSlide) {
|
|
71357
|
-
return false;
|
|
71358
|
-
}
|
|
71359
|
-
if (this.forEnd !== forEnd) {
|
|
71360
|
-
return false;
|
|
71361
|
-
}
|
|
71362
|
-
// same start and endbeat
|
|
71363
|
-
if (this.startNote.beat.id !== startNote.beat.id) {
|
|
71364
|
-
return false;
|
|
71365
|
-
}
|
|
71366
|
-
if (this.endNote.beat.id !== endNote.beat.id) {
|
|
71367
|
-
return false;
|
|
71368
|
-
}
|
|
71369
|
-
// same draw direction
|
|
71370
|
-
if (this._direction !== TabTieGlyph.getBeamDirectionForNote(startNote)) {
|
|
71371
|
-
return false;
|
|
71372
|
-
}
|
|
71373
|
-
// if we can expand, expand in correct direction
|
|
71374
|
-
switch (this._direction) {
|
|
71375
|
-
case BeamDirection.Up:
|
|
71376
|
-
if (startNote.realValue > this.startNote.realValue) {
|
|
71377
|
-
this.startNote = startNote;
|
|
71378
|
-
this.startBeat = startNote.beat;
|
|
71379
|
-
}
|
|
71380
|
-
if (endNote.realValue > this.endNote.realValue) {
|
|
71381
|
-
this.endNote = endNote;
|
|
71382
|
-
this.endBeat = endNote.beat;
|
|
71383
|
-
}
|
|
71384
|
-
break;
|
|
71385
|
-
case BeamDirection.Down:
|
|
71386
|
-
if (startNote.realValue < this.startNote.realValue) {
|
|
71387
|
-
this.startNote = startNote;
|
|
71388
|
-
this.startBeat = startNote.beat;
|
|
71389
|
-
}
|
|
71390
|
-
if (endNote.realValue < this.endNote.realValue) {
|
|
71391
|
-
this.endNote = endNote;
|
|
71392
|
-
this.endBeat = endNote.beat;
|
|
71393
|
-
}
|
|
71394
|
-
break;
|
|
71395
|
-
}
|
|
71396
|
-
return true;
|
|
71397
|
-
}
|
|
71398
|
-
paint(cx, cy, canvas) {
|
|
71399
|
-
const startNoteRenderer = this.renderer.scoreRenderer.layout.getRendererForBar(this.renderer.staff.staffId, this.startBeat.voice.bar);
|
|
71400
|
-
const direction = this.getBeamDirection(this.startBeat, startNoteRenderer);
|
|
71401
|
-
const slurId = `tab.slur.${this.startNote.beat.id}.${this.endNote.beat.id}.${direction}`;
|
|
71402
|
-
const renderer = this.renderer;
|
|
71403
|
-
const isSlurRendered = renderer.staff.getSharedLayoutData(slurId, false);
|
|
71404
|
-
if (!isSlurRendered) {
|
|
71405
|
-
renderer.staff.setSharedLayoutData(slurId, true);
|
|
71406
|
-
super.paint(cx, cy, canvas);
|
|
71407
|
-
}
|
|
71408
|
-
}
|
|
71409
|
-
}
|
|
71410
|
-
|
|
71411
71482
|
/**
|
|
71412
71483
|
* @internal
|
|
71413
71484
|
*/
|
|
@@ -71432,15 +71503,15 @@
|
|
|
71432
71503
|
}
|
|
71433
71504
|
const renderer = this.renderer;
|
|
71434
71505
|
if (n.isTieOrigin && renderer.showTiedNotes && n.tieDestination.isVisible) {
|
|
71435
|
-
const tie = new TabTieGlyph(n, n.tieDestination, false);
|
|
71506
|
+
const tie = new TabTieGlyph(`tab.tie.${n.id}`, n, n.tieDestination, false);
|
|
71436
71507
|
this.addTie(tie);
|
|
71437
71508
|
}
|
|
71438
71509
|
if (n.isTieDestination && renderer.showTiedNotes) {
|
|
71439
|
-
const tie = new TabTieGlyph(n.tieOrigin, n, true);
|
|
71510
|
+
const tie = new TabTieGlyph(`tab.tie.${n.tieOrigin.id}`, n.tieOrigin, n, true);
|
|
71440
71511
|
this.addTie(tie);
|
|
71441
71512
|
}
|
|
71442
71513
|
if (n.isLeftHandTapped && !n.isHammerPullDestination) {
|
|
71443
|
-
const tapSlur = new TabTieGlyph(n, n, false);
|
|
71514
|
+
const tapSlur = new TabTieGlyph(`tab.tie.leftHandTap.${n.id}`, n, n, false);
|
|
71444
71515
|
this.addTie(tapSlur);
|
|
71445
71516
|
}
|
|
71446
71517
|
// start effect slur on first beat
|
|
@@ -71453,7 +71524,7 @@
|
|
|
71453
71524
|
}
|
|
71454
71525
|
}
|
|
71455
71526
|
if (!expanded) {
|
|
71456
|
-
const effectSlur = new TabSlurGlyph(n, n.effectSlurDestination, false, false);
|
|
71527
|
+
const effectSlur = new TabSlurGlyph(`tab.slur.effect.${n.id}`, n, n.effectSlurDestination, false, false);
|
|
71457
71528
|
this._effectSlurs.push(effectSlur);
|
|
71458
71529
|
this.addTie(effectSlur);
|
|
71459
71530
|
}
|
|
@@ -71468,7 +71539,7 @@
|
|
|
71468
71539
|
}
|
|
71469
71540
|
}
|
|
71470
71541
|
if (!expanded) {
|
|
71471
|
-
const effectSlur = new TabSlurGlyph(n.effectSlurOrigin, n, false, true);
|
|
71542
|
+
const effectSlur = new TabSlurGlyph(`tab.slur.effect.${n.effectSlurOrigin.id}`, n.effectSlurOrigin, n, false, true);
|
|
71472
71543
|
this._effectSlurs.push(effectSlur);
|
|
71473
71544
|
this.addTie(effectSlur);
|
|
71474
71545
|
}
|
|
@@ -71887,7 +71958,7 @@
|
|
|
71887
71958
|
}
|
|
71888
71959
|
else {
|
|
71889
71960
|
const line = Math.floor((this.renderer.bar.staff.tuning.length - 1) / 2);
|
|
71890
|
-
const y = tabRenderer.
|
|
71961
|
+
const y = tabRenderer.getLineY(line);
|
|
71891
71962
|
const restGlyph = new TabRestGlyph(0, y, tabRenderer.showRests, this.container.beat.duration);
|
|
71892
71963
|
this.restGlyph = restGlyph;
|
|
71893
71964
|
restGlyph.beat = this.container.beat;
|
|
@@ -71946,8 +72017,8 @@
|
|
|
71946
72017
|
_createNoteGlyph(n) {
|
|
71947
72018
|
const tr = this.renderer;
|
|
71948
72019
|
const noteNumberGlyph = new NoteNumberGlyph(0, 0, n);
|
|
71949
|
-
const l =
|
|
71950
|
-
noteNumberGlyph.y = tr.
|
|
72020
|
+
const l = tr.getNoteLine(n);
|
|
72021
|
+
noteNumberGlyph.y = tr.getLineY(l);
|
|
71951
72022
|
noteNumberGlyph.renderer = this.renderer;
|
|
71952
72023
|
noteNumberGlyph.doLayout();
|
|
71953
72024
|
this.noteNumbers.addNoteGlyph(noteNumberGlyph, n);
|
|
@@ -72138,17 +72209,8 @@
|
|
|
72138
72209
|
}
|
|
72139
72210
|
return mode;
|
|
72140
72211
|
}
|
|
72141
|
-
|
|
72142
|
-
|
|
72143
|
-
* @param line the line of the particular string where 0 is the most top line
|
|
72144
|
-
* @param correction
|
|
72145
|
-
* @returns
|
|
72146
|
-
*/
|
|
72147
|
-
getTabY(line) {
|
|
72148
|
-
return super.getLineY(line);
|
|
72149
|
-
}
|
|
72150
|
-
getTabHeight(line) {
|
|
72151
|
-
return super.getLineHeight(line);
|
|
72212
|
+
getNoteLine(note) {
|
|
72213
|
+
return this.bar.staff.tuning.length - note.string;
|
|
72152
72214
|
}
|
|
72153
72215
|
minString = Number.NaN;
|
|
72154
72216
|
maxString = Number.NaN;
|
|
@@ -72237,7 +72299,7 @@
|
|
|
72237
72299
|
if (this.isFirstOfLine) {
|
|
72238
72300
|
const center = (this.bar.staff.tuning.length - 1) / 2;
|
|
72239
72301
|
this.createStartSpacing();
|
|
72240
|
-
this.addPreBeatGlyph(new TabClefGlyph(0, this.
|
|
72302
|
+
this.addPreBeatGlyph(new TabClefGlyph(0, this.getLineY(center)));
|
|
72241
72303
|
}
|
|
72242
72304
|
// Time Signature
|
|
72243
72305
|
if (this.showTimeSignature &&
|
|
@@ -72258,7 +72320,7 @@
|
|
|
72258
72320
|
_createTimeSignatureGlyphs() {
|
|
72259
72321
|
this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
|
|
72260
72322
|
const lines = (this.bar.staff.tuning.length + 1) / 2 - 1;
|
|
72261
|
-
this.addPreBeatGlyph(new TabTimeSignatureGlyph(0, this.
|
|
72323
|
+
this.addPreBeatGlyph(new TabTimeSignatureGlyph(0, this.getLineY(lines), this.bar.masterBar.timeSignatureNumerator, this.bar.masterBar.timeSignatureDenominator, this.bar.masterBar.timeSignatureCommon, this.bar.masterBar.isFreeTime));
|
|
72262
72324
|
}
|
|
72263
72325
|
createVoiceGlyphs(v) {
|
|
72264
72326
|
super.createVoiceGlyphs(v);
|