@coderline/alphatab 1.8.0-alpha.1640 → 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 +603 -715
- package/dist/alphaTab.js +603 -715
- 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
|
*/
|
|
@@ -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
48416
|
const preBeatStretch = this.preNotes.computedWidth + this.onNotes.onTimeX;
|
|
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
|
-
}
|
|
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;
|
|
@@ -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();
|
|
@@ -48740,6 +48573,26 @@ class BeatContainerGlyph extends Glyph {
|
|
|
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
|
/**
|
|
@@ -56498,6 +56351,31 @@ var EffectBarGlyphSizing;
|
|
|
56498
56351
|
EffectBarGlyphSizing[EffectBarGlyphSizing["FullBar"] = 5] = "FullBar";
|
|
56499
56352
|
})(EffectBarGlyphSizing || (EffectBarGlyphSizing = {}));
|
|
56500
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
|
+
|
|
56501
56379
|
/**
|
|
56502
56380
|
* @internal
|
|
56503
56381
|
*/
|
|
@@ -56625,39 +56503,6 @@ class AlternateEndingsEffectInfo extends EffectInfo {
|
|
|
56625
56503
|
}
|
|
56626
56504
|
}
|
|
56627
56505
|
|
|
56628
|
-
/**
|
|
56629
|
-
* Lists the different position modes for {@link BarRendererBase.getBeatX}
|
|
56630
|
-
* @internal
|
|
56631
|
-
*/
|
|
56632
|
-
var BeatXPosition;
|
|
56633
|
-
(function (BeatXPosition) {
|
|
56634
|
-
/**
|
|
56635
|
-
* Gets the pre-notes position which is located before the accidentals
|
|
56636
|
-
*/
|
|
56637
|
-
BeatXPosition[BeatXPosition["PreNotes"] = 0] = "PreNotes";
|
|
56638
|
-
/**
|
|
56639
|
-
* Gets the on-notes position which is located after the accidentals but before the note heads.
|
|
56640
|
-
*/
|
|
56641
|
-
BeatXPosition[BeatXPosition["OnNotes"] = 1] = "OnNotes";
|
|
56642
|
-
/**
|
|
56643
|
-
* Gets the middle-notes position which is located after in the exact center of the note heads.
|
|
56644
|
-
*/
|
|
56645
|
-
BeatXPosition[BeatXPosition["MiddleNotes"] = 2] = "MiddleNotes";
|
|
56646
|
-
/**
|
|
56647
|
-
* Gets position of the stem for this beat
|
|
56648
|
-
*/
|
|
56649
|
-
BeatXPosition[BeatXPosition["Stem"] = 3] = "Stem";
|
|
56650
|
-
/**
|
|
56651
|
-
* Get the post-notes position which is located at after the note heads.
|
|
56652
|
-
*/
|
|
56653
|
-
BeatXPosition[BeatXPosition["PostNotes"] = 4] = "PostNotes";
|
|
56654
|
-
/**
|
|
56655
|
-
* Get the end-beat position which is located at the end of the beat. This position is almost
|
|
56656
|
-
* equal to the pre-notes position of the next beat.
|
|
56657
|
-
*/
|
|
56658
|
-
BeatXPosition[BeatXPosition["EndBeat"] = 5] = "EndBeat";
|
|
56659
|
-
})(BeatXPosition || (BeatXPosition = {}));
|
|
56660
|
-
|
|
56661
56506
|
/**
|
|
56662
56507
|
* @internal
|
|
56663
56508
|
*/
|
|
@@ -57256,6 +57101,93 @@ class DirectionsEffectInfo extends EffectInfo {
|
|
|
57256
57101
|
}
|
|
57257
57102
|
}
|
|
57258
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
|
+
|
|
57259
57191
|
/**
|
|
57260
57192
|
* @internal
|
|
57261
57193
|
*/
|
|
@@ -57494,17 +57426,6 @@ class FermataEffectInfo extends EffectInfo {
|
|
|
57494
57426
|
}
|
|
57495
57427
|
}
|
|
57496
57428
|
|
|
57497
|
-
/**
|
|
57498
|
-
* This simple glyph allows to put an empty region in to a BarRenderer.
|
|
57499
|
-
* @internal
|
|
57500
|
-
*/
|
|
57501
|
-
class SpacingGlyph extends Glyph {
|
|
57502
|
-
constructor(x, y, width) {
|
|
57503
|
-
super(x, y);
|
|
57504
|
-
this.width = width;
|
|
57505
|
-
}
|
|
57506
|
-
}
|
|
57507
|
-
|
|
57508
57429
|
/**
|
|
57509
57430
|
* This glyph allows to group several other glyphs to be
|
|
57510
57431
|
* drawn at the same x position
|
|
@@ -57520,34 +57441,20 @@ class GlyphGroup extends Glyph {
|
|
|
57520
57441
|
const glyphs = this.glyphs;
|
|
57521
57442
|
if (glyphs) {
|
|
57522
57443
|
for (const g of glyphs) {
|
|
57523
|
-
|
|
57524
|
-
if (g instanceof SpacingGlyph) {
|
|
57525
|
-
continue;
|
|
57526
|
-
}
|
|
57527
|
-
const gTop = g.getBoundingBoxTop();
|
|
57528
|
-
if (Number.isNaN(top) || gTop < top) {
|
|
57529
|
-
top = gTop;
|
|
57530
|
-
}
|
|
57444
|
+
top = ModelUtils.minBoundingBox(top, g.getBoundingBoxTop());
|
|
57531
57445
|
}
|
|
57532
57446
|
}
|
|
57533
|
-
return
|
|
57447
|
+
return top;
|
|
57534
57448
|
}
|
|
57535
57449
|
getBoundingBoxBottom() {
|
|
57536
57450
|
let bottom = Number.NaN;
|
|
57537
57451
|
const glyphs = this.glyphs;
|
|
57538
57452
|
if (glyphs) {
|
|
57539
57453
|
for (const g of glyphs) {
|
|
57540
|
-
|
|
57541
|
-
if (g instanceof SpacingGlyph) {
|
|
57542
|
-
continue;
|
|
57543
|
-
}
|
|
57544
|
-
const gBottom = g.getBoundingBoxBottom();
|
|
57545
|
-
if (Number.isNaN(bottom) || gBottom > bottom) {
|
|
57546
|
-
bottom = gBottom;
|
|
57547
|
-
}
|
|
57454
|
+
bottom = ModelUtils.maxBoundingBox(bottom, g.getBoundingBoxBottom());
|
|
57548
57455
|
}
|
|
57549
57456
|
}
|
|
57550
|
-
return
|
|
57457
|
+
return bottom;
|
|
57551
57458
|
}
|
|
57552
57459
|
doLayout() {
|
|
57553
57460
|
if (!this.glyphs || this.glyphs.length === 0) {
|
|
@@ -57963,6 +57870,38 @@ class FreeTimeEffectInfo extends EffectInfo {
|
|
|
57963
57870
|
}
|
|
57964
57871
|
}
|
|
57965
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
|
+
|
|
57966
57905
|
/**
|
|
57967
57906
|
* @internal
|
|
57968
57907
|
*/
|
|
@@ -59581,12 +59520,12 @@ class VoiceContainerGlyph extends GlyphGroup {
|
|
|
59581
59520
|
// of the next glyph
|
|
59582
59521
|
if (i > 0) {
|
|
59583
59522
|
const beatWidth = currentBeatGlyph.x - beatGlyphs[i - 1].x;
|
|
59584
|
-
beatGlyphs[i - 1].
|
|
59523
|
+
beatGlyphs[i - 1].width = beatWidth;
|
|
59585
59524
|
}
|
|
59586
59525
|
// for the last glyph size based on the full width
|
|
59587
59526
|
if (i === j - 1) {
|
|
59588
59527
|
const beatWidth = this.width - beatGlyphs[beatGlyphs.length - 1].x;
|
|
59589
|
-
currentBeatGlyph.
|
|
59528
|
+
currentBeatGlyph.width = beatWidth;
|
|
59590
59529
|
}
|
|
59591
59530
|
}
|
|
59592
59531
|
}
|
|
@@ -61286,7 +61225,7 @@ class StaffSystem {
|
|
|
61286
61225
|
if (!masterBarBoundsLookup.has(renderer.bar.masterBar.index)) {
|
|
61287
61226
|
masterBarBounds = new MasterBarBounds();
|
|
61288
61227
|
masterBarBounds.index = renderer.bar.masterBar.index;
|
|
61289
|
-
masterBarBounds.isFirstOfLine = renderer.
|
|
61228
|
+
masterBarBounds.isFirstOfLine = renderer.isFirstOfStaff;
|
|
61290
61229
|
masterBarBounds.realBounds = new Bounds();
|
|
61291
61230
|
masterBarBounds.realBounds.x = x + renderer.x;
|
|
61292
61231
|
masterBarBounds.realBounds.y = realTop;
|
|
@@ -61818,11 +61757,9 @@ class BeatGlyphBase extends GlyphGroup {
|
|
|
61818
61757
|
* @internal
|
|
61819
61758
|
*/
|
|
61820
61759
|
class BeatOnNoteGlyphBase extends BeatGlyphBase {
|
|
61821
|
-
beamingHelper;
|
|
61822
61760
|
onTimeX = 0;
|
|
61823
61761
|
middleX = 0;
|
|
61824
|
-
|
|
61825
|
-
}
|
|
61762
|
+
stemX = 0;
|
|
61826
61763
|
buildBoundingsLookup(_beatBounds, _cx, _cy) {
|
|
61827
61764
|
}
|
|
61828
61765
|
getNoteX(_note, _requestedPosition) {
|
|
@@ -61964,14 +61901,6 @@ class MultiBarRestBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
61964
61901
|
}
|
|
61965
61902
|
}
|
|
61966
61903
|
|
|
61967
|
-
/**
|
|
61968
|
-
* @internal
|
|
61969
|
-
*/
|
|
61970
|
-
class BeatLinePositions {
|
|
61971
|
-
staffId = '';
|
|
61972
|
-
up = 0;
|
|
61973
|
-
down = 0;
|
|
61974
|
-
}
|
|
61975
61904
|
/**
|
|
61976
61905
|
* @internal
|
|
61977
61906
|
*/
|
|
@@ -62002,10 +61931,7 @@ class BeamingHelperDrawInfo {
|
|
|
62002
61931
|
*/
|
|
62003
61932
|
class BeamingHelper {
|
|
62004
61933
|
_staff;
|
|
62005
|
-
_beatLineXPositions = new Map();
|
|
62006
61934
|
_renderer;
|
|
62007
|
-
_firstNonRestBeat = null;
|
|
62008
|
-
_lastNonRestBeat = null;
|
|
62009
61935
|
voice = null;
|
|
62010
61936
|
beats = [];
|
|
62011
61937
|
shortestDuration = Duration.QuadrupleWhole;
|
|
@@ -62015,6 +61941,7 @@ class BeamingHelper {
|
|
|
62015
61941
|
*/
|
|
62016
61942
|
hasTuplet = false;
|
|
62017
61943
|
slashBeats = [];
|
|
61944
|
+
restBeats = [];
|
|
62018
61945
|
lowestNoteInHelper = null;
|
|
62019
61946
|
_lowestNoteCompareValueInHelper = -1;
|
|
62020
61947
|
highestNoteInHelper = null;
|
|
@@ -62022,25 +61949,21 @@ class BeamingHelper {
|
|
|
62022
61949
|
invertBeamDirection = false;
|
|
62023
61950
|
preferredBeamDirection = null;
|
|
62024
61951
|
graceType = GraceType.None;
|
|
62025
|
-
minRestSteps = null;
|
|
62026
|
-
beatOfMinRestSteps = null;
|
|
62027
|
-
maxRestSteps = null;
|
|
62028
|
-
beatOfMaxRestSteps = null;
|
|
62029
61952
|
get isRestBeamHelper() {
|
|
62030
61953
|
return this.beats.length === 1 && this.beats[0].isRest;
|
|
62031
61954
|
}
|
|
62032
|
-
|
|
62033
|
-
return ((forceFlagOnSingleBeat && this.
|
|
62034
|
-
(!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)));
|
|
62035
61958
|
}
|
|
62036
|
-
|
|
61959
|
+
_beatHasStem(beat) {
|
|
62037
61960
|
return beat.duration > Duration.Whole;
|
|
62038
61961
|
}
|
|
62039
61962
|
hasFlag(forceFlagOnSingleBeat, beat) {
|
|
62040
|
-
return ((forceFlagOnSingleBeat &&
|
|
62041
|
-
(!forceFlagOnSingleBeat && this.beats.length === 1 &&
|
|
61963
|
+
return ((forceFlagOnSingleBeat && BeamingHelper.beatHasFlag(beat)) ||
|
|
61964
|
+
(!forceFlagOnSingleBeat && this.beats.length === 1 && BeamingHelper.beatHasFlag(this.beats[0])));
|
|
62042
61965
|
}
|
|
62043
|
-
|
|
61966
|
+
static beatHasFlag(beat) {
|
|
62044
61967
|
return (!beat.deadSlapped && !beat.isRest && (beat.duration > Duration.Quarter || beat.graceType !== GraceType.None));
|
|
62045
61968
|
}
|
|
62046
61969
|
constructor(staff, renderer) {
|
|
@@ -62048,38 +61971,12 @@ class BeamingHelper {
|
|
|
62048
61971
|
this._renderer = renderer;
|
|
62049
61972
|
this.beats = [];
|
|
62050
61973
|
}
|
|
62051
|
-
|
|
62052
|
-
direction = direction ?? this.direction;
|
|
62053
|
-
if (this.hasBeatLineX(beat)) {
|
|
62054
|
-
if (direction === BeamDirection.Up) {
|
|
62055
|
-
return this._beatLineXPositions.get(beat.index).up;
|
|
62056
|
-
}
|
|
62057
|
-
return this._beatLineXPositions.get(beat.index).down;
|
|
62058
|
-
}
|
|
62059
|
-
return 0;
|
|
62060
|
-
}
|
|
62061
|
-
hasBeatLineX(beat) {
|
|
62062
|
-
return this._beatLineXPositions.has(beat.index);
|
|
62063
|
-
}
|
|
62064
|
-
registerBeatLineX(staffId, beat, up, down) {
|
|
62065
|
-
const positions = this._getOrCreateBeatPositions(beat);
|
|
62066
|
-
positions.staffId = staffId;
|
|
62067
|
-
positions.up = up;
|
|
62068
|
-
positions.down = down;
|
|
61974
|
+
alignWithBeats() {
|
|
62069
61975
|
for (const v of this.drawingInfos.values()) {
|
|
62070
|
-
|
|
62071
|
-
|
|
62072
|
-
|
|
62073
|
-
else if (v.endBeat === beat) {
|
|
62074
|
-
v.endX = this.getBeatLineX(beat);
|
|
62075
|
-
}
|
|
62076
|
-
}
|
|
62077
|
-
}
|
|
62078
|
-
_getOrCreateBeatPositions(beat) {
|
|
62079
|
-
if (!this._beatLineXPositions.has(beat.index)) {
|
|
62080
|
-
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();
|
|
62081
61979
|
}
|
|
62082
|
-
return this._beatLineXPositions.get(beat.index);
|
|
62083
61980
|
}
|
|
62084
61981
|
direction = BeamDirection.Up;
|
|
62085
61982
|
finish() {
|
|
@@ -62145,36 +62042,6 @@ class BeamingHelper {
|
|
|
62145
62042
|
}
|
|
62146
62043
|
return [0, 0];
|
|
62147
62044
|
}
|
|
62148
|
-
/**
|
|
62149
|
-
* Registers a rest beat within the accidental helper so the rest
|
|
62150
|
-
* symbol is considered properly during beaming.
|
|
62151
|
-
* @param beat The rest beat.
|
|
62152
|
-
* @param steps The steps on which the rest symbol is placed
|
|
62153
|
-
*/
|
|
62154
|
-
applyRest(beat, steps) {
|
|
62155
|
-
// do not accept rests after the last beat which has notes
|
|
62156
|
-
if ((this._lastNonRestBeat && beat.index >= this._lastNonRestBeat.index) ||
|
|
62157
|
-
(this._firstNonRestBeat && beat.index <= this._firstNonRestBeat.index)) {
|
|
62158
|
-
return;
|
|
62159
|
-
}
|
|
62160
|
-
// correct the line of the glyph to a note which would
|
|
62161
|
-
// be placed at the upper / lower end of the glyph.
|
|
62162
|
-
let aboveRest = steps;
|
|
62163
|
-
let belowRest = steps;
|
|
62164
|
-
const offsets = BeamingHelper.computeLineHeightsForRest(beat.duration);
|
|
62165
|
-
aboveRest -= offsets[0];
|
|
62166
|
-
belowRest += offsets[1];
|
|
62167
|
-
const minRestSteps = this.minRestSteps;
|
|
62168
|
-
const maxRestSteps = this.maxRestSteps;
|
|
62169
|
-
if (minRestSteps === null || minRestSteps > aboveRest) {
|
|
62170
|
-
this.minRestSteps = aboveRest;
|
|
62171
|
-
this.beatOfMinRestSteps = beat;
|
|
62172
|
-
}
|
|
62173
|
-
if (maxRestSteps === null || maxRestSteps < belowRest) {
|
|
62174
|
-
this.maxRestSteps = belowRest;
|
|
62175
|
-
this.beatOfMaxRestSteps = beat;
|
|
62176
|
-
}
|
|
62177
|
-
}
|
|
62178
62045
|
_invert(direction) {
|
|
62179
62046
|
if (!this.invertBeamDirection) {
|
|
62180
62047
|
return direction;
|
|
@@ -62238,14 +62105,13 @@ class BeamingHelper {
|
|
|
62238
62105
|
if (this.shortestDuration < beat.duration) {
|
|
62239
62106
|
this.shortestDuration = beat.duration;
|
|
62240
62107
|
}
|
|
62241
|
-
if (!this._firstNonRestBeat) {
|
|
62242
|
-
this._firstNonRestBeat = beat;
|
|
62243
|
-
}
|
|
62244
|
-
this._lastNonRestBeat = beat;
|
|
62245
62108
|
}
|
|
62246
62109
|
else if (this.beats.length === 0) {
|
|
62247
62110
|
this.beats.push(beat);
|
|
62248
62111
|
}
|
|
62112
|
+
else {
|
|
62113
|
+
this.restBeats.push(beat);
|
|
62114
|
+
}
|
|
62249
62115
|
if (beat.slashed) {
|
|
62250
62116
|
this.slashBeats.push(beat);
|
|
62251
62117
|
}
|
|
@@ -62354,19 +62220,6 @@ class BeamingHelper {
|
|
|
62354
62220
|
get beatOfHighestNote() {
|
|
62355
62221
|
return this.highestNoteInHelper.beat;
|
|
62356
62222
|
}
|
|
62357
|
-
/**
|
|
62358
|
-
* Returns whether the the position of the given beat, was registered by the staff of the given ID
|
|
62359
|
-
* @param staffId
|
|
62360
|
-
* @param beat
|
|
62361
|
-
* @returns
|
|
62362
|
-
*/
|
|
62363
|
-
isPositionFrom(staffId, beat) {
|
|
62364
|
-
if (!this._beatLineXPositions.has(beat.index)) {
|
|
62365
|
-
return true;
|
|
62366
|
-
}
|
|
62367
|
-
return (this._beatLineXPositions.get(beat.index).staffId === staffId ||
|
|
62368
|
-
!this._beatLineXPositions.get(beat.index).staffId);
|
|
62369
|
-
}
|
|
62370
62223
|
drawingInfos = new Map();
|
|
62371
62224
|
}
|
|
62372
62225
|
|
|
@@ -62518,8 +62371,8 @@ class BarCollisionHelper {
|
|
|
62518
62371
|
*/
|
|
62519
62372
|
class BarHelpers {
|
|
62520
62373
|
_renderer;
|
|
62374
|
+
_beamHelperLookup = new Map();
|
|
62521
62375
|
beamHelpers = [];
|
|
62522
|
-
beamHelperLookup = [];
|
|
62523
62376
|
collisionHelper;
|
|
62524
62377
|
preferredBeamDirection = null;
|
|
62525
62378
|
constructor(renderer) {
|
|
@@ -62534,7 +62387,6 @@ class BarHelpers {
|
|
|
62534
62387
|
for (let i = 0, j = bar.voices.length; i < j; i++) {
|
|
62535
62388
|
const v = bar.voices[i];
|
|
62536
62389
|
this.beamHelpers.push([]);
|
|
62537
|
-
this.beamHelperLookup.push(new Map());
|
|
62538
62390
|
for (let k = 0, l = v.beats.length; k < l; k++) {
|
|
62539
62391
|
const b = v.beats[k];
|
|
62540
62392
|
let helperForBeat;
|
|
@@ -62543,6 +62395,9 @@ class BarHelpers {
|
|
|
62543
62395
|
}
|
|
62544
62396
|
else {
|
|
62545
62397
|
helperForBeat = currentBeamHelper;
|
|
62398
|
+
if (currentGraceBeamHelper) {
|
|
62399
|
+
currentGraceBeamHelper.finish();
|
|
62400
|
+
}
|
|
62546
62401
|
currentGraceBeamHelper = null;
|
|
62547
62402
|
}
|
|
62548
62403
|
// if a new beaming helper was started, we close our tuplet grouping as well
|
|
@@ -62563,7 +62418,7 @@ class BarHelpers {
|
|
|
62563
62418
|
}
|
|
62564
62419
|
this.beamHelpers[v.index].push(helperForBeat);
|
|
62565
62420
|
}
|
|
62566
|
-
this.
|
|
62421
|
+
this._beamHelperLookup.set(b.id, helperForBeat);
|
|
62567
62422
|
}
|
|
62568
62423
|
if (currentBeamHelper) {
|
|
62569
62424
|
currentBeamHelper.finish();
|
|
@@ -62576,7 +62431,7 @@ class BarHelpers {
|
|
|
62576
62431
|
}
|
|
62577
62432
|
}
|
|
62578
62433
|
getBeamingHelperForBeat(beat) {
|
|
62579
|
-
return this.
|
|
62434
|
+
return this._beamHelperLookup.has(beat.id) ? this._beamHelperLookup.get(beat.id) : undefined;
|
|
62580
62435
|
}
|
|
62581
62436
|
}
|
|
62582
62437
|
|
|
@@ -62686,6 +62541,9 @@ class BarRendererBase {
|
|
|
62686
62541
|
return this._contentBottomOverflow + this.bottomEffects.height;
|
|
62687
62542
|
}
|
|
62688
62543
|
helpers;
|
|
62544
|
+
get collisionHelper() {
|
|
62545
|
+
return this.helpers.collisionHelper;
|
|
62546
|
+
}
|
|
62689
62547
|
/**
|
|
62690
62548
|
* Gets or sets whether this renderer is linked to the next one
|
|
62691
62549
|
* by some glyphs like a vibrato effect
|
|
@@ -62745,6 +62603,11 @@ class BarRendererBase {
|
|
|
62745
62603
|
for (const container of this._voiceContainers.values()) {
|
|
62746
62604
|
container.scaleToWidth(containerWidth);
|
|
62747
62605
|
}
|
|
62606
|
+
for (const v of this.helpers.beamHelpers) {
|
|
62607
|
+
for (const h of v) {
|
|
62608
|
+
h.alignWithBeats();
|
|
62609
|
+
}
|
|
62610
|
+
}
|
|
62748
62611
|
this._postBeatGlyphs.x = this._preBeatGlyphs.x + this._preBeatGlyphs.width + containerWidth;
|
|
62749
62612
|
this.width = width;
|
|
62750
62613
|
this.topEffects.alignGlyphs();
|
|
@@ -62773,10 +62636,13 @@ class BarRendererBase {
|
|
|
62773
62636
|
get barDisplayWidth() {
|
|
62774
62637
|
return this.staff.system.staves.length > 1 ? this.bar.masterBar.displayWidth : this.bar.displayWidth;
|
|
62775
62638
|
}
|
|
62776
|
-
|
|
62777
|
-
get
|
|
62639
|
+
wasFirstOfStaff = false;
|
|
62640
|
+
get isFirstOfStaff() {
|
|
62778
62641
|
return this.index === 0;
|
|
62779
62642
|
}
|
|
62643
|
+
get isLastOfStaff() {
|
|
62644
|
+
return this.index === this.staff.barRenderers.length - 1;
|
|
62645
|
+
}
|
|
62780
62646
|
get isLast() {
|
|
62781
62647
|
return !this.bar || this.bar.index === this.scoreRenderer.layout.lastBarIndex;
|
|
62782
62648
|
}
|
|
@@ -62991,6 +62857,18 @@ class BarRendererBase {
|
|
|
62991
62857
|
}
|
|
62992
62858
|
}
|
|
62993
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
|
+
}
|
|
62994
62872
|
const beatEffectsMinY = this.beatEffectsMinY;
|
|
62995
62873
|
if (!Number.isNaN(beatEffectsMinY)) {
|
|
62996
62874
|
const beatEffectTopOverflow = -beatEffectsMinY;
|
|
@@ -63044,7 +62922,6 @@ class BarRendererBase {
|
|
|
63044
62922
|
g.renderer = this;
|
|
63045
62923
|
g.preNotes.renderer = this;
|
|
63046
62924
|
g.onNotes.renderer = this;
|
|
63047
|
-
g.onNotes.beamingHelper = this.helpers.beamHelperLookup[g.beat.voice.index].get(g.beat.index);
|
|
63048
62925
|
this.getVoiceContainer(g.beat.voice).addGlyph(g);
|
|
63049
62926
|
}
|
|
63050
62927
|
getVoiceContainer(voice) {
|
|
@@ -63123,7 +63000,7 @@ class BarRendererBase {
|
|
|
63123
63000
|
this._postBeatGlyphs.addGlyph(g);
|
|
63124
63001
|
}
|
|
63125
63002
|
createPreBeatGlyphs() {
|
|
63126
|
-
this.
|
|
63003
|
+
this.wasFirstOfStaff = this.isFirstOfStaff;
|
|
63127
63004
|
}
|
|
63128
63005
|
createBeatGlyphs() {
|
|
63129
63006
|
for (const voice of this.bar.voices) {
|
|
@@ -63150,26 +63027,7 @@ class BarRendererBase {
|
|
|
63150
63027
|
getBeatX(beat, requestedPosition = BeatXPosition.PreNotes, useSharedSizes = false) {
|
|
63151
63028
|
const container = this.getBeatContainer(beat);
|
|
63152
63029
|
if (container) {
|
|
63153
|
-
|
|
63154
|
-
case BeatXPosition.PreNotes:
|
|
63155
|
-
return container.voiceContainer.x + container.x;
|
|
63156
|
-
case BeatXPosition.OnNotes:
|
|
63157
|
-
return container.voiceContainer.x + container.x + container.onNotes.x;
|
|
63158
|
-
case BeatXPosition.MiddleNotes:
|
|
63159
|
-
return container.voiceContainer.x + container.x + container.onNotes.x + container.onNotes.middleX;
|
|
63160
|
-
case BeatXPosition.Stem:
|
|
63161
|
-
const offset = container.onNotes.beamingHelper
|
|
63162
|
-
? container.onNotes.beamingHelper.getBeatLineX(beat)
|
|
63163
|
-
: container.onNotes.x + container.onNotes.width / 2;
|
|
63164
|
-
return container.voiceContainer.x + offset;
|
|
63165
|
-
case BeatXPosition.PostNotes:
|
|
63166
|
-
const onNoteSize = useSharedSizes
|
|
63167
|
-
? (this.layoutingInfo.getBeatSizes(beat)?.onBeatSize ?? container.onNotes.width)
|
|
63168
|
-
: container.onNotes.width;
|
|
63169
|
-
return container.voiceContainer.x + container.x + container.onNotes.x + onNoteSize;
|
|
63170
|
-
case BeatXPosition.EndBeat:
|
|
63171
|
-
return container.voiceContainer.x + container.x + container.width;
|
|
63172
|
-
}
|
|
63030
|
+
return container.voiceContainer.x + container.x + container.getBeatX(requestedPosition, useSharedSizes);
|
|
63173
63031
|
}
|
|
63174
63032
|
return 0;
|
|
63175
63033
|
}
|
|
@@ -63204,7 +63062,7 @@ class BarRendererBase {
|
|
|
63204
63062
|
this.updateSizes();
|
|
63205
63063
|
// there are some glyphs which are shown only for renderers at the line start, so we simply recreate them
|
|
63206
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
|
|
63207
|
-
if ((this.
|
|
63065
|
+
if ((this.wasFirstOfStaff && !this.isFirstOfStaff) || (!this.wasFirstOfStaff && this.isFirstOfStaff)) {
|
|
63208
63066
|
this.recreatePreBeatGlyphs();
|
|
63209
63067
|
this._postBeatGlyphs.doLayout();
|
|
63210
63068
|
}
|
|
@@ -63241,7 +63099,7 @@ class BarRendererBase {
|
|
|
63241
63099
|
completeBeamingHelper(_helper) {
|
|
63242
63100
|
}
|
|
63243
63101
|
getBeatDirection(beat) {
|
|
63244
|
-
return this.helpers.getBeamingHelperForBeat(beat).
|
|
63102
|
+
return this.helpers.getBeamingHelperForBeat(beat)?.direction ?? BeamDirection.Up;
|
|
63245
63103
|
}
|
|
63246
63104
|
}
|
|
63247
63105
|
|
|
@@ -65608,8 +65466,18 @@ class BarLineGlyph extends LeftToRightLayoutingGlyphGroup {
|
|
|
65608
65466
|
}
|
|
65609
65467
|
const lineRenderer = this.renderer;
|
|
65610
65468
|
const lineYOffset = lineRenderer.smuflMetrics.staffLineThickness;
|
|
65611
|
-
|
|
65612
|
-
|
|
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
|
+
}
|
|
65613
65481
|
const h = bottom - top;
|
|
65614
65482
|
// round up to have pixel-aligned bar lines, x-shift will be used during rendering
|
|
65615
65483
|
// to avoid shifting again all glyphs
|
|
@@ -65695,6 +65563,54 @@ class BarNumberGlyph extends Glyph {
|
|
|
65695
65563
|
}
|
|
65696
65564
|
}
|
|
65697
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
|
+
|
|
65698
65614
|
/**
|
|
65699
65615
|
* @internal
|
|
65700
65616
|
*/
|
|
@@ -65730,6 +65646,23 @@ class RepeatCountGlyph extends Glyph {
|
|
|
65730
65646
|
}
|
|
65731
65647
|
}
|
|
65732
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
|
+
|
|
65733
65666
|
/**
|
|
65734
65667
|
* This is a base class for any bar renderer which renders music notation on a staff
|
|
65735
65668
|
* with lines like Standard Notation, Guitar Tablatures and Slash Notation.
|
|
@@ -65853,7 +65786,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
65853
65786
|
if (this.hasVoiceContainer(voice)) {
|
|
65854
65787
|
const container = this.getVoiceContainer(voice);
|
|
65855
65788
|
for (const tupletGroup of container.tupletGroups) {
|
|
65856
|
-
this._paintTupletHelper(cx
|
|
65789
|
+
this._paintTupletHelper(cx, cy, canvas, tupletGroup, beatElement, bracketsAsArcs);
|
|
65857
65790
|
}
|
|
65858
65791
|
}
|
|
65859
65792
|
}
|
|
@@ -65927,26 +65860,27 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
65927
65860
|
// check if we need to paint simple footer
|
|
65928
65861
|
const offset = this.tupletOffset;
|
|
65929
65862
|
const size = this.tupletSize;
|
|
65863
|
+
const shift = offset + size * 0.5;
|
|
65930
65864
|
const _ = ElementStyleHelper.beat(canvas, beatElement, h.beats[0]);
|
|
65931
65865
|
try {
|
|
65932
65866
|
const l = canvas.lineWidth;
|
|
65933
65867
|
canvas.lineWidth = this.smuflMetrics.tupletBracketThickness;
|
|
65934
65868
|
if (h.beats.length === 1 || !h.isFull) {
|
|
65935
65869
|
for (const beat of h.beats) {
|
|
65936
|
-
const beamingHelper = this.helpers.
|
|
65870
|
+
const beamingHelper = this.helpers.getBeamingHelperForBeat(beat);
|
|
65937
65871
|
if (!beamingHelper) {
|
|
65938
65872
|
continue;
|
|
65939
65873
|
}
|
|
65940
65874
|
const direction = this.getTupletBeamDirection(beamingHelper);
|
|
65941
|
-
const tupletX =
|
|
65875
|
+
const tupletX = this.getBeatX(beat, BeatXPosition.Stem);
|
|
65942
65876
|
let tupletY = this.calculateBeamYWithDirection(beamingHelper, tupletX, direction);
|
|
65943
65877
|
if (direction === BeamDirection.Down) {
|
|
65944
|
-
tupletY +=
|
|
65878
|
+
tupletY += shift;
|
|
65945
65879
|
}
|
|
65946
65880
|
else {
|
|
65947
|
-
tupletY -=
|
|
65881
|
+
tupletY -= shift;
|
|
65948
65882
|
}
|
|
65949
|
-
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);
|
|
65950
65884
|
}
|
|
65951
65885
|
}
|
|
65952
65886
|
else {
|
|
@@ -65976,12 +65910,12 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
65976
65910
|
}
|
|
65977
65911
|
//
|
|
65978
65912
|
// Calculate the overall area of the tuplet bracket
|
|
65979
|
-
const startX = this.getBeatX(firstBeat, BeatXPosition.OnNotes)
|
|
65980
|
-
const endX = this.getBeatX(lastBeat, BeatXPosition.PostNotes)
|
|
65913
|
+
const startX = this.getBeatX(firstBeat, BeatXPosition.OnNotes);
|
|
65914
|
+
const endX = this.getBeatX(lastBeat, BeatXPosition.PostNotes);
|
|
65981
65915
|
//
|
|
65982
65916
|
// calculate the y positions for our bracket
|
|
65983
|
-
const firstNonRestBeamingHelper = this.helpers.
|
|
65984
|
-
const lastNonRestBeamingHelper = this.helpers.
|
|
65917
|
+
const firstNonRestBeamingHelper = this.helpers.getBeamingHelperForBeat(firstNonRestBeat);
|
|
65918
|
+
const lastNonRestBeamingHelper = this.helpers.getBeamingHelperForBeat(lastNonRestBeat);
|
|
65985
65919
|
const direction = this.getTupletBeamDirection(firstNonRestBeamingHelper);
|
|
65986
65920
|
let startY = this.calculateBeamYWithDirection(firstNonRestBeamingHelper, startX, direction);
|
|
65987
65921
|
let endY = this.calculateBeamYWithDirection(lastNonRestBeamingHelper, endX, direction);
|
|
@@ -65990,7 +65924,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
65990
65924
|
endY = startY;
|
|
65991
65925
|
}
|
|
65992
65926
|
// align line centered in available space
|
|
65993
|
-
const shift = offset + size * 0.5;
|
|
65994
65927
|
if (direction === BeamDirection.Down) {
|
|
65995
65928
|
startY += shift;
|
|
65996
65929
|
endY += shift;
|
|
@@ -66055,14 +65988,24 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66055
65988
|
paintBeams(cx, cy, canvas, flagsElement, beamsElement) {
|
|
66056
65989
|
for (const v of this.helpers.beamHelpers) {
|
|
66057
65990
|
for (const h of v) {
|
|
66058
|
-
this.
|
|
65991
|
+
this.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
|
|
66059
65992
|
}
|
|
66060
65993
|
}
|
|
66061
65994
|
}
|
|
66062
65995
|
drawBeamHelperAsFlags(h) {
|
|
66063
65996
|
return h.beats.length === 1;
|
|
66064
65997
|
}
|
|
66065
|
-
|
|
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) {
|
|
66066
66009
|
canvas.color = h.voice.index === 0 ? this.resources.mainGlyphColor : this.resources.secondaryGlyphColor;
|
|
66067
66010
|
if (!h.isRestBeamHelper) {
|
|
66068
66011
|
if (this.drawBeamHelperAsFlags(h)) {
|
|
@@ -66073,7 +66016,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66073
66016
|
}
|
|
66074
66017
|
}
|
|
66075
66018
|
}
|
|
66076
|
-
shouldPaintFlag(beat
|
|
66019
|
+
shouldPaintFlag(beat) {
|
|
66077
66020
|
// no flags for bend grace beats
|
|
66078
66021
|
if (beat.graceType === GraceType.BendGrace) {
|
|
66079
66022
|
return false;
|
|
@@ -66081,10 +66024,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66081
66024
|
if (beat.deadSlapped) {
|
|
66082
66025
|
return false;
|
|
66083
66026
|
}
|
|
66084
|
-
// we don't have an X-position: cannot paint a flag
|
|
66085
|
-
if (!h.hasBeatLineX(beat)) {
|
|
66086
|
-
return false;
|
|
66087
|
-
}
|
|
66088
66027
|
// no flags for any grace notes on songbook mode
|
|
66089
66028
|
if (beat.graceType !== GraceType.None && this.settings.notation.notationMode === NotationMode.SongBook) {
|
|
66090
66029
|
return false;
|
|
@@ -66099,14 +66038,14 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66099
66038
|
}
|
|
66100
66039
|
paintFlag(cx, cy, canvas, h, flagsElement) {
|
|
66101
66040
|
for (const beat of h.beats) {
|
|
66102
|
-
if (!this.shouldPaintFlag(beat
|
|
66041
|
+
if (!this.shouldPaintFlag(beat)) {
|
|
66103
66042
|
continue;
|
|
66104
66043
|
}
|
|
66105
66044
|
const isGrace = beat.graceType !== GraceType.None;
|
|
66106
66045
|
//
|
|
66107
66046
|
// draw line
|
|
66108
66047
|
//
|
|
66109
|
-
const beatLineX =
|
|
66048
|
+
const beatLineX = this.getBeatX(beat, BeatXPosition.Stem);
|
|
66110
66049
|
const direction = this.getBeamDirection(h);
|
|
66111
66050
|
const topY = cy + this.y + this.getFlagTopY(beat, direction);
|
|
66112
66051
|
const bottomY = cy + this.y + this.getFlagBottomY(beat, direction);
|
|
@@ -66117,7 +66056,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66117
66056
|
else {
|
|
66118
66057
|
flagY = topY;
|
|
66119
66058
|
}
|
|
66120
|
-
if (!h.
|
|
66059
|
+
if (!h.hasStem(true, beat)) {
|
|
66121
66060
|
continue;
|
|
66122
66061
|
}
|
|
66123
66062
|
this.paintBeamingStem(beat, cy + this.y, cx + this.x + beatLineX, topY, bottomY, canvas);
|
|
@@ -66203,10 +66142,10 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66203
66142
|
}
|
|
66204
66143
|
for (let i = 0, j = h.beats.length; i < j; i++) {
|
|
66205
66144
|
const beat = h.beats[i];
|
|
66206
|
-
if (
|
|
66145
|
+
if (beat.deadSlapped) {
|
|
66207
66146
|
continue;
|
|
66208
66147
|
}
|
|
66209
|
-
const beatLineX =
|
|
66148
|
+
const beatLineX = this.getBeatX(beat, BeatXPosition.Stem);
|
|
66210
66149
|
const y1 = cy + this.y + this.getBarLineStart(beat, direction);
|
|
66211
66150
|
// ensure we are pixel aligned on the end of the stem to avoid anti-aliasing artifacts
|
|
66212
66151
|
// when combining stems and beams on sub-pixel level
|
|
@@ -66244,7 +66183,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66244
66183
|
barEndY = barY + this.calculateBeamY(h, barEndX);
|
|
66245
66184
|
LineBarRenderer.paintSingleBar(canvas, cx + this.x + barStartX, barStartY, cx + this.x + barEndX, barEndY, barSize);
|
|
66246
66185
|
// end part
|
|
66247
|
-
barEndX =
|
|
66186
|
+
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.Stem);
|
|
66248
66187
|
barStartX = barEndX - brokenBarOffset;
|
|
66249
66188
|
barStartY = barY + this.calculateBeamY(h, barStartX);
|
|
66250
66189
|
barEndY = barY + this.calculateBeamY(h, barEndX);
|
|
@@ -66254,7 +66193,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66254
66193
|
if (isFullBarJoin) {
|
|
66255
66194
|
// full bar?
|
|
66256
66195
|
barStartX = beatLineX;
|
|
66257
|
-
barEndX =
|
|
66196
|
+
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.Stem);
|
|
66258
66197
|
}
|
|
66259
66198
|
else if (i === 0 || !BeamingHelper.isFullBarJoin(h.beats[i - 1], beat, barIndex)) {
|
|
66260
66199
|
barStartX = beatLineX;
|
|
@@ -66289,7 +66228,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66289
66228
|
}
|
|
66290
66229
|
}
|
|
66291
66230
|
if (h.graceType === GraceType.BeforeBeat) {
|
|
66292
|
-
const beatLineX =
|
|
66231
|
+
const beatLineX = this.getBeatX(h.beats[0], BeatXPosition.Stem);
|
|
66293
66232
|
const flagWidth = this.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
66294
66233
|
let slashY = (cy + this.y + this.calculateBeamY(h, beatLineX)) | 0;
|
|
66295
66234
|
slashY += barSize + barSpacing;
|
|
@@ -66316,20 +66255,7 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66316
66255
|
const noteOverflowPadding = this.getLineHeight(0.5);
|
|
66317
66256
|
for (const v of this.helpers.beamHelpers) {
|
|
66318
66257
|
for (const h of v) {
|
|
66319
|
-
if (h.isRestBeamHelper)
|
|
66320
|
-
if (h.minRestSteps) {
|
|
66321
|
-
const topY = this.getLineY(h.maxRestSteps / 2) - noteOverflowPadding;
|
|
66322
|
-
if (topY < maxNoteY) {
|
|
66323
|
-
maxNoteY = topY;
|
|
66324
|
-
}
|
|
66325
|
-
}
|
|
66326
|
-
if (h.maxRestSteps) {
|
|
66327
|
-
const bottomY = this.getLineY(h.maxRestSteps & 2) + noteOverflowPadding;
|
|
66328
|
-
if (bottomY < maxNoteY) {
|
|
66329
|
-
maxNoteY = bottomY;
|
|
66330
|
-
}
|
|
66331
|
-
}
|
|
66332
|
-
}
|
|
66258
|
+
if (h.isRestBeamHelper) ;
|
|
66333
66259
|
else if (h.beats.length === 1 && h.beats[0].duration >= Duration.Half) {
|
|
66334
66260
|
if (h.direction === BeamDirection.Up) {
|
|
66335
66261
|
let topY = this.getFlagTopY(h.beats[0], h.direction);
|
|
@@ -66380,17 +66306,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66380
66306
|
}
|
|
66381
66307
|
}
|
|
66382
66308
|
}
|
|
66383
|
-
const beatContainer = this.getBeatContainer(h.beats[0]);
|
|
66384
|
-
if (beatContainer) {
|
|
66385
|
-
const bBoxTop = beatContainer.getBoundingBoxTop();
|
|
66386
|
-
const bBoxBottom = beatContainer.getBoundingBoxBottom();
|
|
66387
|
-
if (bBoxBottom > minNoteY) {
|
|
66388
|
-
minNoteY = bBoxBottom;
|
|
66389
|
-
}
|
|
66390
|
-
if (bBoxTop < maxNoteY) {
|
|
66391
|
-
maxNoteY = bBoxTop;
|
|
66392
|
-
}
|
|
66393
|
-
}
|
|
66394
66309
|
}
|
|
66395
66310
|
}
|
|
66396
66311
|
if (maxNoteY < rendererTop) {
|
|
@@ -66406,25 +66321,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66406
66321
|
}
|
|
66407
66322
|
const scale = h.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
66408
66323
|
const barCount = ModelUtils.getIndex(h.shortestDuration) - 2;
|
|
66409
|
-
let stemSize = this.smuflMetrics.standardStemLength * scale;
|
|
66410
|
-
if (h.tremoloDuration) {
|
|
66411
|
-
// for 16th and shorter beats we need more space for all tremolos
|
|
66412
|
-
// for 8th beats we need only more space for 32nd tremolos
|
|
66413
|
-
// the logic here is not perfect but there is no SMuFL guideline
|
|
66414
|
-
// on how tremolos need to extend stems
|
|
66415
|
-
const oneBeamSize = (this.smuflMetrics.beamThickness + this.smuflMetrics.beamSpacing) * scale;
|
|
66416
|
-
if (h.shortestDuration > Duration.Eighth) {
|
|
66417
|
-
if (h.tremoloDuration === Duration.Eighth) {
|
|
66418
|
-
stemSize += oneBeamSize;
|
|
66419
|
-
}
|
|
66420
|
-
else {
|
|
66421
|
-
stemSize += oneBeamSize * 1.5;
|
|
66422
|
-
}
|
|
66423
|
-
}
|
|
66424
|
-
else if (h.tremoloDuration === Duration.ThirtySecond) {
|
|
66425
|
-
stemSize += oneBeamSize * 1.5;
|
|
66426
|
-
}
|
|
66427
|
-
}
|
|
66428
66324
|
const drawingInfo = new BeamingHelperDrawInfo();
|
|
66429
66325
|
h.drawingInfos.set(direction, drawingInfo);
|
|
66430
66326
|
// the beaming logic works like this:
|
|
@@ -66437,33 +66333,17 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66437
66333
|
const isRest = h.isRestBeamHelper;
|
|
66438
66334
|
// 1. put direct diagonal line.
|
|
66439
66335
|
drawingInfo.startBeat = firstBeat;
|
|
66440
|
-
drawingInfo.startX =
|
|
66441
|
-
|
|
66442
|
-
|
|
66443
|
-
|
|
66444
|
-
|
|
66445
|
-
: this.getLineY(h.maxRestSteps / 2);
|
|
66446
|
-
}
|
|
66447
|
-
else {
|
|
66448
|
-
drawingInfo.startY =
|
|
66449
|
-
direction === BeamDirection.Up
|
|
66450
|
-
? this.getFlagTopY(firstBeat, direction)
|
|
66451
|
-
: this.getFlagBottomY(firstBeat, direction);
|
|
66452
|
-
}
|
|
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);
|
|
66453
66341
|
drawingInfo.endBeat = lastBeat;
|
|
66454
|
-
drawingInfo.endX =
|
|
66455
|
-
|
|
66456
|
-
|
|
66457
|
-
|
|
66458
|
-
|
|
66459
|
-
: this.getLineY(h.maxRestSteps / 2);
|
|
66460
|
-
}
|
|
66461
|
-
else {
|
|
66462
|
-
drawingInfo.endY =
|
|
66463
|
-
direction === BeamDirection.Up
|
|
66464
|
-
? this.getFlagTopY(lastBeat, direction)
|
|
66465
|
-
: this.getFlagBottomY(lastBeat, direction);
|
|
66466
|
-
}
|
|
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);
|
|
66467
66347
|
// 2. ensure max slope
|
|
66468
66348
|
// we use the min/max notes to place the beam along their real position
|
|
66469
66349
|
// we only want a maximum of 10 offset for their gradient
|
|
@@ -66488,12 +66368,41 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66488
66368
|
drawingInfo.startY - drawingInfo.endY > maxSlope) {
|
|
66489
66369
|
drawingInfo.startY = drawingInfo.endY + maxSlope;
|
|
66490
66370
|
}
|
|
66491
|
-
// 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
|
|
66492
66401
|
if (h.beats.length > 1) {
|
|
66493
66402
|
// check if highest note shifts bar up or down
|
|
66494
66403
|
if (direction === BeamDirection.Up) {
|
|
66495
|
-
const yNeededForHighestNote = this.
|
|
66496
|
-
const yGivenByCurrentValues = drawingInfo.calcY(
|
|
66404
|
+
const yNeededForHighestNote = barDrawingShift + this.getFlagTopY(h.beatOfHighestNote, direction);
|
|
66405
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(h.beatOfHighestNote, BeatXPosition.Stem));
|
|
66497
66406
|
const diff = yGivenByCurrentValues - yNeededForHighestNote;
|
|
66498
66407
|
if (diff > 0) {
|
|
66499
66408
|
drawingInfo.startY -= diff;
|
|
@@ -66501,8 +66410,8 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66501
66410
|
}
|
|
66502
66411
|
}
|
|
66503
66412
|
else {
|
|
66504
|
-
const yNeededForLowestNote = this.
|
|
66505
|
-
const yGivenByCurrentValues = drawingInfo.calcY(
|
|
66413
|
+
const yNeededForLowestNote = barDrawingShift + this.getFlagBottomY(h.beatOfLowestNote, direction);
|
|
66414
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(h.beatOfLowestNote, BeatXPosition.Stem));
|
|
66506
66415
|
const diff = yNeededForLowestNote - yGivenByCurrentValues;
|
|
66507
66416
|
if (diff > 0) {
|
|
66508
66417
|
drawingInfo.startY += diff;
|
|
@@ -66510,33 +66419,39 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66510
66419
|
}
|
|
66511
66420
|
}
|
|
66512
66421
|
// check if rest shifts bar up or down
|
|
66513
|
-
|
|
66422
|
+
let barSpacing = 0;
|
|
66423
|
+
if (h.restBeats.length > 0) {
|
|
66424
|
+
// space needed for the bars, rests need to be below them
|
|
66514
66425
|
const scaleMod = h.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
66515
|
-
|
|
66516
|
-
|
|
66517
|
-
|
|
66518
|
-
|
|
66519
|
-
|
|
66520
|
-
|
|
66521
|
-
|
|
66522
|
-
drawingInfo.
|
|
66523
|
-
|
|
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
|
+
}
|
|
66524
66439
|
}
|
|
66525
|
-
|
|
66526
|
-
|
|
66527
|
-
|
|
66528
|
-
|
|
66529
|
-
|
|
66530
|
-
|
|
66531
|
-
|
|
66532
|
-
|
|
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
|
+
}
|
|
66533
66448
|
}
|
|
66534
66449
|
}
|
|
66535
66450
|
}
|
|
66536
66451
|
// check if slash shifts bar up or down
|
|
66537
66452
|
if (h.slashBeats.length > 0) {
|
|
66538
66453
|
for (const b of h.slashBeats) {
|
|
66539
|
-
const yGivenByCurrentValues = drawingInfo.calcY(
|
|
66454
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
|
|
66540
66455
|
const yNeededForSlash = h.direction === BeamDirection.Up
|
|
66541
66456
|
? this.getFlagTopY(b, h.direction)
|
|
66542
66457
|
: this.getFlagBottomY(b, h.direction);
|
|
@@ -66548,31 +66463,6 @@ class LineBarRenderer extends BarRendererBase {
|
|
|
66548
66463
|
}
|
|
66549
66464
|
}
|
|
66550
66465
|
}
|
|
66551
|
-
// we can only draw up to 2 beams towards the noteheads, then we have to grow to the other side
|
|
66552
|
-
// here we shift accordingly
|
|
66553
|
-
if (barCount > 2 && !isRest) {
|
|
66554
|
-
const beamSpacing = this.smuflMetrics.beamSpacing * scale;
|
|
66555
|
-
const beamThickness = this.smuflMetrics.beamThickness * scale;
|
|
66556
|
-
const totalBarsHeight = barCount * beamThickness + (barCount - 1) * beamSpacing;
|
|
66557
|
-
if (direction === BeamDirection.Up) {
|
|
66558
|
-
const bottomBarY = drawingInfo.startY + 2 * beamThickness + beamSpacing;
|
|
66559
|
-
const barTopY = bottomBarY - totalBarsHeight;
|
|
66560
|
-
const diff = drawingInfo.startY - barTopY;
|
|
66561
|
-
if (diff > 0) {
|
|
66562
|
-
drawingInfo.startY -= diff;
|
|
66563
|
-
drawingInfo.endY -= diff;
|
|
66564
|
-
}
|
|
66565
|
-
}
|
|
66566
|
-
else {
|
|
66567
|
-
const topBarY = drawingInfo.startY - 2 * beamThickness + beamSpacing;
|
|
66568
|
-
const barBottomY = topBarY + totalBarsHeight;
|
|
66569
|
-
const diff = barBottomY - drawingInfo.startY;
|
|
66570
|
-
if (diff > 0) {
|
|
66571
|
-
drawingInfo.startY += diff;
|
|
66572
|
-
drawingInfo.endY += diff;
|
|
66573
|
-
}
|
|
66574
|
-
}
|
|
66575
|
-
}
|
|
66576
66466
|
}
|
|
66577
66467
|
getMinLineOfBeat(_beat) {
|
|
66578
66468
|
return 0;
|
|
@@ -67093,20 +66983,6 @@ class NumberedBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
67093
66983
|
}
|
|
67094
66984
|
return 0;
|
|
67095
66985
|
}
|
|
67096
|
-
updateBeamingHelper() {
|
|
67097
|
-
if (this.beamingHelper) {
|
|
67098
|
-
let g = null;
|
|
67099
|
-
if (this.noteHeads) {
|
|
67100
|
-
g = this.noteHeads;
|
|
67101
|
-
}
|
|
67102
|
-
else if (this.deadSlapped) {
|
|
67103
|
-
g = this.deadSlapped;
|
|
67104
|
-
}
|
|
67105
|
-
if (g) {
|
|
67106
|
-
this.beamingHelper.registerBeatLineX('numbered', this.container.beat, this.container.x + this.x + g.x, this.container.x + this.x + g.x + g.width);
|
|
67107
|
-
}
|
|
67108
|
-
}
|
|
67109
|
-
}
|
|
67110
66986
|
static majorKeySignatureOneValues = [
|
|
67111
66987
|
// Flats
|
|
67112
66988
|
59, 66, 61, 68, 63, 58, 65,
|
|
@@ -67231,6 +67107,7 @@ class NumberedBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
67231
67107
|
this.onTimeX = this.deadSlapped.x + this.deadSlapped.width / 2;
|
|
67232
67108
|
}
|
|
67233
67109
|
this.middleX = this.onTimeX;
|
|
67110
|
+
this.stemX = this.middleX;
|
|
67234
67111
|
}
|
|
67235
67112
|
}
|
|
67236
67113
|
|
|
@@ -67643,7 +67520,7 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67643
67520
|
const barSize = this.smuflMetrics.numberedBarRendererBarSize;
|
|
67644
67521
|
const barCount = ModelUtils.getIndex(beat.duration) - 2;
|
|
67645
67522
|
const barStart = cy + this.y;
|
|
67646
|
-
const beatLineX = this.getBeatX(beat, BeatXPosition.PreNotes)
|
|
67523
|
+
const beatLineX = this.getBeatX(beat, BeatXPosition.PreNotes);
|
|
67647
67524
|
const beamY = this.calculateBeamY(h, beatLineX);
|
|
67648
67525
|
for (let barIndex = 0; barIndex < barCount; barIndex++) {
|
|
67649
67526
|
let barStartX = 0;
|
|
@@ -67652,11 +67529,11 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67652
67529
|
const barY = barStart + barIndex * barSpacing;
|
|
67653
67530
|
if (i === h.beats.length - 1) {
|
|
67654
67531
|
barStartX = beatLineX;
|
|
67655
|
-
barEndX = this.getBeatX(beat, BeatXPosition.PostNotes)
|
|
67532
|
+
barEndX = this.getBeatX(beat, BeatXPosition.PostNotes);
|
|
67656
67533
|
}
|
|
67657
67534
|
else {
|
|
67658
67535
|
barStartX = beatLineX;
|
|
67659
|
-
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.PreNotes)
|
|
67536
|
+
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.PreNotes);
|
|
67660
67537
|
}
|
|
67661
67538
|
barStartY = barY + beamY;
|
|
67662
67539
|
canvas.fillRect(cx + this.x + barStartX, barStartY, barEndX - barStartX, barSize);
|
|
@@ -67674,7 +67551,7 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67674
67551
|
dotsY = barStart + beamY + barCount * (barSpacing + barSize);
|
|
67675
67552
|
dotsOffset = dotSpacing;
|
|
67676
67553
|
}
|
|
67677
|
-
const dotX = this.getBeatX(beat, BeatXPosition.MiddleNotes)
|
|
67554
|
+
const dotX = this.getBeatX(beat, BeatXPosition.MiddleNotes);
|
|
67678
67555
|
dotCount = Math.abs(dotCount);
|
|
67679
67556
|
for (let d = 0; d < dotCount; d++) {
|
|
67680
67557
|
CanvasHelper.fillMusicFontSymbolSafe(canvas, cx + this.x + dotX, dotsY, 1, MusicFontSymbol.AugmentationDot, true);
|
|
@@ -67723,7 +67600,7 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67723
67600
|
return this.getLineY(0) - noteHeadHeight / 2;
|
|
67724
67601
|
}
|
|
67725
67602
|
createPreBeatGlyphs() {
|
|
67726
|
-
this.
|
|
67603
|
+
this.wasFirstOfStaff = this.isFirstOfStaff;
|
|
67727
67604
|
if (this.index === 0 || (this.bar.masterBar.isRepeatStart && this._isOnlyNumbered)) {
|
|
67728
67605
|
this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
|
|
67729
67606
|
}
|
|
@@ -67779,6 +67656,11 @@ class NumberedBarRenderer extends LineBarRenderer {
|
|
|
67779
67656
|
}
|
|
67780
67657
|
paintBeamingStem(_beat, _cy, _x, _topY, _bottomY, _canvas) {
|
|
67781
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
|
+
}
|
|
67782
67664
|
}
|
|
67783
67665
|
|
|
67784
67666
|
/**
|
|
@@ -68315,9 +68197,8 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68315
68197
|
aboveBeatEffects = new Map();
|
|
68316
68198
|
belowBeatEffects = new Map();
|
|
68317
68199
|
beat;
|
|
68318
|
-
beamingHelper;
|
|
68319
68200
|
get direction() {
|
|
68320
|
-
return this.
|
|
68201
|
+
return this.renderer.getBeatDirection(this.beat);
|
|
68321
68202
|
}
|
|
68322
68203
|
get scale() {
|
|
68323
68204
|
return this.beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
@@ -68359,7 +68240,7 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68359
68240
|
: 0) * scale;
|
|
68360
68241
|
// stem size according to duration
|
|
68361
68242
|
pos -= this.renderer.smuflMetrics.standardStemLength * scale;
|
|
68362
|
-
const topCenterY = this.renderer.centerStaffStemY(this.
|
|
68243
|
+
const topCenterY = this.renderer.centerStaffStemY(this.direction);
|
|
68363
68244
|
return Math.min(topCenterY, pos);
|
|
68364
68245
|
case NoteYPosition.Top:
|
|
68365
68246
|
pos -= n.height / 2;
|
|
@@ -68376,7 +68257,7 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68376
68257
|
: -this.renderer.smuflMetrics.glyphHeights.get(n.symbol) / 2) * scale;
|
|
68377
68258
|
// stem size according to duration
|
|
68378
68259
|
pos += this.renderer.smuflMetrics.standardStemLength * scale;
|
|
68379
|
-
const bottomCenterY = this.renderer.centerStaffStemY(this.
|
|
68260
|
+
const bottomCenterY = this.renderer.centerStaffStemY(this.direction);
|
|
68380
68261
|
return Math.max(bottomCenterY, pos);
|
|
68381
68262
|
case NoteYPosition.StemUp:
|
|
68382
68263
|
pos -=
|
|
@@ -68401,11 +68282,6 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68401
68282
|
addEffectNoteGlyph(noteGlyph, noteLine) {
|
|
68402
68283
|
super.add(noteGlyph, noteLine);
|
|
68403
68284
|
}
|
|
68404
|
-
updateBeamingHelper(cx) {
|
|
68405
|
-
if (this.beamingHelper) {
|
|
68406
|
-
this.beamingHelper.registerBeatLineX('score', this.beat, cx + this.x + this.upLineX, cx + this.x + this.downLineX);
|
|
68407
|
-
}
|
|
68408
|
-
}
|
|
68409
68285
|
doLayout() {
|
|
68410
68286
|
super.doLayout();
|
|
68411
68287
|
const scoreRenderer = this.renderer;
|
|
@@ -68533,7 +68409,6 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
|
|
|
68533
68409
|
* @internal
|
|
68534
68410
|
*/
|
|
68535
68411
|
class ScoreRestGlyph extends MusicFontGlyph {
|
|
68536
|
-
beamingHelper;
|
|
68537
68412
|
constructor(x, y, duration) {
|
|
68538
68413
|
super(x, y, 1, ScoreRestGlyph.getSymbol(duration));
|
|
68539
68414
|
}
|
|
@@ -68565,11 +68440,6 @@ class ScoreRestGlyph extends MusicFontGlyph {
|
|
|
68565
68440
|
return MusicFontSymbol.None;
|
|
68566
68441
|
}
|
|
68567
68442
|
}
|
|
68568
|
-
updateBeamingHelper(cx) {
|
|
68569
|
-
if (this.beamingHelper) {
|
|
68570
|
-
this.beamingHelper.registerBeatLineX('score', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
68571
|
-
}
|
|
68572
|
-
}
|
|
68573
68443
|
paint(cx, cy, canvas) {
|
|
68574
68444
|
this.internalPaint(cx, cy, canvas, BeatSubElement.StandardNotationRests);
|
|
68575
68445
|
}
|
|
@@ -69061,10 +68931,11 @@ class StringNumberContainerGlyph extends EffectGlyph {
|
|
|
69061
68931
|
*/
|
|
69062
68932
|
class SlashNoteHeadGlyph extends MusicFontGlyph {
|
|
69063
68933
|
beatEffects = new Map();
|
|
69064
|
-
beamingHelper;
|
|
69065
68934
|
noteHeadElement = NoteSubElement.SlashNoteHead;
|
|
69066
68935
|
effectElement = BeatSubElement.SlashEffects;
|
|
69067
68936
|
_symbol;
|
|
68937
|
+
upLineX = 0;
|
|
68938
|
+
downLineX = 0;
|
|
69068
68939
|
constructor(x, y, duration, isGrace, beat) {
|
|
69069
68940
|
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, SlashNoteHeadGlyph.getSymbol(duration));
|
|
69070
68941
|
this._symbol = SlashNoteHeadGlyph.getSymbol(duration);
|
|
@@ -69115,6 +68986,15 @@ class SlashNoteHeadGlyph extends MusicFontGlyph {
|
|
|
69115
68986
|
if (!Number.isNaN(minEffectY)) {
|
|
69116
68987
|
this.renderer.registerBeatEffectOverflows(minEffectY, maxEffectY);
|
|
69117
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;
|
|
69118
68998
|
}
|
|
69119
68999
|
static getSymbol(duration) {
|
|
69120
69000
|
switch (duration) {
|
|
@@ -69128,25 +69008,13 @@ class SlashNoteHeadGlyph extends MusicFontGlyph {
|
|
|
69128
69008
|
return MusicFontSymbol.NoteheadSlashHorizontalEnds;
|
|
69129
69009
|
}
|
|
69130
69010
|
}
|
|
69131
|
-
updateBeamingHelper(cx) {
|
|
69132
|
-
if (this.beamingHelper) {
|
|
69133
|
-
const symbol = this._symbol;
|
|
69134
|
-
const stemInfoUp = this.renderer.smuflMetrics.stemUp.has(symbol)
|
|
69135
|
-
? this.renderer.smuflMetrics.stemUp.get(symbol).x
|
|
69136
|
-
: 0;
|
|
69137
|
-
const stemInfoDown = this.renderer.smuflMetrics.stemDown.has(symbol)
|
|
69138
|
-
? this.renderer.smuflMetrics.stemDown.get(symbol).x
|
|
69139
|
-
: 0;
|
|
69140
|
-
this.beamingHelper.registerBeatLineX('slash', this.beat, cx + this.x + stemInfoUp, cx + this.x + stemInfoDown);
|
|
69141
|
-
}
|
|
69142
|
-
}
|
|
69143
69011
|
}
|
|
69144
69012
|
|
|
69145
69013
|
/**
|
|
69146
69014
|
* @internal
|
|
69147
69015
|
*/
|
|
69148
69016
|
class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
69149
|
-
_collisionOffset =
|
|
69017
|
+
_collisionOffset = Number.NaN;
|
|
69150
69018
|
_skipPaint = false;
|
|
69151
69019
|
_whammy;
|
|
69152
69020
|
noteHeads = null;
|
|
@@ -69197,22 +69065,19 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69197
69065
|
getNoteY(note, requestedPosition) {
|
|
69198
69066
|
return this.noteHeads ? this.noteHeads.getNoteY(note, requestedPosition) : 0;
|
|
69199
69067
|
}
|
|
69200
|
-
|
|
69201
|
-
if (this.
|
|
69202
|
-
|
|
69068
|
+
applyRestCollisionOffset() {
|
|
69069
|
+
if (!this.restGlyph) {
|
|
69070
|
+
return;
|
|
69203
69071
|
}
|
|
69204
|
-
|
|
69205
|
-
this.
|
|
69206
|
-
|
|
69207
|
-
|
|
69208
|
-
|
|
69209
|
-
|
|
69210
|
-
|
|
69211
|
-
|
|
69212
|
-
|
|
69213
|
-
this.container.beat.id) {
|
|
69214
|
-
this._skipPaint = true;
|
|
69215
|
-
}
|
|
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;
|
|
69216
69081
|
}
|
|
69217
69082
|
}
|
|
69218
69083
|
}
|
|
@@ -69232,7 +69097,6 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69232
69097
|
const noteHeads = new ScoreNoteChordGlyph();
|
|
69233
69098
|
this.noteHeads = noteHeads;
|
|
69234
69099
|
noteHeads.beat = this.container.beat;
|
|
69235
|
-
noteHeads.beamingHelper = this.beamingHelper;
|
|
69236
69100
|
const ghost = new GhostNoteContainerGlyph(false);
|
|
69237
69101
|
ghost.renderer = this.renderer;
|
|
69238
69102
|
for (const note of this.container.beat.notes) {
|
|
@@ -69282,22 +69146,18 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69282
69146
|
const restGlyph = new ScoreRestGlyph(0, sr.getScoreY(steps), this.container.beat.duration);
|
|
69283
69147
|
this.restGlyph = restGlyph;
|
|
69284
69148
|
restGlyph.beat = this.container.beat;
|
|
69285
|
-
restGlyph.beamingHelper = this.beamingHelper;
|
|
69286
69149
|
this.addNormal(restGlyph);
|
|
69287
69150
|
if (this.renderer.bar.isMultiVoice) {
|
|
69288
69151
|
if (this.container.beat.voice.index === 0) {
|
|
69289
69152
|
const restSizes = BeamingHelper.computeLineHeightsForRest(this.container.beat.duration);
|
|
69290
69153
|
const restTop = restGlyph.y - sr.getScoreHeight(restSizes[0]);
|
|
69291
69154
|
const restBottom = restGlyph.y + sr.getScoreHeight(restSizes[1]);
|
|
69292
|
-
this.renderer.
|
|
69155
|
+
this.renderer.collisionHelper.reserveBeatSlot(this.container.beat, restTop, restBottom);
|
|
69293
69156
|
}
|
|
69294
69157
|
else {
|
|
69295
|
-
this.renderer.
|
|
69158
|
+
this.renderer.collisionHelper.registerRest(this.container.beat);
|
|
69296
69159
|
}
|
|
69297
69160
|
}
|
|
69298
|
-
if (this.beamingHelper) {
|
|
69299
|
-
this.beamingHelper.applyRest(this.container.beat, steps);
|
|
69300
|
-
}
|
|
69301
69161
|
//
|
|
69302
69162
|
// Note dots
|
|
69303
69163
|
//
|
|
@@ -69312,17 +69172,24 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69312
69172
|
}
|
|
69313
69173
|
}
|
|
69314
69174
|
super.doLayout();
|
|
69175
|
+
this.applyRestCollisionOffset();
|
|
69315
69176
|
if (this.container.beat.isEmpty) {
|
|
69316
69177
|
this.onTimeX = this.width / 2;
|
|
69317
69178
|
this.middleX = this.onTimeX;
|
|
69179
|
+
this.stemX = this.middleX;
|
|
69318
69180
|
}
|
|
69319
69181
|
else if (this.restGlyph) {
|
|
69320
69182
|
this.onTimeX = this.restGlyph.x + this.restGlyph.width / 2;
|
|
69321
69183
|
this.middleX = this.onTimeX;
|
|
69184
|
+
this.stemX = this.middleX;
|
|
69322
69185
|
}
|
|
69323
69186
|
else if (this.noteHeads) {
|
|
69324
69187
|
this.onTimeX = this.noteHeads.x + this.noteHeads.onTimeX;
|
|
69325
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);
|
|
69326
69193
|
}
|
|
69327
69194
|
}
|
|
69328
69195
|
_createBeatDot(line, group) {
|
|
@@ -69394,7 +69261,7 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
69394
69261
|
}
|
|
69395
69262
|
const belowBeatEffects = this.noteHeads.belowBeatEffects;
|
|
69396
69263
|
const aboveBeatEffects = this.noteHeads.aboveBeatEffects;
|
|
69397
|
-
const outsideBeatEffects = this.
|
|
69264
|
+
const outsideBeatEffects = this.renderer.getBeatDirection(this.container.beat) === BeamDirection.Up
|
|
69398
69265
|
? this.noteHeads.belowBeatEffects
|
|
69399
69266
|
: this.noteHeads.aboveBeatEffects;
|
|
69400
69267
|
if (n.isStaccato && !belowBeatEffects.has('Staccato')) {
|
|
@@ -69830,7 +69697,7 @@ class ScoreBendGlyph extends ScoreHelperNotesBaseGlyph {
|
|
|
69830
69697
|
// if we have a line break we draw only a line until the end
|
|
69831
69698
|
if (!endNoteRenderer || endNoteRenderer.staff !== startNoteRenderer.staff) {
|
|
69832
69699
|
const endX = cx + startNoteRenderer.x + startNoteRenderer.width;
|
|
69833
|
-
const noteValueToDraw = note.tieDestination.
|
|
69700
|
+
const noteValueToDraw = note.tieDestination.displayValue;
|
|
69834
69701
|
startNoteRenderer.accidentalHelper.applyAccidentalForValue(note.beat, noteValueToDraw, false, true);
|
|
69835
69702
|
const endY = cy +
|
|
69836
69703
|
startNoteRenderer.y +
|
|
@@ -70366,6 +70233,22 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70366
70233
|
doLayout() {
|
|
70367
70234
|
this._effectSlur = null;
|
|
70368
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
|
+
}
|
|
70369
70252
|
super.doLayout();
|
|
70370
70253
|
if (this._bend) {
|
|
70371
70254
|
this._bend.renderer = this.renderer;
|
|
@@ -70375,7 +70258,7 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70375
70258
|
}
|
|
70376
70259
|
getBoundingBoxTop() {
|
|
70377
70260
|
if (this._bend !== null) {
|
|
70378
|
-
return
|
|
70261
|
+
return ModelUtils.minBoundingBox(this._bend.getBoundingBoxTop(), super.getBoundingBoxTop());
|
|
70379
70262
|
}
|
|
70380
70263
|
else {
|
|
70381
70264
|
return super.getBoundingBoxTop();
|
|
@@ -70383,7 +70266,7 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70383
70266
|
}
|
|
70384
70267
|
getBoundingBoxBottom() {
|
|
70385
70268
|
if (this._bend !== null) {
|
|
70386
|
-
return
|
|
70269
|
+
return ModelUtils.maxBoundingBox(this._bend.getBoundingBoxBottom(), super.getBoundingBoxTop());
|
|
70387
70270
|
}
|
|
70388
70271
|
else {
|
|
70389
70272
|
return super.getBoundingBoxBottom();
|
|
@@ -70431,7 +70314,7 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70431
70314
|
}
|
|
70432
70315
|
// end effect slur on last beat
|
|
70433
70316
|
if (!this._effectEndSlur && n.beat.isEffectSlurDestination && n.beat.effectSlurOrigin) {
|
|
70434
|
-
const direction = this.
|
|
70317
|
+
const direction = this.renderer.getBeatDirection(n.beat);
|
|
70435
70318
|
const startNote = direction === BeamDirection.Up ? n.beat.effectSlurOrigin.minNote : n.beat.effectSlurOrigin.maxNote;
|
|
70436
70319
|
const endNote = direction === BeamDirection.Up ? n.beat.minNote : n.beat.maxNote;
|
|
70437
70320
|
const effectEndSlur = new ScoreSlurGlyph(`score.slur.effect.${startNote.beat.id}`, startNote, endNote, true);
|
|
@@ -70470,6 +70353,15 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70470
70353
|
}
|
|
70471
70354
|
}
|
|
70472
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
|
+
}
|
|
70473
70365
|
}
|
|
70474
70366
|
|
|
70475
70367
|
/**
|
|
@@ -70504,7 +70396,7 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70504
70396
|
return this.smuflMetrics.oneStaffSpace;
|
|
70505
70397
|
}
|
|
70506
70398
|
get heightLineCount() {
|
|
70507
|
-
return 5;
|
|
70399
|
+
return Math.max(5, this.bar.staff.standardNotationLineCount);
|
|
70508
70400
|
}
|
|
70509
70401
|
get drawnLineCount() {
|
|
70510
70402
|
return this.bar.staff.standardNotationLineCount;
|
|
@@ -70561,7 +70453,9 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70561
70453
|
slashY -= this.smuflMetrics.stemUp.has(symbol)
|
|
70562
70454
|
? this.smuflMetrics.stemUp.get(symbol).bottomY * scale
|
|
70563
70455
|
: 0;
|
|
70564
|
-
|
|
70456
|
+
if (!beat.isRest) {
|
|
70457
|
+
slashY -= this.smuflMetrics.standardStemLength + scale;
|
|
70458
|
+
}
|
|
70565
70459
|
}
|
|
70566
70460
|
return slashY;
|
|
70567
70461
|
}
|
|
@@ -70570,7 +70464,7 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70570
70464
|
return this.getBeatContainer(beat).onNotes.getNoteY(minNote, direction === BeamDirection.Up ? NoteYPosition.TopWithStem : NoteYPosition.StemDown);
|
|
70571
70465
|
}
|
|
70572
70466
|
let y = this.getScoreY(this.accidentalHelper.getMinSteps(beat));
|
|
70573
|
-
if (direction === BeamDirection.Up) {
|
|
70467
|
+
if (direction === BeamDirection.Up && !beat.isRest) {
|
|
70574
70468
|
const scale = beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
70575
70469
|
y -= this.smuflMetrics.standardStemLength * scale;
|
|
70576
70470
|
}
|
|
@@ -70608,14 +70502,14 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70608
70502
|
getBeamDirection(helper) {
|
|
70609
70503
|
return helper.direction;
|
|
70610
70504
|
}
|
|
70611
|
-
centerStaffStemY(
|
|
70505
|
+
centerStaffStemY(direction) {
|
|
70612
70506
|
const isStandardFive = this.bar.staff.standardNotationLineCount === Staff.DefaultStandardNotationLineCount;
|
|
70613
70507
|
if (isStandardFive) {
|
|
70614
70508
|
// center on the middle line for a standard 5-line staff
|
|
70615
70509
|
return this.getScoreY(this.bar.staff.standardNotationLineCount - 1);
|
|
70616
70510
|
}
|
|
70617
70511
|
// for other staff line counts, we align the stem either on the top or bottom line
|
|
70618
|
-
if (
|
|
70512
|
+
if (direction === BeamDirection.Up) {
|
|
70619
70513
|
return this.getScoreY(this.bar.staff.standardNotationLineCount * 2);
|
|
70620
70514
|
}
|
|
70621
70515
|
return this.getScoreY(0);
|
|
@@ -70717,7 +70611,7 @@ class ScoreBarRenderer extends LineBarRenderer {
|
|
|
70717
70611
|
createLinePreBeatGlyphs() {
|
|
70718
70612
|
// Clef
|
|
70719
70613
|
let hasClef = false;
|
|
70720
|
-
if (this.
|
|
70614
|
+
if (this.isFirstOfStaff ||
|
|
70721
70615
|
this.bar.clef !== this.bar.previousBar.clef ||
|
|
70722
70616
|
this.bar.clefOttava !== this.bar.previousBar.clefOttava) {
|
|
70723
70617
|
// SMUFL: Clefs should be positioned such that the pitch the clef refers to is on the baseline
|
|
@@ -70922,6 +70816,25 @@ class SlashTieGlyph extends NoteTieGlyph {
|
|
|
70922
70816
|
*/
|
|
70923
70817
|
class SlashBeatContainerGlyph extends BeatContainerGlyph {
|
|
70924
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
|
+
}
|
|
70925
70838
|
createTies(n) {
|
|
70926
70839
|
// create a tie if any effect requires it
|
|
70927
70840
|
if (!n.isVisible) {
|
|
@@ -70938,17 +70851,21 @@ class SlashBeatContainerGlyph extends BeatContainerGlyph {
|
|
|
70938
70851
|
this.addTie(tie);
|
|
70939
70852
|
}
|
|
70940
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
|
+
}
|
|
70941
70863
|
}
|
|
70942
70864
|
|
|
70943
70865
|
/**
|
|
70944
70866
|
* @internal
|
|
70945
70867
|
*/
|
|
70946
70868
|
class SlashRestGlyph extends ScoreRestGlyph {
|
|
70947
|
-
updateBeamingHelper(cx) {
|
|
70948
|
-
if (this.beamingHelper) {
|
|
70949
|
-
this.beamingHelper.registerBeatLineX('slash', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
70950
|
-
}
|
|
70951
|
-
}
|
|
70952
70869
|
paint(cx, cy, canvas) {
|
|
70953
70870
|
super.internalPaint(cx, cy, canvas, BeatSubElement.SlashRests);
|
|
70954
70871
|
}
|
|
@@ -71044,19 +70961,6 @@ class SlashBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71044
70961
|
}
|
|
71045
70962
|
return 0;
|
|
71046
70963
|
}
|
|
71047
|
-
updateBeamingHelper() {
|
|
71048
|
-
if (this.noteHeads) {
|
|
71049
|
-
this.noteHeads.updateBeamingHelper(this.container.x + this.x);
|
|
71050
|
-
}
|
|
71051
|
-
else if (this.deadSlapped) {
|
|
71052
|
-
if (this.beamingHelper) {
|
|
71053
|
-
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);
|
|
71054
|
-
}
|
|
71055
|
-
}
|
|
71056
|
-
else if (this.restGlyph) {
|
|
71057
|
-
this.restGlyph.updateBeamingHelper(this.container.x + this.x);
|
|
71058
|
-
}
|
|
71059
|
-
}
|
|
71060
70964
|
doLayout() {
|
|
71061
70965
|
// create glyphs
|
|
71062
70966
|
const sr = this.renderer;
|
|
@@ -71074,18 +70978,13 @@ class SlashBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71074
70978
|
const noteHeadGlyph = new SlashNoteHeadGlyph(0, glyphY, this.container.beat.duration, isGrace, this.container.beat);
|
|
71075
70979
|
this.noteHeads = noteHeadGlyph;
|
|
71076
70980
|
noteHeadGlyph.beat = this.container.beat;
|
|
71077
|
-
noteHeadGlyph.beamingHelper = this.beamingHelper;
|
|
71078
70981
|
this.addNormal(noteHeadGlyph);
|
|
71079
70982
|
}
|
|
71080
70983
|
else {
|
|
71081
70984
|
const restGlyph = new SlashRestGlyph(0, glyphY, this.container.beat.duration);
|
|
71082
70985
|
this.restGlyph = restGlyph;
|
|
71083
70986
|
restGlyph.beat = this.container.beat;
|
|
71084
|
-
restGlyph.beamingHelper = this.beamingHelper;
|
|
71085
70987
|
this.addNormal(restGlyph);
|
|
71086
|
-
if (this.beamingHelper) {
|
|
71087
|
-
this.beamingHelper.applyRest(this.container.beat, 0);
|
|
71088
|
-
}
|
|
71089
70988
|
}
|
|
71090
70989
|
}
|
|
71091
70990
|
//
|
|
@@ -71099,15 +70998,22 @@ class SlashBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71099
70998
|
super.doLayout();
|
|
71100
70999
|
if (this.container.beat.isEmpty) {
|
|
71101
71000
|
this.onTimeX = this.width / 2;
|
|
71001
|
+
this.stemX = this.onTimeX;
|
|
71102
71002
|
}
|
|
71103
71003
|
else if (this.restGlyph) {
|
|
71104
71004
|
this.onTimeX = this.restGlyph.x + this.restGlyph.width / 2;
|
|
71005
|
+
this.stemX = this.onTimeX;
|
|
71105
71006
|
}
|
|
71106
71007
|
else if (this.noteHeads) {
|
|
71107
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);
|
|
71108
71013
|
}
|
|
71109
71014
|
else if (this.deadSlapped) {
|
|
71110
71015
|
this.onTimeX = this.deadSlapped.x + this.deadSlapped.width / 2;
|
|
71016
|
+
this.stemX = this.onTimeX;
|
|
71111
71017
|
}
|
|
71112
71018
|
this.middleX = this.onTimeX;
|
|
71113
71019
|
}
|
|
@@ -71184,7 +71090,9 @@ class SlashBarRenderer extends LineBarRenderer {
|
|
|
71184
71090
|
const symbol = SlashNoteHeadGlyph.getSymbol(beat.duration);
|
|
71185
71091
|
const scale = beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
71186
71092
|
slashY -= this.smuflMetrics.stemUp.has(symbol) ? this.smuflMetrics.stemUp.get(symbol).bottomY * scale : 0;
|
|
71187
|
-
|
|
71093
|
+
if (!beat.isRest) {
|
|
71094
|
+
slashY -= this.smuflMetrics.standardStemLength + scale;
|
|
71095
|
+
}
|
|
71188
71096
|
return slashY;
|
|
71189
71097
|
}
|
|
71190
71098
|
getFlagBottomY(beat, _direction) {
|
|
@@ -71268,6 +71176,11 @@ class SlashBarRenderer extends LineBarRenderer {
|
|
|
71268
71176
|
_?.[Symbol.dispose]?.();
|
|
71269
71177
|
}
|
|
71270
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
|
+
}
|
|
71271
71184
|
}
|
|
71272
71185
|
|
|
71273
71186
|
/**
|
|
@@ -71724,7 +71637,6 @@ class TabNoteChordGlyph extends Glyph {
|
|
|
71724
71637
|
_deadSlapped = null;
|
|
71725
71638
|
_isGrace;
|
|
71726
71639
|
beat;
|
|
71727
|
-
beamingHelper;
|
|
71728
71640
|
maxStringNote = null;
|
|
71729
71641
|
minStringNote = null;
|
|
71730
71642
|
beatEffects = new Map();
|
|
@@ -71873,11 +71785,6 @@ class TabNoteChordGlyph extends Glyph {
|
|
|
71873
71785
|
}
|
|
71874
71786
|
}
|
|
71875
71787
|
}
|
|
71876
|
-
updateBeamingHelper(cx) {
|
|
71877
|
-
if (this.beamingHelper && this.beamingHelper.isPositionFrom('tab', this.beat)) {
|
|
71878
|
-
this.beamingHelper.registerBeatLineX('tab', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
71879
|
-
}
|
|
71880
|
-
}
|
|
71881
71788
|
}
|
|
71882
71789
|
|
|
71883
71790
|
/**
|
|
@@ -71885,7 +71792,6 @@ class TabNoteChordGlyph extends Glyph {
|
|
|
71885
71792
|
*/
|
|
71886
71793
|
class TabRestGlyph extends MusicFontGlyph {
|
|
71887
71794
|
_isVisibleRest;
|
|
71888
|
-
beamingHelper;
|
|
71889
71795
|
constructor(x, y, isVisibleRest, duration) {
|
|
71890
71796
|
super(x, y, 1, ScoreRestGlyph.getSymbol(duration));
|
|
71891
71797
|
this._isVisibleRest = isVisibleRest;
|
|
@@ -71893,11 +71799,6 @@ class TabRestGlyph extends MusicFontGlyph {
|
|
|
71893
71799
|
doLayout() {
|
|
71894
71800
|
super.doLayout();
|
|
71895
71801
|
}
|
|
71896
|
-
updateBeamingHelper(cx) {
|
|
71897
|
-
if (this.beamingHelper && this.beamingHelper.isPositionFrom('tab', this.beat)) {
|
|
71898
|
-
this.beamingHelper.registerBeatLineX('tab', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
71899
|
-
}
|
|
71900
|
-
}
|
|
71901
71802
|
paint(cx, cy, canvas) {
|
|
71902
71803
|
if (this._isVisibleRest) {
|
|
71903
71804
|
const _ = ElementStyleHelper.beat(canvas, BeatSubElement.GuitarTabRests, this.beat);
|
|
@@ -71954,7 +71855,6 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71954
71855
|
slashNoteHead.effectElement = BeatSubElement.GuitarTabEffects;
|
|
71955
71856
|
this.slash = slashNoteHead;
|
|
71956
71857
|
slashNoteHead.beat = this.container.beat;
|
|
71957
|
-
slashNoteHead.beamingHelper = this.beamingHelper;
|
|
71958
71858
|
this.addNormal(slashNoteHead);
|
|
71959
71859
|
beatEffects = slashNoteHead.beatEffects;
|
|
71960
71860
|
}
|
|
@@ -71962,7 +71862,6 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71962
71862
|
const tabNoteNumbers = new TabNoteChordGlyph(0, 0, isGrace);
|
|
71963
71863
|
this.noteNumbers = tabNoteNumbers;
|
|
71964
71864
|
tabNoteNumbers.beat = this.container.beat;
|
|
71965
|
-
tabNoteNumbers.beamingHelper = this.beamingHelper;
|
|
71966
71865
|
for (const note of this.container.beat.notes) {
|
|
71967
71866
|
if (note.isVisible) {
|
|
71968
71867
|
this._createNoteGlyph(note);
|
|
@@ -71984,9 +71883,9 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71984
71883
|
// Note dots
|
|
71985
71884
|
//
|
|
71986
71885
|
if (this.container.beat.dots > 0 && tabRenderer.rhythmMode !== TabRhythmMode.Hidden) {
|
|
71886
|
+
const y = tabRenderer.getFlagAndBarPos();
|
|
71987
71887
|
for (let i = 0; i < this.container.beat.dots; i++) {
|
|
71988
|
-
this.addEffect(new AugmentationDotGlyph(0,
|
|
71989
|
-
tabRenderer.settings.notation.rhythmHeight));
|
|
71888
|
+
this.addEffect(new AugmentationDotGlyph(0, y));
|
|
71990
71889
|
}
|
|
71991
71890
|
}
|
|
71992
71891
|
}
|
|
@@ -71996,7 +71895,6 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
71996
71895
|
const restGlyph = new TabRestGlyph(0, y, tabRenderer.showRests, this.container.beat.duration);
|
|
71997
71896
|
this.restGlyph = restGlyph;
|
|
71998
71897
|
restGlyph.beat = this.container.beat;
|
|
71999
|
-
restGlyph.beamingHelper = this.beamingHelper;
|
|
72000
71898
|
this.addNormal(restGlyph);
|
|
72001
71899
|
//
|
|
72002
71900
|
// Note dots
|
|
@@ -72034,21 +71932,11 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
72034
71932
|
this.onTimeX = this.slash.x + this.slash.width / 2;
|
|
72035
71933
|
}
|
|
72036
71934
|
this.middleX = this.onTimeX;
|
|
71935
|
+
this.stemX = this.middleX;
|
|
72037
71936
|
for (const g of centeredEffectGlyphs) {
|
|
72038
71937
|
g.x = this.onTimeX;
|
|
72039
71938
|
}
|
|
72040
71939
|
}
|
|
72041
|
-
updateBeamingHelper() {
|
|
72042
|
-
if (this.noteNumbers) {
|
|
72043
|
-
this.noteNumbers.updateBeamingHelper(this.container.x + this.x);
|
|
72044
|
-
}
|
|
72045
|
-
else if (this.restGlyph) {
|
|
72046
|
-
this.restGlyph.updateBeamingHelper(this.container.x + this.x);
|
|
72047
|
-
}
|
|
72048
|
-
else if (this.slash) {
|
|
72049
|
-
this.slash.updateBeamingHelper(this.container.x + this.x);
|
|
72050
|
-
}
|
|
72051
|
-
}
|
|
72052
71940
|
_createNoteGlyph(n) {
|
|
72053
71941
|
const tr = this.renderer;
|
|
72054
71942
|
const noteNumberGlyph = new NoteNumberGlyph(0, 0, n);
|
|
@@ -72059,7 +71947,7 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
|
|
|
72059
71947
|
this.noteNumbers.addNoteGlyph(noteNumberGlyph, n);
|
|
72060
71948
|
const topY = noteNumberGlyph.y - noteNumberGlyph.height / 2;
|
|
72061
71949
|
const bottomY = topY + noteNumberGlyph.height;
|
|
72062
|
-
this.renderer.
|
|
71950
|
+
this.renderer.collisionHelper.reserveBeatSlot(this.container.beat, topY, bottomY);
|
|
72063
71951
|
const minString = tr.minString;
|
|
72064
71952
|
const maxString = tr.maxString;
|
|
72065
71953
|
if (Number.isNaN(minString) || minString < n.string) {
|
|
@@ -72331,7 +72219,7 @@ class TabBarRenderer extends LineBarRenderer {
|
|
|
72331
72219
|
}
|
|
72332
72220
|
createLinePreBeatGlyphs() {
|
|
72333
72221
|
// Clef
|
|
72334
|
-
if (this.
|
|
72222
|
+
if (this.isFirstOfStaff) {
|
|
72335
72223
|
const center = (this.bar.staff.tuning.length - 1) / 2;
|
|
72336
72224
|
this.createStartSpacing();
|
|
72337
72225
|
this.addPreBeatGlyph(new TabClefGlyph(0, this.getLineY(center)));
|
|
@@ -72422,14 +72310,14 @@ class TabBarRenderer extends LineBarRenderer {
|
|
|
72422
72310
|
// currently only used for duplets
|
|
72423
72311
|
return this.getFlagAndBarPos();
|
|
72424
72312
|
}
|
|
72425
|
-
shouldPaintFlag(beat
|
|
72426
|
-
if (!super.shouldPaintFlag(beat
|
|
72313
|
+
shouldPaintFlag(beat) {
|
|
72314
|
+
if (!super.shouldPaintFlag(beat)) {
|
|
72427
72315
|
return false;
|
|
72428
72316
|
}
|
|
72429
72317
|
if (beat.graceType !== GraceType.None) {
|
|
72430
72318
|
return false;
|
|
72431
72319
|
}
|
|
72432
|
-
return
|
|
72320
|
+
return true;
|
|
72433
72321
|
}
|
|
72434
72322
|
paintBeamingStem(beat, cy, x, topY, bottomY, canvas) {
|
|
72435
72323
|
if (bottomY < topY) {
|