@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.js
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
|
*
|
|
@@ -209,9 +209,9 @@
|
|
|
209
209
|
* @internal
|
|
210
210
|
*/
|
|
211
211
|
class VersionInfo {
|
|
212
|
-
static version = '1.8.0-alpha.
|
|
213
|
-
static date = '2025-12-
|
|
214
|
-
static commit = '
|
|
212
|
+
static version = '1.8.0-alpha.1643';
|
|
213
|
+
static date = '2025-12-13T02:07:47.380Z';
|
|
214
|
+
static commit = '6cdd7783a14244e9d7efb9f9b9dbad7a27b11eee';
|
|
215
215
|
static print(print) {
|
|
216
216
|
print(`alphaTab ${VersionInfo.version}`);
|
|
217
217
|
print(`commit: ${VersionInfo.commit}`);
|
|
@@ -4721,6 +4721,24 @@
|
|
|
4721
4721
|
static toArticulationId(plain) {
|
|
4722
4722
|
return plain.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
|
|
4723
4723
|
}
|
|
4724
|
+
static minBoundingBox(a, b) {
|
|
4725
|
+
if (Number.isNaN(a)) {
|
|
4726
|
+
return b;
|
|
4727
|
+
}
|
|
4728
|
+
else if (Number.isNaN(b)) {
|
|
4729
|
+
return a;
|
|
4730
|
+
}
|
|
4731
|
+
return a < b ? a : b;
|
|
4732
|
+
}
|
|
4733
|
+
static maxBoundingBox(a, b) {
|
|
4734
|
+
if (Number.isNaN(a)) {
|
|
4735
|
+
return b;
|
|
4736
|
+
}
|
|
4737
|
+
else if (Number.isNaN(b)) {
|
|
4738
|
+
return a;
|
|
4739
|
+
}
|
|
4740
|
+
return a > b ? a : b;
|
|
4741
|
+
}
|
|
4724
4742
|
}
|
|
4725
4743
|
|
|
4726
4744
|
/**
|
|
@@ -48303,6 +48321,39 @@
|
|
|
48303
48321
|
}
|
|
48304
48322
|
}
|
|
48305
48323
|
|
|
48324
|
+
/**
|
|
48325
|
+
* Lists the different position modes for {@link BarRendererBase.getBeatX}
|
|
48326
|
+
* @internal
|
|
48327
|
+
*/
|
|
48328
|
+
var BeatXPosition;
|
|
48329
|
+
(function (BeatXPosition) {
|
|
48330
|
+
/**
|
|
48331
|
+
* Gets the pre-notes position which is located before the accidentals
|
|
48332
|
+
*/
|
|
48333
|
+
BeatXPosition[BeatXPosition["PreNotes"] = 0] = "PreNotes";
|
|
48334
|
+
/**
|
|
48335
|
+
* Gets the on-notes position which is located after the accidentals but before the note heads.
|
|
48336
|
+
*/
|
|
48337
|
+
BeatXPosition[BeatXPosition["OnNotes"] = 1] = "OnNotes";
|
|
48338
|
+
/**
|
|
48339
|
+
* Gets the middle-notes position which is located after in the exact center of the note heads.
|
|
48340
|
+
*/
|
|
48341
|
+
BeatXPosition[BeatXPosition["MiddleNotes"] = 2] = "MiddleNotes";
|
|
48342
|
+
/**
|
|
48343
|
+
* Gets position of the stem for this beat
|
|
48344
|
+
*/
|
|
48345
|
+
BeatXPosition[BeatXPosition["Stem"] = 3] = "Stem";
|
|
48346
|
+
/**
|
|
48347
|
+
* Get the post-notes position which is located at after the note heads.
|
|
48348
|
+
*/
|
|
48349
|
+
BeatXPosition[BeatXPosition["PostNotes"] = 4] = "PostNotes";
|
|
48350
|
+
/**
|
|
48351
|
+
* Get the end-beat position which is located at the end of the beat. This position is almost
|
|
48352
|
+
* equal to the pre-notes position of the next beat.
|
|
48353
|
+
*/
|
|
48354
|
+
BeatXPosition[BeatXPosition["EndBeat"] = 5] = "EndBeat";
|
|
48355
|
+
})(BeatXPosition || (BeatXPosition = {}));
|
|
48356
|
+
|
|
48306
48357
|
/**
|
|
48307
48358
|
* A glyph is a single symbol which can be added to a GlyphBarRenderer for automated
|
|
48308
48359
|
* layouting and drawing of stacked symbols.
|
|
@@ -48330,198 +48381,6 @@
|
|
|
48330
48381
|
}
|
|
48331
48382
|
}
|
|
48332
48383
|
|
|
48333
|
-
/**
|
|
48334
|
-
* Effect-Glyphs implementing this public interface get notified
|
|
48335
|
-
* as they are expanded over multiple beats.
|
|
48336
|
-
* @internal
|
|
48337
|
-
*/
|
|
48338
|
-
class EffectGlyph extends Glyph {
|
|
48339
|
-
/**
|
|
48340
|
-
* Gets or sets the beat where the glyph belongs to.
|
|
48341
|
-
*/
|
|
48342
|
-
beat = null;
|
|
48343
|
-
/**
|
|
48344
|
-
* Gets or sets the next glyph of the same type in case
|
|
48345
|
-
* the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
|
|
48346
|
-
*/
|
|
48347
|
-
nextGlyph = null;
|
|
48348
|
-
/**
|
|
48349
|
-
* Gets or sets the previous glyph of the same type in case
|
|
48350
|
-
* the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
|
|
48351
|
-
*/
|
|
48352
|
-
previousGlyph = null;
|
|
48353
|
-
constructor(x = 0, y = 0) {
|
|
48354
|
-
super(x, y);
|
|
48355
|
-
}
|
|
48356
|
-
}
|
|
48357
|
-
|
|
48358
|
-
/**
|
|
48359
|
-
* @internal
|
|
48360
|
-
*/
|
|
48361
|
-
class MusicFontGlyph extends EffectGlyph {
|
|
48362
|
-
glyphScale = 0;
|
|
48363
|
-
symbol;
|
|
48364
|
-
center = false;
|
|
48365
|
-
colorOverride;
|
|
48366
|
-
offsetX = 0;
|
|
48367
|
-
offsetY = 0;
|
|
48368
|
-
constructor(x, y, glyphScale, symbol) {
|
|
48369
|
-
super(x, y);
|
|
48370
|
-
this.glyphScale = glyphScale;
|
|
48371
|
-
this.symbol = symbol;
|
|
48372
|
-
}
|
|
48373
|
-
getBoundingBoxTop() {
|
|
48374
|
-
const bBoxTop = this.renderer.smuflMetrics.glyphTop.get(this.symbol);
|
|
48375
|
-
return this.y - this.offsetY - bBoxTop;
|
|
48376
|
-
}
|
|
48377
|
-
doLayout() {
|
|
48378
|
-
this.width = this.renderer.smuflMetrics.glyphWidths.get(this.symbol) * this.glyphScale;
|
|
48379
|
-
this.height = this.renderer.smuflMetrics.glyphHeights.get(this.symbol) * this.glyphScale;
|
|
48380
|
-
}
|
|
48381
|
-
paint(cx, cy, canvas) {
|
|
48382
|
-
if (this.width === 0 && this.height === 0) {
|
|
48383
|
-
return;
|
|
48384
|
-
}
|
|
48385
|
-
const c = canvas.color;
|
|
48386
|
-
if (this.colorOverride) {
|
|
48387
|
-
canvas.color = this.colorOverride;
|
|
48388
|
-
}
|
|
48389
|
-
canvas.fillMusicFontSymbol(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbol, this.center);
|
|
48390
|
-
canvas.color = c;
|
|
48391
|
-
}
|
|
48392
|
-
}
|
|
48393
|
-
/**
|
|
48394
|
-
* @internal
|
|
48395
|
-
*/
|
|
48396
|
-
class MusicFontTextGlyph extends EffectGlyph {
|
|
48397
|
-
glyphScale = 0;
|
|
48398
|
-
symbols;
|
|
48399
|
-
center = false;
|
|
48400
|
-
colorOverride;
|
|
48401
|
-
offsetX = 0;
|
|
48402
|
-
offsetY = 0;
|
|
48403
|
-
constructor(x, y, glyphScale, symbols) {
|
|
48404
|
-
super(x, y);
|
|
48405
|
-
this.glyphScale = glyphScale;
|
|
48406
|
-
this.symbols = symbols;
|
|
48407
|
-
}
|
|
48408
|
-
getBoundingBoxTop() {
|
|
48409
|
-
let bBoxTop = 0;
|
|
48410
|
-
for (let i = 0; i < this.symbols.length; i++) {
|
|
48411
|
-
const gTop = this.renderer.smuflMetrics.glyphTop.get(this.symbols[i]);
|
|
48412
|
-
if (i === 0 || gTop < bBoxTop) {
|
|
48413
|
-
bBoxTop = gTop;
|
|
48414
|
-
}
|
|
48415
|
-
}
|
|
48416
|
-
return this.y - this.offsetY - bBoxTop;
|
|
48417
|
-
}
|
|
48418
|
-
doLayout() {
|
|
48419
|
-
this.width = 0;
|
|
48420
|
-
this.height = 0;
|
|
48421
|
-
for (let i = 0; i < this.symbols.length; i++) {
|
|
48422
|
-
const gWidth = this.renderer.smuflMetrics.glyphWidths.get(this.symbols[i]) * this.glyphScale;
|
|
48423
|
-
const gHeight = this.renderer.smuflMetrics.glyphHeights.get(this.symbols[i]) * this.glyphScale;
|
|
48424
|
-
if (i === 0 || gWidth > this.width) {
|
|
48425
|
-
this.width = gWidth;
|
|
48426
|
-
}
|
|
48427
|
-
if (i === 0 || gHeight > this.height) {
|
|
48428
|
-
this.height = gHeight;
|
|
48429
|
-
}
|
|
48430
|
-
}
|
|
48431
|
-
}
|
|
48432
|
-
paint(cx, cy, canvas) {
|
|
48433
|
-
if (this.width === 0 && this.height === 0) {
|
|
48434
|
-
return;
|
|
48435
|
-
}
|
|
48436
|
-
const c = canvas.color;
|
|
48437
|
-
if (this.colorOverride) {
|
|
48438
|
-
canvas.color = this.colorOverride;
|
|
48439
|
-
}
|
|
48440
|
-
canvas.fillMusicFontSymbols(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbols, this.center);
|
|
48441
|
-
canvas.color = c;
|
|
48442
|
-
}
|
|
48443
|
-
}
|
|
48444
|
-
|
|
48445
|
-
/**
|
|
48446
|
-
* @internal
|
|
48447
|
-
*/
|
|
48448
|
-
class NoteHeadGlyph extends MusicFontGlyph {
|
|
48449
|
-
// TODO: SmuFL
|
|
48450
|
-
static GraceScale = 0.75;
|
|
48451
|
-
centerOnStem = false;
|
|
48452
|
-
constructor(x, y, duration, isGrace) {
|
|
48453
|
-
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, NoteHeadGlyph.getSymbol(duration));
|
|
48454
|
-
}
|
|
48455
|
-
paint(cx, cy, canvas) {
|
|
48456
|
-
if (this.centerOnStem) {
|
|
48457
|
-
this.center = true;
|
|
48458
|
-
}
|
|
48459
|
-
super.paint(cx, cy, canvas);
|
|
48460
|
-
}
|
|
48461
|
-
static getSymbol(duration) {
|
|
48462
|
-
switch (duration) {
|
|
48463
|
-
case Duration.QuadrupleWhole:
|
|
48464
|
-
return MusicFontSymbol.NoteheadDoubleWholeSquare;
|
|
48465
|
-
case Duration.DoubleWhole:
|
|
48466
|
-
return MusicFontSymbol.NoteheadDoubleWhole;
|
|
48467
|
-
case Duration.Whole:
|
|
48468
|
-
return MusicFontSymbol.NoteheadWhole;
|
|
48469
|
-
case Duration.Half:
|
|
48470
|
-
return MusicFontSymbol.NoteheadHalf;
|
|
48471
|
-
default:
|
|
48472
|
-
return MusicFontSymbol.NoteheadBlack;
|
|
48473
|
-
}
|
|
48474
|
-
}
|
|
48475
|
-
}
|
|
48476
|
-
|
|
48477
|
-
/**
|
|
48478
|
-
* @internal
|
|
48479
|
-
*/
|
|
48480
|
-
class FlagGlyph extends MusicFontGlyph {
|
|
48481
|
-
constructor(x, y, duration, direction, isGrace) {
|
|
48482
|
-
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, FlagGlyph.getSymbol(duration, direction, isGrace));
|
|
48483
|
-
}
|
|
48484
|
-
static getSymbol(duration, direction, isGrace) {
|
|
48485
|
-
if (isGrace) {
|
|
48486
|
-
duration = Duration.Eighth;
|
|
48487
|
-
}
|
|
48488
|
-
if (direction === BeamDirection.Up) {
|
|
48489
|
-
switch (duration) {
|
|
48490
|
-
case Duration.Eighth:
|
|
48491
|
-
return MusicFontSymbol.Flag8thUp;
|
|
48492
|
-
case Duration.Sixteenth:
|
|
48493
|
-
return MusicFontSymbol.Flag16thUp;
|
|
48494
|
-
case Duration.ThirtySecond:
|
|
48495
|
-
return MusicFontSymbol.Flag32ndUp;
|
|
48496
|
-
case Duration.SixtyFourth:
|
|
48497
|
-
return MusicFontSymbol.Flag64thUp;
|
|
48498
|
-
case Duration.OneHundredTwentyEighth:
|
|
48499
|
-
return MusicFontSymbol.Flag128thUp;
|
|
48500
|
-
case Duration.TwoHundredFiftySixth:
|
|
48501
|
-
return MusicFontSymbol.Flag256thUp;
|
|
48502
|
-
default:
|
|
48503
|
-
return MusicFontSymbol.Flag8thUp;
|
|
48504
|
-
}
|
|
48505
|
-
}
|
|
48506
|
-
switch (duration) {
|
|
48507
|
-
case Duration.Eighth:
|
|
48508
|
-
return MusicFontSymbol.Flag8thDown;
|
|
48509
|
-
case Duration.Sixteenth:
|
|
48510
|
-
return MusicFontSymbol.Flag16thDown;
|
|
48511
|
-
case Duration.ThirtySecond:
|
|
48512
|
-
return MusicFontSymbol.Flag32ndDown;
|
|
48513
|
-
case Duration.SixtyFourth:
|
|
48514
|
-
return MusicFontSymbol.Flag64thDown;
|
|
48515
|
-
case Duration.OneHundredTwentyEighth:
|
|
48516
|
-
return MusicFontSymbol.Flag128thDown;
|
|
48517
|
-
case Duration.TwoHundredFiftySixth:
|
|
48518
|
-
return MusicFontSymbol.Flag128thDown;
|
|
48519
|
-
default:
|
|
48520
|
-
return MusicFontSymbol.Flag8thDown;
|
|
48521
|
-
}
|
|
48522
|
-
}
|
|
48523
|
-
}
|
|
48524
|
-
|
|
48525
48384
|
/**
|
|
48526
48385
|
* @internal
|
|
48527
48386
|
*/
|
|
@@ -48548,28 +48407,20 @@
|
|
|
48548
48407
|
this.renderer.registerTie(tie);
|
|
48549
48408
|
}
|
|
48550
48409
|
getBoundingBoxTop() {
|
|
48551
|
-
return
|
|
48410
|
+
return ModelUtils.minBoundingBox(this.preNotes.getBoundingBoxTop(), this.onNotes.getBoundingBoxTop());
|
|
48552
48411
|
}
|
|
48553
48412
|
getBoundingBoxBottom() {
|
|
48554
|
-
return
|
|
48413
|
+
return ModelUtils.maxBoundingBox(this.preNotes.getBoundingBoxBottom(), this.onNotes.getBoundingBoxBottom());
|
|
48555
48414
|
}
|
|
48556
48415
|
drawBeamHelperAsFlags(helper) {
|
|
48557
48416
|
return helper.hasFlag(false, undefined);
|
|
48558
48417
|
}
|
|
48418
|
+
get postBeatStretch() {
|
|
48419
|
+
return this.onNotes.computedWidth - this.onNotes.onTimeX;
|
|
48420
|
+
}
|
|
48559
48421
|
registerLayoutingInfo(layoutings) {
|
|
48560
48422
|
const preBeatStretch = this.preNotes.computedWidth + this.onNotes.onTimeX;
|
|
48561
|
-
let postBeatStretch = this.
|
|
48562
|
-
// make space for flag
|
|
48563
|
-
const helper = this.renderer.helpers.getBeamingHelperForBeat(this.beat);
|
|
48564
|
-
if (this.beat.graceType !== GraceType.None) {
|
|
48565
|
-
// always use flag size as spacing on grace notes
|
|
48566
|
-
postBeatStretch +=
|
|
48567
|
-
this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
48568
|
-
}
|
|
48569
|
-
else if (helper && this.drawBeamHelperAsFlags(helper)) {
|
|
48570
|
-
postBeatStretch +=
|
|
48571
|
-
this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
48572
|
-
}
|
|
48423
|
+
let postBeatStretch = this.postBeatStretch;
|
|
48573
48424
|
for (const tie of this._ties) {
|
|
48574
48425
|
const tg = tie;
|
|
48575
48426
|
postBeatStretch += tg.width;
|
|
@@ -48584,7 +48435,6 @@
|
|
|
48584
48435
|
});
|
|
48585
48436
|
}
|
|
48586
48437
|
applyLayoutingInfo(_info) {
|
|
48587
|
-
this.onNotes.updateBeamingHelper();
|
|
48588
48438
|
this.updateWidth();
|
|
48589
48439
|
}
|
|
48590
48440
|
doLayout() {
|
|
@@ -48596,7 +48446,6 @@
|
|
|
48596
48446
|
this.onNotes.renderer = this.renderer;
|
|
48597
48447
|
this.onNotes.container = this;
|
|
48598
48448
|
this.onNotes.doLayout();
|
|
48599
|
-
this.onNotes.updateBeamingHelper();
|
|
48600
48449
|
let i = this.beat.notes.length - 1;
|
|
48601
48450
|
while (i >= 0) {
|
|
48602
48451
|
this.createTies(this.beat.notes[i--]);
|
|
@@ -48605,15 +48454,6 @@
|
|
|
48605
48454
|
}
|
|
48606
48455
|
updateWidth() {
|
|
48607
48456
|
this.minWidth = this.preNotes.width + this.onNotes.width;
|
|
48608
|
-
if (!this.beat.isRest) {
|
|
48609
|
-
if (this.onNotes.beamingHelper.beats.length === 1) {
|
|
48610
|
-
// make space for flag
|
|
48611
|
-
if (this.beat.duration >= Duration.Eighth) {
|
|
48612
|
-
const symbol = FlagGlyph.getSymbol(this.beat.duration, this.onNotes.beamingHelper.direction, this.beat.graceType !== GraceType.None);
|
|
48613
|
-
this.minWidth += this.renderer.smuflMetrics.glyphWidths.get(symbol);
|
|
48614
|
-
}
|
|
48615
|
-
}
|
|
48616
|
-
}
|
|
48617
48457
|
let tieWidth = 0;
|
|
48618
48458
|
for (const tie of this._ties) {
|
|
48619
48459
|
const tg = tie;
|
|
@@ -48624,10 +48464,6 @@
|
|
|
48624
48464
|
this.minWidth += tieWidth;
|
|
48625
48465
|
this.width = this.minWidth;
|
|
48626
48466
|
}
|
|
48627
|
-
scaleToWidth(beatWidth) {
|
|
48628
|
-
this.onNotes.updateBeamingHelper();
|
|
48629
|
-
this.width = beatWidth;
|
|
48630
|
-
}
|
|
48631
48467
|
createTies(_n) {
|
|
48632
48468
|
}
|
|
48633
48469
|
static getGroupId(beat) {
|
|
@@ -48637,8 +48473,11 @@
|
|
|
48637
48473
|
// var c = canvas.color;
|
|
48638
48474
|
// canvas.color = Color.random();
|
|
48639
48475
|
// canvas.fillRect(cx + this.x, cy + this.y + this.preNotes.getBoundingBoxTop(), this.width, this.renderer.height);
|
|
48640
|
-
// canvas.color = Color.random();
|
|
48641
48476
|
// canvas.fillRect(cx + this.x, cy + this.y + this.onNotes.getBoundingBoxTop(), this.width, this.renderer.height);
|
|
48477
|
+
// canvas.color = Color.random();
|
|
48478
|
+
// const top = this.getBoundingBoxTop();
|
|
48479
|
+
// const bottom = this.getBoundingBoxBottom();
|
|
48480
|
+
// canvas.fillRect(cx + this.x, cy + this.y + top, this.width, bottom-top);
|
|
48642
48481
|
// canvas.color = c;
|
|
48643
48482
|
// var c = canvas.color;
|
|
48644
48483
|
// var ta = canvas.textAlign;
|
|
@@ -48717,7 +48556,7 @@
|
|
|
48717
48556
|
}
|
|
48718
48557
|
let visualEndX = 0;
|
|
48719
48558
|
if (!this.onNotes.isEmpty) {
|
|
48720
|
-
visualEndX = cx + this.x + this.onNotes.x + this.onNotes.
|
|
48559
|
+
visualEndX = cx + this.x + this.onNotes.x + this.onNotes.onTimeX + this.postBeatStretch;
|
|
48721
48560
|
}
|
|
48722
48561
|
else if (!this.preNotes.isEmpty) {
|
|
48723
48562
|
visualEndX = cx + this.x + this.preNotes.x + this.preNotes.width;
|
|
@@ -48726,12 +48565,6 @@
|
|
|
48726
48565
|
visualEndX = cx + this.x + this.width;
|
|
48727
48566
|
}
|
|
48728
48567
|
beatBoundings.visualBounds.w = visualEndX - beatBoundings.visualBounds.x;
|
|
48729
|
-
const helper = this.renderer.helpers.getBeamingHelperForBeat(this.beat);
|
|
48730
|
-
if ((helper && this.drawBeamHelperAsFlags(helper)) || this.beat.graceType !== GraceType.None) {
|
|
48731
|
-
beatBoundings.visualBounds.w +=
|
|
48732
|
-
this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) *
|
|
48733
|
-
(this.beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1);
|
|
48734
|
-
}
|
|
48735
48568
|
beatBoundings.visualBounds.y = barBounds.visualBounds.y;
|
|
48736
48569
|
beatBoundings.visualBounds.h = barBounds.visualBounds.h;
|
|
48737
48570
|
beatBoundings.realBounds = new Bounds();
|
|
@@ -48746,6 +48579,26 @@
|
|
|
48746
48579
|
this.onNotes.buildBoundingsLookup(beatBoundings, cx + this.x, cy + this.y);
|
|
48747
48580
|
}
|
|
48748
48581
|
}
|
|
48582
|
+
getBeatX(requestedPosition, useSharedSizes = false) {
|
|
48583
|
+
switch (requestedPosition) {
|
|
48584
|
+
case BeatXPosition.PreNotes:
|
|
48585
|
+
return this.preNotes.x;
|
|
48586
|
+
case BeatXPosition.OnNotes:
|
|
48587
|
+
return this.onNotes.x;
|
|
48588
|
+
case BeatXPosition.MiddleNotes:
|
|
48589
|
+
return this.onNotes.x + this.onNotes.middleX;
|
|
48590
|
+
case BeatXPosition.Stem:
|
|
48591
|
+
return this.onNotes.x + this.onNotes.stemX;
|
|
48592
|
+
case BeatXPosition.PostNotes:
|
|
48593
|
+
const onNoteSize = useSharedSizes
|
|
48594
|
+
? (this.renderer.layoutingInfo.getBeatSizes(this.beat)?.onBeatSize ?? this.onNotes.width)
|
|
48595
|
+
: this.onNotes.width;
|
|
48596
|
+
return this.onNotes.x + onNoteSize;
|
|
48597
|
+
case BeatXPosition.EndBeat:
|
|
48598
|
+
return this.width;
|
|
48599
|
+
}
|
|
48600
|
+
return this.preNotes.x;
|
|
48601
|
+
}
|
|
48749
48602
|
}
|
|
48750
48603
|
|
|
48751
48604
|
/**
|
|
@@ -56504,6 +56357,31 @@
|
|
|
56504
56357
|
EffectBarGlyphSizing[EffectBarGlyphSizing["FullBar"] = 5] = "FullBar";
|
|
56505
56358
|
})(EffectBarGlyphSizing || (EffectBarGlyphSizing = {}));
|
|
56506
56359
|
|
|
56360
|
+
/**
|
|
56361
|
+
* Effect-Glyphs implementing this public interface get notified
|
|
56362
|
+
* as they are expanded over multiple beats.
|
|
56363
|
+
* @internal
|
|
56364
|
+
*/
|
|
56365
|
+
class EffectGlyph extends Glyph {
|
|
56366
|
+
/**
|
|
56367
|
+
* Gets or sets the beat where the glyph belongs to.
|
|
56368
|
+
*/
|
|
56369
|
+
beat = null;
|
|
56370
|
+
/**
|
|
56371
|
+
* Gets or sets the next glyph of the same type in case
|
|
56372
|
+
* the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
|
|
56373
|
+
*/
|
|
56374
|
+
nextGlyph = null;
|
|
56375
|
+
/**
|
|
56376
|
+
* Gets or sets the previous glyph of the same type in case
|
|
56377
|
+
* the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
|
|
56378
|
+
*/
|
|
56379
|
+
previousGlyph = null;
|
|
56380
|
+
constructor(x = 0, y = 0) {
|
|
56381
|
+
super(x, y);
|
|
56382
|
+
}
|
|
56383
|
+
}
|
|
56384
|
+
|
|
56507
56385
|
/**
|
|
56508
56386
|
* @internal
|
|
56509
56387
|
*/
|
|
@@ -56631,39 +56509,6 @@
|
|
|
56631
56509
|
}
|
|
56632
56510
|
}
|
|
56633
56511
|
|
|
56634
|
-
/**
|
|
56635
|
-
* Lists the different position modes for {@link BarRendererBase.getBeatX}
|
|
56636
|
-
* @internal
|
|
56637
|
-
*/
|
|
56638
|
-
var BeatXPosition;
|
|
56639
|
-
(function (BeatXPosition) {
|
|
56640
|
-
/**
|
|
56641
|
-
* Gets the pre-notes position which is located before the accidentals
|
|
56642
|
-
*/
|
|
56643
|
-
BeatXPosition[BeatXPosition["PreNotes"] = 0] = "PreNotes";
|
|
56644
|
-
/**
|
|
56645
|
-
* Gets the on-notes position which is located after the accidentals but before the note heads.
|
|
56646
|
-
*/
|
|
56647
|
-
BeatXPosition[BeatXPosition["OnNotes"] = 1] = "OnNotes";
|
|
56648
|
-
/**
|
|
56649
|
-
* Gets the middle-notes position which is located after in the exact center of the note heads.
|
|
56650
|
-
*/
|
|
56651
|
-
BeatXPosition[BeatXPosition["MiddleNotes"] = 2] = "MiddleNotes";
|
|
56652
|
-
/**
|
|
56653
|
-
* Gets position of the stem for this beat
|
|
56654
|
-
*/
|
|
56655
|
-
BeatXPosition[BeatXPosition["Stem"] = 3] = "Stem";
|
|
56656
|
-
/**
|
|
56657
|
-
* Get the post-notes position which is located at after the note heads.
|
|
56658
|
-
*/
|
|
56659
|
-
BeatXPosition[BeatXPosition["PostNotes"] = 4] = "PostNotes";
|
|
56660
|
-
/**
|
|
56661
|
-
* Get the end-beat position which is located at the end of the beat. This position is almost
|
|
56662
|
-
* equal to the pre-notes position of the next beat.
|
|
56663
|
-
*/
|
|
56664
|
-
BeatXPosition[BeatXPosition["EndBeat"] = 5] = "EndBeat";
|
|
56665
|
-
})(BeatXPosition || (BeatXPosition = {}));
|
|
56666
|
-
|
|
56667
56512
|
/**
|
|
56668
56513
|
* @internal
|
|
56669
56514
|
*/
|
|
@@ -57262,6 +57107,93 @@
|
|
|
57262
57107
|
}
|
|
57263
57108
|
}
|
|
57264
57109
|
|
|
57110
|
+
/**
|
|
57111
|
+
* @internal
|
|
57112
|
+
*/
|
|
57113
|
+
class MusicFontGlyph extends EffectGlyph {
|
|
57114
|
+
glyphScale = 0;
|
|
57115
|
+
symbol;
|
|
57116
|
+
center = false;
|
|
57117
|
+
colorOverride;
|
|
57118
|
+
offsetX = 0;
|
|
57119
|
+
offsetY = 0;
|
|
57120
|
+
constructor(x, y, glyphScale, symbol) {
|
|
57121
|
+
super(x, y);
|
|
57122
|
+
this.glyphScale = glyphScale;
|
|
57123
|
+
this.symbol = symbol;
|
|
57124
|
+
}
|
|
57125
|
+
getBoundingBoxTop() {
|
|
57126
|
+
const bBoxTop = this.renderer.smuflMetrics.glyphTop.get(this.symbol);
|
|
57127
|
+
return this.y - this.offsetY - bBoxTop;
|
|
57128
|
+
}
|
|
57129
|
+
doLayout() {
|
|
57130
|
+
this.width = this.renderer.smuflMetrics.glyphWidths.get(this.symbol) * this.glyphScale;
|
|
57131
|
+
this.height = this.renderer.smuflMetrics.glyphHeights.get(this.symbol) * this.glyphScale;
|
|
57132
|
+
}
|
|
57133
|
+
paint(cx, cy, canvas) {
|
|
57134
|
+
if (this.width === 0 && this.height === 0) {
|
|
57135
|
+
return;
|
|
57136
|
+
}
|
|
57137
|
+
const c = canvas.color;
|
|
57138
|
+
if (this.colorOverride) {
|
|
57139
|
+
canvas.color = this.colorOverride;
|
|
57140
|
+
}
|
|
57141
|
+
canvas.fillMusicFontSymbol(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbol, this.center);
|
|
57142
|
+
canvas.color = c;
|
|
57143
|
+
}
|
|
57144
|
+
}
|
|
57145
|
+
/**
|
|
57146
|
+
* @internal
|
|
57147
|
+
*/
|
|
57148
|
+
class MusicFontTextGlyph extends EffectGlyph {
|
|
57149
|
+
glyphScale = 0;
|
|
57150
|
+
symbols;
|
|
57151
|
+
center = false;
|
|
57152
|
+
colorOverride;
|
|
57153
|
+
offsetX = 0;
|
|
57154
|
+
offsetY = 0;
|
|
57155
|
+
constructor(x, y, glyphScale, symbols) {
|
|
57156
|
+
super(x, y);
|
|
57157
|
+
this.glyphScale = glyphScale;
|
|
57158
|
+
this.symbols = symbols;
|
|
57159
|
+
}
|
|
57160
|
+
getBoundingBoxTop() {
|
|
57161
|
+
let bBoxTop = 0;
|
|
57162
|
+
for (let i = 0; i < this.symbols.length; i++) {
|
|
57163
|
+
const gTop = this.renderer.smuflMetrics.glyphTop.get(this.symbols[i]);
|
|
57164
|
+
if (i === 0 || gTop < bBoxTop) {
|
|
57165
|
+
bBoxTop = gTop;
|
|
57166
|
+
}
|
|
57167
|
+
}
|
|
57168
|
+
return this.y - this.offsetY - bBoxTop;
|
|
57169
|
+
}
|
|
57170
|
+
doLayout() {
|
|
57171
|
+
this.width = 0;
|
|
57172
|
+
this.height = 0;
|
|
57173
|
+
for (let i = 0; i < this.symbols.length; i++) {
|
|
57174
|
+
const gWidth = this.renderer.smuflMetrics.glyphWidths.get(this.symbols[i]) * this.glyphScale;
|
|
57175
|
+
const gHeight = this.renderer.smuflMetrics.glyphHeights.get(this.symbols[i]) * this.glyphScale;
|
|
57176
|
+
if (i === 0 || gWidth > this.width) {
|
|
57177
|
+
this.width = gWidth;
|
|
57178
|
+
}
|
|
57179
|
+
if (i === 0 || gHeight > this.height) {
|
|
57180
|
+
this.height = gHeight;
|
|
57181
|
+
}
|
|
57182
|
+
}
|
|
57183
|
+
}
|
|
57184
|
+
paint(cx, cy, canvas) {
|
|
57185
|
+
if (this.width === 0 && this.height === 0) {
|
|
57186
|
+
return;
|
|
57187
|
+
}
|
|
57188
|
+
const c = canvas.color;
|
|
57189
|
+
if (this.colorOverride) {
|
|
57190
|
+
canvas.color = this.colorOverride;
|
|
57191
|
+
}
|
|
57192
|
+
canvas.fillMusicFontSymbols(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbols, this.center);
|
|
57193
|
+
canvas.color = c;
|
|
57194
|
+
}
|
|
57195
|
+
}
|
|
57196
|
+
|
|
57265
57197
|
/**
|
|
57266
57198
|
* @internal
|
|
57267
57199
|
*/
|
|
@@ -57500,17 +57432,6 @@
|
|
|
57500
57432
|
}
|
|
57501
57433
|
}
|
|
57502
57434
|
|
|
57503
|
-
/**
|
|
57504
|
-
* This simple glyph allows to put an empty region in to a BarRenderer.
|
|
57505
|
-
* @internal
|
|
57506
|
-
*/
|
|
57507
|
-
class SpacingGlyph extends Glyph {
|
|
57508
|
-
constructor(x, y, width) {
|
|
57509
|
-
super(x, y);
|
|
57510
|
-
this.width = width;
|
|
57511
|
-
}
|
|
57512
|
-
}
|
|
57513
|
-
|
|
57514
57435
|
/**
|
|
57515
57436
|
* This glyph allows to group several other glyphs to be
|
|
57516
57437
|
* drawn at the same x position
|
|
@@ -57526,34 +57447,20 @@
|
|
|
57526
57447
|
const glyphs = this.glyphs;
|
|
57527
57448
|
if (glyphs) {
|
|
57528
57449
|
for (const g of glyphs) {
|
|
57529
|
-
|
|
57530
|
-
if (g instanceof SpacingGlyph) {
|
|
57531
|
-
continue;
|
|
57532
|
-
}
|
|
57533
|
-
const gTop = g.getBoundingBoxTop();
|
|
57534
|
-
if (Number.isNaN(top) || gTop < top) {
|
|
57535
|
-
top = gTop;
|
|
57536
|
-
}
|
|
57450
|
+
top = ModelUtils.minBoundingBox(top, g.getBoundingBoxTop());
|
|
57537
57451
|
}
|
|
57538
57452
|
}
|
|
57539
|
-
return
|
|
57453
|
+
return top;
|
|
57540
57454
|
}
|
|
57541
57455
|
getBoundingBoxBottom() {
|
|
57542
57456
|
let bottom = Number.NaN;
|
|
57543
57457
|
const glyphs = this.glyphs;
|
|
57544
57458
|
if (glyphs) {
|
|
57545
57459
|
for (const g of glyphs) {
|
|
57546
|
-
|
|
57547
|
-
if (g instanceof SpacingGlyph) {
|
|
57548
|
-
continue;
|
|
57549
|
-
}
|
|
57550
|
-
const gBottom = g.getBoundingBoxBottom();
|
|
57551
|
-
if (Number.isNaN(bottom) || gBottom > bottom) {
|
|
57552
|
-
bottom = gBottom;
|
|
57553
|
-
}
|
|
57460
|
+
bottom = ModelUtils.maxBoundingBox(bottom, g.getBoundingBoxBottom());
|
|
57554
57461
|
}
|
|
57555
57462
|
}
|
|
57556
|
-
return
|
|
57463
|
+
return bottom;
|
|
57557
57464
|
}
|
|
57558
57465
|
doLayout() {
|
|
57559
57466
|
if (!this.glyphs || this.glyphs.length === 0) {
|
|
@@ -57969,6 +57876,38 @@
|
|
|
57969
57876
|
}
|
|
57970
57877
|
}
|
|
57971
57878
|
|
|
57879
|
+
/**
|
|
57880
|
+
* @internal
|
|
57881
|
+
*/
|
|
57882
|
+
class NoteHeadGlyph extends MusicFontGlyph {
|
|
57883
|
+
// TODO: SmuFL
|
|
57884
|
+
static GraceScale = 0.75;
|
|
57885
|
+
centerOnStem = false;
|
|
57886
|
+
constructor(x, y, duration, isGrace) {
|
|
57887
|
+
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, NoteHeadGlyph.getSymbol(duration));
|
|
57888
|
+
}
|
|
57889
|
+
paint(cx, cy, canvas) {
|
|
57890
|
+
if (this.centerOnStem) {
|
|
57891
|
+
this.center = true;
|
|
57892
|
+
}
|
|
57893
|
+
super.paint(cx, cy, canvas);
|
|
57894
|
+
}
|
|
57895
|
+
static getSymbol(duration) {
|
|
57896
|
+
switch (duration) {
|
|
57897
|
+
case Duration.QuadrupleWhole:
|
|
57898
|
+
return MusicFontSymbol.NoteheadDoubleWholeSquare;
|
|
57899
|
+
case Duration.DoubleWhole:
|
|
57900
|
+
return MusicFontSymbol.NoteheadDoubleWhole;
|
|
57901
|
+
case Duration.Whole:
|
|
57902
|
+
return MusicFontSymbol.NoteheadWhole;
|
|
57903
|
+
case Duration.Half:
|
|
57904
|
+
return MusicFontSymbol.NoteheadHalf;
|
|
57905
|
+
default:
|
|
57906
|
+
return MusicFontSymbol.NoteheadBlack;
|
|
57907
|
+
}
|
|
57908
|
+
}
|
|
57909
|
+
}
|
|
57910
|
+
|
|
57972
57911
|
/**
|
|
57973
57912
|
* @internal
|
|
57974
57913
|
*/
|
|
@@ -59587,12 +59526,12 @@
|
|
|
59587
59526
|
// of the next glyph
|
|
59588
59527
|
if (i > 0) {
|
|
59589
59528
|
const beatWidth = currentBeatGlyph.x - beatGlyphs[i - 1].x;
|
|
59590
|
-
beatGlyphs[i - 1].
|
|
59529
|
+
beatGlyphs[i - 1].width = beatWidth;
|
|
59591
59530
|
}
|
|
59592
59531
|
// for the last glyph size based on the full width
|
|
59593
59532
|
if (i === j - 1) {
|
|
59594
59533
|
const beatWidth = this.width - beatGlyphs[beatGlyphs.length - 1].x;
|
|
59595
|
-
currentBeatGlyph.
|
|
59534
|
+
currentBeatGlyph.width = beatWidth;
|
|
59596
59535
|
}
|
|
59597
59536
|
}
|
|
59598
59537
|
}
|
|
@@ -61292,7 +61231,7 @@
|
|
|
61292
61231
|
if (!masterBarBoundsLookup.has(renderer.bar.masterBar.index)) {
|
|
61293
61232
|
masterBarBounds = new MasterBarBounds();
|
|
61294
61233
|
masterBarBounds.index = renderer.bar.masterBar.index;
|
|
61295
|
-
masterBarBounds.isFirstOfLine = renderer.
|
|
61234
|
+
masterBarBounds.isFirstOfLine = renderer.isFirstOfStaff;
|
|
61296
61235
|
masterBarBounds.realBounds = new Bounds();
|
|
61297
61236
|
masterBarBounds.realBounds.x = x + renderer.x;
|
|
61298
61237
|
masterBarBounds.realBounds.y = realTop;
|
|
@@ -61824,11 +61763,9 @@
|
|
|
61824
61763
|
* @internal
|
|
61825
61764
|
*/
|
|
61826
61765
|
class BeatOnNoteGlyphBase extends BeatGlyphBase {
|
|
61827
|
-
beamingHelper;
|
|
61828
61766
|
onTimeX = 0;
|
|
61829
61767
|
middleX = 0;
|
|
61830
|
-
|
|
61831
|
-
}
|
|
61768
|
+
stemX = 0;
|
|
61832
61769
|
buildBoundingsLookup(_beatBounds, _cx, _cy) {
|
|
61833
61770
|
}
|
|
61834
61771
|
getNoteX(_note, _requestedPosition) {
|
|
@@ -61970,14 +61907,6 @@
|
|
|
61970
61907
|
}
|
|
61971
61908
|
}
|
|
61972
61909
|
|
|
61973
|
-
/**
|
|
61974
|
-
* @internal
|
|
61975
|
-
*/
|
|
61976
|
-
class BeatLinePositions {
|
|
61977
|
-
staffId = '';
|
|
61978
|
-
up = 0;
|
|
61979
|
-
down = 0;
|
|
61980
|
-
}
|
|
61981
61910
|
/**
|
|
61982
61911
|
* @internal
|
|
61983
61912
|
*/
|
|
@@ -62008,10 +61937,7 @@
|
|
|
62008
61937
|
*/
|
|
62009
61938
|
class BeamingHelper {
|
|
62010
61939
|
_staff;
|
|
62011
|
-
_beatLineXPositions = new Map();
|
|
62012
61940
|
_renderer;
|
|
62013
|
-
_firstNonRestBeat = null;
|
|
62014
|
-
_lastNonRestBeat = null;
|
|
62015
61941
|
voice = null;
|
|
62016
61942
|
beats = [];
|
|
62017
61943
|
shortestDuration = Duration.QuadrupleWhole;
|
|
@@ -62021,6 +61947,7 @@
|
|
|
62021
61947
|
*/
|
|
62022
61948
|
hasTuplet = false;
|
|
62023
61949
|
slashBeats = [];
|
|
61950
|
+
restBeats = [];
|
|
62024
61951
|
lowestNoteInHelper = null;
|
|
62025
61952
|
_lowestNoteCompareValueInHelper = -1;
|
|
62026
61953
|
highestNoteInHelper = null;
|
|
@@ -62028,25 +61955,21 @@
|
|
|
62028
61955
|
invertBeamDirection = false;
|
|
62029
61956
|
preferredBeamDirection = null;
|
|
62030
61957
|
graceType = GraceType.None;
|
|
62031
|
-
minRestSteps = null;
|
|
62032
|
-
beatOfMinRestSteps = null;
|
|
62033
|
-
maxRestSteps = null;
|
|
62034
|
-
beatOfMaxRestSteps = null;
|
|
62035
61958
|
get isRestBeamHelper() {
|
|
62036
61959
|
return this.beats.length === 1 && this.beats[0].isRest;
|
|
62037
61960
|
}
|
|
62038
|
-
|
|
62039
|
-
return ((forceFlagOnSingleBeat && this.
|
|
62040
|
-
(!forceFlagOnSingleBeat && this.beats.length === 1 && this.
|
|
61961
|
+
hasStem(forceFlagOnSingleBeat, beat) {
|
|
61962
|
+
return ((forceFlagOnSingleBeat && this._beatHasStem(beat)) ||
|
|
61963
|
+
(!forceFlagOnSingleBeat && this.beats.length === 1 && this._beatHasStem(beat)));
|
|
62041
61964
|
}
|
|
62042
|
-
|
|
61965
|
+
_beatHasStem(beat) {
|
|
62043
61966
|
return beat.duration > Duration.Whole;
|
|
62044
61967
|
}
|
|
62045
61968
|
hasFlag(forceFlagOnSingleBeat, beat) {
|
|
62046
|
-
return ((forceFlagOnSingleBeat &&
|
|
62047
|
-
(!forceFlagOnSingleBeat && this.beats.length === 1 &&
|
|
61969
|
+
return ((forceFlagOnSingleBeat && BeamingHelper.beatHasFlag(beat)) ||
|
|
61970
|
+
(!forceFlagOnSingleBeat && this.beats.length === 1 && BeamingHelper.beatHasFlag(this.beats[0])));
|
|
62048
61971
|
}
|
|
62049
|
-
|
|
61972
|
+
static beatHasFlag(beat) {
|
|
62050
61973
|
return (!beat.deadSlapped && !beat.isRest && (beat.duration > Duration.Quarter || beat.graceType !== GraceType.None));
|
|
62051
61974
|
}
|
|
62052
61975
|
constructor(staff, renderer) {
|
|
@@ -62054,38 +61977,12 @@
|
|
|
62054
61977
|
this._renderer = renderer;
|
|
62055
61978
|
this.beats = [];
|
|
62056
61979
|
}
|
|
62057
|
-
|
|
62058
|
-
direction = direction ?? this.direction;
|
|
62059
|
-
if (this.hasBeatLineX(beat)) {
|
|
62060
|
-
if (direction === BeamDirection.Up) {
|
|
62061
|
-
return this._beatLineXPositions.get(beat.index).up;
|
|
62062
|
-
}
|
|
62063
|
-
return this._beatLineXPositions.get(beat.index).down;
|
|
62064
|
-
}
|
|
62065
|
-
return 0;
|
|
62066
|
-
}
|
|
62067
|
-
hasBeatLineX(beat) {
|
|
62068
|
-
return this._beatLineXPositions.has(beat.index);
|
|
62069
|
-
}
|
|
62070
|
-
registerBeatLineX(staffId, beat, up, down) {
|
|
62071
|
-
const positions = this._getOrCreateBeatPositions(beat);
|
|
62072
|
-
positions.staffId = staffId;
|
|
62073
|
-
positions.up = up;
|
|
62074
|
-
positions.down = down;
|
|
61980
|
+
alignWithBeats() {
|
|
62075
61981
|
for (const v of this.drawingInfos.values()) {
|
|
62076
|
-
|
|
62077
|
-
|
|
62078
|
-
|
|
62079
|
-
else if (v.endBeat === beat) {
|
|
62080
|
-
v.endX = this.getBeatLineX(beat);
|
|
62081
|
-
}
|
|
62082
|
-
}
|
|
62083
|
-
}
|
|
62084
|
-
_getOrCreateBeatPositions(beat) {
|
|
62085
|
-
if (!this._beatLineXPositions.has(beat.index)) {
|
|
62086
|
-
this._beatLineXPositions.set(beat.index, new BeatLinePositions());
|
|
61982
|
+
v.startX = this._renderer.getBeatX(v.startBeat, BeatXPosition.Stem);
|
|
61983
|
+
v.endX = this._renderer.getBeatX(v.endBeat, BeatXPosition.Stem);
|
|
61984
|
+
this.drawingInfos.clear();
|
|
62087
61985
|
}
|
|
62088
|
-
return this._beatLineXPositions.get(beat.index);
|
|
62089
61986
|
}
|
|
62090
61987
|
direction = BeamDirection.Up;
|
|
62091
61988
|
finish() {
|
|
@@ -62151,36 +62048,6 @@
|
|
|
62151
62048
|
}
|
|
62152
62049
|
return [0, 0];
|
|
62153
62050
|
}
|
|
62154
|
-
/**
|
|
62155
|
-
* Registers a rest beat within the accidental helper so the rest
|
|
62156
|
-
* symbol is considered properly during beaming.
|
|
62157
|
-
* @param beat The rest beat.
|
|
62158
|
-
* @param steps The steps on which the rest symbol is placed
|
|
62159
|
-
*/
|
|
62160
|
-
applyRest(beat, steps) {
|
|
62161
|
-
// do not accept rests after the last beat which has notes
|
|
62162
|
-
if ((this._lastNonRestBeat && beat.index >= this._lastNonRestBeat.index) ||
|
|
62163
|
-
(this._firstNonRestBeat && beat.index <= this._firstNonRestBeat.index)) {
|
|
62164
|
-
return;
|
|
62165
|
-
}
|
|
62166
|
-
// correct the line of the glyph to a note which would
|
|
62167
|
-
// be placed at the upper / lower end of the glyph.
|
|
62168
|
-
let aboveRest = steps;
|
|
62169
|
-
let belowRest = steps;
|
|
62170
|
-
const offsets = BeamingHelper.computeLineHeightsForRest(beat.duration);
|
|
62171
|
-
aboveRest -= offsets[0];
|
|
62172
|
-
belowRest += offsets[1];
|
|
62173
|
-
const minRestSteps = this.minRestSteps;
|
|
62174
|
-
const maxRestSteps = this.maxRestSteps;
|
|
62175
|
-
if (minRestSteps === null || minRestSteps > aboveRest) {
|
|
62176
|
-
this.minRestSteps = aboveRest;
|
|
62177
|
-
this.beatOfMinRestSteps = beat;
|
|
62178
|
-
}
|
|
62179
|
-
if (maxRestSteps === null || maxRestSteps < belowRest) {
|
|
62180
|
-
this.maxRestSteps = belowRest;
|
|
62181
|
-
this.beatOfMaxRestSteps = beat;
|
|
62182
|
-
}
|
|
62183
|
-
}
|
|
62184
62051
|
_invert(direction) {
|
|
62185
62052
|
if (!this.invertBeamDirection) {
|
|
62186
62053
|
return direction;
|
|
@@ -62244,14 +62111,13 @@
|
|
|
62244
62111
|
if (this.shortestDuration < beat.duration) {
|
|
62245
62112
|
this.shortestDuration = beat.duration;
|
|
62246
62113
|
}
|
|
62247
|
-
if (!this._firstNonRestBeat) {
|
|
62248
|
-
this._firstNonRestBeat = beat;
|
|
62249
|
-
}
|
|
62250
|
-
this._lastNonRestBeat = beat;
|
|
62251
62114
|
}
|
|
62252
62115
|
else if (this.beats.length === 0) {
|
|
62253
62116
|
this.beats.push(beat);
|
|
62254
62117
|
}
|
|
62118
|
+
else {
|
|
62119
|
+
this.restBeats.push(beat);
|
|
62120
|
+
}
|
|
62255
62121
|
if (beat.slashed) {
|
|
62256
62122
|
this.slashBeats.push(beat);
|
|
62257
62123
|
}
|
|
@@ -62360,19 +62226,6 @@
|
|
|
62360
62226
|
get beatOfHighestNote() {
|
|
62361
62227
|
return this.highestNoteInHelper.beat;
|
|
62362
62228
|
}
|
|
62363
|
-
/**
|
|
62364
|
-
* Returns whether the the position of the given beat, was registered by the staff of the given ID
|
|
62365
|
-
* @param staffId
|
|
62366
|
-
* @param beat
|
|
62367
|
-
* @returns
|
|
62368
|
-
*/
|
|
62369
|
-
isPositionFrom(staffId, beat) {
|
|
62370
|
-
if (!this._beatLineXPositions.has(beat.index)) {
|
|
62371
|
-
return true;
|
|
62372
|
-
}
|
|
62373
|
-
return (this._beatLineXPositions.get(beat.index).staffId === staffId ||
|
|
62374
|
-
!this._beatLineXPositions.get(beat.index).staffId);
|
|
62375
|
-
}
|
|
62376
62229
|
drawingInfos = new Map();
|
|
62377
62230
|
}
|
|
62378
62231
|
|
|
@@ -62524,8 +62377,8 @@
|
|
|
62524
62377
|
*/
|
|
62525
62378
|
class BarHelpers {
|
|
62526
62379
|
_renderer;
|
|
62380
|
+
_beamHelperLookup = new Map();
|
|
62527
62381
|
beamHelpers = [];
|
|
62528
|
-
beamHelperLookup = [];
|
|
62529
62382
|
collisionHelper;
|
|
62530
62383
|
preferredBeamDirection = null;
|
|
62531
62384
|
constructor(renderer) {
|
|
@@ -62540,7 +62393,6 @@
|
|
|
62540
62393
|
for (let i = 0, j = bar.voices.length; i < j; i++) {
|
|
62541
62394
|
const v = bar.voices[i];
|
|
62542
62395
|
this.beamHelpers.push([]);
|
|
62543
|
-
this.beamHelperLookup.push(new Map());
|
|
62544
62396
|
for (let k = 0, l = v.beats.length; k < l; k++) {
|
|
62545
62397
|
const b = v.beats[k];
|
|
62546
62398
|
let helperForBeat;
|
|
@@ -62549,6 +62401,9 @@
|
|
|
62549
62401
|
}
|
|
62550
62402
|
else {
|
|
62551
62403
|
helperForBeat = currentBeamHelper;
|
|
62404
|
+
if (currentGraceBeamHelper) {
|
|
62405
|
+
currentGraceBeamHelper.finish();
|
|
62406
|
+
}
|
|
62552
62407
|
currentGraceBeamHelper = null;
|
|
62553
62408
|
}
|
|
62554
62409
|
// if a new beaming helper was started, we close our tuplet grouping as well
|
|
@@ -62569,7 +62424,7 @@
|
|
|
62569
62424
|
}
|
|
62570
62425
|
this.beamHelpers[v.index].push(helperForBeat);
|
|
62571
62426
|
}
|
|
62572
|
-
this.
|
|
62427
|
+
this._beamHelperLookup.set(b.id, helperForBeat);
|
|
62573
62428
|
}
|
|
62574
62429
|
if (currentBeamHelper) {
|
|
62575
62430
|
currentBeamHelper.finish();
|
|
@@ -62582,7 +62437,7 @@
|
|
|
62582
62437
|
}
|
|
62583
62438
|
}
|
|
62584
62439
|
getBeamingHelperForBeat(beat) {
|
|
62585
|
-
return this.
|
|
62440
|
+
return this._beamHelperLookup.has(beat.id) ? this._beamHelperLookup.get(beat.id) : undefined;
|
|
62586
62441
|
}
|
|
62587
62442
|
}
|
|
62588
62443
|
|
|
@@ -62692,6 +62547,9 @@
|
|
|
62692
62547
|
return this._contentBottomOverflow + this.bottomEffects.height;
|
|
62693
62548
|
}
|
|
62694
62549
|
helpers;
|
|
62550
|
+
get collisionHelper() {
|
|
62551
|
+
return this.helpers.collisionHelper;
|
|
62552
|
+
}
|
|
62695
62553
|
/**
|
|
62696
62554
|
* Gets or sets whether this renderer is linked to the next one
|
|
62697
62555
|
* by some glyphs like a vibrato effect
|
|
@@ -62751,6 +62609,11 @@
|
|
|
62751
62609
|
for (const container of this._voiceContainers.values()) {
|
|
62752
62610
|
container.scaleToWidth(containerWidth);
|
|
62753
62611
|
}
|
|
62612
|
+
for (const v of this.helpers.beamHelpers) {
|
|
62613
|
+
for (const h of v) {
|
|
62614
|
+
h.alignWithBeats();
|
|
62615
|
+
}
|
|
62616
|
+
}
|
|
62754
62617
|
this._postBeatGlyphs.x = this._preBeatGlyphs.x + this._preBeatGlyphs.width + containerWidth;
|
|
62755
62618
|
this.width = width;
|
|
62756
62619
|
this.topEffects.alignGlyphs();
|
|
@@ -62779,10 +62642,13 @@
|
|
|
62779
62642
|
get barDisplayWidth() {
|
|
62780
62643
|
return this.staff.system.staves.length > 1 ? this.bar.masterBar.displayWidth : this.bar.displayWidth;
|
|
62781
62644
|
}
|
|
62782
|
-
|
|
62783
|
-
get
|
|
62645
|
+
wasFirstOfStaff = false;
|
|
62646
|
+
get isFirstOfStaff() {
|
|
62784
62647
|
return this.index === 0;
|
|
62785
62648
|
}
|
|
62649
|
+
get isLastOfStaff() {
|
|
62650
|
+
return this.index === this.staff.barRenderers.length - 1;
|
|
62651
|
+
}
|
|
62786
62652
|
get isLast() {
|
|
62787
62653
|
return !this.bar || this.bar.index === this.scoreRenderer.layout.lastBarIndex;
|
|
62788
62654
|
}
|
|
@@ -62997,6 +62863,18 @@
|
|
|
62997
62863
|
}
|
|
62998
62864
|
}
|
|
62999
62865
|
}
|
|
62866
|
+
for (const v of this._voiceContainers.values()) {
|
|
62867
|
+
for (const b of v.beatGlyphs) {
|
|
62868
|
+
const topY = b.getBoundingBoxTop();
|
|
62869
|
+
if (topY < 0) {
|
|
62870
|
+
this.registerOverflowTop(topY * -1);
|
|
62871
|
+
}
|
|
62872
|
+
const bottomY = b.getBoundingBoxBottom();
|
|
62873
|
+
if (bottomY > rendererBottom) {
|
|
62874
|
+
this.registerOverflowBottom(bottomY - rendererBottom);
|
|
62875
|
+
}
|
|
62876
|
+
}
|
|
62877
|
+
}
|
|
63000
62878
|
const beatEffectsMinY = this.beatEffectsMinY;
|
|
63001
62879
|
if (!Number.isNaN(beatEffectsMinY)) {
|
|
63002
62880
|
const beatEffectTopOverflow = -beatEffectsMinY;
|
|
@@ -63050,7 +62928,6 @@
|
|
|
63050
62928
|
g.renderer = this;
|
|
63051
62929
|
g.preNotes.renderer = this;
|
|
63052
62930
|
g.onNotes.renderer = this;
|
|
63053
|
-
g.onNotes.beamingHelper = this.helpers.beamHelperLookup[g.beat.voice.index].get(g.beat.index);
|
|
63054
62931
|
this.getVoiceContainer(g.beat.voice).addGlyph(g);
|
|
63055
62932
|
}
|
|
63056
62933
|
getVoiceContainer(voice) {
|
|
@@ -63129,7 +63006,7 @@
|
|
|
63129
63006
|
this._postBeatGlyphs.addGlyph(g);
|
|
63130
63007
|
}
|
|
63131
63008
|
createPreBeatGlyphs() {
|
|
63132
|
-
this.
|
|
63009
|
+
this.wasFirstOfStaff = this.isFirstOfStaff;
|
|
63133
63010
|
}
|
|
63134
63011
|
createBeatGlyphs() {
|
|
63135
63012
|
for (const voice of this.bar.voices) {
|
|
@@ -63156,26 +63033,7 @@
|
|
|
63156
63033
|
getBeatX(beat, requestedPosition = BeatXPosition.PreNotes, useSharedSizes = false) {
|
|
63157
63034
|
const container = this.getBeatContainer(beat);
|
|
63158
63035
|
if (container) {
|
|
63159
|
-
|
|
63160
|
-
case BeatXPosition.PreNotes:
|
|
63161
|
-
return container.voiceContainer.x + container.x;
|
|
63162
|
-
case BeatXPosition.OnNotes:
|
|
63163
|
-
return container.voiceContainer.x + container.x + container.onNotes.x;
|
|
63164
|
-
case BeatXPosition.MiddleNotes:
|
|
63165
|
-
return container.voiceContainer.x + container.x + container.onNotes.x + container.onNotes.middleX;
|
|
63166
|
-
case BeatXPosition.Stem:
|
|
63167
|
-
const offset = container.onNotes.beamingHelper
|
|
63168
|
-
? container.onNotes.beamingHelper.getBeatLineX(beat)
|
|
63169
|
-
: container.onNotes.x + container.onNotes.width / 2;
|
|
63170
|
-
return container.voiceContainer.x + offset;
|
|
63171
|
-
case BeatXPosition.PostNotes:
|
|
63172
|
-
const onNoteSize = useSharedSizes
|
|
63173
|
-
? (this.layoutingInfo.getBeatSizes(beat)?.onBeatSize ?? container.onNotes.width)
|
|
63174
|
-
: container.onNotes.width;
|
|
63175
|
-
return container.voiceContainer.x + container.x + container.onNotes.x + onNoteSize;
|
|
63176
|
-
case BeatXPosition.EndBeat:
|
|
63177
|
-
return container.voiceContainer.x + container.x + container.width;
|
|
63178
|
-
}
|
|
63036
|
+
return container.voiceContainer.x + container.x + container.getBeatX(requestedPosition, useSharedSizes);
|
|
63179
63037
|
}
|
|
63180
63038
|
return 0;
|
|
63181
63039
|
}
|
|
@@ -63210,7 +63068,7 @@
|
|
|
63210
63068
|
this.updateSizes();
|
|
63211
63069
|
// there are some glyphs which are shown only for renderers at the line start, so we simply recreate them
|
|
63212
63070
|
// 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
|
|
63213
|
-
if ((this.
|
|
63071
|
+
if ((this.wasFirstOfStaff && !this.isFirstOfStaff) || (!this.wasFirstOfStaff && this.isFirstOfStaff)) {
|
|
63214
63072
|
this.recreatePreBeatGlyphs();
|
|
63215
63073
|
this._postBeatGlyphs.doLayout();
|
|
63216
63074
|
}
|
|
@@ -63247,7 +63105,7 @@
|
|
|
63247
63105
|
completeBeamingHelper(_helper) {
|
|
63248
63106
|
}
|
|
63249
63107
|
getBeatDirection(beat) {
|
|
63250
|
-
return this.helpers.getBeamingHelperForBeat(beat).
|
|
63108
|
+
return this.helpers.getBeamingHelperForBeat(beat)?.direction ?? BeamDirection.Up;
|
|
63251
63109
|
}
|
|
63252
63110
|
}
|
|
63253
63111
|
|
|
@@ -65614,8 +65472,18 @@
|
|
|
65614
65472
|
}
|
|
65615
65473
|
const lineRenderer = this.renderer;
|
|
65616
65474
|
const lineYOffset = lineRenderer.smuflMetrics.staffLineThickness;
|
|
65617
|
-
|
|
65618
|
-
|
|
65475
|
+
let top = this.y;
|
|
65476
|
+
let bottom = this.y;
|
|
65477
|
+
if (lineRenderer.drawnLineCount < 2 ||
|
|
65478
|
+
(!this._isRight && lineRenderer.isFirstOfStaff) ||
|
|
65479
|
+
(this._isRight && lineRenderer.isLastOfStaff)) {
|
|
65480
|
+
top -= lineYOffset;
|
|
65481
|
+
bottom += lineRenderer.height;
|
|
65482
|
+
}
|
|
65483
|
+
else {
|
|
65484
|
+
top += lineRenderer.getLineY(0);
|
|
65485
|
+
bottom += lineRenderer.getLineY(lineRenderer.drawnLineCount - 1);
|
|
65486
|
+
}
|
|
65619
65487
|
const h = bottom - top;
|
|
65620
65488
|
// round up to have pixel-aligned bar lines, x-shift will be used during rendering
|
|
65621
65489
|
// to avoid shifting again all glyphs
|
|
@@ -65701,6 +65569,54 @@
|
|
|
65701
65569
|
}
|
|
65702
65570
|
}
|
|
65703
65571
|
|
|
65572
|
+
/**
|
|
65573
|
+
* @internal
|
|
65574
|
+
*/
|
|
65575
|
+
class FlagGlyph extends MusicFontGlyph {
|
|
65576
|
+
constructor(x, y, duration, direction, isGrace) {
|
|
65577
|
+
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, FlagGlyph.getSymbol(duration, direction, isGrace));
|
|
65578
|
+
}
|
|
65579
|
+
static getSymbol(duration, direction, isGrace) {
|
|
65580
|
+
if (isGrace) {
|
|
65581
|
+
duration = Duration.Eighth;
|
|
65582
|
+
}
|
|
65583
|
+
if (direction === BeamDirection.Up) {
|
|
65584
|
+
switch (duration) {
|
|
65585
|
+
case Duration.Eighth:
|
|
65586
|
+
return MusicFontSymbol.Flag8thUp;
|
|
65587
|
+
case Duration.Sixteenth:
|
|
65588
|
+
return MusicFontSymbol.Flag16thUp;
|
|
65589
|
+
case Duration.ThirtySecond:
|
|
65590
|
+
return MusicFontSymbol.Flag32ndUp;
|
|
65591
|
+
case Duration.SixtyFourth:
|
|
65592
|
+
return MusicFontSymbol.Flag64thUp;
|
|
65593
|
+
case Duration.OneHundredTwentyEighth:
|
|
65594
|
+
return MusicFontSymbol.Flag128thUp;
|
|
65595
|
+
case Duration.TwoHundredFiftySixth:
|
|
65596
|
+
return MusicFontSymbol.Flag256thUp;
|
|
65597
|
+
default:
|
|
65598
|
+
return MusicFontSymbol.Flag8thUp;
|
|
65599
|
+
}
|
|
65600
|
+
}
|
|
65601
|
+
switch (duration) {
|
|
65602
|
+
case Duration.Eighth:
|
|
65603
|
+
return MusicFontSymbol.Flag8thDown;
|
|
65604
|
+
case Duration.Sixteenth:
|
|
65605
|
+
return MusicFontSymbol.Flag16thDown;
|
|
65606
|
+
case Duration.ThirtySecond:
|
|
65607
|
+
return MusicFontSymbol.Flag32ndDown;
|
|
65608
|
+
case Duration.SixtyFourth:
|
|
65609
|
+
return MusicFontSymbol.Flag64thDown;
|
|
65610
|
+
case Duration.OneHundredTwentyEighth:
|
|
65611
|
+
return MusicFontSymbol.Flag128thDown;
|
|
65612
|
+
case Duration.TwoHundredFiftySixth:
|
|
65613
|
+
return MusicFontSymbol.Flag128thDown;
|
|
65614
|
+
default:
|
|
65615
|
+
return MusicFontSymbol.Flag8thDown;
|
|
65616
|
+
}
|
|
65617
|
+
}
|
|
65618
|
+
}
|
|
65619
|
+
|
|
65704
65620
|
/**
|
|
65705
65621
|
* @internal
|
|
65706
65622
|
*/
|
|
@@ -65736,6 +65652,23 @@
|
|
|
65736
65652
|
}
|
|
65737
65653
|
}
|
|
65738
65654
|
|
|
65655
|
+
/**
|
|
65656
|
+
* This simple glyph allows to put an empty region in to a BarRenderer.
|
|
65657
|
+
* @internal
|
|
65658
|
+
*/
|
|
65659
|
+
class SpacingGlyph extends Glyph {
|
|
65660
|
+
constructor(x, y, width) {
|
|
65661
|
+
super(x, y);
|
|
65662
|
+
this.width = width;
|
|
65663
|
+
}
|
|
65664
|
+
getBoundingBoxTop() {
|
|
65665
|
+
return Number.NaN;
|
|
65666
|
+
}
|
|
65667
|
+
getBoundingBoxBottom() {
|
|
65668
|
+
return Number.NaN;
|
|
65669
|
+
}
|
|
65670
|
+
}
|
|
65671
|
+
|
|
65739
65672
|
/**
|
|
65740
65673
|
* This is a base class for any bar renderer which renders music notation on a staff
|
|
65741
65674
|
* with lines like Standard Notation, Guitar Tablatures and Slash Notation.
|
|
@@ -65859,7 +65792,7 @@
|
|
|
65859
65792
|
if (this.hasVoiceContainer(voice)) {
|
|
65860
65793
|
const container = this.getVoiceContainer(voice);
|
|
65861
65794
|
for (const tupletGroup of container.tupletGroups) {
|
|
65862
|
-
this._paintTupletHelper(cx
|
|
65795
|
+
this._paintTupletHelper(cx, cy, canvas, tupletGroup, beatElement, bracketsAsArcs);
|
|
65863
65796
|
}
|
|
65864
65797
|
}
|
|
65865
65798
|
}
|
|
@@ -65933,26 +65866,27 @@
|
|
|
65933
65866
|
// check if we need to paint simple footer
|
|
65934
65867
|
const offset = this.tupletOffset;
|
|
65935
65868
|
const size = this.tupletSize;
|
|
65869
|
+
const shift = offset + size * 0.5;
|
|
65936
65870
|
const _ = ElementStyleHelper.beat(canvas, beatElement, h.beats[0]);
|
|
65937
65871
|
try {
|
|
65938
65872
|
const l = canvas.lineWidth;
|
|
65939
65873
|
canvas.lineWidth = this.smuflMetrics.tupletBracketThickness;
|
|
65940
65874
|
if (h.beats.length === 1 || !h.isFull) {
|
|
65941
65875
|
for (const beat of h.beats) {
|
|
65942
|
-
const beamingHelper = this.helpers.
|
|
65876
|
+
const beamingHelper = this.helpers.getBeamingHelperForBeat(beat);
|
|
65943
65877
|
if (!beamingHelper) {
|
|
65944
65878
|
continue;
|
|
65945
65879
|
}
|
|
65946
65880
|
const direction = this.getTupletBeamDirection(beamingHelper);
|
|
65947
|
-
const tupletX =
|
|
65881
|
+
const tupletX = this.getBeatX(beat, BeatXPosition.Stem);
|
|
65948
65882
|
let tupletY = this.calculateBeamYWithDirection(beamingHelper, tupletX, direction);
|
|
65949
65883
|
if (direction === BeamDirection.Down) {
|
|
65950
|
-
tupletY +=
|
|
65884
|
+
tupletY += shift;
|
|
65951
65885
|
}
|
|
65952
65886
|
else {
|
|
65953
|
-
tupletY -=
|
|
65887
|
+
tupletY -= shift;
|
|
65954
65888
|
}
|
|
65955
|
-
canvas.fillMusicFontSymbols(cx + this.x + tupletX, cy + this.y + tupletY, 1, s, true);
|
|
65889
|
+
canvas.fillMusicFontSymbols(cx + this.x + tupletX, cy + this.y + tupletY + size * 0.5, 1, s, true);
|
|
65956
65890
|
}
|
|
65957
65891
|
}
|
|
65958
65892
|
else {
|
|
@@ -65982,12 +65916,12 @@
|
|
|
65982
65916
|
}
|
|
65983
65917
|
//
|
|
65984
65918
|
// Calculate the overall area of the tuplet bracket
|
|
65985
|
-
const startX = this.getBeatX(firstBeat, BeatXPosition.OnNotes)
|
|
65986
|
-
const endX = this.getBeatX(lastBeat, BeatXPosition.PostNotes)
|
|
65919
|
+
const startX = this.getBeatX(firstBeat, BeatXPosition.OnNotes);
|
|
65920
|
+
const endX = this.getBeatX(lastBeat, BeatXPosition.PostNotes);
|
|
65987
65921
|
//
|
|
65988
65922
|
// calculate the y positions for our bracket
|
|
65989
|
-
const firstNonRestBeamingHelper = this.helpers.
|
|
65990
|
-
const lastNonRestBeamingHelper = this.helpers.
|
|
65923
|
+
const firstNonRestBeamingHelper = this.helpers.getBeamingHelperForBeat(firstNonRestBeat);
|
|
65924
|
+
const lastNonRestBeamingHelper = this.helpers.getBeamingHelperForBeat(lastNonRestBeat);
|
|
65991
65925
|
const direction = this.getTupletBeamDirection(firstNonRestBeamingHelper);
|
|
65992
65926
|
let startY = this.calculateBeamYWithDirection(firstNonRestBeamingHelper, startX, direction);
|
|
65993
65927
|
let endY = this.calculateBeamYWithDirection(lastNonRestBeamingHelper, endX, direction);
|
|
@@ -65996,7 +65930,6 @@
|
|
|
65996
65930
|
endY = startY;
|
|
65997
65931
|
}
|
|
65998
65932
|
// align line centered in available space
|
|
65999
|
-
const shift = offset + size * 0.5;
|
|
66000
65933
|
if (direction === BeamDirection.Down) {
|
|
66001
65934
|
startY += shift;
|
|
66002
65935
|
endY += shift;
|
|
@@ -66061,14 +65994,24 @@
|
|
|
66061
65994
|
paintBeams(cx, cy, canvas, flagsElement, beamsElement) {
|
|
66062
65995
|
for (const v of this.helpers.beamHelpers) {
|
|
66063
65996
|
for (const h of v) {
|
|
66064
|
-
this.
|
|
65997
|
+
this.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
|
|
66065
65998
|
}
|
|
66066
65999
|
}
|
|
66067
66000
|
}
|
|
66068
66001
|
drawBeamHelperAsFlags(h) {
|
|
66069
66002
|
return h.beats.length === 1;
|
|
66070
66003
|
}
|
|
66071
|
-
|
|
66004
|
+
hasFlag(beat) {
|
|
66005
|
+
if (beat.isRest) {
|
|
66006
|
+
return false;
|
|
66007
|
+
}
|
|
66008
|
+
const helper = this.helpers.getBeamingHelperForBeat(beat);
|
|
66009
|
+
if (helper) {
|
|
66010
|
+
return helper.hasFlag(this.drawBeamHelperAsFlags(helper), beat);
|
|
66011
|
+
}
|
|
66012
|
+
return BeamingHelper.beatHasFlag(beat);
|
|
66013
|
+
}
|
|
66014
|
+
paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
|
|
66072
66015
|
canvas.color = h.voice.index === 0 ? this.resources.mainGlyphColor : this.resources.secondaryGlyphColor;
|
|
66073
66016
|
if (!h.isRestBeamHelper) {
|
|
66074
66017
|
if (this.drawBeamHelperAsFlags(h)) {
|
|
@@ -66079,7 +66022,7 @@
|
|
|
66079
66022
|
}
|
|
66080
66023
|
}
|
|
66081
66024
|
}
|
|
66082
|
-
shouldPaintFlag(beat
|
|
66025
|
+
shouldPaintFlag(beat) {
|
|
66083
66026
|
// no flags for bend grace beats
|
|
66084
66027
|
if (beat.graceType === GraceType.BendGrace) {
|
|
66085
66028
|
return false;
|
|
@@ -66087,10 +66030,6 @@
|
|
|
66087
66030
|
if (beat.deadSlapped) {
|
|
66088
66031
|
return false;
|
|
66089
66032
|
}
|
|
66090
|
-
// we don't have an X-position: cannot paint a flag
|
|
66091
|
-
if (!h.hasBeatLineX(beat)) {
|
|
66092
|
-
return false;
|
|
66093
|
-
}
|
|
66094
66033
|
// no flags for any grace notes on songbook mode
|
|
66095
66034
|
if (beat.graceType !== GraceType.None && this.settings.notation.notationMode === exports.NotationMode.SongBook) {
|
|
66096
66035
|
return false;
|
|
@@ -66105,14 +66044,14 @@
|
|
|
66105
66044
|
}
|
|
66106
66045
|
paintFlag(cx, cy, canvas, h, flagsElement) {
|
|
66107
66046
|
for (const beat of h.beats) {
|
|
66108
|
-
if (!this.shouldPaintFlag(beat
|
|
66047
|
+
if (!this.shouldPaintFlag(beat)) {
|
|
66109
66048
|
continue;
|
|
66110
66049
|
}
|
|
66111
66050
|
const isGrace = beat.graceType !== GraceType.None;
|
|
66112
66051
|
//
|
|
66113
66052
|
// draw line
|
|
66114
66053
|
//
|
|
66115
|
-
const beatLineX =
|
|
66054
|
+
const beatLineX = this.getBeatX(beat, BeatXPosition.Stem);
|
|
66116
66055
|
const direction = this.getBeamDirection(h);
|
|
66117
66056
|
const topY = cy + this.y + this.getFlagTopY(beat, direction);
|
|
66118
66057
|
const bottomY = cy + this.y + this.getFlagBottomY(beat, direction);
|
|
@@ -66123,7 +66062,7 @@
|
|
|
66123
66062
|
else {
|
|
66124
66063
|
flagY = topY;
|
|
66125
66064
|
}
|
|
66126
|
-
if (!h.
|
|
66065
|
+
if (!h.hasStem(true, beat)) {
|
|
66127
66066
|
continue;
|
|
66128
66067
|
}
|
|
66129
66068
|
this.paintBeamingStem(beat, cy + this.y, cx + this.x + beatLineX, topY, bottomY, canvas);
|
|
@@ -66209,10 +66148,10 @@
|
|
|
66209
66148
|
}
|
|
66210
66149
|
for (let i = 0, j = h.beats.length; i < j; i++) {
|
|
66211
66150
|
const beat = h.beats[i];
|
|
66212
|
-
if (
|
|
66151
|
+
if (beat.deadSlapped) {
|
|
66213
66152
|
continue;
|
|
66214
66153
|
}
|
|
66215
|
-
const beatLineX =
|
|
66154
|
+
const beatLineX = this.getBeatX(beat, BeatXPosition.Stem);
|
|
66216
66155
|
const y1 = cy + this.y + this.getBarLineStart(beat, direction);
|
|
66217
66156
|
// ensure we are pixel aligned on the end of the stem to avoid anti-aliasing artifacts
|
|
66218
66157
|
// when combining stems and beams on sub-pixel level
|
|
@@ -66250,7 +66189,7 @@
|
|
|
66250
66189
|
barEndY = barY + this.calculateBeamY(h, barEndX);
|
|
66251
66190
|
LineBarRenderer.paintSingleBar(canvas, cx + this.x + barStartX, barStartY, cx + this.x + barEndX, barEndY, barSize);
|
|
66252
66191
|
// end part
|
|
66253
|
-
barEndX =
|
|
66192
|
+
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.Stem);
|
|
66254
66193
|
barStartX = barEndX - brokenBarOffset;
|
|
66255
66194
|
barStartY = barY + this.calculateBeamY(h, barStartX);
|
|
66256
66195
|
barEndY = barY + this.calculateBeamY(h, barEndX);
|
|
@@ -66260,7 +66199,7 @@
|
|
|
66260
66199
|
if (isFullBarJoin) {
|
|
66261
66200
|
// full bar?
|
|
66262
66201
|
barStartX = beatLineX;
|
|
66263
|
-
barEndX =
|
|
66202
|
+
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.Stem);
|
|
66264
66203
|
}
|
|
66265
66204
|
else if (i === 0 || !BeamingHelper.isFullBarJoin(h.beats[i - 1], beat, barIndex)) {
|
|
66266
66205
|
barStartX = beatLineX;
|
|
@@ -66295,7 +66234,7 @@
|
|
|
66295
66234
|
}
|
|
66296
66235
|
}
|
|
66297
66236
|
if (h.graceType === GraceType.BeforeBeat) {
|
|
66298
|
-
const beatLineX =
|
|
66237
|
+
const beatLineX = this.getBeatX(h.beats[0], BeatXPosition.Stem);
|
|
66299
66238
|
const flagWidth = this.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
66300
66239
|
let slashY = (cy + this.y + this.calculateBeamY(h, beatLineX)) | 0;
|
|
66301
66240
|
slashY += barSize + barSpacing;
|
|
@@ -66322,20 +66261,7 @@
|
|
|
66322
66261
|
const noteOverflowPadding = this.getLineHeight(0.5);
|
|
66323
66262
|
for (const v of this.helpers.beamHelpers) {
|
|
66324
66263
|
for (const h of v) {
|
|
66325
|
-
if (h.isRestBeamHelper)
|
|
66326
|
-
if (h.minRestSteps) {
|
|
66327
|
-
const topY = this.getLineY(h.maxRestSteps / 2) - noteOverflowPadding;
|
|
66328
|
-
if (topY < maxNoteY) {
|
|
66329
|
-
maxNoteY = topY;
|
|
66330
|
-
}
|
|
66331
|
-
}
|
|
66332
|
-
if (h.maxRestSteps) {
|
|
66333
|
-
const bottomY = this.getLineY(h.maxRestSteps & 2) + noteOverflowPadding;
|
|
66334
|
-
if (bottomY < maxNoteY) {
|
|
66335
|
-
maxNoteY = bottomY;
|
|
66336
|
-
}
|
|
66337
|
-
}
|
|
66338
|
-
}
|
|
66264
|
+
if (h.isRestBeamHelper) ;
|
|
66339
66265
|
else if (h.beats.length === 1 && h.beats[0].duration >= Duration.Half) {
|
|
66340
66266
|
if (h.direction === BeamDirection.Up) {
|
|
66341
66267
|
let topY = this.getFlagTopY(h.beats[0], h.direction);
|
|
@@ -66386,17 +66312,6 @@
|
|
|
66386
66312
|
}
|
|
66387
66313
|
}
|
|
66388
66314
|
}
|
|
66389
|
-
const beatContainer = this.getBeatContainer(h.beats[0]);
|
|
66390
|
-
if (beatContainer) {
|
|
66391
|
-
const bBoxTop = beatContainer.getBoundingBoxTop();
|
|
66392
|
-
const bBoxBottom = beatContainer.getBoundingBoxBottom();
|
|
66393
|
-
if (bBoxBottom > minNoteY) {
|
|
66394
|
-
minNoteY = bBoxBottom;
|
|
66395
|
-
}
|
|
66396
|
-
if (bBoxTop < maxNoteY) {
|
|
66397
|
-
maxNoteY = bBoxTop;
|
|
66398
|
-
}
|
|
66399
|
-
}
|
|
66400
66315
|
}
|
|
66401
66316
|
}
|
|
66402
66317
|
if (maxNoteY < rendererTop) {
|
|
@@ -66412,25 +66327,6 @@
|
|
|
66412
66327
|
}
|
|
66413
66328
|
const scale = h.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
66414
66329
|
const barCount = ModelUtils.getIndex(h.shortestDuration) - 2;
|
|
66415
|
-
let stemSize = this.smuflMetrics.standardStemLength * scale;
|
|
66416
|
-
if (h.tremoloDuration) {
|
|
66417
|
-
// for 16th and shorter beats we need more space for all tremolos
|
|
66418
|
-
// for 8th beats we need only more space for 32nd tremolos
|
|
66419
|
-
// the logic here is not perfect but there is no SMuFL guideline
|
|
66420
|
-
// on how tremolos need to extend stems
|
|
66421
|
-
const oneBeamSize = (this.smuflMetrics.beamThickness + this.smuflMetrics.beamSpacing) * scale;
|
|
66422
|
-
if (h.shortestDuration > Duration.Eighth) {
|
|
66423
|
-
if (h.tremoloDuration === Duration.Eighth) {
|
|
66424
|
-
stemSize += oneBeamSize;
|
|
66425
|
-
}
|
|
66426
|
-
else {
|
|
66427
|
-
stemSize += oneBeamSize * 1.5;
|
|
66428
|
-
}
|
|
66429
|
-
}
|
|
66430
|
-
else if (h.tremoloDuration === Duration.ThirtySecond) {
|
|
66431
|
-
stemSize += oneBeamSize * 1.5;
|
|
66432
|
-
}
|
|
66433
|
-
}
|
|
66434
66330
|
const drawingInfo = new BeamingHelperDrawInfo();
|
|
66435
66331
|
h.drawingInfos.set(direction, drawingInfo);
|
|
66436
66332
|
// the beaming logic works like this:
|
|
@@ -66443,33 +66339,17 @@
|
|
|
66443
66339
|
const isRest = h.isRestBeamHelper;
|
|
66444
66340
|
// 1. put direct diagonal line.
|
|
66445
66341
|
drawingInfo.startBeat = firstBeat;
|
|
66446
|
-
drawingInfo.startX =
|
|
66447
|
-
|
|
66448
|
-
|
|
66449
|
-
|
|
66450
|
-
|
|
66451
|
-
: this.getLineY(h.maxRestSteps / 2);
|
|
66452
|
-
}
|
|
66453
|
-
else {
|
|
66454
|
-
drawingInfo.startY =
|
|
66455
|
-
direction === BeamDirection.Up
|
|
66456
|
-
? this.getFlagTopY(firstBeat, direction)
|
|
66457
|
-
: this.getFlagBottomY(firstBeat, direction);
|
|
66458
|
-
}
|
|
66342
|
+
drawingInfo.startX = this.getBeatX(firstBeat, BeatXPosition.Stem);
|
|
66343
|
+
drawingInfo.startY =
|
|
66344
|
+
direction === BeamDirection.Up
|
|
66345
|
+
? this.getFlagTopY(firstBeat, direction)
|
|
66346
|
+
: this.getFlagBottomY(firstBeat, direction);
|
|
66459
66347
|
drawingInfo.endBeat = lastBeat;
|
|
66460
|
-
drawingInfo.endX =
|
|
66461
|
-
|
|
66462
|
-
|
|
66463
|
-
|
|
66464
|
-
|
|
66465
|
-
: this.getLineY(h.maxRestSteps / 2);
|
|
66466
|
-
}
|
|
66467
|
-
else {
|
|
66468
|
-
drawingInfo.endY =
|
|
66469
|
-
direction === BeamDirection.Up
|
|
66470
|
-
? this.getFlagTopY(lastBeat, direction)
|
|
66471
|
-
: this.getFlagBottomY(lastBeat, direction);
|
|
66472
|
-
}
|
|
66348
|
+
drawingInfo.endX = this.getBeatX(lastBeat, BeatXPosition.Stem);
|
|
66349
|
+
drawingInfo.endY =
|
|
66350
|
+
direction === BeamDirection.Up
|
|
66351
|
+
? this.getFlagTopY(lastBeat, direction)
|
|
66352
|
+
: this.getFlagBottomY(lastBeat, direction);
|
|
66473
66353
|
// 2. ensure max slope
|
|
66474
66354
|
// we use the min/max notes to place the beam along their real position
|
|
66475
66355
|
// we only want a maximum of 10 offset for their gradient
|
|
@@ -66494,12 +66374,41 @@
|
|
|
66494
66374
|
drawingInfo.startY - drawingInfo.endY > maxSlope) {
|
|
66495
66375
|
drawingInfo.startY = drawingInfo.endY + maxSlope;
|
|
66496
66376
|
}
|
|
66497
|
-
// 3.
|
|
66377
|
+
// 3. adjust beam drawing order
|
|
66378
|
+
// we can only draw up to 2 beams towards the noteheads, then we have to grow to the other side
|
|
66379
|
+
// here we shift accordingly
|
|
66380
|
+
let barDrawingShift = 0;
|
|
66381
|
+
if (barCount > 2 && !isRest) {
|
|
66382
|
+
const beamSpacing = this.smuflMetrics.beamSpacing * scale;
|
|
66383
|
+
const beamThickness = this.smuflMetrics.beamThickness * scale;
|
|
66384
|
+
const totalBarsHeight = barCount * beamThickness + (barCount - 1) * beamSpacing;
|
|
66385
|
+
if (direction === BeamDirection.Up) {
|
|
66386
|
+
const bottomBarY = drawingInfo.startY + 2 * beamThickness + beamSpacing;
|
|
66387
|
+
const barTopY = bottomBarY - totalBarsHeight;
|
|
66388
|
+
const diff = drawingInfo.startY - barTopY;
|
|
66389
|
+
if (diff > 0) {
|
|
66390
|
+
barDrawingShift = diff * -1;
|
|
66391
|
+
drawingInfo.startY -= diff;
|
|
66392
|
+
drawingInfo.endY -= diff;
|
|
66393
|
+
}
|
|
66394
|
+
}
|
|
66395
|
+
else {
|
|
66396
|
+
const topBarY = drawingInfo.startY - 2 * beamThickness + beamSpacing;
|
|
66397
|
+
const barBottomY = topBarY + totalBarsHeight;
|
|
66398
|
+
const diff = barBottomY - drawingInfo.startY;
|
|
66399
|
+
if (diff > 0) {
|
|
66400
|
+
barDrawingShift = diff;
|
|
66401
|
+
drawingInfo.startY += diff;
|
|
66402
|
+
drawingInfo.endY += diff;
|
|
66403
|
+
}
|
|
66404
|
+
}
|
|
66405
|
+
}
|
|
66406
|
+
// 4. let middle elements shift up/down
|
|
66498
66407
|
if (h.beats.length > 1) {
|
|
66499
66408
|
// check if highest note shifts bar up or down
|
|
66500
66409
|
if (direction === BeamDirection.Up) {
|
|
66501
|
-
const yNeededForHighestNote = this.
|
|
66502
|
-
const yGivenByCurrentValues = drawingInfo.calcY(
|
|
66410
|
+
const yNeededForHighestNote = barDrawingShift + this.getFlagTopY(h.beatOfHighestNote, direction);
|
|
66411
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(h.beatOfHighestNote, BeatXPosition.Stem));
|
|
66503
66412
|
const diff = yGivenByCurrentValues - yNeededForHighestNote;
|
|
66504
66413
|
if (diff > 0) {
|
|
66505
66414
|
drawingInfo.startY -= diff;
|
|
@@ -66507,8 +66416,8 @@
|
|
|
66507
66416
|
}
|
|
66508
66417
|
}
|
|
66509
66418
|
else {
|
|
66510
|
-
const yNeededForLowestNote = this.
|
|
66511
|
-
const yGivenByCurrentValues = drawingInfo.calcY(
|
|
66419
|
+
const yNeededForLowestNote = barDrawingShift + this.getFlagBottomY(h.beatOfLowestNote, direction);
|
|
66420
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(h.beatOfLowestNote, BeatXPosition.Stem));
|
|
66512
66421
|
const diff = yNeededForLowestNote - yGivenByCurrentValues;
|
|
66513
66422
|
if (diff > 0) {
|
|
66514
66423
|
drawingInfo.startY += diff;
|
|
@@ -66516,33 +66425,39 @@
|
|
|
66516
66425
|
}
|
|
66517
66426
|
}
|
|
66518
66427
|
// check if rest shifts bar up or down
|
|
66519
|
-
|
|
66428
|
+
let barSpacing = 0;
|
|
66429
|
+
if (h.restBeats.length > 0) {
|
|
66430
|
+
// space needed for the bars, rests need to be below them
|
|
66520
66431
|
const scaleMod = h.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
66521
|
-
|
|
66522
|
-
|
|
66523
|
-
|
|
66524
|
-
|
|
66525
|
-
|
|
66526
|
-
|
|
66527
|
-
|
|
66528
|
-
drawingInfo.
|
|
66529
|
-
|
|
66432
|
+
barSpacing = barCount * (this.smuflMetrics.beamSpacing + this.smuflMetrics.beamThickness) * scaleMod;
|
|
66433
|
+
}
|
|
66434
|
+
for (const b of h.restBeats) {
|
|
66435
|
+
// rest beats which are "under" the beam
|
|
66436
|
+
if (b.isRest && b.index < h.beats[h.beats.length - 1].index) {
|
|
66437
|
+
if (direction === BeamDirection.Up) {
|
|
66438
|
+
const yNeededForRest = this.getBeatContainer(b).getBoundingBoxTop() - barSpacing;
|
|
66439
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
|
|
66440
|
+
const diff = yGivenByCurrentValues - yNeededForRest;
|
|
66441
|
+
if (diff > 0) {
|
|
66442
|
+
drawingInfo.startY -= diff;
|
|
66443
|
+
drawingInfo.endY -= diff;
|
|
66444
|
+
}
|
|
66530
66445
|
}
|
|
66531
|
-
|
|
66532
|
-
|
|
66533
|
-
|
|
66534
|
-
|
|
66535
|
-
|
|
66536
|
-
|
|
66537
|
-
|
|
66538
|
-
|
|
66446
|
+
else if (direction === BeamDirection.Down) {
|
|
66447
|
+
const yNeededForRest = this.getBeatContainer(b).getBoundingBoxBottom() + barSpacing;
|
|
66448
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
|
|
66449
|
+
const diff = yNeededForRest - yGivenByCurrentValues;
|
|
66450
|
+
if (diff > 0) {
|
|
66451
|
+
drawingInfo.startY += diff;
|
|
66452
|
+
drawingInfo.endY += diff;
|
|
66453
|
+
}
|
|
66539
66454
|
}
|
|
66540
66455
|
}
|
|
66541
66456
|
}
|
|
66542
66457
|
// check if slash shifts bar up or down
|
|
66543
66458
|
if (h.slashBeats.length > 0) {
|
|
66544
66459
|
for (const b of h.slashBeats) {
|
|
66545
|
-
const yGivenByCurrentValues = drawingInfo.calcY(
|
|
66460
|
+
const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
|
|
66546
66461
|
const yNeededForSlash = h.direction === BeamDirection.Up
|
|
66547
66462
|
? this.getFlagTopY(b, h.direction)
|
|
66548
66463
|
: this.getFlagBottomY(b, h.direction);
|
|
@@ -66554,31 +66469,6 @@
|
|
|
66554
66469
|
}
|
|
66555
66470
|
}
|
|
66556
66471
|
}
|
|
66557
|
-
// we can only draw up to 2 beams towards the noteheads, then we have to grow to the other side
|
|
66558
|
-
// here we shift accordingly
|
|
66559
|
-
if (barCount > 2 && !isRest) {
|
|
66560
|
-
const beamSpacing = this.smuflMetrics.beamSpacing * scale;
|
|
66561
|
-
const beamThickness = this.smuflMetrics.beamThickness * scale;
|
|
66562
|
-
const totalBarsHeight = barCount * beamThickness + (barCount - 1) * beamSpacing;
|
|
66563
|
-
if (direction === BeamDirection.Up) {
|
|
66564
|
-
const bottomBarY = drawingInfo.startY + 2 * beamThickness + beamSpacing;
|
|
66565
|
-
const barTopY = bottomBarY - totalBarsHeight;
|
|
66566
|
-
const diff = drawingInfo.startY - barTopY;
|
|
66567
|
-
if (diff > 0) {
|
|
66568
|
-
drawingInfo.startY -= diff;
|
|
66569
|
-
drawingInfo.endY -= diff;
|
|
66570
|
-
}
|
|
66571
|
-
}
|
|
66572
|
-
else {
|
|
66573
|
-
const topBarY = drawingInfo.startY - 2 * beamThickness + beamSpacing;
|
|
66574
|
-
const barBottomY = topBarY + totalBarsHeight;
|
|
66575
|
-
const diff = barBottomY - drawingInfo.startY;
|
|
66576
|
-
if (diff > 0) {
|
|
66577
|
-
drawingInfo.startY += diff;
|
|
66578
|
-
drawingInfo.endY += diff;
|
|
66579
|
-
}
|
|
66580
|
-
}
|
|
66581
|
-
}
|
|
66582
66472
|
}
|
|
66583
66473
|
getMinLineOfBeat(_beat) {
|
|
66584
66474
|
return 0;
|
|
@@ -67099,20 +66989,6 @@
|
|
|
67099
66989
|
}
|
|
67100
66990
|
return 0;
|
|
67101
66991
|
}
|
|
67102
|
-
updateBeamingHelper() {
|
|
67103
|
-
if (this.beamingHelper) {
|
|
67104
|
-
let g = null;
|
|
67105
|
-
if (this.noteHeads) {
|
|
67106
|
-
g = this.noteHeads;
|
|
67107
|
-
}
|
|
67108
|
-
else if (this.deadSlapped) {
|
|
67109
|
-
g = this.deadSlapped;
|
|
67110
|
-
}
|
|
67111
|
-
if (g) {
|
|
67112
|
-
this.beamingHelper.registerBeatLineX('numbered', this.container.beat, this.container.x + this.x + g.x, this.container.x + this.x + g.x + g.width);
|
|
67113
|
-
}
|
|
67114
|
-
}
|
|
67115
|
-
}
|
|
67116
66992
|
static majorKeySignatureOneValues = [
|
|
67117
66993
|
// Flats
|
|
67118
66994
|
59, 66, 61, 68, 63, 58, 65,
|
|
@@ -67237,6 +67113,7 @@
|
|
|
67237
67113
|
this.onTimeX = this.deadSlapped.x + this.deadSlapped.width / 2;
|
|
67238
67114
|
}
|
|
67239
67115
|
this.middleX = this.onTimeX;
|
|
67116
|
+
this.stemX = this.middleX;
|
|
67240
67117
|
}
|
|
67241
67118
|
}
|
|
67242
67119
|
|
|
@@ -67649,7 +67526,7 @@
|
|
|
67649
67526
|
const barSize = this.smuflMetrics.numberedBarRendererBarSize;
|
|
67650
67527
|
const barCount = ModelUtils.getIndex(beat.duration) - 2;
|
|
67651
67528
|
const barStart = cy + this.y;
|
|
67652
|
-
const beatLineX = this.getBeatX(beat, BeatXPosition.PreNotes)
|
|
67529
|
+
const beatLineX = this.getBeatX(beat, BeatXPosition.PreNotes);
|
|
67653
67530
|
const beamY = this.calculateBeamY(h, beatLineX);
|
|
67654
67531
|
for (let barIndex = 0; barIndex < barCount; barIndex++) {
|
|
67655
67532
|
let barStartX = 0;
|
|
@@ -67658,11 +67535,11 @@
|
|
|
67658
67535
|
const barY = barStart + barIndex * barSpacing;
|
|
67659
67536
|
if (i === h.beats.length - 1) {
|
|
67660
67537
|
barStartX = beatLineX;
|
|
67661
|
-
barEndX = this.getBeatX(beat, BeatXPosition.PostNotes)
|
|
67538
|
+
barEndX = this.getBeatX(beat, BeatXPosition.PostNotes);
|
|
67662
67539
|
}
|
|
67663
67540
|
else {
|
|
67664
67541
|
barStartX = beatLineX;
|
|
67665
|
-
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.PreNotes)
|
|
67542
|
+
barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.PreNotes);
|
|
67666
67543
|
}
|
|
67667
67544
|
barStartY = barY + beamY;
|
|
67668
67545
|
canvas.fillRect(cx + this.x + barStartX, barStartY, barEndX - barStartX, barSize);
|
|
@@ -67680,7 +67557,7 @@
|
|
|
67680
67557
|
dotsY = barStart + beamY + barCount * (barSpacing + barSize);
|
|
67681
67558
|
dotsOffset = dotSpacing;
|
|
67682
67559
|
}
|
|
67683
|
-
const dotX = this.getBeatX(beat, BeatXPosition.MiddleNotes)
|
|
67560
|
+
const dotX = this.getBeatX(beat, BeatXPosition.MiddleNotes);
|
|
67684
67561
|
dotCount = Math.abs(dotCount);
|
|
67685
67562
|
for (let d = 0; d < dotCount; d++) {
|
|
67686
67563
|
CanvasHelper.fillMusicFontSymbolSafe(canvas, cx + this.x + dotX, dotsY, 1, MusicFontSymbol.AugmentationDot, true);
|
|
@@ -67729,7 +67606,7 @@
|
|
|
67729
67606
|
return this.getLineY(0) - noteHeadHeight / 2;
|
|
67730
67607
|
}
|
|
67731
67608
|
createPreBeatGlyphs() {
|
|
67732
|
-
this.
|
|
67609
|
+
this.wasFirstOfStaff = this.isFirstOfStaff;
|
|
67733
67610
|
if (this.index === 0 || (this.bar.masterBar.isRepeatStart && this._isOnlyNumbered)) {
|
|
67734
67611
|
this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
|
|
67735
67612
|
}
|
|
@@ -67785,6 +67662,11 @@
|
|
|
67785
67662
|
}
|
|
67786
67663
|
paintBeamingStem(_beat, _cy, _x, _topY, _bottomY, _canvas) {
|
|
67787
67664
|
}
|
|
67665
|
+
paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
|
|
67666
|
+
if (h.voice?.index === 0) {
|
|
67667
|
+
super.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
|
|
67668
|
+
}
|
|
67669
|
+
}
|
|
67788
67670
|
}
|
|
67789
67671
|
|
|
67790
67672
|
/**
|
|
@@ -68321,9 +68203,8 @@
|
|
|
68321
68203
|
aboveBeatEffects = new Map();
|
|
68322
68204
|
belowBeatEffects = new Map();
|
|
68323
68205
|
beat;
|
|
68324
|
-
beamingHelper;
|
|
68325
68206
|
get direction() {
|
|
68326
|
-
return this.
|
|
68207
|
+
return this.renderer.getBeatDirection(this.beat);
|
|
68327
68208
|
}
|
|
68328
68209
|
get scale() {
|
|
68329
68210
|
return this.beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
@@ -68365,7 +68246,7 @@
|
|
|
68365
68246
|
: 0) * scale;
|
|
68366
68247
|
// stem size according to duration
|
|
68367
68248
|
pos -= this.renderer.smuflMetrics.standardStemLength * scale;
|
|
68368
|
-
const topCenterY = this.renderer.centerStaffStemY(this.
|
|
68249
|
+
const topCenterY = this.renderer.centerStaffStemY(this.direction);
|
|
68369
68250
|
return Math.min(topCenterY, pos);
|
|
68370
68251
|
case NoteYPosition.Top:
|
|
68371
68252
|
pos -= n.height / 2;
|
|
@@ -68382,7 +68263,7 @@
|
|
|
68382
68263
|
: -this.renderer.smuflMetrics.glyphHeights.get(n.symbol) / 2) * scale;
|
|
68383
68264
|
// stem size according to duration
|
|
68384
68265
|
pos += this.renderer.smuflMetrics.standardStemLength * scale;
|
|
68385
|
-
const bottomCenterY = this.renderer.centerStaffStemY(this.
|
|
68266
|
+
const bottomCenterY = this.renderer.centerStaffStemY(this.direction);
|
|
68386
68267
|
return Math.max(bottomCenterY, pos);
|
|
68387
68268
|
case NoteYPosition.StemUp:
|
|
68388
68269
|
pos -=
|
|
@@ -68407,11 +68288,6 @@
|
|
|
68407
68288
|
addEffectNoteGlyph(noteGlyph, noteLine) {
|
|
68408
68289
|
super.add(noteGlyph, noteLine);
|
|
68409
68290
|
}
|
|
68410
|
-
updateBeamingHelper(cx) {
|
|
68411
|
-
if (this.beamingHelper) {
|
|
68412
|
-
this.beamingHelper.registerBeatLineX('score', this.beat, cx + this.x + this.upLineX, cx + this.x + this.downLineX);
|
|
68413
|
-
}
|
|
68414
|
-
}
|
|
68415
68291
|
doLayout() {
|
|
68416
68292
|
super.doLayout();
|
|
68417
68293
|
const scoreRenderer = this.renderer;
|
|
@@ -68539,7 +68415,6 @@
|
|
|
68539
68415
|
* @internal
|
|
68540
68416
|
*/
|
|
68541
68417
|
class ScoreRestGlyph extends MusicFontGlyph {
|
|
68542
|
-
beamingHelper;
|
|
68543
68418
|
constructor(x, y, duration) {
|
|
68544
68419
|
super(x, y, 1, ScoreRestGlyph.getSymbol(duration));
|
|
68545
68420
|
}
|
|
@@ -68571,11 +68446,6 @@
|
|
|
68571
68446
|
return MusicFontSymbol.None;
|
|
68572
68447
|
}
|
|
68573
68448
|
}
|
|
68574
|
-
updateBeamingHelper(cx) {
|
|
68575
|
-
if (this.beamingHelper) {
|
|
68576
|
-
this.beamingHelper.registerBeatLineX('score', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
68577
|
-
}
|
|
68578
|
-
}
|
|
68579
68449
|
paint(cx, cy, canvas) {
|
|
68580
68450
|
this.internalPaint(cx, cy, canvas, BeatSubElement.StandardNotationRests);
|
|
68581
68451
|
}
|
|
@@ -69067,10 +68937,11 @@
|
|
|
69067
68937
|
*/
|
|
69068
68938
|
class SlashNoteHeadGlyph extends MusicFontGlyph {
|
|
69069
68939
|
beatEffects = new Map();
|
|
69070
|
-
beamingHelper;
|
|
69071
68940
|
noteHeadElement = NoteSubElement.SlashNoteHead;
|
|
69072
68941
|
effectElement = BeatSubElement.SlashEffects;
|
|
69073
68942
|
_symbol;
|
|
68943
|
+
upLineX = 0;
|
|
68944
|
+
downLineX = 0;
|
|
69074
68945
|
constructor(x, y, duration, isGrace, beat) {
|
|
69075
68946
|
super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, SlashNoteHeadGlyph.getSymbol(duration));
|
|
69076
68947
|
this._symbol = SlashNoteHeadGlyph.getSymbol(duration);
|
|
@@ -69121,6 +68992,15 @@
|
|
|
69121
68992
|
if (!Number.isNaN(minEffectY)) {
|
|
69122
68993
|
this.renderer.registerBeatEffectOverflows(minEffectY, maxEffectY);
|
|
69123
68994
|
}
|
|
68995
|
+
const symbol = this._symbol;
|
|
68996
|
+
const stemInfoUp = this.renderer.smuflMetrics.stemUp.has(symbol)
|
|
68997
|
+
? this.renderer.smuflMetrics.stemUp.get(symbol).x
|
|
68998
|
+
: 0;
|
|
68999
|
+
this.upLineX = stemInfoUp;
|
|
69000
|
+
const stemInfoDown = this.renderer.smuflMetrics.stemDown.has(symbol)
|
|
69001
|
+
? this.renderer.smuflMetrics.stemDown.get(symbol).x
|
|
69002
|
+
: 0;
|
|
69003
|
+
this.downLineX = stemInfoDown;
|
|
69124
69004
|
}
|
|
69125
69005
|
static getSymbol(duration) {
|
|
69126
69006
|
switch (duration) {
|
|
@@ -69134,25 +69014,13 @@
|
|
|
69134
69014
|
return MusicFontSymbol.NoteheadSlashHorizontalEnds;
|
|
69135
69015
|
}
|
|
69136
69016
|
}
|
|
69137
|
-
updateBeamingHelper(cx) {
|
|
69138
|
-
if (this.beamingHelper) {
|
|
69139
|
-
const symbol = this._symbol;
|
|
69140
|
-
const stemInfoUp = this.renderer.smuflMetrics.stemUp.has(symbol)
|
|
69141
|
-
? this.renderer.smuflMetrics.stemUp.get(symbol).x
|
|
69142
|
-
: 0;
|
|
69143
|
-
const stemInfoDown = this.renderer.smuflMetrics.stemDown.has(symbol)
|
|
69144
|
-
? this.renderer.smuflMetrics.stemDown.get(symbol).x
|
|
69145
|
-
: 0;
|
|
69146
|
-
this.beamingHelper.registerBeatLineX('slash', this.beat, cx + this.x + stemInfoUp, cx + this.x + stemInfoDown);
|
|
69147
|
-
}
|
|
69148
|
-
}
|
|
69149
69017
|
}
|
|
69150
69018
|
|
|
69151
69019
|
/**
|
|
69152
69020
|
* @internal
|
|
69153
69021
|
*/
|
|
69154
69022
|
class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
|
|
69155
|
-
_collisionOffset =
|
|
69023
|
+
_collisionOffset = Number.NaN;
|
|
69156
69024
|
_skipPaint = false;
|
|
69157
69025
|
_whammy;
|
|
69158
69026
|
noteHeads = null;
|
|
@@ -69203,22 +69071,19 @@
|
|
|
69203
69071
|
getNoteY(note, requestedPosition) {
|
|
69204
69072
|
return this.noteHeads ? this.noteHeads.getNoteY(note, requestedPosition) : 0;
|
|
69205
69073
|
}
|
|
69206
|
-
|
|
69207
|
-
if (this.
|
|
69208
|
-
|
|
69074
|
+
applyRestCollisionOffset() {
|
|
69075
|
+
if (!this.restGlyph) {
|
|
69076
|
+
return;
|
|
69209
69077
|
}
|
|
69210
|
-
|
|
69211
|
-
this.
|
|
69212
|
-
|
|
69213
|
-
|
|
69214
|
-
|
|
69215
|
-
|
|
69216
|
-
|
|
69217
|
-
|
|
69218
|
-
|
|
69219
|
-
this.container.beat.id) {
|
|
69220
|
-
this._skipPaint = true;
|
|
69221
|
-
}
|
|
69078
|
+
if (this.renderer.bar.isMultiVoice && Number.isNaN(this._collisionOffset)) {
|
|
69079
|
+
this._collisionOffset = this.renderer.collisionHelper.applyRestCollisionOffset(this.container.beat, this.restGlyph.y, this.renderer.getScoreHeight(1));
|
|
69080
|
+
this.y += this._collisionOffset;
|
|
69081
|
+
const existingRests = this.renderer.collisionHelper.restDurationsByDisplayTime;
|
|
69082
|
+
if (existingRests.has(this.container.beat.playbackStart) &&
|
|
69083
|
+
existingRests.get(this.container.beat.playbackStart).has(this.container.beat.playbackDuration) &&
|
|
69084
|
+
existingRests.get(this.container.beat.playbackStart).get(this.container.beat.playbackDuration) !==
|
|
69085
|
+
this.container.beat.id) {
|
|
69086
|
+
this._skipPaint = true;
|
|
69222
69087
|
}
|
|
69223
69088
|
}
|
|
69224
69089
|
}
|
|
@@ -69238,7 +69103,6 @@
|
|
|
69238
69103
|
const noteHeads = new ScoreNoteChordGlyph();
|
|
69239
69104
|
this.noteHeads = noteHeads;
|
|
69240
69105
|
noteHeads.beat = this.container.beat;
|
|
69241
|
-
noteHeads.beamingHelper = this.beamingHelper;
|
|
69242
69106
|
const ghost = new GhostNoteContainerGlyph(false);
|
|
69243
69107
|
ghost.renderer = this.renderer;
|
|
69244
69108
|
for (const note of this.container.beat.notes) {
|
|
@@ -69288,22 +69152,18 @@
|
|
|
69288
69152
|
const restGlyph = new ScoreRestGlyph(0, sr.getScoreY(steps), this.container.beat.duration);
|
|
69289
69153
|
this.restGlyph = restGlyph;
|
|
69290
69154
|
restGlyph.beat = this.container.beat;
|
|
69291
|
-
restGlyph.beamingHelper = this.beamingHelper;
|
|
69292
69155
|
this.addNormal(restGlyph);
|
|
69293
69156
|
if (this.renderer.bar.isMultiVoice) {
|
|
69294
69157
|
if (this.container.beat.voice.index === 0) {
|
|
69295
69158
|
const restSizes = BeamingHelper.computeLineHeightsForRest(this.container.beat.duration);
|
|
69296
69159
|
const restTop = restGlyph.y - sr.getScoreHeight(restSizes[0]);
|
|
69297
69160
|
const restBottom = restGlyph.y + sr.getScoreHeight(restSizes[1]);
|
|
69298
|
-
this.renderer.
|
|
69161
|
+
this.renderer.collisionHelper.reserveBeatSlot(this.container.beat, restTop, restBottom);
|
|
69299
69162
|
}
|
|
69300
69163
|
else {
|
|
69301
|
-
this.renderer.
|
|
69164
|
+
this.renderer.collisionHelper.registerRest(this.container.beat);
|
|
69302
69165
|
}
|
|
69303
69166
|
}
|
|
69304
|
-
if (this.beamingHelper) {
|
|
69305
|
-
this.beamingHelper.applyRest(this.container.beat, steps);
|
|
69306
|
-
}
|
|
69307
69167
|
//
|
|
69308
69168
|
// Note dots
|
|
69309
69169
|
//
|
|
@@ -69318,17 +69178,24 @@
|
|
|
69318
69178
|
}
|
|
69319
69179
|
}
|
|
69320
69180
|
super.doLayout();
|
|
69181
|
+
this.applyRestCollisionOffset();
|
|
69321
69182
|
if (this.container.beat.isEmpty) {
|
|
69322
69183
|
this.onTimeX = this.width / 2;
|
|
69323
69184
|
this.middleX = this.onTimeX;
|
|
69185
|
+
this.stemX = this.middleX;
|
|
69324
69186
|
}
|
|
69325
69187
|
else if (this.restGlyph) {
|
|
69326
69188
|
this.onTimeX = this.restGlyph.x + this.restGlyph.width / 2;
|
|
69327
69189
|
this.middleX = this.onTimeX;
|
|
69190
|
+
this.stemX = this.middleX;
|
|
69328
69191
|
}
|
|
69329
69192
|
else if (this.noteHeads) {
|
|
69330
69193
|
this.onTimeX = this.noteHeads.x + this.noteHeads.onTimeX;
|
|
69331
69194
|
this.middleX = this.noteHeads.x + this.noteHeads.width / 2;
|
|
69195
|
+
const direction = this.renderer.getBeatDirection(this.container.beat);
|
|
69196
|
+
this.stemX =
|
|
69197
|
+
this.noteHeads.x +
|
|
69198
|
+
(direction === BeamDirection.Up ? this.noteHeads.upLineX : this.noteHeads.downLineX);
|
|
69332
69199
|
}
|
|
69333
69200
|
}
|
|
69334
69201
|
_createBeatDot(line, group) {
|
|
@@ -69400,7 +69267,7 @@
|
|
|
69400
69267
|
}
|
|
69401
69268
|
const belowBeatEffects = this.noteHeads.belowBeatEffects;
|
|
69402
69269
|
const aboveBeatEffects = this.noteHeads.aboveBeatEffects;
|
|
69403
|
-
const outsideBeatEffects = this.
|
|
69270
|
+
const outsideBeatEffects = this.renderer.getBeatDirection(this.container.beat) === BeamDirection.Up
|
|
69404
69271
|
? this.noteHeads.belowBeatEffects
|
|
69405
69272
|
: this.noteHeads.aboveBeatEffects;
|
|
69406
69273
|
if (n.isStaccato && !belowBeatEffects.has('Staccato')) {
|
|
@@ -69836,7 +69703,7 @@
|
|
|
69836
69703
|
// if we have a line break we draw only a line until the end
|
|
69837
69704
|
if (!endNoteRenderer || endNoteRenderer.staff !== startNoteRenderer.staff) {
|
|
69838
69705
|
const endX = cx + startNoteRenderer.x + startNoteRenderer.width;
|
|
69839
|
-
const noteValueToDraw = note.tieDestination.
|
|
69706
|
+
const noteValueToDraw = note.tieDestination.displayValue;
|
|
69840
69707
|
startNoteRenderer.accidentalHelper.applyAccidentalForValue(note.beat, noteValueToDraw, false, true);
|
|
69841
69708
|
const endY = cy +
|
|
69842
69709
|
startNoteRenderer.y +
|
|
@@ -70372,6 +70239,22 @@
|
|
|
70372
70239
|
doLayout() {
|
|
70373
70240
|
this._effectSlur = null;
|
|
70374
70241
|
this._effectEndSlur = null;
|
|
70242
|
+
// make space for flag
|
|
70243
|
+
const sr = this.renderer;
|
|
70244
|
+
const beat = this.beat;
|
|
70245
|
+
const isGrace = beat.graceType !== GraceType.None;
|
|
70246
|
+
if (sr.hasFlag(beat)) {
|
|
70247
|
+
const direction = this.renderer.getBeatDirection(beat);
|
|
70248
|
+
const scale = isGrace ? NoteHeadGlyph.GraceScale : 1;
|
|
70249
|
+
const symbol = FlagGlyph.getSymbol(beat.duration, direction, isGrace);
|
|
70250
|
+
const flagWidth = this.renderer.smuflMetrics.glyphWidths.get(symbol) * scale;
|
|
70251
|
+
this._flagStretch = flagWidth;
|
|
70252
|
+
}
|
|
70253
|
+
else if (isGrace) {
|
|
70254
|
+
// always use flag size as spacing on grace notes
|
|
70255
|
+
const graceSpacing = this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
70256
|
+
this._flagStretch = graceSpacing;
|
|
70257
|
+
}
|
|
70375
70258
|
super.doLayout();
|
|
70376
70259
|
if (this._bend) {
|
|
70377
70260
|
this._bend.renderer = this.renderer;
|
|
@@ -70381,7 +70264,7 @@
|
|
|
70381
70264
|
}
|
|
70382
70265
|
getBoundingBoxTop() {
|
|
70383
70266
|
if (this._bend !== null) {
|
|
70384
|
-
return
|
|
70267
|
+
return ModelUtils.minBoundingBox(this._bend.getBoundingBoxTop(), super.getBoundingBoxTop());
|
|
70385
70268
|
}
|
|
70386
70269
|
else {
|
|
70387
70270
|
return super.getBoundingBoxTop();
|
|
@@ -70389,7 +70272,7 @@
|
|
|
70389
70272
|
}
|
|
70390
70273
|
getBoundingBoxBottom() {
|
|
70391
70274
|
if (this._bend !== null) {
|
|
70392
|
-
return
|
|
70275
|
+
return ModelUtils.maxBoundingBox(this._bend.getBoundingBoxBottom(), super.getBoundingBoxTop());
|
|
70393
70276
|
}
|
|
70394
70277
|
else {
|
|
70395
70278
|
return super.getBoundingBoxBottom();
|
|
@@ -70437,7 +70320,7 @@
|
|
|
70437
70320
|
}
|
|
70438
70321
|
// end effect slur on last beat
|
|
70439
70322
|
if (!this._effectEndSlur && n.beat.isEffectSlurDestination && n.beat.effectSlurOrigin) {
|
|
70440
|
-
const direction = this.
|
|
70323
|
+
const direction = this.renderer.getBeatDirection(n.beat);
|
|
70441
70324
|
const startNote = direction === BeamDirection.Up ? n.beat.effectSlurOrigin.minNote : n.beat.effectSlurOrigin.maxNote;
|
|
70442
70325
|
const endNote = direction === BeamDirection.Up ? n.beat.minNote : n.beat.maxNote;
|
|
70443
70326
|
const effectEndSlur = new ScoreSlurGlyph(`score.slur.effect.${startNote.beat.id}`, startNote, endNote, true);
|
|
@@ -70476,6 +70359,15 @@
|
|
|
70476
70359
|
}
|
|
70477
70360
|
}
|
|
70478
70361
|
}
|
|
70362
|
+
_flagStretch = 0;
|
|
70363
|
+
get postBeatStretch() {
|
|
70364
|
+
return super.postBeatStretch + this._flagStretch;
|
|
70365
|
+
}
|
|
70366
|
+
updateWidth() {
|
|
70367
|
+
super.updateWidth();
|
|
70368
|
+
this.width += this._flagStretch;
|
|
70369
|
+
this.minWidth += this._flagStretch;
|
|
70370
|
+
}
|
|
70479
70371
|
}
|
|
70480
70372
|
|
|
70481
70373
|
/**
|
|
@@ -70510,7 +70402,7 @@
|
|
|
70510
70402
|
return this.smuflMetrics.oneStaffSpace;
|
|
70511
70403
|
}
|
|
70512
70404
|
get heightLineCount() {
|
|
70513
|
-
return 5;
|
|
70405
|
+
return Math.max(5, this.bar.staff.standardNotationLineCount);
|
|
70514
70406
|
}
|
|
70515
70407
|
get drawnLineCount() {
|
|
70516
70408
|
return this.bar.staff.standardNotationLineCount;
|
|
@@ -70567,7 +70459,9 @@
|
|
|
70567
70459
|
slashY -= this.smuflMetrics.stemUp.has(symbol)
|
|
70568
70460
|
? this.smuflMetrics.stemUp.get(symbol).bottomY * scale
|
|
70569
70461
|
: 0;
|
|
70570
|
-
|
|
70462
|
+
if (!beat.isRest) {
|
|
70463
|
+
slashY -= this.smuflMetrics.standardStemLength + scale;
|
|
70464
|
+
}
|
|
70571
70465
|
}
|
|
70572
70466
|
return slashY;
|
|
70573
70467
|
}
|
|
@@ -70576,7 +70470,7 @@
|
|
|
70576
70470
|
return this.getBeatContainer(beat).onNotes.getNoteY(minNote, direction === BeamDirection.Up ? NoteYPosition.TopWithStem : NoteYPosition.StemDown);
|
|
70577
70471
|
}
|
|
70578
70472
|
let y = this.getScoreY(this.accidentalHelper.getMinSteps(beat));
|
|
70579
|
-
if (direction === BeamDirection.Up) {
|
|
70473
|
+
if (direction === BeamDirection.Up && !beat.isRest) {
|
|
70580
70474
|
const scale = beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
70581
70475
|
y -= this.smuflMetrics.standardStemLength * scale;
|
|
70582
70476
|
}
|
|
@@ -70614,14 +70508,14 @@
|
|
|
70614
70508
|
getBeamDirection(helper) {
|
|
70615
70509
|
return helper.direction;
|
|
70616
70510
|
}
|
|
70617
|
-
centerStaffStemY(
|
|
70511
|
+
centerStaffStemY(direction) {
|
|
70618
70512
|
const isStandardFive = this.bar.staff.standardNotationLineCount === Staff.DefaultStandardNotationLineCount;
|
|
70619
70513
|
if (isStandardFive) {
|
|
70620
70514
|
// center on the middle line for a standard 5-line staff
|
|
70621
70515
|
return this.getScoreY(this.bar.staff.standardNotationLineCount - 1);
|
|
70622
70516
|
}
|
|
70623
70517
|
// for other staff line counts, we align the stem either on the top or bottom line
|
|
70624
|
-
if (
|
|
70518
|
+
if (direction === BeamDirection.Up) {
|
|
70625
70519
|
return this.getScoreY(this.bar.staff.standardNotationLineCount * 2);
|
|
70626
70520
|
}
|
|
70627
70521
|
return this.getScoreY(0);
|
|
@@ -70723,7 +70617,7 @@
|
|
|
70723
70617
|
createLinePreBeatGlyphs() {
|
|
70724
70618
|
// Clef
|
|
70725
70619
|
let hasClef = false;
|
|
70726
|
-
if (this.
|
|
70620
|
+
if (this.isFirstOfStaff ||
|
|
70727
70621
|
this.bar.clef !== this.bar.previousBar.clef ||
|
|
70728
70622
|
this.bar.clefOttava !== this.bar.previousBar.clefOttava) {
|
|
70729
70623
|
// SMUFL: Clefs should be positioned such that the pitch the clef refers to is on the baseline
|
|
@@ -70928,6 +70822,25 @@
|
|
|
70928
70822
|
*/
|
|
70929
70823
|
class SlashBeatContainerGlyph extends BeatContainerGlyph {
|
|
70930
70824
|
_tiedNoteTie = null;
|
|
70825
|
+
doLayout() {
|
|
70826
|
+
// make space for flag
|
|
70827
|
+
const sr = this.renderer;
|
|
70828
|
+
const beat = this.beat;
|
|
70829
|
+
const isGrace = beat.graceType !== GraceType.None;
|
|
70830
|
+
if (sr.hasFlag(beat)) {
|
|
70831
|
+
const direction = this.renderer.getBeatDirection(beat);
|
|
70832
|
+
const scale = isGrace ? NoteHeadGlyph.GraceScale : 1;
|
|
70833
|
+
const symbol = FlagGlyph.getSymbol(beat.duration, direction, isGrace);
|
|
70834
|
+
const flagWidth = this.renderer.smuflMetrics.glyphWidths.get(symbol) * scale;
|
|
70835
|
+
this._flagStretch = flagWidth;
|
|
70836
|
+
}
|
|
70837
|
+
else if (isGrace) {
|
|
70838
|
+
// always use flag size as spacing on grace notes
|
|
70839
|
+
const graceSpacing = this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
|
|
70840
|
+
this._flagStretch = graceSpacing;
|
|
70841
|
+
}
|
|
70842
|
+
super.doLayout();
|
|
70843
|
+
}
|
|
70931
70844
|
createTies(n) {
|
|
70932
70845
|
// create a tie if any effect requires it
|
|
70933
70846
|
if (!n.isVisible) {
|
|
@@ -70944,17 +70857,21 @@
|
|
|
70944
70857
|
this.addTie(tie);
|
|
70945
70858
|
}
|
|
70946
70859
|
}
|
|
70860
|
+
_flagStretch = 0;
|
|
70861
|
+
get postBeatStretch() {
|
|
70862
|
+
return super.postBeatStretch + this._flagStretch;
|
|
70863
|
+
}
|
|
70864
|
+
updateWidth() {
|
|
70865
|
+
super.updateWidth();
|
|
70866
|
+
this.width += this._flagStretch;
|
|
70867
|
+
this.minWidth += this._flagStretch;
|
|
70868
|
+
}
|
|
70947
70869
|
}
|
|
70948
70870
|
|
|
70949
70871
|
/**
|
|
70950
70872
|
* @internal
|
|
70951
70873
|
*/
|
|
70952
70874
|
class SlashRestGlyph extends ScoreRestGlyph {
|
|
70953
|
-
updateBeamingHelper(cx) {
|
|
70954
|
-
if (this.beamingHelper) {
|
|
70955
|
-
this.beamingHelper.registerBeatLineX('slash', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
70956
|
-
}
|
|
70957
|
-
}
|
|
70958
70875
|
paint(cx, cy, canvas) {
|
|
70959
70876
|
super.internalPaint(cx, cy, canvas, BeatSubElement.SlashRests);
|
|
70960
70877
|
}
|
|
@@ -71050,19 +70967,6 @@
|
|
|
71050
70967
|
}
|
|
71051
70968
|
return 0;
|
|
71052
70969
|
}
|
|
71053
|
-
updateBeamingHelper() {
|
|
71054
|
-
if (this.noteHeads) {
|
|
71055
|
-
this.noteHeads.updateBeamingHelper(this.container.x + this.x);
|
|
71056
|
-
}
|
|
71057
|
-
else if (this.deadSlapped) {
|
|
71058
|
-
if (this.beamingHelper) {
|
|
71059
|
-
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);
|
|
71060
|
-
}
|
|
71061
|
-
}
|
|
71062
|
-
else if (this.restGlyph) {
|
|
71063
|
-
this.restGlyph.updateBeamingHelper(this.container.x + this.x);
|
|
71064
|
-
}
|
|
71065
|
-
}
|
|
71066
70970
|
doLayout() {
|
|
71067
70971
|
// create glyphs
|
|
71068
70972
|
const sr = this.renderer;
|
|
@@ -71080,18 +70984,13 @@
|
|
|
71080
70984
|
const noteHeadGlyph = new SlashNoteHeadGlyph(0, glyphY, this.container.beat.duration, isGrace, this.container.beat);
|
|
71081
70985
|
this.noteHeads = noteHeadGlyph;
|
|
71082
70986
|
noteHeadGlyph.beat = this.container.beat;
|
|
71083
|
-
noteHeadGlyph.beamingHelper = this.beamingHelper;
|
|
71084
70987
|
this.addNormal(noteHeadGlyph);
|
|
71085
70988
|
}
|
|
71086
70989
|
else {
|
|
71087
70990
|
const restGlyph = new SlashRestGlyph(0, glyphY, this.container.beat.duration);
|
|
71088
70991
|
this.restGlyph = restGlyph;
|
|
71089
70992
|
restGlyph.beat = this.container.beat;
|
|
71090
|
-
restGlyph.beamingHelper = this.beamingHelper;
|
|
71091
70993
|
this.addNormal(restGlyph);
|
|
71092
|
-
if (this.beamingHelper) {
|
|
71093
|
-
this.beamingHelper.applyRest(this.container.beat, 0);
|
|
71094
|
-
}
|
|
71095
70994
|
}
|
|
71096
70995
|
}
|
|
71097
70996
|
//
|
|
@@ -71105,15 +71004,22 @@
|
|
|
71105
71004
|
super.doLayout();
|
|
71106
71005
|
if (this.container.beat.isEmpty) {
|
|
71107
71006
|
this.onTimeX = this.width / 2;
|
|
71007
|
+
this.stemX = this.onTimeX;
|
|
71108
71008
|
}
|
|
71109
71009
|
else if (this.restGlyph) {
|
|
71110
71010
|
this.onTimeX = this.restGlyph.x + this.restGlyph.width / 2;
|
|
71011
|
+
this.stemX = this.onTimeX;
|
|
71111
71012
|
}
|
|
71112
71013
|
else if (this.noteHeads) {
|
|
71113
71014
|
this.onTimeX = this.noteHeads.x + this.noteHeads.width / 2;
|
|
71015
|
+
const direction = this.renderer.getBeatDirection(this.container.beat);
|
|
71016
|
+
this.stemX =
|
|
71017
|
+
this.noteHeads.x +
|
|
71018
|
+
(direction === BeamDirection.Up ? this.noteHeads.upLineX : this.noteHeads.downLineX);
|
|
71114
71019
|
}
|
|
71115
71020
|
else if (this.deadSlapped) {
|
|
71116
71021
|
this.onTimeX = this.deadSlapped.x + this.deadSlapped.width / 2;
|
|
71022
|
+
this.stemX = this.onTimeX;
|
|
71117
71023
|
}
|
|
71118
71024
|
this.middleX = this.onTimeX;
|
|
71119
71025
|
}
|
|
@@ -71190,7 +71096,9 @@
|
|
|
71190
71096
|
const symbol = SlashNoteHeadGlyph.getSymbol(beat.duration);
|
|
71191
71097
|
const scale = beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
|
|
71192
71098
|
slashY -= this.smuflMetrics.stemUp.has(symbol) ? this.smuflMetrics.stemUp.get(symbol).bottomY * scale : 0;
|
|
71193
|
-
|
|
71099
|
+
if (!beat.isRest) {
|
|
71100
|
+
slashY -= this.smuflMetrics.standardStemLength + scale;
|
|
71101
|
+
}
|
|
71194
71102
|
return slashY;
|
|
71195
71103
|
}
|
|
71196
71104
|
getFlagBottomY(beat, _direction) {
|
|
@@ -71274,6 +71182,11 @@
|
|
|
71274
71182
|
_?.[Symbol.dispose]?.();
|
|
71275
71183
|
}
|
|
71276
71184
|
}
|
|
71185
|
+
paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
|
|
71186
|
+
if (h.voice?.index === 0) {
|
|
71187
|
+
super.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
|
|
71188
|
+
}
|
|
71189
|
+
}
|
|
71277
71190
|
}
|
|
71278
71191
|
|
|
71279
71192
|
/**
|
|
@@ -71730,7 +71643,6 @@
|
|
|
71730
71643
|
_deadSlapped = null;
|
|
71731
71644
|
_isGrace;
|
|
71732
71645
|
beat;
|
|
71733
|
-
beamingHelper;
|
|
71734
71646
|
maxStringNote = null;
|
|
71735
71647
|
minStringNote = null;
|
|
71736
71648
|
beatEffects = new Map();
|
|
@@ -71879,11 +71791,6 @@
|
|
|
71879
71791
|
}
|
|
71880
71792
|
}
|
|
71881
71793
|
}
|
|
71882
|
-
updateBeamingHelper(cx) {
|
|
71883
|
-
if (this.beamingHelper && this.beamingHelper.isPositionFrom('tab', this.beat)) {
|
|
71884
|
-
this.beamingHelper.registerBeatLineX('tab', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
71885
|
-
}
|
|
71886
|
-
}
|
|
71887
71794
|
}
|
|
71888
71795
|
|
|
71889
71796
|
/**
|
|
@@ -71891,7 +71798,6 @@
|
|
|
71891
71798
|
*/
|
|
71892
71799
|
class TabRestGlyph extends MusicFontGlyph {
|
|
71893
71800
|
_isVisibleRest;
|
|
71894
|
-
beamingHelper;
|
|
71895
71801
|
constructor(x, y, isVisibleRest, duration) {
|
|
71896
71802
|
super(x, y, 1, ScoreRestGlyph.getSymbol(duration));
|
|
71897
71803
|
this._isVisibleRest = isVisibleRest;
|
|
@@ -71899,11 +71805,6 @@
|
|
|
71899
71805
|
doLayout() {
|
|
71900
71806
|
super.doLayout();
|
|
71901
71807
|
}
|
|
71902
|
-
updateBeamingHelper(cx) {
|
|
71903
|
-
if (this.beamingHelper && this.beamingHelper.isPositionFrom('tab', this.beat)) {
|
|
71904
|
-
this.beamingHelper.registerBeatLineX('tab', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
|
|
71905
|
-
}
|
|
71906
|
-
}
|
|
71907
71808
|
paint(cx, cy, canvas) {
|
|
71908
71809
|
if (this._isVisibleRest) {
|
|
71909
71810
|
const _ = ElementStyleHelper.beat(canvas, BeatSubElement.GuitarTabRests, this.beat);
|
|
@@ -71960,7 +71861,6 @@
|
|
|
71960
71861
|
slashNoteHead.effectElement = BeatSubElement.GuitarTabEffects;
|
|
71961
71862
|
this.slash = slashNoteHead;
|
|
71962
71863
|
slashNoteHead.beat = this.container.beat;
|
|
71963
|
-
slashNoteHead.beamingHelper = this.beamingHelper;
|
|
71964
71864
|
this.addNormal(slashNoteHead);
|
|
71965
71865
|
beatEffects = slashNoteHead.beatEffects;
|
|
71966
71866
|
}
|
|
@@ -71968,7 +71868,6 @@
|
|
|
71968
71868
|
const tabNoteNumbers = new TabNoteChordGlyph(0, 0, isGrace);
|
|
71969
71869
|
this.noteNumbers = tabNoteNumbers;
|
|
71970
71870
|
tabNoteNumbers.beat = this.container.beat;
|
|
71971
|
-
tabNoteNumbers.beamingHelper = this.beamingHelper;
|
|
71972
71871
|
for (const note of this.container.beat.notes) {
|
|
71973
71872
|
if (note.isVisible) {
|
|
71974
71873
|
this._createNoteGlyph(note);
|
|
@@ -71990,9 +71889,9 @@
|
|
|
71990
71889
|
// Note dots
|
|
71991
71890
|
//
|
|
71992
71891
|
if (this.container.beat.dots > 0 && tabRenderer.rhythmMode !== exports.TabRhythmMode.Hidden) {
|
|
71892
|
+
const y = tabRenderer.getFlagAndBarPos();
|
|
71993
71893
|
for (let i = 0; i < this.container.beat.dots; i++) {
|
|
71994
|
-
this.addEffect(new AugmentationDotGlyph(0,
|
|
71995
|
-
tabRenderer.settings.notation.rhythmHeight));
|
|
71894
|
+
this.addEffect(new AugmentationDotGlyph(0, y));
|
|
71996
71895
|
}
|
|
71997
71896
|
}
|
|
71998
71897
|
}
|
|
@@ -72002,7 +71901,6 @@
|
|
|
72002
71901
|
const restGlyph = new TabRestGlyph(0, y, tabRenderer.showRests, this.container.beat.duration);
|
|
72003
71902
|
this.restGlyph = restGlyph;
|
|
72004
71903
|
restGlyph.beat = this.container.beat;
|
|
72005
|
-
restGlyph.beamingHelper = this.beamingHelper;
|
|
72006
71904
|
this.addNormal(restGlyph);
|
|
72007
71905
|
//
|
|
72008
71906
|
// Note dots
|
|
@@ -72040,21 +71938,11 @@
|
|
|
72040
71938
|
this.onTimeX = this.slash.x + this.slash.width / 2;
|
|
72041
71939
|
}
|
|
72042
71940
|
this.middleX = this.onTimeX;
|
|
71941
|
+
this.stemX = this.middleX;
|
|
72043
71942
|
for (const g of centeredEffectGlyphs) {
|
|
72044
71943
|
g.x = this.onTimeX;
|
|
72045
71944
|
}
|
|
72046
71945
|
}
|
|
72047
|
-
updateBeamingHelper() {
|
|
72048
|
-
if (this.noteNumbers) {
|
|
72049
|
-
this.noteNumbers.updateBeamingHelper(this.container.x + this.x);
|
|
72050
|
-
}
|
|
72051
|
-
else if (this.restGlyph) {
|
|
72052
|
-
this.restGlyph.updateBeamingHelper(this.container.x + this.x);
|
|
72053
|
-
}
|
|
72054
|
-
else if (this.slash) {
|
|
72055
|
-
this.slash.updateBeamingHelper(this.container.x + this.x);
|
|
72056
|
-
}
|
|
72057
|
-
}
|
|
72058
71946
|
_createNoteGlyph(n) {
|
|
72059
71947
|
const tr = this.renderer;
|
|
72060
71948
|
const noteNumberGlyph = new NoteNumberGlyph(0, 0, n);
|
|
@@ -72065,7 +71953,7 @@
|
|
|
72065
71953
|
this.noteNumbers.addNoteGlyph(noteNumberGlyph, n);
|
|
72066
71954
|
const topY = noteNumberGlyph.y - noteNumberGlyph.height / 2;
|
|
72067
71955
|
const bottomY = topY + noteNumberGlyph.height;
|
|
72068
|
-
this.renderer.
|
|
71956
|
+
this.renderer.collisionHelper.reserveBeatSlot(this.container.beat, topY, bottomY);
|
|
72069
71957
|
const minString = tr.minString;
|
|
72070
71958
|
const maxString = tr.maxString;
|
|
72071
71959
|
if (Number.isNaN(minString) || minString < n.string) {
|
|
@@ -72337,7 +72225,7 @@
|
|
|
72337
72225
|
}
|
|
72338
72226
|
createLinePreBeatGlyphs() {
|
|
72339
72227
|
// Clef
|
|
72340
|
-
if (this.
|
|
72228
|
+
if (this.isFirstOfStaff) {
|
|
72341
72229
|
const center = (this.bar.staff.tuning.length - 1) / 2;
|
|
72342
72230
|
this.createStartSpacing();
|
|
72343
72231
|
this.addPreBeatGlyph(new TabClefGlyph(0, this.getLineY(center)));
|
|
@@ -72428,14 +72316,14 @@
|
|
|
72428
72316
|
// currently only used for duplets
|
|
72429
72317
|
return this.getFlagAndBarPos();
|
|
72430
72318
|
}
|
|
72431
|
-
shouldPaintFlag(beat
|
|
72432
|
-
if (!super.shouldPaintFlag(beat
|
|
72319
|
+
shouldPaintFlag(beat) {
|
|
72320
|
+
if (!super.shouldPaintFlag(beat)) {
|
|
72433
72321
|
return false;
|
|
72434
72322
|
}
|
|
72435
72323
|
if (beat.graceType !== GraceType.None) {
|
|
72436
72324
|
return false;
|
|
72437
72325
|
}
|
|
72438
|
-
return
|
|
72326
|
+
return true;
|
|
72439
72327
|
}
|
|
72440
72328
|
paintBeamingStem(beat, cy, x, topY, bottomY, canvas) {
|
|
72441
72329
|
if (bottomY < topY) {
|