@coderline/alphatab 1.8.0-alpha.1639 → 1.8.0-alpha.1643
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 +666 -737
- package/dist/alphaTab.js +666 -737
- 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 +1 -1
package/dist/alphaTab.core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* alphaTab v1.8.0-alpha.
|
|
2
|
+
* alphaTab v1.8.0-alpha.1643 (develop, build 1643)
|
|
3
3
|
*
|
|
4
4
|
* Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
5
|
*
|
|
@@ -203,9 +203,9 @@ class AlphaTabError extends Error {
|
|
|
203
203
|
* @internal
|
|
204
204
|
*/
|
|
205
205
|
class VersionInfo {
|
|
206
|
-
static version = '1.8.0-alpha.
|
|
207
|
-
static date = '2025-12-
|
|
208
|
-
static commit = '
|
|
206
|
+
static version = '1.8.0-alpha.1643';
|
|
207
|
+
static date = '2025-12-13T02:07:47.380Z';
|
|
208
|
+
static commit = '6cdd7783a14244e9d7efb9f9b9dbad7a27b11eee';
|
|
209
209
|
static print(print) {
|
|
210
210
|
print(`alphaTab ${VersionInfo.version}`);
|
|
211
211
|
print(`commit: ${VersionInfo.commit}`);
|
|
@@ -4715,6 +4715,24 @@ class ModelUtils {
|
|
|
4715
4715
|
static toArticulationId(plain) {
|
|
4716
4716
|
return plain.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
|
4717
4717
|
}
|
|
4718
|
+
static minBoundingBox(a, b) {
|
|
4719
|
+
if (Number.isNaN(a)) {
|
|
4720
|
+
return b;
|
|
4721
|
+
}
|
|
4722
|
+
else if (Number.isNaN(b)) {
|
|
4723
|
+
return a;
|
|
4724
|
+
}
|
|
4725
|
+
return a < b ? a : b;
|
|
4726
|
+
}
|
|
4727
|
+
static maxBoundingBox(a, b) {
|
|
4728
|
+
if (Number.isNaN(a)) {
|
|
4729
|
+
return b;
|
|
4730
|
+
}
|
|
4731
|
+
else if (Number.isNaN(b)) {
|
|
4732
|
+
return a;
|
|
4733
|
+
}
|
|
4734
|
+
return a > b ? a : b;
|
|
4735
|
+
}
|
|
4718
4736
|
}
|
|
4719
4737
|
|
|
4720
4738
|
/**
|
|
@@ -48297,6 +48315,39 @@ class MidiFileGenerator {
|
|
|
48297
48315
|
}
|
|
48298
48316
|
}
|
|
48299
48317
|
|
|
48318
|
+
/**
|
|
48319
|
+
* Lists the different position modes for {@link BarRendererBase.getBeatX}
|
|
48320
|
+
* @internal
|
|
48321
|
+
*/
|
|
48322
|
+
var BeatXPosition;
|
|
48323
|
+
(function (BeatXPosition) {
|
|
48324
|
+
/**
|
|
48325
|
+
* Gets the pre-notes position which is located before the accidentals
|
|
48326
|
+
*/
|
|
48327
|
+
BeatXPosition[BeatXPosition["PreNotes"] = 0] = "PreNotes";
|
|
48328
|
+
/**
|
|
48329
|
+
* Gets the on-notes position which is located after the accidentals but before the note heads.
|
|
48330
|
+
*/
|
|
48331
|
+
BeatXPosition[BeatXPosition["OnNotes"] = 1] = "OnNotes";
|
|
48332
|
+
/**
|
|
48333
|
+
* Gets the middle-notes position which is located after in the exact center of the note heads.
|
|
48334
|
+
*/
|
|
48335
|
+
BeatXPosition[BeatXPosition["MiddleNotes"] = 2] = "MiddleNotes";
|
|
48336
|
+
/**
|
|
48337
|
+
* Gets position of the stem for this beat
|
|
48338
|
+
*/
|
|
48339
|
+
BeatXPosition[BeatXPosition["Stem"] = 3] = "Stem";
|
|
48340
|
+
/**
|
|
48341
|
+
* Get the post-notes position which is located at after the note heads.
|
|
48342
|
+
*/
|
|
48343
|
+
BeatXPosition[BeatXPosition["PostNotes"] = 4] = "PostNotes";
|
|
48344
|
+
/**
|
|
48345
|
+
* Get the end-beat position which is located at the end of the beat. This position is almost
|
|
48346
|
+
* equal to the pre-notes position of the next beat.
|
|
48347
|
+
*/
|
|
48348
|
+
BeatXPosition[BeatXPosition["EndBeat"] = 5] = "EndBeat";
|
|
48349
|
+
})(BeatXPosition || (BeatXPosition = {}));
|
|
48350
|
+
|
|
48300
48351
|
/**
|
|
48301
48352
|
* A glyph is a single symbol which can be added to a GlyphBarRenderer for automated
|
|
48302
48353
|
* layouting and drawing of stacked symbols.
|
|
@@ -48324,198 +48375,6 @@ class Glyph {
|
|
|
48324
48375
|
}
|
|
48325
48376
|
}
|
|
48326
48377
|
|
|
48327
|
-
/**
|
|
48328
|
-
* Effect-Glyphs implementing this public interface get notified
|
|
48329
|
-
* as they are expanded over multiple beats.
|
|
48330
|
-
* @internal
|
|
48331
|
-
*/
|
|
48332
|
-
class EffectGlyph extends Glyph {
|
|
48333
|
-
/**
|
|
48334
|
-
* Gets or sets the beat where the glyph belongs to.
|
|
48335
|
-
*/
|
|
48336
|
-
beat = null;
|
|
48337
|
-
/**
|
|
48338
|
-
* Gets or sets the next glyph of the same type in case
|
|
48339
|
-
* the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
|
|
48340
|
-
*/
|
|
48341
|
-
nextGlyph = null;
|
|
48342
|
-
/**
|
|
48343
|
-
* Gets or sets the previous glyph of the same type in case
|
|
48344
|
-
* the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
|
|
48345
|
-
*/
|
|
48346
|
-
previousGlyph = null;
|
|
48347
|
-
constructor(x = 0, y = 0) {
|
|
48348
|
-
super(x, y);
|
|
48349
|
-
}
|
|
48350
|
-
}
|
|
48351
|
-
|
|
48352
|
-
/**
|
|
48353
|
-
* @internal
|
|
48354
|
-
*/
|
|
48355
|
-
class MusicFontGlyph extends EffectGlyph {
|
|
48356
|
-
glyphScale = 0;
|
|
48357
|
-
symbol;
|
|
48358
|
-
center = false;
|
|
48359
|
-
colorOverride;
|
|
48360
|
-
offsetX = 0;
|
|
48361
|
-
offsetY = 0;
|
|
48362
|
-
constructor(x, y, glyphScale, symbol) {
|
|
48363
|
-
super(x, y);
|
|
48364
|
-
this.glyphScale = glyphScale;
|
|
48365
|
-
this.symbol = symbol;
|
|
48366
|
-
}
|
|
48367
|
-
getBoundingBoxTop() {
|
|
48368
|
-
const bBoxTop = this.renderer.smuflMetrics.glyphTop.get(this.symbol);
|
|
48369
|
-
return this.y - this.offsetY - bBoxTop;
|
|
48370
|
-
}
|
|
48371
|
-
doLayout() {
|
|
48372
|
-
this.width = this.renderer.smuflMetrics.glyphWidths.get(this.symbol) * this.glyphScale;
|
|
48373
|
-
this.height = this.renderer.smuflMetrics.glyphHeights.get(this.symbol) * this.glyphScale;
|
|
48374
|
-
}
|
|
48375
|
-
paint(cx, cy, canvas) {
|
|
48376
|
-
if (this.width === 0 && this.height === 0) {
|
|
48377
|
-
return;
|
|
48378
|
-
}
|
|
48379
|
-
const c = canvas.color;
|
|
48380
|
-
if (this.colorOverride) {
|
|
48381
|
-
canvas.color = this.colorOverride;
|
|
48382
|
-
}
|
|
48383
|
-
canvas.fillMusicFontSymbol(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbol, this.center);
|
|
48384
|
-
canvas.color = c;
|
|
48385
|
-
}
|
|
48386
|
-
}
|
|
48387
|
-
/**
|
|
48388
|
-
* @internal
|
|
48389
|
-
*/
|
|
48390
|
-
class MusicFontTextGlyph extends EffectGlyph {
|
|
48391
|
-
glyphScale = 0;
|
|
48392
|
-
symbols;
|
|
48393
|
-
center = false;
|
|
48394
|
-
colorOverride;
|
|
48395
|
-
offsetX = 0;
|
|
48396
|
-
offsetY = 0;
|
|
48397
|
-
constructor(x, y, glyphScale, symbols) {
|
|
48398
|
-
super(x, y);
|
|
48399
|
-
this.glyphScale = glyphScale;
|
|
48400
|
-
this.symbols = symbols;
|
|
48401
|
-
}
|
|
48402
|
-
getBoundingBoxTop() {
|
|
48403
|
-
let bBoxTop = 0;
|
|
48404
|
-
for (let i = 0; i < this.symbols.length; i++) {
|
|
48405
|
-
const gTop = this.renderer.smuflMetrics.glyphTop.get(this.symbols[i]);
|
|
48406
|
-
if (i === 0 || gTop < bBoxTop) {
|
|
48407
|
-
bBoxTop = gTop;
|
|
48408
|
-
}
|
|
48409
|
-
}
|
|
48410
|
-
return this.y - this.offsetY - bBoxTop;
|
|
48411
|
-
}
|
|
48412
|
-
doLayout() {
|
|
48413
|
-
this.width = 0;
|
|
48414
|
-
this.height = 0;
|
|
48415
|
-
for (let i = 0; i < this.symbols.length; i++) {
|
|
48416
|
-
const gWidth = this.renderer.smuflMetrics.glyphWidths.get(this.symbols[i]) * this.glyphScale;
|
|
48417
|
-
const gHeight = this.renderer.smuflMetrics.glyphHeights.get(this.symbols[i]) * this.glyphScale;
|
|
48418
|
-
if (i === 0 || gWidth > this.width) {
|
|
48419
|
-
this.width = gWidth;
|
|
48420
|
-
}
|
|
48421
|
-
if (i === 0 || gHeight > this.height) {
|
|
48422
|
-
this.height = gHeight;
|
|
48423
|
-
}
|
|
48424
|
-
}
|
|
48425
|
-
}
|
|
48426
|
-
paint(cx, cy, canvas) {
|
|
48427
|
-
if (this.width === 0 && this.height === 0) {
|
|
48428
|
-
return;
|
|
48429
|
-
}
|
|
48430
|
-
const c = canvas.color;
|
|
48431
|
-
if (this.colorOverride) {
|
|
48432
|
-
canvas.color = this.colorOverride;
|
|
48433
|
-
}
|
|
48434
|
-
canvas.fillMusicFontSymbols(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbols, this.center);
|
|
48435
|
-
canvas.color = c;
|
|
48436
|
-
}
|
|
48437
|
-
}
|
|
48438
|
-
|
|
48439
|
-
/**
|
|
48440
|
-
* @internal
|
|
48441
|
-
*/
|
|
48442
|
-
class NoteHeadGlyph extends MusicFontGlyph {
|
|
48443
|
-
// TODO: SmuFL
|
|
48444
|
-
static GraceScale = 0.75;
|
|
48445
|
-
centerOnStem = false;
|
|
48446
|
-
constructor(x, y, duration, isGrace) {
|
|
48447
|
-
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, NoteHeadGlyph.getSymbol(duration));
|
|
48448
|
-
}
|
|
48449
|
-
paint(cx, cy, canvas) {
|
|
48450
|
-
if (this.centerOnStem) {
|
|
48451
|
-
this.center = true;
|
|
48452
|
-
}
|
|
48453
|
-
super.paint(cx, cy, canvas);
|
|
48454
|
-
}
|
|
48455
|
-
static getSymbol(duration) {
|
|
48456
|
-
switch (duration) {
|
|
48457
|
-
case Duration.QuadrupleWhole:
|
|
48458
|
-
return MusicFontSymbol.NoteheadDoubleWholeSquare;
|
|
48459
|
-
case Duration.DoubleWhole:
|
|
48460
|
-
return MusicFontSymbol.NoteheadDoubleWhole;
|
|
48461
|
-
case Duration.Whole:
|
|
48462
|
-
return MusicFontSymbol.NoteheadWhole;
|
|
48463
|
-
case Duration.Half:
|
|
48464
|
-
return MusicFontSymbol.NoteheadHalf;
|
|
48465
|
-
default:
|
|
48466
|
-
return MusicFontSymbol.NoteheadBlack;
|
|
48467
|
-
}
|
|
48468
|
-
}
|
|
48469
|
-
}
|
|
48470
|
-
|
|
48471
|
-
/**
|
|
48472
|
-
* @internal
|
|
48473
|
-
*/
|
|
48474
|
-
class FlagGlyph extends MusicFontGlyph {
|
|
48475
|
-
constructor(x, y, duration, direction, isGrace) {
|
|
48476
|
-
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, FlagGlyph.getSymbol(duration, direction, isGrace));
|
|
48477
|
-
}
|
|
48478
|
-
static getSymbol(duration, direction, isGrace) {
|
|
48479
|
-
if (isGrace) {
|
|
48480
|
-
duration = Duration.Eighth;
|
|
48481
|
-
}
|
|
48482
|
-
if (direction === BeamDirection.Up) {
|
|
48483
|
-
switch (duration) {
|
|
48484
|
-
case Duration.Eighth:
|
|
48485
|
-
return MusicFontSymbol.Flag8thUp;
|
|
48486
|
-
case Duration.Sixteenth:
|
|
48487
|
-
return MusicFontSymbol.Flag16thUp;
|
|
48488
|
-
case Duration.ThirtySecond:
|
|
48489
|
-
return MusicFontSymbol.Flag32ndUp;
|
|
48490
|
-
case Duration.SixtyFourth:
|
|
48491
|
-
return MusicFontSymbol.Flag64thUp;
|
|
48492
|
-
case Duration.OneHundredTwentyEighth:
|
|
48493
|
-
return MusicFontSymbol.Flag128thUp;
|
|
48494
|
-
case Duration.TwoHundredFiftySixth:
|
|
48495
|
-
return MusicFontSymbol.Flag256thUp;
|
|
48496
|
-
default:
|
|
48497
|
-
return MusicFontSymbol.Flag8thUp;
|
|
48498
|
-
}
|
|
48499
|
-
}
|
|
48500
|
-
switch (duration) {
|
|
48501
|
-
case Duration.Eighth:
|
|
48502
|
-
return MusicFontSymbol.Flag8thDown;
|
|
48503
|
-
case Duration.Sixteenth:
|
|
48504
|
-
return MusicFontSymbol.Flag16thDown;
|
|
48505
|
-
case Duration.ThirtySecond:
|
|
48506
|
-
return MusicFontSymbol.Flag32ndDown;
|
|
48507
|
-
case Duration.SixtyFourth:
|
|
48508
|
-
return MusicFontSymbol.Flag64thDown;
|
|
48509
|
-
case Duration.OneHundredTwentyEighth:
|
|
48510
|
-
return MusicFontSymbol.Flag128thDown;
|
|
48511
|
-
case Duration.TwoHundredFiftySixth:
|
|
48512
|
-
return MusicFontSymbol.Flag128thDown;
|
|
48513
|
-
default:
|
|
48514
|
-
return MusicFontSymbol.Flag8thDown;
|
|
48515
|
-
}
|
|
48516
|
-
}
|
|
48517
|
-
}
|
|
48518
|
-
|
|
48519
48378
|
/**
|
|
48520
48379
|
* @internal
|
|
48521
48380
|
*/
|
|
@@ -48527,7 +48386,7 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48527
48386
|
onNotes;
|
|
48528
48387
|
minWidth = 0;
|
|
48529
48388
|
get onTimeX() {
|
|
48530
|
-
return this.onNotes.x + this.onNotes.
|
|
48389
|
+
return this.onNotes.x + this.onNotes.onTimeX;
|
|
48531
48390
|
}
|
|
48532
48391
|
constructor(beat, voiceContainer) {
|
|
48533
48392
|
super(0, 0);
|
|
@@ -48542,28 +48401,20 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48542
48401
|
this.renderer.registerTie(tie);
|
|
48543
48402
|
}
|
|
48544
48403
|
getBoundingBoxTop() {
|
|
48545
|
-
return
|
|
48404
|
+
return ModelUtils.minBoundingBox(this.preNotes.getBoundingBoxTop(), this.onNotes.getBoundingBoxTop());
|
|
48546
48405
|
}
|
|
48547
48406
|
getBoundingBoxBottom() {
|
|
48548
|
-
return
|
|
48407
|
+
return ModelUtils.maxBoundingBox(this.preNotes.getBoundingBoxBottom(), this.onNotes.getBoundingBoxBottom());
|
|
48549
48408
|
}
|
|
48550
48409
|
drawBeamHelperAsFlags(helper) {
|
|
48551
48410
|
return helper.hasFlag(false, undefined);
|
|
48552
48411
|
}
|
|
48412
|
+
get postBeatStretch() {
|
|
48413
|
+
return this.onNotes.computedWidth - this.onNotes.onTimeX;
|
|
48414
|
+
}
|
|
48553
48415
|
registerLayoutingInfo(layoutings) {
|
|
48554
|
-
const preBeatStretch = this.preNotes.computedWidth + this.onNotes.
|
|
48555
|
-
let postBeatStretch = this.
|
|
48556
|
-
// make space for flag
|
|
48557
|
-
const helper = this.renderer.helpers.getBeamingHelperForBeat(this.beat);
|
|
48558
|
-
if (this.beat.graceType !== GraceType.None) {
|
|
48559
|
-
// always use flag size as spacing on grace notes
|
|
48560
|
-
postBeatStretch +=
|
|
48561
|
-
this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
48562
|
-
}
|
|
48563
|
-
else if (helper && this.drawBeamHelperAsFlags(helper)) {
|
|
48564
|
-
postBeatStretch +=
|
|
48565
|
-
this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
48566
|
-
}
|
|
48416
|
+
const preBeatStretch = this.preNotes.computedWidth + this.onNotes.onTimeX;
|
|
48417
|
+
let postBeatStretch = this.postBeatStretch;
|
|
48567
48418
|
for (const tie of this._ties) {
|
|
48568
48419
|
const tg = tie;
|
|
48569
48420
|
postBeatStretch += tg.width;
|
|
@@ -48578,7 +48429,6 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48578
48429
|
});
|
|
48579
48430
|
}
|
|
48580
48431
|
applyLayoutingInfo(_info) {
|
|
48581
|
-
this.onNotes.updateBeamingHelper();
|
|
48582
48432
|
this.updateWidth();
|
|
48583
48433
|
}
|
|
48584
48434
|
doLayout() {
|
|
@@ -48590,7 +48440,6 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48590
48440
|
this.onNotes.renderer = this.renderer;
|
|
48591
48441
|
this.onNotes.container = this;
|
|
48592
48442
|
this.onNotes.doLayout();
|
|
48593
|
-
this.onNotes.updateBeamingHelper();
|
|
48594
48443
|
let i = this.beat.notes.length - 1;
|
|
48595
48444
|
while (i >= 0) {
|
|
48596
48445
|
this.createTies(this.beat.notes[i--]);
|
|
@@ -48599,15 +48448,6 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48599
48448
|
}
|
|
48600
48449
|
updateWidth() {
|
|
48601
48450
|
this.minWidth = this.preNotes.width + this.onNotes.width;
|
|
48602
|
-
if (!this.beat.isRest) {
|
|
48603
|
-
if (this.onNotes.beamingHelper.beats.length === 1) {
|
|
48604
|
-
// make space for flag
|
|
48605
|
-
if (this.beat.duration >= Duration.Eighth) {
|
|
48606
|
-
const symbol = FlagGlyph.getSymbol(this.beat.duration, this.onNotes.beamingHelper.direction, this.beat.graceType !== GraceType.None);
|
|
48607
|
-
this.minWidth += this.renderer.smuflMetrics.glyphWidths.get(symbol);
|
|
48608
|
-
}
|
|
48609
|
-
}
|
|
48610
|
-
}
|
|
48611
48451
|
let tieWidth = 0;
|
|
48612
48452
|
for (const tie of this._ties) {
|
|
48613
48453
|
const tg = tie;
|
|
@@ -48618,10 +48458,6 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48618
48458
|
this.minWidth += tieWidth;
|
|
48619
48459
|
this.width = this.minWidth;
|
|
48620
48460
|
}
|
|
48621
|
-
scaleToWidth(beatWidth) {
|
|
48622
|
-
this.onNotes.updateBeamingHelper();
|
|
48623
|
-
this.width = beatWidth;
|
|
48624
|
-
}
|
|
48625
48461
|
createTies(_n) {
|
|
48626
48462
|
}
|
|
48627
48463
|
static getGroupId(beat) {
|
|
@@ -48631,8 +48467,11 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48631
48467
|
// var c = canvas.color;
|
|
48632
48468
|
// canvas.color = Color.random();
|
|
48633
48469
|
// canvas.fillRect(cx + this.x, cy + this.y + this.preNotes.getBoundingBoxTop(), this.width, this.renderer.height);
|
|
48634
|
-
// canvas.color = Color.random();
|
|
48635
48470
|
// canvas.fillRect(cx + this.x, cy + this.y + this.onNotes.getBoundingBoxTop(), this.width, this.renderer.height);
|
|
48471
|
+
// canvas.color = Color.random();
|
|
48472
|
+
// const top = this.getBoundingBoxTop();
|
|
48473
|
+
// const bottom = this.getBoundingBoxBottom();
|
|
48474
|
+
// canvas.fillRect(cx + this.x, cy + this.y + top, this.width, bottom-top);
|
|
48636
48475
|
// canvas.color = c;
|
|
48637
48476
|
// var c = canvas.color;
|
|
48638
48477
|
// var ta = canvas.textAlign;
|
|
@@ -48695,7 +48534,7 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48695
48534
|
beatBoundings.realBounds.y = barBounds.realBounds.y;
|
|
48696
48535
|
beatBoundings.realBounds.w = this.width;
|
|
48697
48536
|
beatBoundings.realBounds.h = barBounds.realBounds.h;
|
|
48698
|
-
beatBoundings.onNotesX = cx + this.x + this.onNotes.
|
|
48537
|
+
beatBoundings.onNotesX = cx + this.x + this.onNotes.x + this.onNotes.onTimeX;
|
|
48699
48538
|
}
|
|
48700
48539
|
else {
|
|
48701
48540
|
beatBoundings.visualBounds = new Bounds();
|
|
@@ -48711,7 +48550,7 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48711
48550
|
}
|
|
48712
48551
|
let visualEndX = 0;
|
|
48713
48552
|
if (!this.onNotes.isEmpty) {
|
|
48714
|
-
visualEndX = cx + this.x + this.onNotes.x + this.onNotes.
|
|
48553
|
+
visualEndX = cx + this.x + this.onNotes.x + this.onNotes.onTimeX + this.postBeatStretch;
|
|
48715
48554
|
}
|
|
48716
48555
|
else if (!this.preNotes.isEmpty) {
|
|
48717
48556
|
visualEndX = cx + this.x + this.preNotes.x + this.preNotes.width;
|
|
@@ -48720,12 +48559,6 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48720
48559
|
visualEndX = cx + this.x + this.width;
|
|
48721
48560
|
}
|
|
48722
48561
|
beatBoundings.visualBounds.w = visualEndX - beatBoundings.visualBounds.x;
|
|
48723
|
-
const helper = this.renderer.helpers.getBeamingHelperForBeat(this.beat);
|
|
48724
|
-
if ((helper && this.drawBeamHelperAsFlags(helper)) || this.beat.graceType !== GraceType.None) {
|
|
48725
|
-
beatBoundings.visualBounds.w +=
|
|
48726
|
-
this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) *
|
|
48727
|
-
(this.beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1);
|
|
48728
|
-
}
|
|
48729
48562
|
beatBoundings.visualBounds.y = barBounds.visualBounds.y;
|
|
48730
48563
|
beatBoundings.visualBounds.h = barBounds.visualBounds.h;
|
|
48731
48564
|
beatBoundings.realBounds = new Bounds();
|
|
@@ -48733,13 +48566,33 @@ class BeatContainerGlyph extends Glyph {
|
|
|
48733
48566
|
beatBoundings.realBounds.y = barBounds.realBounds.y;
|
|
48734
48567
|
beatBoundings.realBounds.w = this.width;
|
|
48735
48568
|
beatBoundings.realBounds.h = barBounds.realBounds.h;
|
|
48736
|
-
beatBoundings.onNotesX = cx + this.x + this.onNotes.x + this.onNotes.
|
|
48569
|
+
beatBoundings.onNotesX = cx + this.x + this.onNotes.x + this.onNotes.onTimeX;
|
|
48737
48570
|
}
|
|
48738
48571
|
barBounds.addBeat(beatBoundings);
|
|
48739
48572
|
if (this.renderer.settings.core.includeNoteBounds) {
|
|
48740
48573
|
this.onNotes.buildBoundingsLookup(beatBoundings, cx + this.x, cy + this.y);
|
|
48741
48574
|
}
|
|
48742
48575
|
}
|
|
48576
|
+
getBeatX(requestedPosition, useSharedSizes = false) {
|
|
48577
|
+
switch (requestedPosition) {
|
|
48578
|
+
case BeatXPosition.PreNotes:
|
|
48579
|
+
return this.preNotes.x;
|
|
48580
|
+
case BeatXPosition.OnNotes:
|
|
48581
|
+
return this.onNotes.x;
|
|
48582
|
+
case BeatXPosition.MiddleNotes:
|
|
48583
|
+
return this.onNotes.x + this.onNotes.middleX;
|
|
48584
|
+
case BeatXPosition.Stem:
|
|
48585
|
+
return this.onNotes.x + this.onNotes.stemX;
|
|
48586
|
+
case BeatXPosition.PostNotes:
|
|
48587
|
+
const onNoteSize = useSharedSizes
|
|
48588
|
+
? (this.renderer.layoutingInfo.getBeatSizes(this.beat)?.onBeatSize ?? this.onNotes.width)
|
|
48589
|
+
: this.onNotes.width;
|
|
48590
|
+
return this.onNotes.x + onNoteSize;
|
|
48591
|
+
case BeatXPosition.EndBeat:
|
|
48592
|
+
return this.width;
|
|
48593
|
+
}
|
|
48594
|
+
return this.preNotes.x;
|
|
48595
|
+
}
|
|
48743
48596
|
}
|
|
48744
48597
|
|
|
48745
48598
|
/**
|
|
@@ -54358,6 +54211,7 @@ class Cursors {
|
|
|
54358
54211
|
class ScalableHtmlElementContainer extends HtmlElementContainer {
|
|
54359
54212
|
_xscale;
|
|
54360
54213
|
_yscale;
|
|
54214
|
+
centerAtPosition = false;
|
|
54361
54215
|
constructor(element, xscale, yscale) {
|
|
54362
54216
|
super(element);
|
|
54363
54217
|
this._xscale = xscale;
|
|
@@ -54399,7 +54253,11 @@ class ScalableHtmlElementContainer extends HtmlElementContainer {
|
|
|
54399
54253
|
else {
|
|
54400
54254
|
h = h / this._yscale;
|
|
54401
54255
|
}
|
|
54402
|
-
|
|
54256
|
+
let transform = `translate(${x}px, ${y}px) scale(${w}, ${h})`;
|
|
54257
|
+
if (this.centerAtPosition) {
|
|
54258
|
+
transform += ` translateX(-50%)`;
|
|
54259
|
+
}
|
|
54260
|
+
this.element.style.transform = transform;
|
|
54403
54261
|
this.element.style.transformOrigin = 'top left';
|
|
54404
54262
|
this.lastBounds.x = x;
|
|
54405
54263
|
this.lastBounds.y = y;
|
|
@@ -55260,6 +55118,7 @@ class BrowserUiFacade {
|
|
|
55260
55118
|
beatCursor.style.willChange = 'transform';
|
|
55261
55119
|
beatCursorContainer.width = 3;
|
|
55262
55120
|
beatCursorContainer.height = 1;
|
|
55121
|
+
beatCursorContainer.centerAtPosition = true;
|
|
55263
55122
|
beatCursorContainer.setBounds(0, 0, 1, 1);
|
|
55264
55123
|
// add cursors to UI
|
|
55265
55124
|
element.insertBefore(cursorWrapper, element.firstChild);
|
|
@@ -56492,6 +56351,31 @@ var EffectBarGlyphSizing;
|
|
|
56492
56351
|
EffectBarGlyphSizing[EffectBarGlyphSizing["FullBar"] = 5] = "FullBar";
|
|
56493
56352
|
})(EffectBarGlyphSizing || (EffectBarGlyphSizing = {}));
|
|
56494
56353
|
|
|
56354
|
+
/**
|
|
56355
|
+
* Effect-Glyphs implementing this public interface get notified
|
|
56356
|
+
* as they are expanded over multiple beats.
|
|
56357
|
+
* @internal
|
|
56358
|
+
*/
|
|
56359
|
+
class EffectGlyph extends Glyph {
|
|
56360
|
+
/**
|
|
56361
|
+
* Gets or sets the beat where the glyph belongs to.
|
|
56362
|
+
*/
|
|
56363
|
+
beat = null;
|
|
56364
|
+
/**
|
|
56365
|
+
* Gets or sets the next glyph of the same type in case
|
|
56366
|
+
* the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
|
|
56367
|
+
*/
|
|
56368
|
+
nextGlyph = null;
|
|
56369
|
+
/**
|
|
56370
|
+
* Gets or sets the previous glyph of the same type in case
|
|
56371
|
+
* the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
|
|
56372
|
+
*/
|
|
56373
|
+
previousGlyph = null;
|
|
56374
|
+
constructor(x = 0, y = 0) {
|
|
56375
|
+
super(x, y);
|
|
56376
|
+
}
|
|
56377
|
+
}
|
|
56378
|
+
|
|
56495
56379
|
/**
|
|
56496
56380
|
* @internal
|
|
56497
56381
|
*/
|
|
@@ -56619,39 +56503,6 @@ class AlternateEndingsEffectInfo extends EffectInfo {
|
|
|
56619
56503
|
}
|
|
56620
56504
|
}
|
|
56621
56505
|
|
|
56622
|
-
/**
|
|
56623
|
-
* Lists the different position modes for {@link BarRendererBase.getBeatX}
|
|
56624
|
-
* @internal
|
|
56625
|
-
*/
|
|
56626
|
-
var BeatXPosition;
|
|
56627
|
-
(function (BeatXPosition) {
|
|
56628
|
-
/**
|
|
56629
|
-
* Gets the pre-notes position which is located before the accidentals
|
|
56630
|
-
*/
|
|
56631
|
-
BeatXPosition[BeatXPosition["PreNotes"] = 0] = "PreNotes";
|
|
56632
|
-
/**
|
|
56633
|
-
* Gets the on-notes position which is located after the accidentals but before the note heads.
|
|
56634
|
-
*/
|
|
56635
|
-
BeatXPosition[BeatXPosition["OnNotes"] = 1] = "OnNotes";
|
|
56636
|
-
/**
|
|
56637
|
-
* Gets the middle-notes position which is located after in the middle the note heads.
|
|
56638
|
-
*/
|
|
56639
|
-
BeatXPosition[BeatXPosition["MiddleNotes"] = 2] = "MiddleNotes";
|
|
56640
|
-
/**
|
|
56641
|
-
* Gets position of the stem for this beat
|
|
56642
|
-
*/
|
|
56643
|
-
BeatXPosition[BeatXPosition["Stem"] = 3] = "Stem";
|
|
56644
|
-
/**
|
|
56645
|
-
* Get the post-notes position which is located at after the note heads.
|
|
56646
|
-
*/
|
|
56647
|
-
BeatXPosition[BeatXPosition["PostNotes"] = 4] = "PostNotes";
|
|
56648
|
-
/**
|
|
56649
|
-
* Get the end-beat position which is located at the end of the beat. This position is almost
|
|
56650
|
-
* equal to the pre-notes position of the next beat.
|
|
56651
|
-
*/
|
|
56652
|
-
BeatXPosition[BeatXPosition["EndBeat"] = 5] = "EndBeat";
|
|
56653
|
-
})(BeatXPosition || (BeatXPosition = {}));
|
|
56654
|
-
|
|
56655
56506
|
/**
|
|
56656
56507
|
* @internal
|
|
56657
56508
|
*/
|
|
@@ -57250,6 +57101,93 @@ class DirectionsEffectInfo extends EffectInfo {
|
|
|
57250
57101
|
}
|
|
57251
57102
|
}
|
|
57252
57103
|
|
|
57104
|
+
/**
|
|
57105
|
+
* @internal
|
|
57106
|
+
*/
|
|
57107
|
+
class MusicFontGlyph extends EffectGlyph {
|
|
57108
|
+
glyphScale = 0;
|
|
57109
|
+
symbol;
|
|
57110
|
+
center = false;
|
|
57111
|
+
colorOverride;
|
|
57112
|
+
offsetX = 0;
|
|
57113
|
+
offsetY = 0;
|
|
57114
|
+
constructor(x, y, glyphScale, symbol) {
|
|
57115
|
+
super(x, y);
|
|
57116
|
+
this.glyphScale = glyphScale;
|
|
57117
|
+
this.symbol = symbol;
|
|
57118
|
+
}
|
|
57119
|
+
getBoundingBoxTop() {
|
|
57120
|
+
const bBoxTop = this.renderer.smuflMetrics.glyphTop.get(this.symbol);
|
|
57121
|
+
return this.y - this.offsetY - bBoxTop;
|
|
57122
|
+
}
|
|
57123
|
+
doLayout() {
|
|
57124
|
+
this.width = this.renderer.smuflMetrics.glyphWidths.get(this.symbol) * this.glyphScale;
|
|
57125
|
+
this.height = this.renderer.smuflMetrics.glyphHeights.get(this.symbol) * this.glyphScale;
|
|
57126
|
+
}
|
|
57127
|
+
paint(cx, cy, canvas) {
|
|
57128
|
+
if (this.width === 0 && this.height === 0) {
|
|
57129
|
+
return;
|
|
57130
|
+
}
|
|
57131
|
+
const c = canvas.color;
|
|
57132
|
+
if (this.colorOverride) {
|
|
57133
|
+
canvas.color = this.colorOverride;
|
|
57134
|
+
}
|
|
57135
|
+
canvas.fillMusicFontSymbol(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbol, this.center);
|
|
57136
|
+
canvas.color = c;
|
|
57137
|
+
}
|
|
57138
|
+
}
|
|
57139
|
+
/**
|
|
57140
|
+
* @internal
|
|
57141
|
+
*/
|
|
57142
|
+
class MusicFontTextGlyph extends EffectGlyph {
|
|
57143
|
+
glyphScale = 0;
|
|
57144
|
+
symbols;
|
|
57145
|
+
center = false;
|
|
57146
|
+
colorOverride;
|
|
57147
|
+
offsetX = 0;
|
|
57148
|
+
offsetY = 0;
|
|
57149
|
+
constructor(x, y, glyphScale, symbols) {
|
|
57150
|
+
super(x, y);
|
|
57151
|
+
this.glyphScale = glyphScale;
|
|
57152
|
+
this.symbols = symbols;
|
|
57153
|
+
}
|
|
57154
|
+
getBoundingBoxTop() {
|
|
57155
|
+
let bBoxTop = 0;
|
|
57156
|
+
for (let i = 0; i < this.symbols.length; i++) {
|
|
57157
|
+
const gTop = this.renderer.smuflMetrics.glyphTop.get(this.symbols[i]);
|
|
57158
|
+
if (i === 0 || gTop < bBoxTop) {
|
|
57159
|
+
bBoxTop = gTop;
|
|
57160
|
+
}
|
|
57161
|
+
}
|
|
57162
|
+
return this.y - this.offsetY - bBoxTop;
|
|
57163
|
+
}
|
|
57164
|
+
doLayout() {
|
|
57165
|
+
this.width = 0;
|
|
57166
|
+
this.height = 0;
|
|
57167
|
+
for (let i = 0; i < this.symbols.length; i++) {
|
|
57168
|
+
const gWidth = this.renderer.smuflMetrics.glyphWidths.get(this.symbols[i]) * this.glyphScale;
|
|
57169
|
+
const gHeight = this.renderer.smuflMetrics.glyphHeights.get(this.symbols[i]) * this.glyphScale;
|
|
57170
|
+
if (i === 0 || gWidth > this.width) {
|
|
57171
|
+
this.width = gWidth;
|
|
57172
|
+
}
|
|
57173
|
+
if (i === 0 || gHeight > this.height) {
|
|
57174
|
+
this.height = gHeight;
|
|
57175
|
+
}
|
|
57176
|
+
}
|
|
57177
|
+
}
|
|
57178
|
+
paint(cx, cy, canvas) {
|
|
57179
|
+
if (this.width === 0 && this.height === 0) {
|
|
57180
|
+
return;
|
|
57181
|
+
}
|
|
57182
|
+
const c = canvas.color;
|
|
57183
|
+
if (this.colorOverride) {
|
|
57184
|
+
canvas.color = this.colorOverride;
|
|
57185
|
+
}
|
|
57186
|
+
canvas.fillMusicFontSymbols(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbols, this.center);
|
|
57187
|
+
canvas.color = c;
|
|
57188
|
+
}
|
|
57189
|
+
}
|
|
57190
|
+
|
|
57253
57191
|
/**
|
|
57254
57192
|
* @internal
|
|
57255
57193
|
*/
|
|
@@ -57488,17 +57426,6 @@ class FermataEffectInfo extends EffectInfo {
|
|
|
57488
57426
|
}
|
|
57489
57427
|
}
|
|
57490
57428
|
|
|
57491
|
-
/**
|
|
57492
|
-
* This simple glyph allows to put an empty region in to a BarRenderer.
|
|
57493
|
-
* @internal
|
|
57494
|
-
*/
|
|
57495
|
-
class SpacingGlyph extends Glyph {
|
|
57496
|
-
constructor(x, y, width) {
|
|
57497
|
-
super(x, y);
|
|
57498
|
-
this.width = width;
|
|
57499
|
-
}
|
|
57500
|
-
}
|
|
57501
|
-
|
|
57502
57429
|
/**
|
|
57503
57430
|
* This glyph allows to group several other glyphs to be
|
|
57504
57431
|
* drawn at the same x position
|
|
@@ -57514,34 +57441,20 @@ class GlyphGroup extends Glyph {
|
|
|
57514
57441
|
const glyphs = this.glyphs;
|
|
57515
57442
|
if (glyphs) {
|
|
57516
57443
|
for (const g of glyphs) {
|
|
57517
|
-
|
|
57518
|
-
if (g instanceof SpacingGlyph) {
|
|
57519
|
-
continue;
|
|
57520
|
-
}
|
|
57521
|
-
const gTop = g.getBoundingBoxTop();
|
|
57522
|
-
if (Number.isNaN(top) || gTop < top) {
|
|
57523
|
-
top = gTop;
|
|
57524
|
-
}
|
|
57444
|
+
top = ModelUtils.minBoundingBox(top, g.getBoundingBoxTop());
|
|
57525
57445
|
}
|
|
57526
57446
|
}
|
|
57527
|
-
return
|
|
57447
|
+
return top;
|
|
57528
57448
|
}
|
|
57529
57449
|
getBoundingBoxBottom() {
|
|
57530
57450
|
let bottom = Number.NaN;
|
|
57531
57451
|
const glyphs = this.glyphs;
|
|
57532
57452
|
if (glyphs) {
|
|
57533
57453
|
for (const g of glyphs) {
|
|
57534
|
-
|
|
57535
|
-
if (g instanceof SpacingGlyph) {
|
|
57536
|
-
continue;
|
|
57537
|
-
}
|
|
57538
|
-
const gBottom = g.getBoundingBoxBottom();
|
|
57539
|
-
if (Number.isNaN(bottom) || gBottom > bottom) {
|
|
57540
|
-
bottom = gBottom;
|
|
57541
|
-
}
|
|
57454
|
+
bottom = ModelUtils.maxBoundingBox(bottom, g.getBoundingBoxBottom());
|
|
57542
57455
|
}
|
|
57543
57456
|
}
|
|
57544
|
-
return
|
|
57457
|
+
return bottom;
|
|
57545
57458
|
}
|
|
57546
57459
|
doLayout() {
|
|
57547
57460
|
if (!this.glyphs || this.glyphs.length === 0) {
|
|
@@ -57957,6 +57870,38 @@ class FreeTimeEffectInfo extends EffectInfo {
|
|
|
57957
57870
|
}
|
|
57958
57871
|
}
|
|
57959
57872
|
|
|
57873
|
+
/**
|
|
57874
|
+
* @internal
|
|
57875
|
+
*/
|
|
57876
|
+
class NoteHeadGlyph extends MusicFontGlyph {
|
|
57877
|
+
// TODO: SmuFL
|
|
57878
|
+
static GraceScale = 0.75;
|
|
57879
|
+
centerOnStem = false;
|
|
57880
|
+
constructor(x, y, duration, isGrace) {
|
|
57881
|
+
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, NoteHeadGlyph.getSymbol(duration));
|
|
57882
|
+
}
|
|
57883
|
+
paint(cx, cy, canvas) {
|
|
57884
|
+
if (this.centerOnStem) {
|
|
57885
|
+
this.center = true;
|
|
57886
|
+
}
|
|
57887
|
+
super.paint(cx, cy, canvas);
|
|
57888
|
+
}
|
|
57889
|
+
static getSymbol(duration) {
|
|
57890
|
+
switch (duration) {
|
|
57891
|
+
case Duration.QuadrupleWhole:
|
|
57892
|
+
return MusicFontSymbol.NoteheadDoubleWholeSquare;
|
|
57893
|
+
case Duration.DoubleWhole:
|
|
57894
|
+
return MusicFontSymbol.NoteheadDoubleWhole;
|
|
57895
|
+
case Duration.Whole:
|
|
57896
|
+
return MusicFontSymbol.NoteheadWhole;
|
|
57897
|
+
case Duration.Half:
|
|
57898
|
+
return MusicFontSymbol.NoteheadHalf;
|
|
57899
|
+
default:
|
|
57900
|
+
return MusicFontSymbol.NoteheadBlack;
|
|
57901
|
+
}
|
|
57902
|
+
}
|
|
57903
|
+
}
|
|
57904
|
+
|
|
57960
57905
|
/**
|
|
57961
57906
|
* @internal
|
|
57962
57907
|
*/
|
|
@@ -59575,12 +59520,12 @@ class VoiceContainerGlyph extends GlyphGroup {
|
|
|
59575
59520
|
// of the next glyph
|
|
59576
59521
|
if (i > 0) {
|
|
59577
59522
|
const beatWidth = currentBeatGlyph.x - beatGlyphs[i - 1].x;
|
|
59578
|
-
beatGlyphs[i - 1].
|
|
59523
|
+
beatGlyphs[i - 1].width = beatWidth;
|
|
59579
59524
|
}
|
|
59580
59525
|
// for the last glyph size based on the full width
|
|
59581
59526
|
if (i === j - 1) {
|
|
59582
59527
|
const beatWidth = this.width - beatGlyphs[beatGlyphs.length - 1].x;
|
|
59583
|
-
currentBeatGlyph.
|
|
59528
|
+
currentBeatGlyph.width = beatWidth;
|
|
59584
59529
|
}
|
|
59585
59530
|
}
|
|
59586
59531
|
}
|
|
@@ -61280,7 +61225,7 @@ class StaffSystem {
|
|
|
61280
61225
|
if (!masterBarBoundsLookup.has(renderer.bar.masterBar.index)) {
|
|
61281
61226
|
masterBarBounds = new MasterBarBounds();
|
|
61282
61227
|
masterBarBounds.index = renderer.bar.masterBar.index;
|
|
61283
|
-
masterBarBounds.isFirstOfLine = renderer.
|
|
61228
|
+
masterBarBounds.isFirstOfLine = renderer.isFirstOfStaff;
|
|
61284
61229
|
masterBarBounds.realBounds = new Bounds();
|
|
61285
61230
|
masterBarBounds.realBounds.x = x + renderer.x;
|
|
61286
61231
|
masterBarBounds.realBounds.y = realTop;
|
|
@@ -61812,10 +61757,9 @@ class BeatGlyphBase extends GlyphGroup {
|
|
|
61812
61757
|
* @internal
|
|
61813
61758
|
*/
|
|
61814
61759
|
class BeatOnNoteGlyphBase extends BeatGlyphBase {
|
|
61815
|
-
|
|
61816
|
-
|
|
61817
|
-
|
|
61818
|
-
}
|
|
61760
|
+
onTimeX = 0;
|
|
61761
|
+
middleX = 0;
|
|
61762
|
+
stemX = 0;
|
|
61819
61763
|
buildBoundingsLookup(_beatBounds, _cx, _cy) {
|
|
61820
61764
|
}
|
|
61821
61765
|
getNoteX(_note, _requestedPosition) {
|
|
@@ -61957,14 +61901,6 @@ class MultiBarRestBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
61957
61901
|
}
|
|
61958
61902
|
}
|
|
61959
61903
|
|
|
61960
|
-
/**
|
|
61961
|
-
* @internal
|
|
61962
|
-
*/
|
|
61963
|
-
class BeatLinePositions {
|
|
61964
|
-
staffId = '';
|
|
61965
|
-
up = 0;
|
|
61966
|
-
down = 0;
|
|
61967
|
-
}
|
|
61968
61904
|
/**
|
|
61969
61905
|
* @internal
|
|
61970
61906
|
*/
|
|
@@ -61995,10 +61931,7 @@ class BeamingHelperDrawInfo {
|
|
|
61995
61931
|
*/
|
|
61996
61932
|
class BeamingHelper {
|
|
61997
61933
|
_staff;
|
|
61998
|
-
_beatLineXPositions = new Map();
|
|
61999
61934
|
_renderer;
|
|
62000
|
-
_firstNonRestBeat = null;
|
|
62001
|
-
_lastNonRestBeat = null;
|
|
62002
61935
|
voice = null;
|
|
62003
61936
|
beats = [];
|
|
62004
61937
|
shortestDuration = Duration.QuadrupleWhole;
|
|
@@ -62008,6 +61941,7 @@ class BeamingHelper {
|
|
|
62008
61941
|
*/
|
|
62009
61942
|
hasTuplet = false;
|
|
62010
61943
|
slashBeats = [];
|
|
61944
|
+
restBeats = [];
|
|
62011
61945
|
lowestNoteInHelper = null;
|
|
62012
61946
|
_lowestNoteCompareValueInHelper = -1;
|
|
62013
61947
|
highestNoteInHelper = null;
|
|
@@ -62015,25 +61949,21 @@ class BeamingHelper {
|
|
|
62015
61949
|
invertBeamDirection = false;
|
|
62016
61950
|
preferredBeamDirection = null;
|
|
62017
61951
|
graceType = GraceType.None;
|
|
62018
|
-
minRestSteps = null;
|
|
62019
|
-
beatOfMinRestSteps = null;
|
|
62020
|
-
maxRestSteps = null;
|
|
62021
|
-
beatOfMaxRestSteps = null;
|
|
62022
61952
|
get isRestBeamHelper() {
|
|
62023
61953
|
return this.beats.length === 1 && this.beats[0].isRest;
|
|
62024
61954
|
}
|
|
62025
|
-
|
|
62026
|
-
return ((forceFlagOnSingleBeat && this.
|
|
62027
|
-
(!forceFlagOnSingleBeat && this.beats.length === 1 && this.
|
|
61955
|
+
hasStem(forceFlagOnSingleBeat, beat) {
|
|
61956
|
+
return ((forceFlagOnSingleBeat && this._beatHasStem(beat)) ||
|
|
61957
|
+
(!forceFlagOnSingleBeat && this.beats.length === 1 && this._beatHasStem(beat)));
|
|
62028
61958
|
}
|
|
62029
|
-
|
|
61959
|
+
_beatHasStem(beat) {
|
|
62030
61960
|
return beat.duration > Duration.Whole;
|
|
62031
61961
|
}
|
|
62032
61962
|
hasFlag(forceFlagOnSingleBeat, beat) {
|
|
62033
|
-
return ((forceFlagOnSingleBeat &&
|
|
62034
|
-
(!forceFlagOnSingleBeat && this.beats.length === 1 &&
|
|
61963
|
+
return ((forceFlagOnSingleBeat && BeamingHelper.beatHasFlag(beat)) ||
|
|
61964
|
+
(!forceFlagOnSingleBeat && this.beats.length === 1 && BeamingHelper.beatHasFlag(this.beats[0])));
|
|
62035
61965
|
}
|
|
62036
|
-
|
|
61966
|
+
static beatHasFlag(beat) {
|
|
62037
61967
|
return (!beat.deadSlapped && !beat.isRest && (beat.duration > Duration.Quarter || beat.graceType !== GraceType.None));
|
|
62038
61968
|
}
|
|
62039
61969
|
constructor(staff, renderer) {
|
|
@@ -62041,38 +61971,12 @@ class BeamingHelper {
|
|
|
62041
61971
|
this._renderer = renderer;
|
|
62042
61972
|
this.beats = [];
|
|
62043
61973
|
}
|
|
62044
|
-
|
|
62045
|
-
direction = direction ?? this.direction;
|
|
62046
|
-
if (this.hasBeatLineX(beat)) {
|
|
62047
|
-
if (direction === BeamDirection.Up) {
|
|
62048
|
-
return this._beatLineXPositions.get(beat.index).up;
|
|
62049
|
-
}
|
|
62050
|
-
return this._beatLineXPositions.get(beat.index).down;
|
|
62051
|
-
}
|
|
62052
|
-
return 0;
|
|
62053
|
-
}
|
|
62054
|
-
hasBeatLineX(beat) {
|
|
62055
|
-
return this._beatLineXPositions.has(beat.index);
|
|
62056
|
-
}
|
|
62057
|
-
registerBeatLineX(staffId, beat, up, down) {
|
|
62058
|
-
const positions = this._getOrCreateBeatPositions(beat);
|
|
62059
|
-
positions.staffId = staffId;
|
|
62060
|
-
positions.up = up;
|
|
62061
|
-
positions.down = down;
|
|
61974
|
+
alignWithBeats() {
|
|
62062
61975
|
for (const v of this.drawingInfos.values()) {
|
|
62063
|
-
|
|
62064
|
-
|
|
62065
|
-
|
|
62066
|
-
else if (v.endBeat === beat) {
|
|
62067
|
-
v.endX = this.getBeatLineX(beat);
|
|
62068
|
-
}
|
|
62069
|
-
}
|
|
62070
|
-
}
|
|
62071
|
-
_getOrCreateBeatPositions(beat) {
|
|
62072
|
-
if (!this._beatLineXPositions.has(beat.index)) {
|
|
62073
|
-
this._beatLineXPositions.set(beat.index, new BeatLinePositions());
|
|
61976
|
+
v.startX = this._renderer.getBeatX(v.startBeat, BeatXPosition.Stem);
|
|
61977
|
+
v.endX = this._renderer.getBeatX(v.endBeat, BeatXPosition.Stem);
|
|
61978
|
+
this.drawingInfos.clear();
|
|
62074
61979
|
}
|
|
62075
|
-
return this._beatLineXPositions.get(beat.index);
|
|
62076
61980
|
}
|
|
62077
61981
|
direction = BeamDirection.Up;
|
|
62078
61982
|
finish() {
|
|
@@ -62138,36 +62042,6 @@ class BeamingHelper {
|
|
|
62138
62042
|
}
|
|
62139
62043
|
return [0, 0];
|
|
62140
62044
|
}
|
|
62141
|
-
/**
|
|
62142
|
-
* Registers a rest beat within the accidental helper so the rest
|
|
62143
|
-
* symbol is considered properly during beaming.
|
|
62144
|
-
* @param beat The rest beat.
|
|
62145
|
-
* @param steps The steps on which the rest symbol is placed
|
|
62146
|
-
*/
|
|
62147
|
-
applyRest(beat, steps) {
|
|
62148
|
-
// do not accept rests after the last beat which has notes
|
|
62149
|
-
if ((this._lastNonRestBeat && beat.index >= this._lastNonRestBeat.index) ||
|
|
62150
|
-
(this._firstNonRestBeat && beat.index <= this._firstNonRestBeat.index)) {
|
|
62151
|
-
return;
|
|
62152
|
-
}
|
|
62153
|
-
// correct the line of the glyph to a note which would
|
|
62154
|
-
// be placed at the upper / lower end of the glyph.
|
|
62155
|
-
let aboveRest = steps;
|
|
62156
|
-
let belowRest = steps;
|
|
62157
|
-
const offsets = BeamingHelper.computeLineHeightsForRest(beat.duration);
|
|
62158
|
-
aboveRest -= offsets[0];
|
|
62159
|
-
belowRest += offsets[1];
|
|
62160
|
-
const minRestSteps = this.minRestSteps;
|
|
62161
|
-
const maxRestSteps = this.maxRestSteps;
|
|
62162
|
-
if (minRestSteps === null || minRestSteps > aboveRest) {
|
|
62163
|
-
this.minRestSteps = aboveRest;
|
|
62164
|
-
this.beatOfMinRestSteps = beat;
|
|
62165
|
-
}
|
|
62166
|
-
if (maxRestSteps === null || maxRestSteps < belowRest) {
|
|
62167
|
-
this.maxRestSteps = belowRest;
|
|
62168
|
-
this.beatOfMaxRestSteps = beat;
|
|
62169
|
-
}
|
|
62170
|
-
}
|
|
62171
62045
|
_invert(direction) {
|
|
62172
62046
|
if (!this.invertBeamDirection) {
|
|
62173
62047
|
return direction;
|
|
@@ -62231,14 +62105,13 @@ class BeamingHelper {
|
|
|
62231
62105
|
if (this.shortestDuration < beat.duration) {
|
|
62232
62106
|
this.shortestDuration = beat.duration;
|
|
62233
62107
|
}
|
|
62234
|
-
if (!this._firstNonRestBeat) {
|
|
62235
|
-
this._firstNonRestBeat = beat;
|
|
62236
|
-
}
|
|
62237
|
-
this._lastNonRestBeat = beat;
|
|
62238
62108
|
}
|
|
62239
62109
|
else if (this.beats.length === 0) {
|
|
62240
62110
|
this.beats.push(beat);
|
|
62241
62111
|
}
|
|
62112
|
+
else {
|
|
62113
|
+
this.restBeats.push(beat);
|
|
62114
|
+
}
|
|
62242
62115
|
if (beat.slashed) {
|
|
62243
62116
|
this.slashBeats.push(beat);
|
|
62244
62117
|
}
|
|
@@ -62347,19 +62220,6 @@ class BeamingHelper {
|
|
|
62347
62220
|
get beatOfHighestNote() {
|
|
62348
62221
|
return this.highestNoteInHelper.beat;
|
|
62349
62222
|
}
|
|
62350
|
-
/**
|
|
62351
|
-
* Returns whether the the position of the given beat, was registered by the staff of the given ID
|
|
62352
|
-
* @param staffId
|
|
62353
|
-
* @param beat
|
|
62354
|
-
* @returns
|
|
62355
|
-
*/
|
|
62356
|
-
isPositionFrom(staffId, beat) {
|
|
62357
|
-
if (!this._beatLineXPositions.has(beat.index)) {
|
|
62358
|
-
return true;
|
|
62359
|
-
}
|
|
62360
|
-
return (this._beatLineXPositions.get(beat.index).staffId === staffId ||
|
|
62361
|
-
!this._beatLineXPositions.get(beat.index).staffId);
|
|
62362
|
-
}
|
|
62363
62223
|
drawingInfos = new Map();
|
|
62364
62224
|
}
|
|
62365
62225
|
|
|
@@ -62511,8 +62371,8 @@ class BarCollisionHelper {
|
|
|
62511
62371
|
*/
|
|
62512
62372
|
class BarHelpers {
|
|
62513
62373
|
_renderer;
|
|
62374
|
+
_beamHelperLookup = new Map();
|
|
62514
62375
|
beamHelpers = [];
|
|
62515
|
-
beamHelperLookup = [];
|
|
62516
62376
|
collisionHelper;
|
|
62517
62377
|
preferredBeamDirection = null;
|
|
62518
62378
|
constructor(renderer) {
|
|
@@ -62527,7 +62387,6 @@ class BarHelpers {
|
|
|
62527
62387
|
for (let i = 0, j = bar.voices.length; i < j; i++) {
|
|
62528
62388
|
const v = bar.voices[i];
|
|
62529
62389
|
this.beamHelpers.push([]);
|
|
62530
|
-
this.beamHelperLookup.push(new Map());
|
|
62531
62390
|
for (let k = 0, l = v.beats.length; k < l; k++) {
|
|
62532
62391
|
const b = v.beats[k];
|
|
62533
62392
|
let helperForBeat;
|
|
@@ -62536,6 +62395,9 @@ class BarHelpers {
|
|
|
62536
62395
|
}
|
|
62537
62396
|
else {
|
|
62538
62397
|
helperForBeat = currentBeamHelper;
|
|
62398
|
+
if (currentGraceBeamHelper) {
|
|
62399
|
+
currentGraceBeamHelper.finish();
|
|
62400
|
+
}
|
|
62539
62401
|
currentGraceBeamHelper = null;
|
|
62540
62402
|
}
|
|
62541
62403
|
// if a new beaming helper was started, we close our tuplet grouping as well
|
|
@@ -62556,7 +62418,7 @@ class BarHelpers {
|
|
|
62556
62418
|
}
|
|
62557
62419
|
this.beamHelpers[v.index].push(helperForBeat);
|
|
62558
62420
|
}
|
|
62559
|
-
this.
|
|
62421
|
+
this._beamHelperLookup.set(b.id, helperForBeat);
|
|
62560
62422
|
}
|
|
62561
62423
|
if (currentBeamHelper) {
|
|
62562
62424
|
currentBeamHelper.finish();
|
|
@@ -62569,7 +62431,7 @@ class BarHelpers {
|
|
|
62569
62431
|
}
|
|
62570
62432
|
}
|
|
62571
62433
|
getBeamingHelperForBeat(beat) {
|
|
62572
|
-
return this.
|
|
62434
|
+
return this._beamHelperLookup.has(beat.id) ? this._beamHelperLookup.get(beat.id) : undefined;
|
|
62573
62435
|
}
|
|
62574
62436
|
}
|
|
62575
62437
|
|
|
@@ -62679,6 +62541,9 @@ class BarRendererBase {
|
|
|
62679
62541
|
return this._contentBottomOverflow + this.bottomEffects.height;
|
|
62680
62542
|
}
|
|
62681
62543
|
helpers;
|
|
62544
|
+
get collisionHelper() {
|
|
62545
|
+
return this.helpers.collisionHelper;
|
|
62546
|
+
}
|
|
62682
62547
|
/**
|
|
62683
62548
|
* Gets or sets whether this renderer is linked to the next one
|
|
62684
62549
|
* by some glyphs like a vibrato effect
|
|
@@ -62738,6 +62603,11 @@ class BarRendererBase {
|
|
|
62738
62603
|
for (const container of this._voiceContainers.values()) {
|
|
62739
62604
|
container.scaleToWidth(containerWidth);
|
|
62740
62605
|
}
|
|
62606
|
+
for (const v of this.helpers.beamHelpers) {
|
|
62607
|
+
for (const h of v) {
|
|
62608
|
+
h.alignWithBeats();
|
|
62609
|
+
}
|
|
62610
|
+
}
|
|
62741
62611
|
this._postBeatGlyphs.x = this._preBeatGlyphs.x + this._preBeatGlyphs.width + containerWidth;
|
|
62742
62612
|
this.width = width;
|
|
62743
62613
|
this.topEffects.alignGlyphs();
|
|
@@ -62766,10 +62636,13 @@ class BarRendererBase {
|
|
|
62766
62636
|
get barDisplayWidth() {
|
|
62767
62637
|
return this.staff.system.staves.length > 1 ? this.bar.masterBar.displayWidth : this.bar.displayWidth;
|
|
62768
62638
|
}
|
|
62769
|
-
|
|
62770
|
-
get
|
|
62639
|
+
wasFirstOfStaff = false;
|
|
62640
|
+
get isFirstOfStaff() {
|
|
62771
62641
|
return this.index === 0;
|
|
62772
62642
|
}
|
|
62643
|
+
get isLastOfStaff() {
|
|
62644
|
+
return this.index === this.staff.barRenderers.length - 1;
|
|
62645
|
+
}
|
|
62773
62646
|
get isLast() {
|
|
62774
62647
|
return !this.bar || this.bar.index === this.scoreRenderer.layout.lastBarIndex;
|
|
62775
62648
|
}
|
|
@@ -62984,6 +62857,18 @@ class BarRendererBase {
|
|
|
62984
62857
|
}
|
|
62985
62858
|
}
|
|
62986
62859
|
}
|
|
62860
|
+
for (const v of this._voiceContainers.values()) {
|
|
62861
|
+
for (const b of v.beatGlyphs) {
|
|
62862
|
+
const topY = b.getBoundingBoxTop();
|
|
62863
|
+
if (topY < 0) {
|
|
62864
|
+
this.registerOverflowTop(topY * -1);
|
|
62865
|
+
}
|
|
62866
|
+
const bottomY = b.getBoundingBoxBottom();
|
|
62867
|
+
if (bottomY > rendererBottom) {
|
|
62868
|
+
this.registerOverflowBottom(bottomY - rendererBottom);
|
|
62869
|
+
}
|
|
62870
|
+
}
|
|
62871
|
+
}
|
|
62987
62872
|
const beatEffectsMinY = this.beatEffectsMinY;
|
|
62988
62873
|
if (!Number.isNaN(beatEffectsMinY)) {
|
|
62989
62874
|
const beatEffectTopOverflow = -beatEffectsMinY;
|
|
@@ -63037,7 +62922,6 @@ class BarRendererBase {
|
|
|
63037
62922
|
g.renderer = this;
|
|
63038
62923
|
g.preNotes.renderer = this;
|
|
63039
62924
|
g.onNotes.renderer = this;
|
|
63040
|
-
g.onNotes.beamingHelper = this.helpers.beamHelperLookup[g.beat.voice.index].get(g.beat.index);
|
|
63041
62925
|
this.getVoiceContainer(g.beat.voice).addGlyph(g);
|
|
63042
62926
|
}
|
|
63043
62927
|
getVoiceContainer(voice) {
|
|
@@ -63116,7 +63000,7 @@ class BarRendererBase {
|
|
|
63116
63000
|
this._postBeatGlyphs.addGlyph(g);
|
|
63117
63001
|
}
|
|
63118
63002
|
createPreBeatGlyphs() {
|
|
63119
|
-
this.
|
|
63003
|
+
this.wasFirstOfStaff = this.isFirstOfStaff;
|
|
63120
63004
|
}
|
|
63121
63005
|
createBeatGlyphs() {
|
|
63122
63006
|
for (const voice of this.bar.voices) {
|
|
@@ -63143,26 +63027,7 @@ class BarRendererBase {
|
|
|
63143
63027
|
getBeatX(beat, requestedPosition = BeatXPosition.PreNotes, useSharedSizes = false) {
|
|
63144
63028
|
const container = this.getBeatContainer(beat);
|
|
63145
63029
|
if (container) {
|
|
63146
|
-
|
|
63147
|
-
case BeatXPosition.PreNotes:
|
|
63148
|
-
return container.voiceContainer.x + container.x;
|
|
63149
|
-
case BeatXPosition.OnNotes:
|
|
63150
|
-
return container.voiceContainer.x + container.x + container.onNotes.x;
|
|
63151
|
-
case BeatXPosition.MiddleNotes:
|
|
63152
|
-
return container.voiceContainer.x + container.x + container.onTimeX;
|
|
63153
|
-
case BeatXPosition.Stem:
|
|
63154
|
-
const offset = container.onNotes.beamingHelper
|
|
63155
|
-
? container.onNotes.beamingHelper.getBeatLineX(beat)
|
|
63156
|
-
: container.onNotes.x + container.onNotes.width / 2;
|
|
63157
|
-
return container.voiceContainer.x + offset;
|
|
63158
|
-
case BeatXPosition.PostNotes:
|
|
63159
|
-
const onNoteSize = useSharedSizes
|
|
63160
|
-
? (this.layoutingInfo.getBeatSizes(beat)?.onBeatSize ?? container.onNotes.width)
|
|
63161
|
-
: container.onNotes.width;
|
|
63162
|
-
return container.voiceContainer.x + container.x + container.onNotes.x + onNoteSize;
|
|
63163
|
-
case BeatXPosition.EndBeat:
|
|
63164
|
-
return container.voiceContainer.x + container.x + container.width;
|
|
63165
|
-
}
|
|
63030
|
+
return container.voiceContainer.x + container.x + container.getBeatX(requestedPosition, useSharedSizes);
|
|
63166
63031
|
}
|
|
63167
63032
|
return 0;
|
|
63168
63033
|
}
|
|
@@ -63197,7 +63062,7 @@ class BarRendererBase {
|
|
|
63197
63062
|
this.updateSizes();
|
|
63198
63063
|
// there are some glyphs which are shown only for renderers at the line start, so we simply recreate them
|
|
63199
63064
|
// but we only need to recreate them for the renderers that were the first of the line or are now the first of the line
|
|
63200
|
-
if ((this.
|
|
63065
|
+
if ((this.wasFirstOfStaff && !this.isFirstOfStaff) || (!this.wasFirstOfStaff && this.isFirstOfStaff)) {
|
|
63201
63066
|
this.recreatePreBeatGlyphs();
|
|
63202
63067
|
this._postBeatGlyphs.doLayout();
|
|
63203
63068
|
}
|
|
@@ -63234,7 +63099,7 @@ class BarRendererBase {
|
|
|
63234
63099
|
completeBeamingHelper(_helper) {
|
|
63235
63100
|
}
|
|
63236
63101
|
getBeatDirection(beat) {
|
|
63237
|
-
return this.helpers.getBeamingHelperForBeat(beat).
|
|
63102
|
+
return this.helpers.getBeamingHelperForBeat(beat)?.direction ?? BeamDirection.Up;
|
|
63238
63103
|
}
|
|
63239
63104
|
}
|
|
63240
63105
|
|
|
@@ -65601,8 +65466,18 @@ class BarLineGlyph extends LeftToRightLayoutingGlyphGroup {
|
|
|
65601
65466
|
}
|
|
65602
65467
|
const lineRenderer = this.renderer;
|
|
65603
65468
|
const lineYOffset = lineRenderer.smuflMetrics.staffLineThickness;
|
|
65604
|
-
|
|
65605
|
-
|
|
65469
|
+
let top = this.y;
|
|
65470
|
+
let bottom = this.y;
|
|
65471
|
+
if (lineRenderer.drawnLineCount < 2 ||
|
|
65472
|
+
(!this._isRight && lineRenderer.isFirstOfStaff) ||
|
|
65473
|
+
(this._isRight && lineRenderer.isLastOfStaff)) {
|
|
65474
|
+
top -= lineYOffset;
|
|
65475
|
+
bottom += lineRenderer.height;
|
|
65476
|
+
}
|
|
65477
|
+
else {
|
|
65478
|
+
top += lineRenderer.getLineY(0);
|
|
65479
|
+
bottom += lineRenderer.getLineY(lineRenderer.drawnLineCount - 1);
|
|
65480
|
+
}
|
|
65606
65481
|
const h = bottom - top;
|
|
65607
65482
|
// round up to have pixel-aligned bar lines, x-shift will be used during rendering
|
|
65608
65483
|
// to avoid shifting again all glyphs
|
|
@@ -65688,6 +65563,54 @@ class BarNumberGlyph extends Glyph {
|
|
|
65688
65563
|
}
|
|
65689
65564
|
}
|
|
65690
65565
|
|
|
65566
|
+
/**
|
|
65567
|
+
* @internal
|
|
65568
|
+
*/
|
|
65569
|
+
class FlagGlyph extends MusicFontGlyph {
|
|
65570
|
+
constructor(x, y, duration, direction, isGrace) {
|
|
65571
|
+
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, FlagGlyph.getSymbol(duration, direction, isGrace));
|
|
65572
|
+
}
|
|
65573
|
+
static getSymbol(duration, direction, isGrace) {
|
|
65574
|
+
if (isGrace) {
|
|
65575
|
+
duration = Duration.Eighth;
|
|
65576
|
+
}
|
|
65577
|
+
if (direction === BeamDirection.Up) {
|
|
65578
|
+
switch (duration) {
|
|
65579
|
+
case Duration.Eighth:
|
|
65580
|
+
return MusicFontSymbol.Flag8thUp;
|
|
65581
|
+
case Duration.Sixteenth:
|
|
65582
|
+
return MusicFontSymbol.Flag16thUp;
|
|
65583
|
+
case Duration.ThirtySecond:
|
|
65584
|
+
return MusicFontSymbol.Flag32ndUp;
|
|
65585
|
+
case Duration.SixtyFourth:
|
|
65586
|
+
return MusicFontSymbol.Flag64thUp;
|
|
65587
|
+
case Duration.OneHundredTwentyEighth:
|
|
65588
|
+
return MusicFontSymbol.Flag128thUp;
|
|
65589
|
+
case Duration.TwoHundredFiftySixth:
|
|
65590
|
+
return MusicFontSymbol.Flag256thUp;
|
|
65591
|
+
default:
|
|
65592
|
+
return MusicFontSymbol.Flag8thUp;
|
|
65593
|
+
}
|
|
65594
|
+
}
|
|
65595
|
+
switch (duration) {
|
|
65596
|
+
case Duration.Eighth:
|
|
65597
|
+
return MusicFontSymbol.Flag8thDown;
|
|
65598
|
+
case Duration.Sixteenth:
|
|
65599
|
+
return MusicFontSymbol.Flag16thDown;
|
|
65600
|
+
case Duration.ThirtySecond:
|
|
65601
|
+
return MusicFontSymbol.Flag32ndDown;
|
|
65602
|
+
case Duration.SixtyFourth:
|
|
65603
|
+
return MusicFontSymbol.Flag64thDown;
|
|
65604
|
+
case Duration.OneHundredTwentyEighth:
|
|
65605
|
+
return MusicFontSymbol.Flag128thDown;
|
|
65606
|
+
case Duration.TwoHundredFiftySixth:
|
|
65607
|
+
return MusicFontSymbol.Flag128thDown;
|
|
65608
|
+
default:
|
|
65609
|
+
return MusicFontSymbol.Flag8thDown;
|
|
65610
|
+
}
|
|
65611
|
+
}
|
|
65612
|
+
}
|
|
65613
|
+
|
|
65691
65614
|
/**
|
|
65692
65615
|
* @internal
|
|
65693
65616
|
*/
|
|
@@ -65723,6 +65646,23 @@ class RepeatCountGlyph extends Glyph {
|
|
|
65723
65646
|
}
|
|
65724
65647
|
}
|
|
65725
65648
|
|
|
65649
|
+
/**
|
|
65650
|
+
* This simple glyph allows to put an empty region in to a BarRenderer.
|
|
65651
|
+
* @internal
|
|
65652
|
+
*/
|
|
65653
|
+
class SpacingGlyph extends Glyph {
|
|
65654
|
+
constructor(x, y, width) {
|
|
65655
|
+
super(x, y);
|
|
65656
|
+
this.width = width;
|
|
65657
|
+
}
|
|
65658
|
+
getBoundingBoxTop() {
|
|
65659
|
+
return Number.NaN;
|
|
65660
|
+
}
|
|
65661
|
+
getBoundingBoxBottom() {
|
|
65662
|
+
return Number.NaN;
|
|
65663
|
+
}
|
|
65664
|
+
}
|
|
65665
|
+
|
|
65726
65666
|
/**
|
|
65727
65667
|
* This is a base class for any bar renderer which renders music notation on a staff
|
|
65728
65668
|
* with lines like Standard Notation, Guitar Tablatures and Slash Notation.
|
|
@@ -65846,7 +65786,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
65846
65786
|
if (this.hasVoiceContainer(voice)) {
|
|
65847
65787
|
const container = this.getVoiceContainer(voice);
|
|
65848
65788
|
for (const tupletGroup of container.tupletGroups) {
|
|
65849
|
-
this._paintTupletHelper(cx
|
|
65789
|
+
this._paintTupletHelper(cx, cy, canvas, tupletGroup, beatElement, bracketsAsArcs);
|
|
65850
65790
|
}
|
|
65851
65791
|
}
|
|
65852
65792
|
}
|
|
@@ -65920,26 +65860,27 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
65920
65860
|
// check if we need to paint simple footer
|
|
65921
65861
|
const offset = this.tupletOffset;
|
|
65922
65862
|
const size = this.tupletSize;
|
|
65863
|
+
const shift = offset + size * 0.5;
|
|
65923
65864
|
const _ = ElementStyleHelper.beat(canvas, beatElement, h.beats[0]);
|
|
65924
65865
|
try {
|
|
65925
65866
|
const l = canvas.lineWidth;
|
|
65926
65867
|
canvas.lineWidth = this.smuflMetrics.tupletBracketThickness;
|
|
65927
65868
|
if (h.beats.length === 1 || !h.isFull) {
|
|
65928
65869
|
for (const beat of h.beats) {
|
|
65929
|
-
const beamingHelper = this.helpers.
|
|
65870
|
+
const beamingHelper = this.helpers.getBeamingHelperForBeat(beat);
|
|
65930
65871
|
if (!beamingHelper) {
|
|
65931
65872
|
continue;
|
|
65932
65873
|
}
|
|
65933
65874
|
const direction = this.getTupletBeamDirection(beamingHelper);
|
|
65934
|
-
const tupletX =
|
|
65875
|
+
const tupletX = this.getBeatX(beat, BeatXPosition.Stem);
|
|
65935
65876
|
let tupletY = this.calculateBeamYWithDirection(beamingHelper, tupletX, direction);
|
|
65936
65877
|
if (direction === BeamDirection.Down) {
|
|
65937
|
-
tupletY +=
|
|
65878
|
+
tupletY += shift;
|
|
65938
65879
|
}
|
|
65939
65880
|
else {
|
|
65940
|
-
tupletY -=
|
|
65881
|
+
tupletY -= shift;
|
|
65941
65882
|
}
|
|
65942
|
-
canvas.fillMusicFontSymbols(cx + this.x + tupletX, cy + this.y + tupletY, 1, s, true);
|
|
65883
|
+
canvas.fillMusicFontSymbols(cx + this.x + tupletX, cy + this.y + tupletY + size * 0.5, 1, s, true);
|
|
65943
65884
|
}
|
|
65944
65885
|
}
|
|
65945
65886
|
else {
|
|
@@ -65969,12 +65910,12 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
65969
65910
|
}
|
|
65970
65911
|
//
|
|
65971
65912
|
// Calculate the overall area of the tuplet bracket
|
|
65972
|
-
const startX = this.getBeatX(firstBeat, BeatXPosition.OnNotes)
|
|
65973
|
-
const endX = this.getBeatX(lastBeat, BeatXPosition.PostNotes)
|
|
65913
|
+
const startX = this.getBeatX(firstBeat, BeatXPosition.OnNotes);
|
|
65914
|
+
const endX = this.getBeatX(lastBeat, BeatXPosition.PostNotes);
|
|
65974
65915
|
//
|
|
65975
65916
|
// calculate the y positions for our bracket
|
|
65976
|
-
const firstNonRestBeamingHelper = this.helpers.
|
|
65977
|
-
const lastNonRestBeamingHelper = this.helpers.
|
|
65917
|
+
const firstNonRestBeamingHelper = this.helpers.getBeamingHelperForBeat(firstNonRestBeat);
|
|
65918
|
+
const lastNonRestBeamingHelper = this.helpers.getBeamingHelperForBeat(lastNonRestBeat);
|
|
65978
65919
|
const direction = this.getTupletBeamDirection(firstNonRestBeamingHelper);
|
|
65979
65920
|
let startY = this.calculateBeamYWithDirection(firstNonRestBeamingHelper, startX, direction);
|
|
65980
65921
|
let endY = this.calculateBeamYWithDirection(lastNonRestBeamingHelper, endX, direction);
|
|
@@ -65983,7 +65924,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
65983
65924
|
endY = startY;
|
|
65984
65925
|
}
|
|
65985
65926
|
// align line centered in available space
|
|
65986
|
-
const shift = offset + size * 0.5;
|
|
65987
65927
|
if (direction === BeamDirection.Down) {
|
|
65988
65928
|
startY += shift;
|
|
65989
65929
|
endY += shift;
|
|
@@ -66048,14 +65988,24 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66048
65988
|
paintBeams(cx, cy, canvas, flagsElement, beamsElement) {
|
|
66049
65989
|
for (const v of this.helpers.beamHelpers) {
|
|
66050
65990
|
for (const h of v) {
|
|
66051
|
-
this.
|
|
65991
|
+
this.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
|
|
66052
65992
|
}
|
|
66053
65993
|
}
|
|
66054
65994
|
}
|
|
66055
65995
|
drawBeamHelperAsFlags(h) {
|
|
66056
65996
|
return h.beats.length === 1;
|
|
66057
65997
|
}
|
|
66058
|
-
|
|
65998
|
+
hasFlag(beat) {
|
|
65999
|
+
if (beat.isRest) {
|
|
66000
|
+
return false;
|
|
66001
|
+
}
|
|
66002
|
+
const helper = this.helpers.getBeamingHelperForBeat(beat);
|
|
66003
|
+
if (helper) {
|
|
66004
|
+
return helper.hasFlag(this.drawBeamHelperAsFlags(helper), beat);
|
|
66005
|
+
}
|
|
66006
|
+
return BeamingHelper.beatHasFlag(beat);
|
|
66007
|
+
}
|
|
66008
|
+
paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
|
|
66059
66009
|
canvas.color = h.voice.index === 0 ? this.resources.mainGlyphColor : this.resources.secondaryGlyphColor;
|
|
66060
66010
|
if (!h.isRestBeamHelper) {
|
|
66061
66011
|
if (this.drawBeamHelperAsFlags(h)) {
|
|
@@ -66066,7 +66016,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66066
66016
|
}
|
|
66067
66017
|
}
|
|
66068
66018
|
}
|
|
66069
|
-
shouldPaintFlag(beat
|
|
66019
|
+
shouldPaintFlag(beat) {
|
|
66070
66020
|
// no flags for bend grace beats
|
|
66071
66021
|
if (beat.graceType === GraceType.BendGrace) {
|
|
66072
66022
|
return false;
|
|
@@ -66074,10 +66024,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66074
66024
|
if (beat.deadSlapped) {
|
|
66075
66025
|
return false;
|
|
66076
66026
|
}
|
|
66077
|
-
// we don't have an X-position: cannot paint a flag
|
|
66078
|
-
if (!h.hasBeatLineX(beat)) {
|
|
66079
|
-
return false;
|
|
66080
|
-
}
|
|
66081
66027
|
// no flags for any grace notes on songbook mode
|
|
66082
66028
|
if (beat.graceType !== GraceType.None && this.settings.notation.notationMode === NotationMode.SongBook) {
|
|
66083
66029
|
return false;
|
|
@@ -66092,14 +66038,14 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66092
66038
|
}
|
|
66093
66039
|
paintFlag(cx, cy, canvas, h, flagsElement) {
|
|
66094
66040
|
for (const beat of h.beats) {
|
|
66095
|
-
if (!this.shouldPaintFlag(beat
|
|
66041
|
+
if (!this.shouldPaintFlag(beat)) {
|
|
66096
66042
|
continue;
|
|
66097
66043
|
}
|
|
66098
66044
|
const isGrace = beat.graceType !== GraceType.None;
|
|
66099
66045
|
//
|
|
66100
66046
|
// draw line
|
|
66101
66047
|
//
|
|
66102
|
-
const beatLineX =
|
|
66048
|
+
const beatLineX = this.getBeatX(beat, BeatXPosition.Stem);
|
|
66103
66049
|
const direction = this.getBeamDirection(h);
|
|
66104
66050
|
const topY = cy + this.y + this.getFlagTopY(beat, direction);
|
|
66105
66051
|
const bottomY = cy + this.y + this.getFlagBottomY(beat, direction);
|
|
@@ -66110,7 +66056,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66110
66056
|
else {
|
|
66111
66057
|
flagY = topY;
|
|
66112
66058
|
}
|
|
66113
|
-
if (!h.
|
|
66059
|
+
if (!h.hasStem(true, beat)) {
|
|
66114
66060
|
continue;
|
|
66115
66061
|
}
|
|
66116
66062
|
this.paintBeamingStem(beat, cy + this.y, cx + this.x + beatLineX, topY, bottomY, canvas);
|
|
@@ -66196,10 +66142,10 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66196
66142
|
}
|
|
66197
66143
|
for (let i = 0, j = h.beats.length; i < j; i++) {
|
|
66198
66144
|
const beat = h.beats[i];
|
|
66199
|
-
if (
|
|
66145
|
+
if (beat.deadSlapped) {
|
|
66200
66146
|
continue;
|
|
66201
66147
|
}
|
|
66202
|
-
const beatLineX =
|
|
66148
|
+
const beatLineX = this.getBeatX(beat, BeatXPosition.Stem);
|
|
66203
66149
|
const y1 = cy + this.y + this.getBarLineStart(beat, direction);
|
|
66204
66150
|
// ensure we are pixel aligned on the end of the stem to avoid anti-aliasing artifacts
|
|
66205
66151
|
// when combining stems and beams on sub-pixel level
|
|
@@ -66237,7 +66183,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66237
66183
|
barEndY = barY + this.calculateBeamY(h, barEndX);
|
|
66238
66184
|
LineBarRenderer.paintSingleBar(canvas, cx + this.x + barStartX, barStartY, cx + this.x + barEndX, barEndY, barSize);
|
|
66239
66185
|
// end part
|
|
66240
|
-
barEndX =
|
|
66186
|
+
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.Stem);
|
|
66241
66187
|
barStartX = barEndX - brokenBarOffset;
|
|
66242
66188
|
barStartY = barY + this.calculateBeamY(h, barStartX);
|
|
66243
66189
|
barEndY = barY + this.calculateBeamY(h, barEndX);
|
|
@@ -66247,7 +66193,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66247
66193
|
if (isFullBarJoin) {
|
|
66248
66194
|
// full bar?
|
|
66249
66195
|
barStartX = beatLineX;
|
|
66250
|
-
barEndX =
|
|
66196
|
+
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.Stem);
|
|
66251
66197
|
}
|
|
66252
66198
|
else if (i === 0 || !BeamingHelper.isFullBarJoin(h.beats[i - 1], beat, barIndex)) {
|
|
66253
66199
|
barStartX = beatLineX;
|
|
@@ -66282,7 +66228,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66282
66228
|
}
|
|
66283
66229
|
}
|
|
66284
66230
|
if (h.graceType === GraceType.BeforeBeat) {
|
|
66285
|
-
const beatLineX =
|
|
66231
|
+
const beatLineX = this.getBeatX(h.beats[0], BeatXPosition.Stem);
|
|
66286
66232
|
const flagWidth = this.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
66287
66233
|
let slashY = (cy + this.y + this.calculateBeamY(h, beatLineX)) | 0;
|
|
66288
66234
|
slashY += barSize + barSpacing;
|
|
@@ -66309,20 +66255,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66309
66255
|
const noteOverflowPadding = this.getLineHeight(0.5);
|
|
66310
66256
|
for (const v of this.helpers.beamHelpers) {
|
|
66311
66257
|
for (const h of v) {
|
|
66312
|
-
if (h.isRestBeamHelper)
|
|
66313
|
-
if (h.minRestSteps) {
|
|
66314
|
-
const topY = this.getLineY(h.maxRestSteps / 2) - noteOverflowPadding;
|
|
66315
|
-
if (topY < maxNoteY) {
|
|
66316
|
-
maxNoteY = topY;
|
|
66317
|
-
}
|
|
66318
|
-
}
|
|
66319
|
-
if (h.maxRestSteps) {
|
|
66320
|
-
const bottomY = this.getLineY(h.maxRestSteps & 2) + noteOverflowPadding;
|
|
66321
|
-
if (bottomY < maxNoteY) {
|
|
66322
|
-
maxNoteY = bottomY;
|
|
66323
|
-
}
|
|
66324
|
-
}
|
|
66325
|
-
}
|
|
66258
|
+
if (h.isRestBeamHelper) ;
|
|
66326
66259
|
else if (h.beats.length === 1 && h.beats[0].duration >= Duration.Half) {
|
|
66327
66260
|
if (h.direction === BeamDirection.Up) {
|
|
66328
66261
|
let topY = this.getFlagTopY(h.beats[0], h.direction);
|
|
@@ -66373,17 +66306,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66373
66306
|
}
|
|
66374
66307
|
}
|
|
66375
66308
|
}
|
|
66376
|
-
const beatContainer = this.getBeatContainer(h.beats[0]);
|
|
66377
|
-
if (beatContainer) {
|
|
66378
|
-
const bBoxTop = beatContainer.getBoundingBoxTop();
|
|
66379
|
-
const bBoxBottom = beatContainer.getBoundingBoxBottom();
|
|
66380
|
-
if (bBoxBottom > minNoteY) {
|
|
66381
|
-
minNoteY = bBoxBottom;
|
|
66382
|
-
}
|
|
66383
|
-
if (bBoxTop < maxNoteY) {
|
|
66384
|
-
maxNoteY = bBoxTop;
|
|
66385
|
-
}
|
|
66386
|
-
}
|
|
66387
66309
|
}
|
|
66388
66310
|
}
|
|
66389
66311
|
if (maxNoteY < rendererTop) {
|
|
@@ -66399,25 +66321,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66399
66321
|
}
|
|
66400
66322
|
const scale = h.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
66401
66323
|
const barCount = ModelUtils.getIndex(h.shortestDuration) - 2;
|
|
66402
|
-
let stemSize = this.smuflMetrics.standardStemLength * scale;
|
|
66403
|
-
if (h.tremoloDuration) {
|
|
66404
|
-
// for 16th and shorter beats we need more space for all tremolos
|
|
66405
|
-
// for 8th beats we need only more space for 32nd tremolos
|
|
66406
|
-
// the logic here is not perfect but there is no SMuFL guideline
|
|
66407
|
-
// on how tremolos need to extend stems
|
|
66408
|
-
const oneBeamSize = (this.smuflMetrics.beamThickness + this.smuflMetrics.beamSpacing) * scale;
|
|
66409
|
-
if (h.shortestDuration > Duration.Eighth) {
|
|
66410
|
-
if (h.tremoloDuration === Duration.Eighth) {
|
|
66411
|
-
stemSize += oneBeamSize;
|
|
66412
|
-
}
|
|
66413
|
-
else {
|
|
66414
|
-
stemSize += oneBeamSize * 1.5;
|
|
66415
|
-
}
|
|
66416
|
-
}
|
|
66417
|
-
else if (h.tremoloDuration === Duration.ThirtySecond) {
|
|
66418
|
-
stemSize += oneBeamSize * 1.5;
|
|
66419
|
-
}
|
|
66420
|
-
}
|
|
66421
66324
|
const drawingInfo = new BeamingHelperDrawInfo();
|
|
66422
66325
|
h.drawingInfos.set(direction, drawingInfo);
|
|
66423
66326
|
// the beaming logic works like this:
|
|
@@ -66430,33 +66333,17 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66430
66333
|
const isRest = h.isRestBeamHelper;
|
|
66431
66334
|
// 1. put direct diagonal line.
|
|
66432
66335
|
drawingInfo.startBeat = firstBeat;
|
|
66433
|
-
drawingInfo.startX =
|
|
66434
|
-
|
|
66435
|
-
|
|
66436
|
-
|
|
66437
|
-
|
|
66438
|
-
: this.getLineY(h.maxRestSteps / 2);
|
|
66439
|
-
}
|
|
66440
|
-
else {
|
|
66441
|
-
drawingInfo.startY =
|
|
66442
|
-
direction === BeamDirection.Up
|
|
66443
|
-
? this.getFlagTopY(firstBeat, direction)
|
|
66444
|
-
: this.getFlagBottomY(firstBeat, direction);
|
|
66445
|
-
}
|
|
66336
|
+
drawingInfo.startX = this.getBeatX(firstBeat, BeatXPosition.Stem);
|
|
66337
|
+
drawingInfo.startY =
|
|
66338
|
+
direction === BeamDirection.Up
|
|
66339
|
+
? this.getFlagTopY(firstBeat, direction)
|
|
66340
|
+
: this.getFlagBottomY(firstBeat, direction);
|
|
66446
66341
|
drawingInfo.endBeat = lastBeat;
|
|
66447
|
-
drawingInfo.endX =
|
|
66448
|
-
|
|
66449
|
-
|
|
66450
|
-
|
|
66451
|
-
|
|
66452
|
-
: this.getLineY(h.maxRestSteps / 2);
|
|
66453
|
-
}
|
|
66454
|
-
else {
|
|
66455
|
-
drawingInfo.endY =
|
|
66456
|
-
direction === BeamDirection.Up
|
|
66457
|
-
? this.getFlagTopY(lastBeat, direction)
|
|
66458
|
-
: this.getFlagBottomY(lastBeat, direction);
|
|
66459
|
-
}
|
|
66342
|
+
drawingInfo.endX = this.getBeatX(lastBeat, BeatXPosition.Stem);
|
|
66343
|
+
drawingInfo.endY =
|
|
66344
|
+
direction === BeamDirection.Up
|
|
66345
|
+
? this.getFlagTopY(lastBeat, direction)
|
|
66346
|
+
: this.getFlagBottomY(lastBeat, direction);
|
|
66460
66347
|
// 2. ensure max slope
|
|
66461
66348
|
// we use the min/max notes to place the beam along their real position
|
|
66462
66349
|
// we only want a maximum of 10 offset for their gradient
|
|
@@ -66481,12 +66368,41 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66481
66368
|
drawingInfo.startY - drawingInfo.endY > maxSlope) {
|
|
66482
66369
|
drawingInfo.startY = drawingInfo.endY + maxSlope;
|
|
66483
66370
|
}
|
|
66484
|
-
// 3.
|
|
66371
|
+
// 3. adjust beam drawing order
|
|
66372
|
+
// we can only draw up to 2 beams towards the noteheads, then we have to grow to the other side
|
|
66373
|
+
// here we shift accordingly
|
|
66374
|
+
let barDrawingShift = 0;
|
|
66375
|
+
if (barCount > 2 && !isRest) {
|
|
66376
|
+
const beamSpacing = this.smuflMetrics.beamSpacing * scale;
|
|
66377
|
+
const beamThickness = this.smuflMetrics.beamThickness * scale;
|
|
66378
|
+
const totalBarsHeight = barCount * beamThickness + (barCount - 1) * beamSpacing;
|
|
66379
|
+
if (direction === BeamDirection.Up) {
|
|
66380
|
+
const bottomBarY = drawingInfo.startY + 2 * beamThickness + beamSpacing;
|
|
66381
|
+
const barTopY = bottomBarY - totalBarsHeight;
|
|
66382
|
+
const diff = drawingInfo.startY - barTopY;
|
|
66383
|
+
if (diff > 0) {
|
|
66384
|
+
barDrawingShift = diff * -1;
|
|
66385
|
+
drawingInfo.startY -= diff;
|
|
66386
|
+
drawingInfo.endY -= diff;
|
|
66387
|
+
}
|
|
66388
|
+
}
|
|
66389
|
+
else {
|
|
66390
|
+
const topBarY = drawingInfo.startY - 2 * beamThickness + beamSpacing;
|
|
66391
|
+
const barBottomY = topBarY + totalBarsHeight;
|
|
66392
|
+
const diff = barBottomY - drawingInfo.startY;
|
|
66393
|
+
if (diff > 0) {
|
|
66394
|
+
barDrawingShift = diff;
|
|
66395
|
+
drawingInfo.startY += diff;
|
|
66396
|
+
drawingInfo.endY += diff;
|
|
66397
|
+
}
|
|
66398
|
+
}
|
|
66399
|
+
}
|
|
66400
|
+
// 4. let middle elements shift up/down
|
|
66485
66401
|
if (h.beats.length > 1) {
|
|
66486
66402
|
// check if highest note shifts bar up or down
|
|
66487
66403
|
if (direction === BeamDirection.Up) {
|
|
66488
|
-
const yNeededForHighestNote = this.
|
|
66489
|
-
const yGivenByCurrentValues = drawingInfo.calcY(
|
|
66404
|
+
const yNeededForHighestNote = barDrawingShift + this.getFlagTopY(h.beatOfHighestNote, direction);
|
|
66405
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(h.beatOfHighestNote, BeatXPosition.Stem));
|
|
66490
66406
|
const diff = yGivenByCurrentValues - yNeededForHighestNote;
|
|
66491
66407
|
if (diff > 0) {
|
|
66492
66408
|
drawingInfo.startY -= diff;
|
|
@@ -66494,8 +66410,8 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66494
66410
|
}
|
|
66495
66411
|
}
|
|
66496
66412
|
else {
|
|
66497
|
-
const yNeededForLowestNote = this.
|
|
66498
|
-
const yGivenByCurrentValues = drawingInfo.calcY(
|
|
66413
|
+
const yNeededForLowestNote = barDrawingShift + this.getFlagBottomY(h.beatOfLowestNote, direction);
|
|
66414
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(h.beatOfLowestNote, BeatXPosition.Stem));
|
|
66499
66415
|
const diff = yNeededForLowestNote - yGivenByCurrentValues;
|
|
66500
66416
|
if (diff > 0) {
|
|
66501
66417
|
drawingInfo.startY += diff;
|
|
@@ -66503,33 +66419,39 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66503
66419
|
}
|
|
66504
66420
|
}
|
|
66505
66421
|
// check if rest shifts bar up or down
|
|
66506
|
-
|
|
66422
|
+
let barSpacing = 0;
|
|
66423
|
+
if (h.restBeats.length > 0) {
|
|
66424
|
+
// space needed for the bars, rests need to be below them
|
|
66507
66425
|
const scaleMod = h.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
66508
|
-
|
|
66509
|
-
|
|
66510
|
-
|
|
66511
|
-
|
|
66512
|
-
|
|
66513
|
-
|
|
66514
|
-
|
|
66515
|
-
drawingInfo.
|
|
66516
|
-
|
|
66426
|
+
barSpacing = barCount * (this.smuflMetrics.beamSpacing + this.smuflMetrics.beamThickness) * scaleMod;
|
|
66427
|
+
}
|
|
66428
|
+
for (const b of h.restBeats) {
|
|
66429
|
+
// rest beats which are "under" the beam
|
|
66430
|
+
if (b.isRest && b.index < h.beats[h.beats.length - 1].index) {
|
|
66431
|
+
if (direction === BeamDirection.Up) {
|
|
66432
|
+
const yNeededForRest = this.getBeatContainer(b).getBoundingBoxTop() - barSpacing;
|
|
66433
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
|
|
66434
|
+
const diff = yGivenByCurrentValues - yNeededForRest;
|
|
66435
|
+
if (diff > 0) {
|
|
66436
|
+
drawingInfo.startY -= diff;
|
|
66437
|
+
drawingInfo.endY -= diff;
|
|
66438
|
+
}
|
|
66517
66439
|
}
|
|
66518
|
-
|
|
66519
|
-
|
|
66520
|
-
|
|
66521
|
-
|
|
66522
|
-
|
|
66523
|
-
|
|
66524
|
-
|
|
66525
|
-
|
|
66440
|
+
else if (direction === BeamDirection.Down) {
|
|
66441
|
+
const yNeededForRest = this.getBeatContainer(b).getBoundingBoxBottom() + barSpacing;
|
|
66442
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
|
|
66443
|
+
const diff = yNeededForRest - yGivenByCurrentValues;
|
|
66444
|
+
if (diff > 0) {
|
|
66445
|
+
drawingInfo.startY += diff;
|
|
66446
|
+
drawingInfo.endY += diff;
|
|
66447
|
+
}
|
|
66526
66448
|
}
|
|
66527
66449
|
}
|
|
66528
66450
|
}
|
|
66529
66451
|
// check if slash shifts bar up or down
|
|
66530
66452
|
if (h.slashBeats.length > 0) {
|
|
66531
66453
|
for (const b of h.slashBeats) {
|
|
66532
|
-
const yGivenByCurrentValues = drawingInfo.calcY(
|
|
66454
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
|
|
66533
66455
|
const yNeededForSlash = h.direction === BeamDirection.Up
|
|
66534
66456
|
? this.getFlagTopY(b, h.direction)
|
|
66535
66457
|
: this.getFlagBottomY(b, h.direction);
|
|
@@ -66541,31 +66463,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66541
66463
|
}
|
|
66542
66464
|
}
|
|
66543
66465
|
}
|
|
66544
|
-
// we can only draw up to 2 beams towards the noteheads, then we have to grow to the other side
|
|
66545
|
-
// here we shift accordingly
|
|
66546
|
-
if (barCount > 2 && !isRest) {
|
|
66547
|
-
const beamSpacing = this.smuflMetrics.beamSpacing * scale;
|
|
66548
|
-
const beamThickness = this.smuflMetrics.beamThickness * scale;
|
|
66549
|
-
const totalBarsHeight = barCount * beamThickness + (barCount - 1) * beamSpacing;
|
|
66550
|
-
if (direction === BeamDirection.Up) {
|
|
66551
|
-
const bottomBarY = drawingInfo.startY + 2 * beamThickness + beamSpacing;
|
|
66552
|
-
const barTopY = bottomBarY - totalBarsHeight;
|
|
66553
|
-
const diff = drawingInfo.startY - barTopY;
|
|
66554
|
-
if (diff > 0) {
|
|
66555
|
-
drawingInfo.startY -= diff;
|
|
66556
|
-
drawingInfo.endY -= diff;
|
|
66557
|
-
}
|
|
66558
|
-
}
|
|
66559
|
-
else {
|
|
66560
|
-
const topBarY = drawingInfo.startY - 2 * beamThickness + beamSpacing;
|
|
66561
|
-
const barBottomY = topBarY + totalBarsHeight;
|
|
66562
|
-
const diff = barBottomY - drawingInfo.startY;
|
|
66563
|
-
if (diff > 0) {
|
|
66564
|
-
drawingInfo.startY += diff;
|
|
66565
|
-
drawingInfo.endY += diff;
|
|
66566
|
-
}
|
|
66567
|
-
}
|
|
66568
|
-
}
|
|
66569
66466
|
}
|
|
66570
66467
|
getMinLineOfBeat(_beat) {
|
|
66571
66468
|
return 0;
|
|
@@ -67086,20 +66983,6 @@ class NumberedBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
67086
66983
|
}
|
|
67087
66984
|
return 0;
|
|
67088
66985
|
}
|
|
67089
|
-
updateBeamingHelper() {
|
|
67090
|
-
if (this.beamingHelper) {
|
|
67091
|
-
let g = null;
|
|
67092
|
-
if (this.noteHeads) {
|
|
67093
|
-
g = this.noteHeads;
|
|
67094
|
-
}
|
|
67095
|
-
else if (this.deadSlapped) {
|
|
67096
|
-
g = this.deadSlapped;
|
|
67097
|
-
}
|
|
67098
|
-
if (g) {
|
|
67099
|
-
this.beamingHelper.registerBeatLineX('numbered', this.container.beat, this.container.x + this.x + g.x, this.container.x + this.x + g.x + g.width);
|
|
67100
|
-
}
|
|
67101
|
-
}
|
|
67102
|
-
}
|
|
67103
66986
|
static majorKeySignatureOneValues = [
|
|
67104
66987
|
// Flats
|
|
67105
66988
|
59, 66, 61, 68, 63, 58, 65,
|
|
@@ -67215,14 +67098,16 @@ class NumberedBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
67215
67098
|
}
|
|
67216
67099
|
super.doLayout();
|
|
67217
67100
|
if (this.container.beat.isEmpty) {
|
|
67218
|
-
this.
|
|
67101
|
+
this.onTimeX = this.width / 2;
|
|
67219
67102
|
}
|
|
67220
67103
|
else if (this.noteHeads) {
|
|
67221
|
-
this.
|
|
67104
|
+
this.onTimeX = this.noteHeads.x + this.noteHeads.width / 2;
|
|
67222
67105
|
}
|
|
67223
67106
|
else if (this.deadSlapped) {
|
|
67224
|
-
this.
|
|
67107
|
+
this.onTimeX = this.deadSlapped.x + this.deadSlapped.width / 2;
|
|
67225
67108
|
}
|
|
67109
|
+
this.middleX = this.onTimeX;
|
|
67110
|
+
this.stemX = this.middleX;
|
|
67226
67111
|
}
|
|
67227
67112
|
}
|
|
67228
67113
|
|
|
@@ -67635,7 +67520,7 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67635
67520
|
const barSize = this.smuflMetrics.numberedBarRendererBarSize;
|
|
67636
67521
|
const barCount = ModelUtils.getIndex(beat.duration) - 2;
|
|
67637
67522
|
const barStart = cy + this.y;
|
|
67638
|
-
const beatLineX = this.getBeatX(beat, BeatXPosition.PreNotes)
|
|
67523
|
+
const beatLineX = this.getBeatX(beat, BeatXPosition.PreNotes);
|
|
67639
67524
|
const beamY = this.calculateBeamY(h, beatLineX);
|
|
67640
67525
|
for (let barIndex = 0; barIndex < barCount; barIndex++) {
|
|
67641
67526
|
let barStartX = 0;
|
|
@@ -67644,11 +67529,11 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67644
67529
|
const barY = barStart + barIndex * barSpacing;
|
|
67645
67530
|
if (i === h.beats.length - 1) {
|
|
67646
67531
|
barStartX = beatLineX;
|
|
67647
|
-
barEndX = this.getBeatX(beat, BeatXPosition.PostNotes)
|
|
67532
|
+
barEndX = this.getBeatX(beat, BeatXPosition.PostNotes);
|
|
67648
67533
|
}
|
|
67649
67534
|
else {
|
|
67650
67535
|
barStartX = beatLineX;
|
|
67651
|
-
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.PreNotes)
|
|
67536
|
+
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.PreNotes);
|
|
67652
67537
|
}
|
|
67653
67538
|
barStartY = barY + beamY;
|
|
67654
67539
|
canvas.fillRect(cx + this.x + barStartX, barStartY, barEndX - barStartX, barSize);
|
|
@@ -67666,7 +67551,7 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67666
67551
|
dotsY = barStart + beamY + barCount * (barSpacing + barSize);
|
|
67667
67552
|
dotsOffset = dotSpacing;
|
|
67668
67553
|
}
|
|
67669
|
-
const dotX = this.getBeatX(beat, BeatXPosition.MiddleNotes)
|
|
67554
|
+
const dotX = this.getBeatX(beat, BeatXPosition.MiddleNotes);
|
|
67670
67555
|
dotCount = Math.abs(dotCount);
|
|
67671
67556
|
for (let d = 0; d < dotCount; d++) {
|
|
67672
67557
|
CanvasHelper.fillMusicFontSymbolSafe(canvas, cx + this.x + dotX, dotsY, 1, MusicFontSymbol.AugmentationDot, true);
|
|
@@ -67715,7 +67600,7 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67715
67600
|
return this.getLineY(0) - noteHeadHeight / 2;
|
|
67716
67601
|
}
|
|
67717
67602
|
createPreBeatGlyphs() {
|
|
67718
|
-
this.
|
|
67603
|
+
this.wasFirstOfStaff = this.isFirstOfStaff;
|
|
67719
67604
|
if (this.index === 0 || (this.bar.masterBar.isRepeatStart && this._isOnlyNumbered)) {
|
|
67720
67605
|
this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
|
|
67721
67606
|
}
|
|
@@ -67771,6 +67656,11 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67771
67656
|
}
|
|
67772
67657
|
paintBeamingStem(_beat, _cy, _x, _topY, _bottomY, _canvas) {
|
|
67773
67658
|
}
|
|
67659
|
+
paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
|
|
67660
|
+
if (h.voice?.index === 0) {
|
|
67661
|
+
super.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
|
|
67662
|
+
}
|
|
67663
|
+
}
|
|
67774
67664
|
}
|
|
67775
67665
|
|
|
67776
67666
|
/**
|
|
@@ -68088,6 +67978,7 @@ class ScoreNoteChordGlyphBase extends Glyph {
|
|
|
68088
67978
|
upLineX = 0;
|
|
68089
67979
|
downLineX = 0;
|
|
68090
67980
|
noteStartX = 0;
|
|
67981
|
+
onTimeX = 0;
|
|
68091
67982
|
constructor() {
|
|
68092
67983
|
super(0, 0);
|
|
68093
67984
|
}
|
|
@@ -68174,6 +68065,8 @@ class ScoreNoteChordGlyphBase extends Glyph {
|
|
|
68174
68065
|
// align all notes so that they align with the stem positions
|
|
68175
68066
|
const stemPosition = anyDisplaced || direction === BeamDirection.Up ? stemUpX : stemDownX;
|
|
68176
68067
|
let w = 0;
|
|
68068
|
+
let displacedWidth = 0;
|
|
68069
|
+
let nonDisplacedWidth = 0;
|
|
68177
68070
|
for (let i = 0, j = this._infos.length; i < j; i++) {
|
|
68178
68071
|
const g = this._infos[i].glyph;
|
|
68179
68072
|
const alignDisplaced = displaced.get(i);
|
|
@@ -68189,7 +68082,14 @@ class ScoreNoteChordGlyphBase extends Glyph {
|
|
|
68189
68082
|
}
|
|
68190
68083
|
}
|
|
68191
68084
|
g.x += this.noteStartX;
|
|
68192
|
-
|
|
68085
|
+
const gw = g.x + g.width;
|
|
68086
|
+
w = Math.max(w, gw);
|
|
68087
|
+
if (alignDisplaced) {
|
|
68088
|
+
displacedWidth = Math.max(displacedWidth, gw);
|
|
68089
|
+
}
|
|
68090
|
+
else {
|
|
68091
|
+
nonDisplacedWidth = Math.max(nonDisplacedWidth, gw);
|
|
68092
|
+
}
|
|
68193
68093
|
// after size calculation, re-align glyph to stem if needed
|
|
68194
68094
|
if (g instanceof NoteHeadGlyph && g.centerOnStem) {
|
|
68195
68095
|
g.x = stemPosition;
|
|
@@ -68203,6 +68103,23 @@ class ScoreNoteChordGlyphBase extends Glyph {
|
|
|
68203
68103
|
this.upLineX = stemUpX;
|
|
68204
68104
|
this.downLineX = stemDownX;
|
|
68205
68105
|
}
|
|
68106
|
+
// the center of score notes, (used for aligning the beat to the right on-time position)
|
|
68107
|
+
// is always the center of the "correct note" position.
|
|
68108
|
+
// * If the stem is upwards, the center is the middle of the left hand side note head
|
|
68109
|
+
// * If the stem is downards, the center is the middle of the right-hand-side note head
|
|
68110
|
+
if (anyDisplaced) {
|
|
68111
|
+
if (direction === BeamDirection.Up) {
|
|
68112
|
+
this.onTimeX = nonDisplacedWidth / 2;
|
|
68113
|
+
}
|
|
68114
|
+
else {
|
|
68115
|
+
const displacedRawWith = displacedWidth - stemPosition;
|
|
68116
|
+
this.onTimeX = stemPosition + (displacedRawWith / 2);
|
|
68117
|
+
}
|
|
68118
|
+
}
|
|
68119
|
+
else {
|
|
68120
|
+
// for no displaced notes it is simply the center
|
|
68121
|
+
this.onTimeX = w / 2;
|
|
68122
|
+
}
|
|
68206
68123
|
this.width = w;
|
|
68207
68124
|
}
|
|
68208
68125
|
paint(cx, cy, canvas) {
|
|
@@ -68280,9 +68197,8 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68280
68197
|
aboveBeatEffects = new Map();
|
|
68281
68198
|
belowBeatEffects = new Map();
|
|
68282
68199
|
beat;
|
|
68283
|
-
beamingHelper;
|
|
68284
68200
|
get direction() {
|
|
68285
|
-
return this.
|
|
68201
|
+
return this.renderer.getBeatDirection(this.beat);
|
|
68286
68202
|
}
|
|
68287
68203
|
get scale() {
|
|
68288
68204
|
return this.beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
@@ -68324,7 +68240,7 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68324
68240
|
: 0) * scale;
|
|
68325
68241
|
// stem size according to duration
|
|
68326
68242
|
pos -= this.renderer.smuflMetrics.standardStemLength * scale;
|
|
68327
|
-
const topCenterY = this.renderer.centerStaffStemY(this.
|
|
68243
|
+
const topCenterY = this.renderer.centerStaffStemY(this.direction);
|
|
68328
68244
|
return Math.min(topCenterY, pos);
|
|
68329
68245
|
case NoteYPosition.Top:
|
|
68330
68246
|
pos -= n.height / 2;
|
|
@@ -68341,7 +68257,7 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68341
68257
|
: -this.renderer.smuflMetrics.glyphHeights.get(n.symbol) / 2) * scale;
|
|
68342
68258
|
// stem size according to duration
|
|
68343
68259
|
pos += this.renderer.smuflMetrics.standardStemLength * scale;
|
|
68344
|
-
const bottomCenterY = this.renderer.centerStaffStemY(this.
|
|
68260
|
+
const bottomCenterY = this.renderer.centerStaffStemY(this.direction);
|
|
68345
68261
|
return Math.max(bottomCenterY, pos);
|
|
68346
68262
|
case NoteYPosition.StemUp:
|
|
68347
68263
|
pos -=
|
|
@@ -68366,11 +68282,6 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68366
68282
|
addEffectNoteGlyph(noteGlyph, noteLine) {
|
|
68367
68283
|
super.add(noteGlyph, noteLine);
|
|
68368
68284
|
}
|
|
68369
|
-
updateBeamingHelper(cx) {
|
|
68370
|
-
if (this.beamingHelper) {
|
|
68371
|
-
this.beamingHelper.registerBeatLineX('score', this.beat, cx + this.x + this.upLineX, cx + this.x + this.downLineX);
|
|
68372
|
-
}
|
|
68373
|
-
}
|
|
68374
68285
|
doLayout() {
|
|
68375
68286
|
super.doLayout();
|
|
68376
68287
|
const scoreRenderer = this.renderer;
|
|
@@ -68379,6 +68290,7 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68379
68290
|
this._deadSlapped.renderer = this.renderer;
|
|
68380
68291
|
this._deadSlapped.doLayout();
|
|
68381
68292
|
this.width = this._deadSlapped.width;
|
|
68293
|
+
this.onTimeX = this.width / 2;
|
|
68382
68294
|
}
|
|
68383
68295
|
let aboveBeatEffectsY = 0;
|
|
68384
68296
|
let belowBeatEffectsY = 0;
|
|
@@ -68497,7 +68409,6 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68497
68409
|
* @internal
|
|
68498
68410
|
*/
|
|
68499
68411
|
class ScoreRestGlyph extends MusicFontGlyph {
|
|
68500
|
-
beamingHelper;
|
|
68501
68412
|
constructor(x, y, duration) {
|
|
68502
68413
|
super(x, y, 1, ScoreRestGlyph.getSymbol(duration));
|
|
68503
68414
|
}
|
|
@@ -68529,11 +68440,6 @@ class ScoreRestGlyph extends MusicFontGlyph {
|
|
|
68529
68440
|
return MusicFontSymbol.None;
|
|
68530
68441
|
}
|
|
68531
68442
|
}
|
|
68532
|
-
updateBeamingHelper(cx) {
|
|
68533
|
-
if (this.beamingHelper) {
|
|
68534
|
-
this.beamingHelper.registerBeatLineX('score', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
68535
|
-
}
|
|
68536
|
-
}
|
|
68537
68443
|
paint(cx, cy, canvas) {
|
|
68538
68444
|
this.internalPaint(cx, cy, canvas, BeatSubElement.StandardNotationRests);
|
|
68539
68445
|
}
|
|
@@ -69025,10 +68931,11 @@ class StringNumberContainerGlyph extends EffectGlyph {
|
|
|
69025
68931
|
*/
|
|
69026
68932
|
class SlashNoteHeadGlyph extends MusicFontGlyph {
|
|
69027
68933
|
beatEffects = new Map();
|
|
69028
|
-
beamingHelper;
|
|
69029
68934
|
noteHeadElement = NoteSubElement.SlashNoteHead;
|
|
69030
68935
|
effectElement = BeatSubElement.SlashEffects;
|
|
69031
68936
|
_symbol;
|
|
68937
|
+
upLineX = 0;
|
|
68938
|
+
downLineX = 0;
|
|
69032
68939
|
constructor(x, y, duration, isGrace, beat) {
|
|
69033
68940
|
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, SlashNoteHeadGlyph.getSymbol(duration));
|
|
69034
68941
|
this._symbol = SlashNoteHeadGlyph.getSymbol(duration);
|
|
@@ -69079,6 +68986,15 @@ class SlashNoteHeadGlyph extends MusicFontGlyph {
|
|
|
69079
68986
|
if (!Number.isNaN(minEffectY)) {
|
|
69080
68987
|
this.renderer.registerBeatEffectOverflows(minEffectY, maxEffectY);
|
|
69081
68988
|
}
|
|
68989
|
+
const symbol = this._symbol;
|
|
68990
|
+
const stemInfoUp = this.renderer.smuflMetrics.stemUp.has(symbol)
|
|
68991
|
+
? this.renderer.smuflMetrics.stemUp.get(symbol).x
|
|
68992
|
+
: 0;
|
|
68993
|
+
this.upLineX = stemInfoUp;
|
|
68994
|
+
const stemInfoDown = this.renderer.smuflMetrics.stemDown.has(symbol)
|
|
68995
|
+
? this.renderer.smuflMetrics.stemDown.get(symbol).x
|
|
68996
|
+
: 0;
|
|
68997
|
+
this.downLineX = stemInfoDown;
|
|
69082
68998
|
}
|
|
69083
68999
|
static getSymbol(duration) {
|
|
69084
69000
|
switch (duration) {
|
|
@@ -69092,25 +69008,13 @@ class SlashNoteHeadGlyph extends MusicFontGlyph {
|
|
|
69092
69008
|
return MusicFontSymbol.NoteheadSlashHorizontalEnds;
|
|
69093
69009
|
}
|
|
69094
69010
|
}
|
|
69095
|
-
updateBeamingHelper(cx) {
|
|
69096
|
-
if (this.beamingHelper) {
|
|
69097
|
-
const symbol = this._symbol;
|
|
69098
|
-
const stemInfoUp = this.renderer.smuflMetrics.stemUp.has(symbol)
|
|
69099
|
-
? this.renderer.smuflMetrics.stemUp.get(symbol).x
|
|
69100
|
-
: 0;
|
|
69101
|
-
const stemInfoDown = this.renderer.smuflMetrics.stemDown.has(symbol)
|
|
69102
|
-
? this.renderer.smuflMetrics.stemDown.get(symbol).x
|
|
69103
|
-
: 0;
|
|
69104
|
-
this.beamingHelper.registerBeatLineX('slash', this.beat, cx + this.x + stemInfoUp, cx + this.x + stemInfoDown);
|
|
69105
|
-
}
|
|
69106
|
-
}
|
|
69107
69011
|
}
|
|
69108
69012
|
|
|
69109
69013
|
/**
|
|
69110
69014
|
* @internal
|
|
69111
69015
|
*/
|
|
69112
69016
|
class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
69113
|
-
_collisionOffset =
|
|
69017
|
+
_collisionOffset = Number.NaN;
|
|
69114
69018
|
_skipPaint = false;
|
|
69115
69019
|
_whammy;
|
|
69116
69020
|
noteHeads = null;
|
|
@@ -69161,22 +69065,19 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69161
69065
|
getNoteY(note, requestedPosition) {
|
|
69162
69066
|
return this.noteHeads ? this.noteHeads.getNoteY(note, requestedPosition) : 0;
|
|
69163
69067
|
}
|
|
69164
|
-
|
|
69165
|
-
if (this.
|
|
69166
|
-
|
|
69068
|
+
applyRestCollisionOffset() {
|
|
69069
|
+
if (!this.restGlyph) {
|
|
69070
|
+
return;
|
|
69167
69071
|
}
|
|
69168
|
-
|
|
69169
|
-
this.
|
|
69170
|
-
|
|
69171
|
-
|
|
69172
|
-
|
|
69173
|
-
|
|
69174
|
-
|
|
69175
|
-
|
|
69176
|
-
|
|
69177
|
-
this.container.beat.id) {
|
|
69178
|
-
this._skipPaint = true;
|
|
69179
|
-
}
|
|
69072
|
+
if (this.renderer.bar.isMultiVoice && Number.isNaN(this._collisionOffset)) {
|
|
69073
|
+
this._collisionOffset = this.renderer.collisionHelper.applyRestCollisionOffset(this.container.beat, this.restGlyph.y, this.renderer.getScoreHeight(1));
|
|
69074
|
+
this.y += this._collisionOffset;
|
|
69075
|
+
const existingRests = this.renderer.collisionHelper.restDurationsByDisplayTime;
|
|
69076
|
+
if (existingRests.has(this.container.beat.playbackStart) &&
|
|
69077
|
+
existingRests.get(this.container.beat.playbackStart).has(this.container.beat.playbackDuration) &&
|
|
69078
|
+
existingRests.get(this.container.beat.playbackStart).get(this.container.beat.playbackDuration) !==
|
|
69079
|
+
this.container.beat.id) {
|
|
69080
|
+
this._skipPaint = true;
|
|
69180
69081
|
}
|
|
69181
69082
|
}
|
|
69182
69083
|
}
|
|
@@ -69196,7 +69097,6 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69196
69097
|
const noteHeads = new ScoreNoteChordGlyph();
|
|
69197
69098
|
this.noteHeads = noteHeads;
|
|
69198
69099
|
noteHeads.beat = this.container.beat;
|
|
69199
|
-
noteHeads.beamingHelper = this.beamingHelper;
|
|
69200
69100
|
const ghost = new GhostNoteContainerGlyph(false);
|
|
69201
69101
|
ghost.renderer = this.renderer;
|
|
69202
69102
|
for (const note of this.container.beat.notes) {
|
|
@@ -69246,22 +69146,18 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69246
69146
|
const restGlyph = new ScoreRestGlyph(0, sr.getScoreY(steps), this.container.beat.duration);
|
|
69247
69147
|
this.restGlyph = restGlyph;
|
|
69248
69148
|
restGlyph.beat = this.container.beat;
|
|
69249
|
-
restGlyph.beamingHelper = this.beamingHelper;
|
|
69250
69149
|
this.addNormal(restGlyph);
|
|
69251
69150
|
if (this.renderer.bar.isMultiVoice) {
|
|
69252
69151
|
if (this.container.beat.voice.index === 0) {
|
|
69253
69152
|
const restSizes = BeamingHelper.computeLineHeightsForRest(this.container.beat.duration);
|
|
69254
69153
|
const restTop = restGlyph.y - sr.getScoreHeight(restSizes[0]);
|
|
69255
69154
|
const restBottom = restGlyph.y + sr.getScoreHeight(restSizes[1]);
|
|
69256
|
-
this.renderer.
|
|
69155
|
+
this.renderer.collisionHelper.reserveBeatSlot(this.container.beat, restTop, restBottom);
|
|
69257
69156
|
}
|
|
69258
69157
|
else {
|
|
69259
|
-
this.renderer.
|
|
69158
|
+
this.renderer.collisionHelper.registerRest(this.container.beat);
|
|
69260
69159
|
}
|
|
69261
69160
|
}
|
|
69262
|
-
if (this.beamingHelper) {
|
|
69263
|
-
this.beamingHelper.applyRest(this.container.beat, steps);
|
|
69264
|
-
}
|
|
69265
69161
|
//
|
|
69266
69162
|
// Note dots
|
|
69267
69163
|
//
|
|
@@ -69276,14 +69172,24 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69276
69172
|
}
|
|
69277
69173
|
}
|
|
69278
69174
|
super.doLayout();
|
|
69175
|
+
this.applyRestCollisionOffset();
|
|
69279
69176
|
if (this.container.beat.isEmpty) {
|
|
69280
|
-
this.
|
|
69177
|
+
this.onTimeX = this.width / 2;
|
|
69178
|
+
this.middleX = this.onTimeX;
|
|
69179
|
+
this.stemX = this.middleX;
|
|
69281
69180
|
}
|
|
69282
69181
|
else if (this.restGlyph) {
|
|
69283
|
-
this.
|
|
69182
|
+
this.onTimeX = this.restGlyph.x + this.restGlyph.width / 2;
|
|
69183
|
+
this.middleX = this.onTimeX;
|
|
69184
|
+
this.stemX = this.middleX;
|
|
69284
69185
|
}
|
|
69285
69186
|
else if (this.noteHeads) {
|
|
69286
|
-
this.
|
|
69187
|
+
this.onTimeX = this.noteHeads.x + this.noteHeads.onTimeX;
|
|
69188
|
+
this.middleX = this.noteHeads.x + this.noteHeads.width / 2;
|
|
69189
|
+
const direction = this.renderer.getBeatDirection(this.container.beat);
|
|
69190
|
+
this.stemX =
|
|
69191
|
+
this.noteHeads.x +
|
|
69192
|
+
(direction === BeamDirection.Up ? this.noteHeads.upLineX : this.noteHeads.downLineX);
|
|
69287
69193
|
}
|
|
69288
69194
|
}
|
|
69289
69195
|
_createBeatDot(line, group) {
|
|
@@ -69355,7 +69261,7 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69355
69261
|
}
|
|
69356
69262
|
const belowBeatEffects = this.noteHeads.belowBeatEffects;
|
|
69357
69263
|
const aboveBeatEffects = this.noteHeads.aboveBeatEffects;
|
|
69358
|
-
const outsideBeatEffects = this.
|
|
69264
|
+
const outsideBeatEffects = this.renderer.getBeatDirection(this.container.beat) === BeamDirection.Up
|
|
69359
69265
|
? this.noteHeads.belowBeatEffects
|
|
69360
69266
|
: this.noteHeads.aboveBeatEffects;
|
|
69361
69267
|
if (n.isStaccato && !belowBeatEffects.has('Staccato')) {
|
|
@@ -69791,7 +69697,7 @@ class ScoreBendGlyph extends ScoreHelperNotesBaseGlyph {
|
|
|
69791
69697
|
// if we have a line break we draw only a line until the end
|
|
69792
69698
|
if (!endNoteRenderer || endNoteRenderer.staff !== startNoteRenderer.staff) {
|
|
69793
69699
|
const endX = cx + startNoteRenderer.x + startNoteRenderer.width;
|
|
69794
|
-
const noteValueToDraw = note.tieDestination.
|
|
69700
|
+
const noteValueToDraw = note.tieDestination.displayValue;
|
|
69795
69701
|
startNoteRenderer.accidentalHelper.applyAccidentalForValue(note.beat, noteValueToDraw, false, true);
|
|
69796
69702
|
const endY = cy +
|
|
69797
69703
|
startNoteRenderer.y +
|
|
@@ -70327,6 +70233,22 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70327
70233
|
doLayout() {
|
|
70328
70234
|
this._effectSlur = null;
|
|
70329
70235
|
this._effectEndSlur = null;
|
|
70236
|
+
// make space for flag
|
|
70237
|
+
const sr = this.renderer;
|
|
70238
|
+
const beat = this.beat;
|
|
70239
|
+
const isGrace = beat.graceType !== GraceType.None;
|
|
70240
|
+
if (sr.hasFlag(beat)) {
|
|
70241
|
+
const direction = this.renderer.getBeatDirection(beat);
|
|
70242
|
+
const scale = isGrace ? NoteHeadGlyph.GraceScale : 1;
|
|
70243
|
+
const symbol = FlagGlyph.getSymbol(beat.duration, direction, isGrace);
|
|
70244
|
+
const flagWidth = this.renderer.smuflMetrics.glyphWidths.get(symbol) * scale;
|
|
70245
|
+
this._flagStretch = flagWidth;
|
|
70246
|
+
}
|
|
70247
|
+
else if (isGrace) {
|
|
70248
|
+
// always use flag size as spacing on grace notes
|
|
70249
|
+
const graceSpacing = this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
70250
|
+
this._flagStretch = graceSpacing;
|
|
70251
|
+
}
|
|
70330
70252
|
super.doLayout();
|
|
70331
70253
|
if (this._bend) {
|
|
70332
70254
|
this._bend.renderer = this.renderer;
|
|
@@ -70336,7 +70258,7 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70336
70258
|
}
|
|
70337
70259
|
getBoundingBoxTop() {
|
|
70338
70260
|
if (this._bend !== null) {
|
|
70339
|
-
return
|
|
70261
|
+
return ModelUtils.minBoundingBox(this._bend.getBoundingBoxTop(), super.getBoundingBoxTop());
|
|
70340
70262
|
}
|
|
70341
70263
|
else {
|
|
70342
70264
|
return super.getBoundingBoxTop();
|
|
@@ -70344,7 +70266,7 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70344
70266
|
}
|
|
70345
70267
|
getBoundingBoxBottom() {
|
|
70346
70268
|
if (this._bend !== null) {
|
|
70347
|
-
return
|
|
70269
|
+
return ModelUtils.maxBoundingBox(this._bend.getBoundingBoxBottom(), super.getBoundingBoxTop());
|
|
70348
70270
|
}
|
|
70349
70271
|
else {
|
|
70350
70272
|
return super.getBoundingBoxBottom();
|
|
@@ -70392,7 +70314,7 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70392
70314
|
}
|
|
70393
70315
|
// end effect slur on last beat
|
|
70394
70316
|
if (!this._effectEndSlur && n.beat.isEffectSlurDestination && n.beat.effectSlurOrigin) {
|
|
70395
|
-
const direction = this.
|
|
70317
|
+
const direction = this.renderer.getBeatDirection(n.beat);
|
|
70396
70318
|
const startNote = direction === BeamDirection.Up ? n.beat.effectSlurOrigin.minNote : n.beat.effectSlurOrigin.maxNote;
|
|
70397
70319
|
const endNote = direction === BeamDirection.Up ? n.beat.minNote : n.beat.maxNote;
|
|
70398
70320
|
const effectEndSlur = new ScoreSlurGlyph(`score.slur.effect.${startNote.beat.id}`, startNote, endNote, true);
|
|
@@ -70431,6 +70353,15 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70431
70353
|
}
|
|
70432
70354
|
}
|
|
70433
70355
|
}
|
|
70356
|
+
_flagStretch = 0;
|
|
70357
|
+
get postBeatStretch() {
|
|
70358
|
+
return super.postBeatStretch + this._flagStretch;
|
|
70359
|
+
}
|
|
70360
|
+
updateWidth() {
|
|
70361
|
+
super.updateWidth();
|
|
70362
|
+
this.width += this._flagStretch;
|
|
70363
|
+
this.minWidth += this._flagStretch;
|
|
70364
|
+
}
|
|
70434
70365
|
}
|
|
70435
70366
|
|
|
70436
70367
|
/**
|
|
@@ -70465,7 +70396,7 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70465
70396
|
return this.smuflMetrics.oneStaffSpace;
|
|
70466
70397
|
}
|
|
70467
70398
|
get heightLineCount() {
|
|
70468
|
-
return 5;
|
|
70399
|
+
return Math.max(5, this.bar.staff.standardNotationLineCount);
|
|
70469
70400
|
}
|
|
70470
70401
|
get drawnLineCount() {
|
|
70471
70402
|
return this.bar.staff.standardNotationLineCount;
|
|
@@ -70522,7 +70453,9 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70522
70453
|
slashY -= this.smuflMetrics.stemUp.has(symbol)
|
|
70523
70454
|
? this.smuflMetrics.stemUp.get(symbol).bottomY * scale
|
|
70524
70455
|
: 0;
|
|
70525
|
-
|
|
70456
|
+
if (!beat.isRest) {
|
|
70457
|
+
slashY -= this.smuflMetrics.standardStemLength + scale;
|
|
70458
|
+
}
|
|
70526
70459
|
}
|
|
70527
70460
|
return slashY;
|
|
70528
70461
|
}
|
|
@@ -70531,7 +70464,7 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70531
70464
|
return this.getBeatContainer(beat).onNotes.getNoteY(minNote, direction === BeamDirection.Up ? NoteYPosition.TopWithStem : NoteYPosition.StemDown);
|
|
70532
70465
|
}
|
|
70533
70466
|
let y = this.getScoreY(this.accidentalHelper.getMinSteps(beat));
|
|
70534
|
-
if (direction === BeamDirection.Up) {
|
|
70467
|
+
if (direction === BeamDirection.Up && !beat.isRest) {
|
|
70535
70468
|
const scale = beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
70536
70469
|
y -= this.smuflMetrics.standardStemLength * scale;
|
|
70537
70470
|
}
|
|
@@ -70569,14 +70502,14 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70569
70502
|
getBeamDirection(helper) {
|
|
70570
70503
|
return helper.direction;
|
|
70571
70504
|
}
|
|
70572
|
-
centerStaffStemY(
|
|
70505
|
+
centerStaffStemY(direction) {
|
|
70573
70506
|
const isStandardFive = this.bar.staff.standardNotationLineCount === Staff.DefaultStandardNotationLineCount;
|
|
70574
70507
|
if (isStandardFive) {
|
|
70575
70508
|
// center on the middle line for a standard 5-line staff
|
|
70576
70509
|
return this.getScoreY(this.bar.staff.standardNotationLineCount - 1);
|
|
70577
70510
|
}
|
|
70578
70511
|
// for other staff line counts, we align the stem either on the top or bottom line
|
|
70579
|
-
if (
|
|
70512
|
+
if (direction === BeamDirection.Up) {
|
|
70580
70513
|
return this.getScoreY(this.bar.staff.standardNotationLineCount * 2);
|
|
70581
70514
|
}
|
|
70582
70515
|
return this.getScoreY(0);
|
|
@@ -70678,7 +70611,7 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70678
70611
|
createLinePreBeatGlyphs() {
|
|
70679
70612
|
// Clef
|
|
70680
70613
|
let hasClef = false;
|
|
70681
|
-
if (this.
|
|
70614
|
+
if (this.isFirstOfStaff ||
|
|
70682
70615
|
this.bar.clef !== this.bar.previousBar.clef ||
|
|
70683
70616
|
this.bar.clefOttava !== this.bar.previousBar.clefOttava) {
|
|
70684
70617
|
// SMUFL: Clefs should be positioned such that the pitch the clef refers to is on the baseline
|
|
@@ -70883,6 +70816,25 @@ class SlashTieGlyph extends NoteTieGlyph {
|
|
|
70883
70816
|
*/
|
|
70884
70817
|
class SlashBeatContainerGlyph extends BeatContainerGlyph {
|
|
70885
70818
|
_tiedNoteTie = null;
|
|
70819
|
+
doLayout() {
|
|
70820
|
+
// make space for flag
|
|
70821
|
+
const sr = this.renderer;
|
|
70822
|
+
const beat = this.beat;
|
|
70823
|
+
const isGrace = beat.graceType !== GraceType.None;
|
|
70824
|
+
if (sr.hasFlag(beat)) {
|
|
70825
|
+
const direction = this.renderer.getBeatDirection(beat);
|
|
70826
|
+
const scale = isGrace ? NoteHeadGlyph.GraceScale : 1;
|
|
70827
|
+
const symbol = FlagGlyph.getSymbol(beat.duration, direction, isGrace);
|
|
70828
|
+
const flagWidth = this.renderer.smuflMetrics.glyphWidths.get(symbol) * scale;
|
|
70829
|
+
this._flagStretch = flagWidth;
|
|
70830
|
+
}
|
|
70831
|
+
else if (isGrace) {
|
|
70832
|
+
// always use flag size as spacing on grace notes
|
|
70833
|
+
const graceSpacing = this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
70834
|
+
this._flagStretch = graceSpacing;
|
|
70835
|
+
}
|
|
70836
|
+
super.doLayout();
|
|
70837
|
+
}
|
|
70886
70838
|
createTies(n) {
|
|
70887
70839
|
// create a tie if any effect requires it
|
|
70888
70840
|
if (!n.isVisible) {
|
|
@@ -70899,17 +70851,21 @@ class SlashBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70899
70851
|
this.addTie(tie);
|
|
70900
70852
|
}
|
|
70901
70853
|
}
|
|
70854
|
+
_flagStretch = 0;
|
|
70855
|
+
get postBeatStretch() {
|
|
70856
|
+
return super.postBeatStretch + this._flagStretch;
|
|
70857
|
+
}
|
|
70858
|
+
updateWidth() {
|
|
70859
|
+
super.updateWidth();
|
|
70860
|
+
this.width += this._flagStretch;
|
|
70861
|
+
this.minWidth += this._flagStretch;
|
|
70862
|
+
}
|
|
70902
70863
|
}
|
|
70903
70864
|
|
|
70904
70865
|
/**
|
|
70905
70866
|
* @internal
|
|
70906
70867
|
*/
|
|
70907
70868
|
class SlashRestGlyph extends ScoreRestGlyph {
|
|
70908
|
-
updateBeamingHelper(cx) {
|
|
70909
|
-
if (this.beamingHelper) {
|
|
70910
|
-
this.beamingHelper.registerBeatLineX('slash', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
70911
|
-
}
|
|
70912
|
-
}
|
|
70913
70869
|
paint(cx, cy, canvas) {
|
|
70914
70870
|
super.internalPaint(cx, cy, canvas, BeatSubElement.SlashRests);
|
|
70915
70871
|
}
|
|
@@ -71005,19 +70961,6 @@ class SlashBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71005
70961
|
}
|
|
71006
70962
|
return 0;
|
|
71007
70963
|
}
|
|
71008
|
-
updateBeamingHelper() {
|
|
71009
|
-
if (this.noteHeads) {
|
|
71010
|
-
this.noteHeads.updateBeamingHelper(this.container.x + this.x);
|
|
71011
|
-
}
|
|
71012
|
-
else if (this.deadSlapped) {
|
|
71013
|
-
if (this.beamingHelper) {
|
|
71014
|
-
this.beamingHelper.registerBeatLineX('slash', this.container.beat, this.container.x + this.x + this.deadSlapped.x + this.width, this.container.x + this.x + this.deadSlapped.x);
|
|
71015
|
-
}
|
|
71016
|
-
}
|
|
71017
|
-
else if (this.restGlyph) {
|
|
71018
|
-
this.restGlyph.updateBeamingHelper(this.container.x + this.x);
|
|
71019
|
-
}
|
|
71020
|
-
}
|
|
71021
70964
|
doLayout() {
|
|
71022
70965
|
// create glyphs
|
|
71023
70966
|
const sr = this.renderer;
|
|
@@ -71035,18 +70978,13 @@ class SlashBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71035
70978
|
const noteHeadGlyph = new SlashNoteHeadGlyph(0, glyphY, this.container.beat.duration, isGrace, this.container.beat);
|
|
71036
70979
|
this.noteHeads = noteHeadGlyph;
|
|
71037
70980
|
noteHeadGlyph.beat = this.container.beat;
|
|
71038
|
-
noteHeadGlyph.beamingHelper = this.beamingHelper;
|
|
71039
70981
|
this.addNormal(noteHeadGlyph);
|
|
71040
70982
|
}
|
|
71041
70983
|
else {
|
|
71042
70984
|
const restGlyph = new SlashRestGlyph(0, glyphY, this.container.beat.duration);
|
|
71043
70985
|
this.restGlyph = restGlyph;
|
|
71044
70986
|
restGlyph.beat = this.container.beat;
|
|
71045
|
-
restGlyph.beamingHelper = this.beamingHelper;
|
|
71046
70987
|
this.addNormal(restGlyph);
|
|
71047
|
-
if (this.beamingHelper) {
|
|
71048
|
-
this.beamingHelper.applyRest(this.container.beat, 0);
|
|
71049
|
-
}
|
|
71050
70988
|
}
|
|
71051
70989
|
}
|
|
71052
70990
|
//
|
|
@@ -71059,17 +70997,25 @@ class SlashBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71059
70997
|
}
|
|
71060
70998
|
super.doLayout();
|
|
71061
70999
|
if (this.container.beat.isEmpty) {
|
|
71062
|
-
this.
|
|
71000
|
+
this.onTimeX = this.width / 2;
|
|
71001
|
+
this.stemX = this.onTimeX;
|
|
71063
71002
|
}
|
|
71064
71003
|
else if (this.restGlyph) {
|
|
71065
|
-
this.
|
|
71004
|
+
this.onTimeX = this.restGlyph.x + this.restGlyph.width / 2;
|
|
71005
|
+
this.stemX = this.onTimeX;
|
|
71066
71006
|
}
|
|
71067
71007
|
else if (this.noteHeads) {
|
|
71068
|
-
this.
|
|
71008
|
+
this.onTimeX = this.noteHeads.x + this.noteHeads.width / 2;
|
|
71009
|
+
const direction = this.renderer.getBeatDirection(this.container.beat);
|
|
71010
|
+
this.stemX =
|
|
71011
|
+
this.noteHeads.x +
|
|
71012
|
+
(direction === BeamDirection.Up ? this.noteHeads.upLineX : this.noteHeads.downLineX);
|
|
71069
71013
|
}
|
|
71070
71014
|
else if (this.deadSlapped) {
|
|
71071
|
-
this.
|
|
71015
|
+
this.onTimeX = this.deadSlapped.x + this.deadSlapped.width / 2;
|
|
71016
|
+
this.stemX = this.onTimeX;
|
|
71072
71017
|
}
|
|
71018
|
+
this.middleX = this.onTimeX;
|
|
71073
71019
|
}
|
|
71074
71020
|
}
|
|
71075
71021
|
|
|
@@ -71144,7 +71090,9 @@ class SlashBarRenderer extends LineBarRenderer {
|
|
|
71144
71090
|
const symbol = SlashNoteHeadGlyph.getSymbol(beat.duration);
|
|
71145
71091
|
const scale = beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
71146
71092
|
slashY -= this.smuflMetrics.stemUp.has(symbol) ? this.smuflMetrics.stemUp.get(symbol).bottomY * scale : 0;
|
|
71147
|
-
|
|
71093
|
+
if (!beat.isRest) {
|
|
71094
|
+
slashY -= this.smuflMetrics.standardStemLength + scale;
|
|
71095
|
+
}
|
|
71148
71096
|
return slashY;
|
|
71149
71097
|
}
|
|
71150
71098
|
getFlagBottomY(beat, _direction) {
|
|
@@ -71228,6 +71176,11 @@ class SlashBarRenderer extends LineBarRenderer {
|
|
|
71228
71176
|
_?.[Symbol.dispose]?.();
|
|
71229
71177
|
}
|
|
71230
71178
|
}
|
|
71179
|
+
paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
|
|
71180
|
+
if (h.voice?.index === 0) {
|
|
71181
|
+
super.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
|
|
71182
|
+
}
|
|
71183
|
+
}
|
|
71231
71184
|
}
|
|
71232
71185
|
|
|
71233
71186
|
/**
|
|
@@ -71684,7 +71637,6 @@ class TabNoteChordGlyph extends Glyph {
|
|
|
71684
71637
|
_deadSlapped = null;
|
|
71685
71638
|
_isGrace;
|
|
71686
71639
|
beat;
|
|
71687
|
-
beamingHelper;
|
|
71688
71640
|
maxStringNote = null;
|
|
71689
71641
|
minStringNote = null;
|
|
71690
71642
|
beatEffects = new Map();
|
|
@@ -71833,11 +71785,6 @@ class TabNoteChordGlyph extends Glyph {
|
|
|
71833
71785
|
}
|
|
71834
71786
|
}
|
|
71835
71787
|
}
|
|
71836
|
-
updateBeamingHelper(cx) {
|
|
71837
|
-
if (this.beamingHelper && this.beamingHelper.isPositionFrom('tab', this.beat)) {
|
|
71838
|
-
this.beamingHelper.registerBeatLineX('tab', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
71839
|
-
}
|
|
71840
|
-
}
|
|
71841
71788
|
}
|
|
71842
71789
|
|
|
71843
71790
|
/**
|
|
@@ -71845,7 +71792,6 @@ class TabNoteChordGlyph extends Glyph {
|
|
|
71845
71792
|
*/
|
|
71846
71793
|
class TabRestGlyph extends MusicFontGlyph {
|
|
71847
71794
|
_isVisibleRest;
|
|
71848
|
-
beamingHelper;
|
|
71849
71795
|
constructor(x, y, isVisibleRest, duration) {
|
|
71850
71796
|
super(x, y, 1, ScoreRestGlyph.getSymbol(duration));
|
|
71851
71797
|
this._isVisibleRest = isVisibleRest;
|
|
@@ -71853,11 +71799,6 @@ class TabRestGlyph extends MusicFontGlyph {
|
|
|
71853
71799
|
doLayout() {
|
|
71854
71800
|
super.doLayout();
|
|
71855
71801
|
}
|
|
71856
|
-
updateBeamingHelper(cx) {
|
|
71857
|
-
if (this.beamingHelper && this.beamingHelper.isPositionFrom('tab', this.beat)) {
|
|
71858
|
-
this.beamingHelper.registerBeatLineX('tab', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
71859
|
-
}
|
|
71860
|
-
}
|
|
71861
71802
|
paint(cx, cy, canvas) {
|
|
71862
71803
|
if (this._isVisibleRest) {
|
|
71863
71804
|
const _ = ElementStyleHelper.beat(canvas, BeatSubElement.GuitarTabRests, this.beat);
|
|
@@ -71914,7 +71855,6 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71914
71855
|
slashNoteHead.effectElement = BeatSubElement.GuitarTabEffects;
|
|
71915
71856
|
this.slash = slashNoteHead;
|
|
71916
71857
|
slashNoteHead.beat = this.container.beat;
|
|
71917
|
-
slashNoteHead.beamingHelper = this.beamingHelper;
|
|
71918
71858
|
this.addNormal(slashNoteHead);
|
|
71919
71859
|
beatEffects = slashNoteHead.beatEffects;
|
|
71920
71860
|
}
|
|
@@ -71922,7 +71862,6 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71922
71862
|
const tabNoteNumbers = new TabNoteChordGlyph(0, 0, isGrace);
|
|
71923
71863
|
this.noteNumbers = tabNoteNumbers;
|
|
71924
71864
|
tabNoteNumbers.beat = this.container.beat;
|
|
71925
|
-
tabNoteNumbers.beamingHelper = this.beamingHelper;
|
|
71926
71865
|
for (const note of this.container.beat.notes) {
|
|
71927
71866
|
if (note.isVisible) {
|
|
71928
71867
|
this._createNoteGlyph(note);
|
|
@@ -71944,9 +71883,9 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71944
71883
|
// Note dots
|
|
71945
71884
|
//
|
|
71946
71885
|
if (this.container.beat.dots > 0 && tabRenderer.rhythmMode !== TabRhythmMode.Hidden) {
|
|
71886
|
+
const y = tabRenderer.getFlagAndBarPos();
|
|
71947
71887
|
for (let i = 0; i < this.container.beat.dots; i++) {
|
|
71948
|
-
this.addEffect(new AugmentationDotGlyph(0,
|
|
71949
|
-
tabRenderer.settings.notation.rhythmHeight));
|
|
71888
|
+
this.addEffect(new AugmentationDotGlyph(0, y));
|
|
71950
71889
|
}
|
|
71951
71890
|
}
|
|
71952
71891
|
}
|
|
@@ -71956,7 +71895,6 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71956
71895
|
const restGlyph = new TabRestGlyph(0, y, tabRenderer.showRests, this.container.beat.duration);
|
|
71957
71896
|
this.restGlyph = restGlyph;
|
|
71958
71897
|
restGlyph.beat = this.container.beat;
|
|
71959
|
-
restGlyph.beamingHelper = this.beamingHelper;
|
|
71960
71898
|
this.addNormal(restGlyph);
|
|
71961
71899
|
//
|
|
71962
71900
|
// Note dots
|
|
@@ -71982,30 +71920,21 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71982
71920
|
this.width = w;
|
|
71983
71921
|
this.computedWidth = w;
|
|
71984
71922
|
if (this.container.beat.isEmpty) {
|
|
71985
|
-
this.
|
|
71923
|
+
this.onTimeX = this.width / 2;
|
|
71986
71924
|
}
|
|
71987
71925
|
else if (this.restGlyph) {
|
|
71988
|
-
this.
|
|
71926
|
+
this.onTimeX = this.restGlyph.x + this.restGlyph.width / 2;
|
|
71989
71927
|
}
|
|
71990
71928
|
else if (this.noteNumbers) {
|
|
71991
|
-
this.
|
|
71929
|
+
this.onTimeX = this.noteNumbers.x + this.noteNumbers.noteStringWidth / 2;
|
|
71992
71930
|
}
|
|
71993
71931
|
else if (this.slash) {
|
|
71994
|
-
this.
|
|
71932
|
+
this.onTimeX = this.slash.x + this.slash.width / 2;
|
|
71995
71933
|
}
|
|
71934
|
+
this.middleX = this.onTimeX;
|
|
71935
|
+
this.stemX = this.middleX;
|
|
71996
71936
|
for (const g of centeredEffectGlyphs) {
|
|
71997
|
-
g.x = this.
|
|
71998
|
-
}
|
|
71999
|
-
}
|
|
72000
|
-
updateBeamingHelper() {
|
|
72001
|
-
if (this.noteNumbers) {
|
|
72002
|
-
this.noteNumbers.updateBeamingHelper(this.container.x + this.x);
|
|
72003
|
-
}
|
|
72004
|
-
else if (this.restGlyph) {
|
|
72005
|
-
this.restGlyph.updateBeamingHelper(this.container.x + this.x);
|
|
72006
|
-
}
|
|
72007
|
-
else if (this.slash) {
|
|
72008
|
-
this.slash.updateBeamingHelper(this.container.x + this.x);
|
|
71937
|
+
g.x = this.onTimeX;
|
|
72009
71938
|
}
|
|
72010
71939
|
}
|
|
72011
71940
|
_createNoteGlyph(n) {
|
|
@@ -72018,7 +71947,7 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
72018
71947
|
this.noteNumbers.addNoteGlyph(noteNumberGlyph, n);
|
|
72019
71948
|
const topY = noteNumberGlyph.y - noteNumberGlyph.height / 2;
|
|
72020
71949
|
const bottomY = topY + noteNumberGlyph.height;
|
|
72021
|
-
this.renderer.
|
|
71950
|
+
this.renderer.collisionHelper.reserveBeatSlot(this.container.beat, topY, bottomY);
|
|
72022
71951
|
const minString = tr.minString;
|
|
72023
71952
|
const maxString = tr.maxString;
|
|
72024
71953
|
if (Number.isNaN(minString) || minString < n.string) {
|
|
@@ -72290,7 +72219,7 @@ class TabBarRenderer extends LineBarRenderer {
|
|
|
72290
72219
|
}
|
|
72291
72220
|
createLinePreBeatGlyphs() {
|
|
72292
72221
|
// Clef
|
|
72293
|
-
if (this.
|
|
72222
|
+
if (this.isFirstOfStaff) {
|
|
72294
72223
|
const center = (this.bar.staff.tuning.length - 1) / 2;
|
|
72295
72224
|
this.createStartSpacing();
|
|
72296
72225
|
this.addPreBeatGlyph(new TabClefGlyph(0, this.getLineY(center)));
|
|
@@ -72381,14 +72310,14 @@ class TabBarRenderer extends LineBarRenderer {
|
|
|
72381
72310
|
// currently only used for duplets
|
|
72382
72311
|
return this.getFlagAndBarPos();
|
|
72383
72312
|
}
|
|
72384
|
-
shouldPaintFlag(beat
|
|
72385
|
-
if (!super.shouldPaintFlag(beat
|
|
72313
|
+
shouldPaintFlag(beat) {
|
|
72314
|
+
if (!super.shouldPaintFlag(beat)) {
|
|
72386
72315
|
return false;
|
|
72387
72316
|
}
|
|
72388
72317
|
if (beat.graceType !== GraceType.None) {
|
|
72389
72318
|
return false;
|
|
72390
72319
|
}
|
|
72391
|
-
return
|
|
72320
|
+
return true;
|
|
72392
72321
|
}
|
|
72393
72322
|
paintBeamingStem(beat, cy, x, topY, bottomY, canvas) {
|
|
72394
72323
|
if (bottomY < topY) {
|