@coderline/alphatab 1.8.0-alpha.1647 → 1.8.0-alpha.1650
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 +458 -143
- package/dist/alphaTab.d.ts +41 -0
- package/dist/alphaTab.js +458 -143
- package/dist/alphaTab.min.js +2 -2
- package/dist/alphaTab.min.mjs +1 -1
- package/dist/alphaTab.mjs +1 -1
- package/dist/alphaTab.worker.min.mjs +1 -1
- package/dist/alphaTab.worker.mjs +1 -1
- package/dist/alphaTab.worklet.min.mjs +1 -1
- package/dist/alphaTab.worklet.mjs +1 -1
- package/package.json +1 -1
package/dist/alphaTab.core.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* alphaTab v1.8.0-alpha.
|
|
2
|
+
* alphaTab v1.8.0-alpha.1650 (develop, build 1650)
|
|
3
3
|
*
|
|
4
4
|
* Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
5
|
*
|
|
@@ -203,9 +203,9 @@ class AlphaTabError extends Error {
|
|
|
203
203
|
* @internal
|
|
204
204
|
*/
|
|
205
205
|
class VersionInfo {
|
|
206
|
-
static version = '1.8.0-alpha.
|
|
207
|
-
static date = '2025-12-
|
|
208
|
-
static commit = '
|
|
206
|
+
static version = '1.8.0-alpha.1650';
|
|
207
|
+
static date = '2025-12-20T02:07:19.755Z';
|
|
208
|
+
static commit = '5789b59da2b7f8897debe003c9b75e4d48b5e9b3';
|
|
209
209
|
static print(print) {
|
|
210
210
|
print(`alphaTab ${VersionInfo.version}`);
|
|
211
211
|
print(`commit: ${VersionInfo.commit}`);
|
|
@@ -2744,6 +2744,23 @@ class RenderStylesheet {
|
|
|
2744
2744
|
* Whether barlines should be drawn across staves within the same system.
|
|
2745
2745
|
*/
|
|
2746
2746
|
extendBarLines = false;
|
|
2747
|
+
/**
|
|
2748
|
+
* Whether to hide empty staves.
|
|
2749
|
+
*/
|
|
2750
|
+
hideEmptyStaves = false;
|
|
2751
|
+
/**
|
|
2752
|
+
* Whether to also hide empty staves in the first system.
|
|
2753
|
+
* @remarks
|
|
2754
|
+
* Only has an effect when activating {@link hideEmptyStaves}.
|
|
2755
|
+
*/
|
|
2756
|
+
hideEmptyStavesInFirstSystem = false;
|
|
2757
|
+
/**
|
|
2758
|
+
* Whether to show brackets and braces across single staves.
|
|
2759
|
+
* @remarks
|
|
2760
|
+
* This allows a more consistent view for identifying staves when using
|
|
2761
|
+
* {@link hideEmptyStaves}
|
|
2762
|
+
*/
|
|
2763
|
+
showSingleStaffBrackets = false;
|
|
2747
2764
|
}
|
|
2748
2765
|
|
|
2749
2766
|
/**
|
|
@@ -8673,7 +8690,10 @@ class AlphaTex1LanguageDefinitions {
|
|
|
8673
8690
|
['firstsystemtracknameorientation', [[[[10, 17], 0, ['horizontal', 'vertical']]]]],
|
|
8674
8691
|
['othersystemstracknameorientation', [[[[10, 17], 0, ['horizontal', 'vertical']]]]],
|
|
8675
8692
|
['extendbarlines', null],
|
|
8676
|
-
['chorddiagramsinscore', [[[[10], 1, ['true', 'false']]]]]
|
|
8693
|
+
['chorddiagramsinscore', [[[[10], 1, ['true', 'false']]]]],
|
|
8694
|
+
['hideemptystaves', null],
|
|
8695
|
+
['hideemptystavesinfirstsystem', null],
|
|
8696
|
+
['showsinglestaffbrackets', null]
|
|
8677
8697
|
]);
|
|
8678
8698
|
static staffMetaDataSignatures = AlphaTex1LanguageDefinitions._signatures([
|
|
8679
8699
|
['tuning', [[[[10, 17], 0, ['piano', 'none', 'voice']]], [[[10, 17], 5]]]],
|
|
@@ -9013,6 +9033,9 @@ class AlphaTex1LanguageDefinitions {
|
|
|
9013
9033
|
['othersystemstracknameorientation', null],
|
|
9014
9034
|
['extendbarlines', null],
|
|
9015
9035
|
['chorddiagramsinscore', null],
|
|
9036
|
+
['hideemptystaves', null],
|
|
9037
|
+
['hideemptystavesinfirstsystem', null],
|
|
9038
|
+
['showsinglestaffbrackets', null],
|
|
9016
9039
|
[
|
|
9017
9040
|
'tuning',
|
|
9018
9041
|
[
|
|
@@ -13887,6 +13910,15 @@ class AlphaTex1LanguageHandler {
|
|
|
13887
13910
|
? AlphaTex1LanguageHandler._booleanLikeValue(metaData.arguments.arguments, 0)
|
|
13888
13911
|
: true;
|
|
13889
13912
|
return ApplyNodeResult.Applied;
|
|
13913
|
+
case 'hideemptystaves':
|
|
13914
|
+
score.stylesheet.hideEmptyStaves = true;
|
|
13915
|
+
return ApplyNodeResult.Applied;
|
|
13916
|
+
case 'hideemptystavesinfirstsystem':
|
|
13917
|
+
score.stylesheet.hideEmptyStavesInFirstSystem = true;
|
|
13918
|
+
return ApplyNodeResult.Applied;
|
|
13919
|
+
case 'showsinglestaffbrackets':
|
|
13920
|
+
score.stylesheet.showSingleStaffBrackets = true;
|
|
13921
|
+
return ApplyNodeResult.Applied;
|
|
13890
13922
|
default:
|
|
13891
13923
|
return ApplyNodeResult.NotAppliedUnrecognizedMarker;
|
|
13892
13924
|
}
|
|
@@ -15718,6 +15750,15 @@ class AlphaTex1LanguageHandler {
|
|
|
15718
15750
|
if (stylesheet.globalDisplayChordDiagramsInScore) {
|
|
15719
15751
|
nodes.push(Atnf.meta('chordDiagramsInScore'));
|
|
15720
15752
|
}
|
|
15753
|
+
if (stylesheet.hideEmptyStaves) {
|
|
15754
|
+
nodes.push(Atnf.meta('hideEmptyStaves'));
|
|
15755
|
+
}
|
|
15756
|
+
if (stylesheet.hideEmptyStavesInFirstSystem) {
|
|
15757
|
+
nodes.push(Atnf.meta('hideEmptyStavesInFirstSystem'));
|
|
15758
|
+
}
|
|
15759
|
+
if (stylesheet.showSingleStaffBrackets) {
|
|
15760
|
+
nodes.push(Atnf.meta('showSingleStaffBrackets'));
|
|
15761
|
+
}
|
|
15721
15762
|
// Unsupported:
|
|
15722
15763
|
// 'globaldisplaychorddiagramsontop',
|
|
15723
15764
|
// 'pertrackchorddiagramsontop',
|
|
@@ -38804,6 +38845,9 @@ class RenderStylesheetSerializer {
|
|
|
38804
38845
|
}
|
|
38805
38846
|
}
|
|
38806
38847
|
o.set("extendbarlines", obj.extendBarLines);
|
|
38848
|
+
o.set("hideemptystaves", obj.hideEmptyStaves);
|
|
38849
|
+
o.set("hideemptystavesinfirstsystem", obj.hideEmptyStavesInFirstSystem);
|
|
38850
|
+
o.set("showsinglestaffbrackets", obj.showSingleStaffBrackets);
|
|
38807
38851
|
return o;
|
|
38808
38852
|
}
|
|
38809
38853
|
static setProperty(obj, property, v) {
|
|
@@ -38865,6 +38909,15 @@ class RenderStylesheetSerializer {
|
|
|
38865
38909
|
case "extendbarlines":
|
|
38866
38910
|
obj.extendBarLines = v;
|
|
38867
38911
|
return true;
|
|
38912
|
+
case "hideemptystaves":
|
|
38913
|
+
obj.hideEmptyStaves = v;
|
|
38914
|
+
return true;
|
|
38915
|
+
case "hideemptystavesinfirstsystem":
|
|
38916
|
+
obj.hideEmptyStavesInFirstSystem = v;
|
|
38917
|
+
return true;
|
|
38918
|
+
case "showsinglestaffbrackets":
|
|
38919
|
+
obj.showSingleStaffBrackets = v;
|
|
38920
|
+
return true;
|
|
38868
38921
|
}
|
|
38869
38922
|
return false;
|
|
38870
38923
|
}
|
|
@@ -45892,6 +45945,19 @@ class BeatTickLookup {
|
|
|
45892
45945
|
}
|
|
45893
45946
|
return null;
|
|
45894
45947
|
}
|
|
45948
|
+
/**
|
|
45949
|
+
* Looks for the first visible beat which starts at this lookup so it can be used for cursor placement.
|
|
45950
|
+
* @param checker The custom checker to see if a beat is visible.
|
|
45951
|
+
* @returns The first beat which is visible according to the given tracks or null.
|
|
45952
|
+
*/
|
|
45953
|
+
getVisibleBeatAtStartWithChecker(checker) {
|
|
45954
|
+
for (const b of this.highlightedBeats) {
|
|
45955
|
+
if (b.playbackStart === this.start && checker.isVisible(b.beat)) {
|
|
45956
|
+
return b.beat;
|
|
45957
|
+
}
|
|
45958
|
+
}
|
|
45959
|
+
return null;
|
|
45960
|
+
}
|
|
45895
45961
|
}
|
|
45896
45962
|
|
|
45897
45963
|
/**
|
|
@@ -46331,6 +46397,18 @@ class MidiTickLookupFindBeatResult {
|
|
|
46331
46397
|
}
|
|
46332
46398
|
}
|
|
46333
46399
|
}
|
|
46400
|
+
/**
|
|
46401
|
+
* @internal
|
|
46402
|
+
*/
|
|
46403
|
+
class TrackLookupBeatVisibilityChecker {
|
|
46404
|
+
_lookup;
|
|
46405
|
+
constructor(lookup) {
|
|
46406
|
+
this._lookup = lookup;
|
|
46407
|
+
}
|
|
46408
|
+
isVisible(beat) {
|
|
46409
|
+
return this._lookup.has(beat.voice.bar.staff.track.index);
|
|
46410
|
+
}
|
|
46411
|
+
}
|
|
46334
46412
|
/**
|
|
46335
46413
|
* This class holds all information about when {@link MasterBar}s and {@link Beat}s are played.
|
|
46336
46414
|
*
|
|
@@ -46391,31 +46469,44 @@ class MidiTickLookup {
|
|
|
46391
46469
|
* @returns The information about the current beat or null if no beat could be found.
|
|
46392
46470
|
*/
|
|
46393
46471
|
findBeat(trackLookup, tick, currentBeatHint = null) {
|
|
46472
|
+
return this.findBeatWithChecker(new TrackLookupBeatVisibilityChecker(trackLookup), tick, currentBeatHint);
|
|
46473
|
+
}
|
|
46474
|
+
/**
|
|
46475
|
+
* Finds the currently played beat given a list of tracks and the current time.
|
|
46476
|
+
* @param checker The checker to ask whether a beat is visible and should be considered for result.
|
|
46477
|
+
* @param tick The current time in midi ticks.
|
|
46478
|
+
* @param currentBeatHint Used for optimized lookup during playback. By passing in a previous result lookup of the next one can be optimized using heuristics. (optional).
|
|
46479
|
+
* @returns The information about the current beat or null if no beat could be found.
|
|
46480
|
+
*/
|
|
46481
|
+
findBeatWithChecker(checker, tick, currentBeatHint = null) {
|
|
46394
46482
|
let result = null;
|
|
46395
46483
|
if (currentBeatHint) {
|
|
46396
|
-
result = this._findBeatFast(
|
|
46484
|
+
result = this._findBeatFast(checker, currentBeatHint, tick);
|
|
46397
46485
|
}
|
|
46398
46486
|
if (!result) {
|
|
46399
|
-
result = this._findBeatSlow(
|
|
46487
|
+
result = this._findBeatSlow(checker, currentBeatHint, tick, false);
|
|
46400
46488
|
}
|
|
46401
46489
|
return result;
|
|
46402
46490
|
}
|
|
46403
|
-
_findBeatFast(
|
|
46491
|
+
_findBeatFast(checker, currentBeatHint, tick) {
|
|
46404
46492
|
// still within current lookup.
|
|
46405
46493
|
if (tick >= currentBeatHint.start && tick < currentBeatHint.end) {
|
|
46406
46494
|
return currentBeatHint;
|
|
46407
46495
|
}
|
|
46408
46496
|
// already on the next beat?
|
|
46409
|
-
if (currentBeatHint.nextBeat &&
|
|
46497
|
+
if (currentBeatHint.nextBeat &&
|
|
46498
|
+
tick >= currentBeatHint.nextBeat.start &&
|
|
46499
|
+
tick < currentBeatHint.nextBeat.end &&
|
|
46500
|
+
(checker === undefined || checker.isVisible(currentBeatHint.nextBeat.beat))) {
|
|
46410
46501
|
const next = currentBeatHint.nextBeat;
|
|
46411
46502
|
// fill next in chain
|
|
46412
|
-
this._fillNextBeat(next,
|
|
46503
|
+
this._fillNextBeat(next, checker);
|
|
46413
46504
|
return next;
|
|
46414
46505
|
}
|
|
46415
46506
|
// likely a loop or manual seek, need to fallback to slow path
|
|
46416
46507
|
return null;
|
|
46417
46508
|
}
|
|
46418
|
-
_fillNextBeatMultiBarRest(current,
|
|
46509
|
+
_fillNextBeatMultiBarRest(current, checker) {
|
|
46419
46510
|
const group = this.multiBarRestInfo.get(current.masterBar.masterBar.index);
|
|
46420
46511
|
// this is a bit sensitive. we assume that the sequence of multi-rest bars and the
|
|
46421
46512
|
// chained nextMasterBar equal. so we just jump over X bars
|
|
@@ -46429,7 +46520,7 @@ class MidiTickLookup {
|
|
|
46429
46520
|
if (endMasterBar) {
|
|
46430
46521
|
// one more following -> use start of next
|
|
46431
46522
|
if (endMasterBar.nextMasterBar) {
|
|
46432
|
-
current.nextBeat = this._firstBeatInMasterBar(
|
|
46523
|
+
current.nextBeat = this._firstBeatInMasterBar(checker, endMasterBar.nextMasterBar, endMasterBar.nextMasterBar.start, true);
|
|
46433
46524
|
// if we have the next beat take the difference between the times as duration
|
|
46434
46525
|
if (current.nextBeat) {
|
|
46435
46526
|
current.tickDuration = current.nextBeat.start - current.start;
|
|
@@ -46459,19 +46550,19 @@ class MidiTickLookup {
|
|
|
46459
46550
|
}
|
|
46460
46551
|
current.calculateDuration();
|
|
46461
46552
|
}
|
|
46462
|
-
_fillNextBeat(current,
|
|
46553
|
+
_fillNextBeat(current, checker) {
|
|
46463
46554
|
// on multibar rests take the duration until the end.
|
|
46464
46555
|
if (this._isMultiBarRestResult(current)) {
|
|
46465
|
-
this._fillNextBeatMultiBarRest(current,
|
|
46556
|
+
this._fillNextBeatMultiBarRest(current, checker);
|
|
46466
46557
|
}
|
|
46467
46558
|
else {
|
|
46468
|
-
this._fillNextBeatDefault(current,
|
|
46559
|
+
this._fillNextBeatDefault(current, checker);
|
|
46469
46560
|
}
|
|
46470
46561
|
}
|
|
46471
|
-
_fillNextBeatDefault(current,
|
|
46472
|
-
current.nextBeat = this._findBeatInMasterBar(current.masterBar, current.beatLookup.nextBeat, current.end,
|
|
46562
|
+
_fillNextBeatDefault(current, checker) {
|
|
46563
|
+
current.nextBeat = this._findBeatInMasterBar(current.masterBar, current.beatLookup.nextBeat, current.end, checker, true);
|
|
46473
46564
|
if (current.nextBeat == null) {
|
|
46474
|
-
current.nextBeat = this._findBeatSlow(
|
|
46565
|
+
current.nextBeat = this._findBeatSlow(checker, current, current.end, true);
|
|
46475
46566
|
}
|
|
46476
46567
|
// if we have the next beat take the difference between the times as duration
|
|
46477
46568
|
if (current.nextBeat) {
|
|
@@ -46502,7 +46593,7 @@ class MidiTickLookup {
|
|
|
46502
46593
|
beat.isRest &&
|
|
46503
46594
|
beat.voice.bar.isRestOnly);
|
|
46504
46595
|
}
|
|
46505
|
-
_findBeatSlow(
|
|
46596
|
+
_findBeatSlow(checker, currentBeatHint, tick, isNextSearch) {
|
|
46506
46597
|
// get all beats within the masterbar
|
|
46507
46598
|
let masterBar = null;
|
|
46508
46599
|
if (currentBeatHint != null) {
|
|
@@ -46524,14 +46615,14 @@ class MidiTickLookup {
|
|
|
46524
46615
|
if (!masterBar) {
|
|
46525
46616
|
return null;
|
|
46526
46617
|
}
|
|
46527
|
-
return this._firstBeatInMasterBar(
|
|
46618
|
+
return this._firstBeatInMasterBar(checker, masterBar, tick, isNextSearch);
|
|
46528
46619
|
}
|
|
46529
|
-
_firstBeatInMasterBar(
|
|
46620
|
+
_firstBeatInMasterBar(checker, startMasterBar, tick, isNextSearch) {
|
|
46530
46621
|
let masterBar = startMasterBar;
|
|
46531
46622
|
// scan through beats and find first one which has a beat visible
|
|
46532
46623
|
while (masterBar) {
|
|
46533
46624
|
if (masterBar.firstBeat) {
|
|
46534
|
-
const beat = this._findBeatInMasterBar(masterBar, masterBar.firstBeat, tick,
|
|
46625
|
+
const beat = this._findBeatInMasterBar(masterBar, masterBar.firstBeat, tick, checker, isNextSearch);
|
|
46535
46626
|
if (beat) {
|
|
46536
46627
|
return beat;
|
|
46537
46628
|
}
|
|
@@ -46549,7 +46640,7 @@ class MidiTickLookup {
|
|
|
46549
46640
|
* @param isNextSearch
|
|
46550
46641
|
* @returns
|
|
46551
46642
|
*/
|
|
46552
|
-
_findBeatInMasterBar(masterBar, currentStartLookup, tick,
|
|
46643
|
+
_findBeatInMasterBar(masterBar, currentStartLookup, tick, checker, isNextSearch) {
|
|
46553
46644
|
if (!currentStartLookup) {
|
|
46554
46645
|
return null;
|
|
46555
46646
|
}
|
|
@@ -46563,7 +46654,7 @@ class MidiTickLookup {
|
|
|
46563
46654
|
(currentStartLookup.start <= relativeTick || (isNextSearch && relativeTick < 0)) &&
|
|
46564
46655
|
relativeTick < currentStartLookup.end) {
|
|
46565
46656
|
startBeatLookup = currentStartLookup;
|
|
46566
|
-
startBeat = currentStartLookup.
|
|
46657
|
+
startBeat = currentStartLookup.getVisibleBeatAtStartWithChecker(checker);
|
|
46567
46658
|
// found the matching beat lookup but none of the beats are visible
|
|
46568
46659
|
// in this case scan further to the next lookup which has any visible beat
|
|
46569
46660
|
if (!startBeat) {
|
|
@@ -46571,7 +46662,7 @@ class MidiTickLookup {
|
|
|
46571
46662
|
let currentMasterBar = masterBar;
|
|
46572
46663
|
while (currentMasterBar != null && startBeat == null) {
|
|
46573
46664
|
while (currentStartLookup != null) {
|
|
46574
|
-
startBeat = currentStartLookup.
|
|
46665
|
+
startBeat = currentStartLookup.getVisibleBeatAtStartWithChecker(checker);
|
|
46575
46666
|
if (startBeat) {
|
|
46576
46667
|
startBeatLookup = currentStartLookup;
|
|
46577
46668
|
masterBar = currentMasterBar;
|
|
@@ -46589,7 +46680,7 @@ class MidiTickLookup {
|
|
|
46589
46680
|
let currentMasterBar = masterBar;
|
|
46590
46681
|
while (currentMasterBar != null && startBeat == null) {
|
|
46591
46682
|
while (currentStartLookup != null) {
|
|
46592
|
-
startBeat = currentStartLookup.
|
|
46683
|
+
startBeat = currentStartLookup.getVisibleBeatAtStartWithChecker(checker);
|
|
46593
46684
|
if (startBeat) {
|
|
46594
46685
|
startBeatLookup = currentStartLookup;
|
|
46595
46686
|
masterBar = currentMasterBar;
|
|
@@ -46613,17 +46704,17 @@ class MidiTickLookup {
|
|
|
46613
46704
|
if (startBeat == null) {
|
|
46614
46705
|
return null;
|
|
46615
46706
|
}
|
|
46616
|
-
const result = this._createResult(masterBar, startBeatLookup, startBeat, isNextSearch,
|
|
46707
|
+
const result = this._createResult(masterBar, startBeatLookup, startBeat, isNextSearch, checker);
|
|
46617
46708
|
return result;
|
|
46618
46709
|
}
|
|
46619
|
-
_createResult(masterBar, beatLookup, beat, isNextSearch,
|
|
46710
|
+
_createResult(masterBar, beatLookup, beat, isNextSearch, checker) {
|
|
46620
46711
|
const result = new MidiTickLookupFindBeatResult(masterBar);
|
|
46621
46712
|
result.beat = beat;
|
|
46622
46713
|
result.beatLookup = beatLookup;
|
|
46623
46714
|
result.tickDuration = beatLookup.end - beatLookup.start;
|
|
46624
46715
|
if (!isNextSearch) {
|
|
46625
46716
|
// the next beat filling will adjust this result with the respective durations
|
|
46626
|
-
this._fillNextBeat(result,
|
|
46717
|
+
this._fillNextBeat(result, checker);
|
|
46627
46718
|
}
|
|
46628
46719
|
else if (this._isMultiBarRestResult(result)) {
|
|
46629
46720
|
const multiRest = this.multiBarRestInfo.get(masterBar.masterBar.index);
|
|
@@ -49550,6 +49641,19 @@ class ExternalMediaPlayer extends BackingTrackPlayer {
|
|
|
49550
49641
|
}
|
|
49551
49642
|
}
|
|
49552
49643
|
|
|
49644
|
+
/**
|
|
49645
|
+
* @internal
|
|
49646
|
+
*/
|
|
49647
|
+
class BoundsLookupVisibilityChecker {
|
|
49648
|
+
bounds = null;
|
|
49649
|
+
isVisible(beat) {
|
|
49650
|
+
const bounds = this.bounds;
|
|
49651
|
+
if (!bounds) {
|
|
49652
|
+
return false;
|
|
49653
|
+
}
|
|
49654
|
+
return bounds.findBeat(beat) !== null;
|
|
49655
|
+
}
|
|
49656
|
+
}
|
|
49553
49657
|
/**
|
|
49554
49658
|
* This class represents the public API of alphaTab and provides all logic to display
|
|
49555
49659
|
* a music sheet in any UI using the given {@link IUiFacade}
|
|
@@ -49560,6 +49664,7 @@ class AlphaTabApiBase {
|
|
|
49560
49664
|
_startTime = 0;
|
|
49561
49665
|
_trackIndexes = null;
|
|
49562
49666
|
_trackIndexLookup = null;
|
|
49667
|
+
_beatVisibilityChecker = new BoundsLookupVisibilityChecker();
|
|
49563
49668
|
_isDestroyed = false;
|
|
49564
49669
|
_score = null;
|
|
49565
49670
|
_tracks = [];
|
|
@@ -51356,12 +51461,9 @@ class AlphaTabApiBase {
|
|
|
51356
51461
|
this._previousTick = tick;
|
|
51357
51462
|
const cache = this._tickCache;
|
|
51358
51463
|
if (cache) {
|
|
51359
|
-
const
|
|
51360
|
-
if (
|
|
51361
|
-
|
|
51362
|
-
if (beat) {
|
|
51363
|
-
this._cursorUpdateBeat(beat, stop, shouldScroll, cursorSpeed, forceUpdate || this.playerState === PlayerState.Paused);
|
|
51364
|
-
}
|
|
51464
|
+
const beat = cache.findBeatWithChecker(this._beatVisibilityChecker, tick, this._currentBeat);
|
|
51465
|
+
if (beat) {
|
|
51466
|
+
this._cursorUpdateBeat(beat, stop, shouldScroll, cursorSpeed, forceUpdate || this.playerState === PlayerState.Paused);
|
|
51365
51467
|
}
|
|
51366
51468
|
}
|
|
51367
51469
|
}
|
|
@@ -52563,6 +52665,7 @@ class AlphaTabApiBase {
|
|
|
52563
52665
|
if (this._isDestroyed) {
|
|
52564
52666
|
return;
|
|
52565
52667
|
}
|
|
52668
|
+
this._beatVisibilityChecker.bounds = this.boundsLookup;
|
|
52566
52669
|
this._currentBeat = null;
|
|
52567
52670
|
this._cursorUpdateTick(this._previousTick, false, 1, true, true);
|
|
52568
52671
|
this.postRenderFinished.trigger();
|
|
@@ -60570,8 +60673,10 @@ class RenderStaff {
|
|
|
60570
60673
|
height = 0;
|
|
60571
60674
|
index = 0;
|
|
60572
60675
|
staffIndex = 0;
|
|
60676
|
+
isVisible = false;
|
|
60677
|
+
_emptyBarCount = 0;
|
|
60573
60678
|
get isFirstInSystem() {
|
|
60574
|
-
return this.
|
|
60679
|
+
return this.system.firstVisibleStaff === this;
|
|
60575
60680
|
}
|
|
60576
60681
|
topEffectInfos = [];
|
|
60577
60682
|
bottomEffectInfos = [];
|
|
@@ -60606,10 +60711,11 @@ class RenderStaff {
|
|
|
60606
60711
|
get contentBottom() {
|
|
60607
60712
|
return this.y + this.topPadding + this.topOverflow + this.staffBottom;
|
|
60608
60713
|
}
|
|
60609
|
-
constructor(trackIndex, staff, factory) {
|
|
60714
|
+
constructor(system, trackIndex, staff, factory) {
|
|
60610
60715
|
this._factory = factory;
|
|
60611
60716
|
this.trackIndex = trackIndex;
|
|
60612
60717
|
this.modelStaff = staff;
|
|
60718
|
+
this.system = system;
|
|
60613
60719
|
for (const b of factory.effectBands) {
|
|
60614
60720
|
if (b.shouldCreate && !b.shouldCreate(staff)) {
|
|
60615
60721
|
continue;
|
|
@@ -60625,6 +60731,7 @@ class RenderStaff {
|
|
|
60625
60731
|
break;
|
|
60626
60732
|
}
|
|
60627
60733
|
}
|
|
60734
|
+
this._updateVisibility();
|
|
60628
60735
|
}
|
|
60629
60736
|
getSharedLayoutData(key, def) {
|
|
60630
60737
|
if (this._sharedLayoutData.has(key)) {
|
|
@@ -60651,6 +60758,20 @@ class RenderStaff {
|
|
|
60651
60758
|
renderer.reLayout();
|
|
60652
60759
|
this.barRenderers.push(renderer);
|
|
60653
60760
|
this.system.layout.registerBarRenderer(this.staffId, renderer);
|
|
60761
|
+
if (renderer.bar.isEmpty || renderer.bar.isRestOnly) {
|
|
60762
|
+
this._emptyBarCount++;
|
|
60763
|
+
}
|
|
60764
|
+
this._updateVisibility();
|
|
60765
|
+
}
|
|
60766
|
+
_updateVisibility() {
|
|
60767
|
+
const stylesheet = this.modelStaff.track.score.stylesheet;
|
|
60768
|
+
const canHideEmptyStaves = stylesheet.hideEmptyStaves && (stylesheet.hideEmptyStavesInFirstSystem || this.system.index > 0);
|
|
60769
|
+
if (canHideEmptyStaves) {
|
|
60770
|
+
this.isVisible = this._emptyBarCount < this.barRenderers.length;
|
|
60771
|
+
}
|
|
60772
|
+
else {
|
|
60773
|
+
this.isVisible = true;
|
|
60774
|
+
}
|
|
60654
60775
|
}
|
|
60655
60776
|
addBar(bar, layoutingInfo, additionalMultiBarsRestBars) {
|
|
60656
60777
|
const renderer = this._factory.create(this.system.layout.renderer, bar);
|
|
@@ -60670,6 +60791,10 @@ class RenderStaff {
|
|
|
60670
60791
|
}
|
|
60671
60792
|
this.barRenderers.push(renderer);
|
|
60672
60793
|
this.system.layout.registerBarRenderer(this.staffId, renderer);
|
|
60794
|
+
if (bar.isEmpty || bar.isRestOnly) {
|
|
60795
|
+
this._emptyBarCount++;
|
|
60796
|
+
}
|
|
60797
|
+
this._updateVisibility();
|
|
60673
60798
|
}
|
|
60674
60799
|
revertLastBar() {
|
|
60675
60800
|
this._sharedLayoutData = new Map();
|
|
@@ -60680,6 +60805,10 @@ class RenderStaff {
|
|
|
60680
60805
|
for (const r of this.barRenderers) {
|
|
60681
60806
|
r.afterStaffBarReverted();
|
|
60682
60807
|
}
|
|
60808
|
+
if (lastBar.bar.isEmpty || lastBar.bar.isRestOnly) {
|
|
60809
|
+
this._emptyBarCount--;
|
|
60810
|
+
}
|
|
60811
|
+
this._updateVisibility();
|
|
60683
60812
|
return lastBar;
|
|
60684
60813
|
}
|
|
60685
60814
|
scaleToWidth(width) {
|
|
@@ -60790,6 +60919,7 @@ class RenderStaff {
|
|
|
60790
60919
|
this.height += this.topPadding + topOverflow + this.bottomOverflow + this.bottomPadding;
|
|
60791
60920
|
}
|
|
60792
60921
|
this.height = Math.ceil(this.height);
|
|
60922
|
+
this._updateVisibility();
|
|
60793
60923
|
}
|
|
60794
60924
|
paint(cx, cy, canvas, startIndex, count) {
|
|
60795
60925
|
if (this.height === 0 || count === 0) {
|
|
@@ -61190,6 +61320,8 @@ class StaffTrackGroup {
|
|
|
61190
61320
|
track;
|
|
61191
61321
|
staffSystem;
|
|
61192
61322
|
staves = [];
|
|
61323
|
+
firstVisibleStaff;
|
|
61324
|
+
lastVisibleStaff;
|
|
61193
61325
|
bracket = null;
|
|
61194
61326
|
constructor(staffSystem, track) {
|
|
61195
61327
|
this.staffSystem = staffSystem;
|
|
@@ -61204,18 +61336,47 @@ class StaffTrackGroup {
|
|
|
61204
61336
|
* @internal
|
|
61205
61337
|
*/
|
|
61206
61338
|
class SystemBracket {
|
|
61207
|
-
|
|
61208
|
-
|
|
61339
|
+
_system;
|
|
61340
|
+
firstStaffInBracket;
|
|
61341
|
+
lastStaffInBracket;
|
|
61342
|
+
firstVisibleStaffInBracket;
|
|
61343
|
+
lastVisibleStaffInBracket;
|
|
61209
61344
|
drawAsBrace = false;
|
|
61210
61345
|
braceScale = 1;
|
|
61211
61346
|
width = 0;
|
|
61212
61347
|
index = 0;
|
|
61213
|
-
|
|
61214
|
-
|
|
61348
|
+
canPaint = false;
|
|
61349
|
+
constructor(system) {
|
|
61350
|
+
this._system = system;
|
|
61351
|
+
}
|
|
61352
|
+
updateCanPaint() {
|
|
61353
|
+
let firstVisibleStaff = undefined;
|
|
61354
|
+
let lastVisibleStaff = undefined;
|
|
61355
|
+
for (let i = this.firstStaffInBracket.index; i <= this.lastStaffInBracket.index; i++) {
|
|
61356
|
+
const staff = this._system.allStaves[i];
|
|
61357
|
+
if (staff.isVisible) {
|
|
61358
|
+
if (!firstVisibleStaff) {
|
|
61359
|
+
firstVisibleStaff = staff;
|
|
61360
|
+
}
|
|
61361
|
+
lastVisibleStaff = staff;
|
|
61362
|
+
}
|
|
61363
|
+
}
|
|
61364
|
+
this.firstVisibleStaffInBracket = firstVisibleStaff;
|
|
61365
|
+
this.lastVisibleStaffInBracket = lastVisibleStaff;
|
|
61366
|
+
if (!firstVisibleStaff || !lastVisibleStaff) {
|
|
61367
|
+
this.canPaint = false;
|
|
61368
|
+
return;
|
|
61369
|
+
}
|
|
61370
|
+
// single staff brackets?
|
|
61371
|
+
const singleStaffBrackets = this._system.layout.renderer.score.stylesheet.showSingleStaffBrackets;
|
|
61372
|
+
if (!singleStaffBrackets && firstVisibleStaff === lastVisibleStaff) {
|
|
61373
|
+
this.canPaint = false;
|
|
61374
|
+
return;
|
|
61375
|
+
}
|
|
61376
|
+
this.canPaint = true;
|
|
61215
61377
|
}
|
|
61216
61378
|
finalizeBracket(smuflMetrics) {
|
|
61217
|
-
|
|
61218
|
-
if (this.firstStaffInBracket === this.lastStaffInBracket) {
|
|
61379
|
+
if (!this.canPaint) {
|
|
61219
61380
|
this.width = 0;
|
|
61220
61381
|
return;
|
|
61221
61382
|
}
|
|
@@ -61229,11 +61390,11 @@ class SystemBracket {
|
|
|
61229
61390
|
else {
|
|
61230
61391
|
this.width = smuflMetrics.bracketThickness;
|
|
61231
61392
|
}
|
|
61232
|
-
if (!this.drawAsBrace
|
|
61393
|
+
if (!this.drawAsBrace) {
|
|
61233
61394
|
return;
|
|
61234
61395
|
}
|
|
61235
|
-
const firstStart = this.
|
|
61236
|
-
const lastEnd = this.
|
|
61396
|
+
const firstStart = this.firstVisibleStaffInBracket.contentTop;
|
|
61397
|
+
const lastEnd = this.lastVisibleStaffInBracket.contentBottom;
|
|
61237
61398
|
const requiredHeight = lastEnd - firstStart;
|
|
61238
61399
|
const requiredScaleForBracket = requiredHeight / bravuraBraceHeightAtMusicFontSize;
|
|
61239
61400
|
this.braceScale = requiredScaleForBracket;
|
|
@@ -61245,8 +61406,8 @@ class SystemBracket {
|
|
|
61245
61406
|
*/
|
|
61246
61407
|
class SingleTrackSystemBracket extends SystemBracket {
|
|
61247
61408
|
track;
|
|
61248
|
-
constructor(track) {
|
|
61249
|
-
super();
|
|
61409
|
+
constructor(system, track) {
|
|
61410
|
+
super(system);
|
|
61250
61411
|
this.track = track;
|
|
61251
61412
|
this.drawAsBrace = SingleTrackSystemBracket.isTrackDrawAsBrace(track);
|
|
61252
61413
|
}
|
|
@@ -61311,6 +61472,7 @@ class StaffSystem {
|
|
|
61311
61472
|
topPadding;
|
|
61312
61473
|
bottomPadding;
|
|
61313
61474
|
allStaves = [];
|
|
61475
|
+
firstVisibleStaff;
|
|
61314
61476
|
constructor(layout) {
|
|
61315
61477
|
this.layout = layout;
|
|
61316
61478
|
this.topPadding = layout.renderer.settings.display.systemPaddingTop;
|
|
@@ -61329,14 +61491,40 @@ class StaffSystem {
|
|
|
61329
61491
|
this.masterBarsRenderers.push(renderers);
|
|
61330
61492
|
renderers.layoutingInfo.preBeatSize = 0;
|
|
61331
61493
|
let src = 0;
|
|
61332
|
-
|
|
61333
|
-
|
|
61334
|
-
|
|
61335
|
-
|
|
61494
|
+
let firstVisibleStaff = undefined;
|
|
61495
|
+
let anyStaffVisible = false;
|
|
61496
|
+
for (const g of this.staves) {
|
|
61497
|
+
let firstVisibleStaffInGroup = undefined;
|
|
61498
|
+
let lastVisibleStaffInGroup = undefined;
|
|
61499
|
+
for (const s of g.staves) {
|
|
61336
61500
|
const renderer = renderers.renderers[src++];
|
|
61337
61501
|
s.addBarRenderer(renderer);
|
|
61502
|
+
if (s.isVisible) {
|
|
61503
|
+
anyStaffVisible = true;
|
|
61504
|
+
if (!firstVisibleStaffInGroup) {
|
|
61505
|
+
firstVisibleStaffInGroup = s;
|
|
61506
|
+
}
|
|
61507
|
+
if (!firstVisibleStaff) {
|
|
61508
|
+
firstVisibleStaff = s;
|
|
61509
|
+
}
|
|
61510
|
+
lastVisibleStaffInGroup = s;
|
|
61511
|
+
}
|
|
61338
61512
|
}
|
|
61513
|
+
g.firstVisibleStaff = firstVisibleStaffInGroup;
|
|
61514
|
+
g.lastVisibleStaff = lastVisibleStaffInGroup;
|
|
61515
|
+
if (!firstVisibleStaff) {
|
|
61516
|
+
firstVisibleStaff = firstVisibleStaffInGroup;
|
|
61517
|
+
}
|
|
61518
|
+
}
|
|
61519
|
+
if (!anyStaffVisible) {
|
|
61520
|
+
const group = this.staves[0];
|
|
61521
|
+
const firstStaff = group.staves[0];
|
|
61522
|
+
firstStaff.isVisible = true;
|
|
61523
|
+
group.firstVisibleStaff = firstStaff;
|
|
61524
|
+
group.lastVisibleStaff = firstStaff;
|
|
61525
|
+
firstVisibleStaff = firstStaff;
|
|
61339
61526
|
}
|
|
61527
|
+
this.firstVisibleStaff = firstVisibleStaff;
|
|
61340
61528
|
this._calculateAccoladeSpacing(tracks);
|
|
61341
61529
|
this._updateWidthFromLastBar();
|
|
61342
61530
|
return renderers;
|
|
@@ -61347,15 +61535,26 @@ class StaffSystem {
|
|
|
61347
61535
|
result.layoutingInfo = new BarLayoutingInfo();
|
|
61348
61536
|
result.masterBar = tracks[0].score.masterBars[barIndex];
|
|
61349
61537
|
this.masterBarsRenderers.push(result);
|
|
61538
|
+
let firstVisibleStaff = undefined;
|
|
61539
|
+
let anyStaffVisible = false;
|
|
61350
61540
|
// add renderers
|
|
61351
61541
|
const barLayoutingInfo = result.layoutingInfo;
|
|
61352
61542
|
for (const g of this.staves) {
|
|
61543
|
+
let firstVisibleStaffInGroup = undefined;
|
|
61544
|
+
let lastVisibleStaffInGroup = undefined;
|
|
61353
61545
|
for (const s of g.staves) {
|
|
61354
61546
|
const bar = g.track.staves[s.modelStaff.index].bars[barIndex];
|
|
61355
61547
|
const additionalMultiBarsRestBars = additionalMultiBarRestIndexes == null
|
|
61356
61548
|
? null
|
|
61357
61549
|
: additionalMultiBarRestIndexes.map(b => g.track.staves[s.modelStaff.index].bars[b]);
|
|
61358
61550
|
s.addBar(bar, barLayoutingInfo, additionalMultiBarsRestBars);
|
|
61551
|
+
if (s.isVisible) {
|
|
61552
|
+
anyStaffVisible = true;
|
|
61553
|
+
if (!firstVisibleStaffInGroup) {
|
|
61554
|
+
firstVisibleStaffInGroup = s;
|
|
61555
|
+
}
|
|
61556
|
+
lastVisibleStaffInGroup = s;
|
|
61557
|
+
}
|
|
61359
61558
|
const renderer = s.barRenderers[s.barRenderers.length - 1];
|
|
61360
61559
|
result.renderers.push(renderer);
|
|
61361
61560
|
if (renderer.isLinkedToPrevious) {
|
|
@@ -61365,7 +61564,21 @@ class StaffSystem {
|
|
|
61365
61564
|
result.canWrap = false;
|
|
61366
61565
|
}
|
|
61367
61566
|
}
|
|
61567
|
+
g.firstVisibleStaff = firstVisibleStaffInGroup;
|
|
61568
|
+
g.lastVisibleStaff = lastVisibleStaffInGroup;
|
|
61569
|
+
if (!firstVisibleStaff) {
|
|
61570
|
+
firstVisibleStaff = firstVisibleStaffInGroup;
|
|
61571
|
+
}
|
|
61572
|
+
}
|
|
61573
|
+
if (!anyStaffVisible) {
|
|
61574
|
+
const group = this.staves[0];
|
|
61575
|
+
const firstStaff = group.staves[0];
|
|
61576
|
+
firstStaff.isVisible = true;
|
|
61577
|
+
group.firstVisibleStaff = firstStaff;
|
|
61578
|
+
group.lastVisibleStaff = firstStaff;
|
|
61579
|
+
firstVisibleStaff = firstStaff;
|
|
61368
61580
|
}
|
|
61581
|
+
this.firstVisibleStaff = firstVisibleStaff;
|
|
61369
61582
|
this._calculateAccoladeSpacing(tracks);
|
|
61370
61583
|
barLayoutingInfo.finish();
|
|
61371
61584
|
// ensure same widths of new renderer
|
|
@@ -61378,19 +61591,35 @@ class StaffSystem {
|
|
|
61378
61591
|
this.masterBarsRenderers.splice(this.masterBarsRenderers.length - 1, 1);
|
|
61379
61592
|
let width = 0;
|
|
61380
61593
|
let barDisplayScale = 0;
|
|
61381
|
-
|
|
61382
|
-
|
|
61383
|
-
|
|
61384
|
-
|
|
61385
|
-
|
|
61386
|
-
|
|
61594
|
+
let firstVisibleStaff = undefined;
|
|
61595
|
+
for (const g of this.staves) {
|
|
61596
|
+
let firstVisibleStaffInGroup = undefined;
|
|
61597
|
+
let lastVisibleStaffInGroup = undefined;
|
|
61598
|
+
for (const s of g.staves) {
|
|
61599
|
+
const lastBar = s.revertLastBar();
|
|
61600
|
+
const computedWidth = lastBar.computedWidth;
|
|
61601
|
+
if (computedWidth > width) {
|
|
61602
|
+
width = computedWidth;
|
|
61603
|
+
}
|
|
61604
|
+
const newBarDisplayScale = lastBar.barDisplayScale;
|
|
61605
|
+
if (newBarDisplayScale > barDisplayScale) {
|
|
61606
|
+
barDisplayScale = newBarDisplayScale;
|
|
61607
|
+
}
|
|
61608
|
+
lastBar.afterReverted();
|
|
61609
|
+
if (s.isVisible) {
|
|
61610
|
+
if (!firstVisibleStaffInGroup) {
|
|
61611
|
+
firstVisibleStaffInGroup = s;
|
|
61612
|
+
}
|
|
61613
|
+
lastVisibleStaffInGroup = s;
|
|
61614
|
+
}
|
|
61387
61615
|
}
|
|
61388
|
-
|
|
61389
|
-
|
|
61390
|
-
|
|
61616
|
+
g.firstVisibleStaff = firstVisibleStaffInGroup;
|
|
61617
|
+
g.lastVisibleStaff = lastVisibleStaffInGroup;
|
|
61618
|
+
if (!firstVisibleStaff) {
|
|
61619
|
+
firstVisibleStaff = firstVisibleStaffInGroup;
|
|
61391
61620
|
}
|
|
61392
|
-
lastBar.afterReverted();
|
|
61393
61621
|
}
|
|
61622
|
+
this.firstVisibleStaff = firstVisibleStaff;
|
|
61394
61623
|
this.width -= width;
|
|
61395
61624
|
this.computedWidth -= width;
|
|
61396
61625
|
this.totalBarDisplayScale -= barDisplayScale;
|
|
@@ -61497,6 +61726,7 @@ class StaffSystem {
|
|
|
61497
61726
|
}
|
|
61498
61727
|
let braceWidth = 0;
|
|
61499
61728
|
for (const b of this._brackets) {
|
|
61729
|
+
b.updateCanPaint();
|
|
61500
61730
|
b.finalizeBracket(settings.display.resources.engravingSettings);
|
|
61501
61731
|
braceWidth = Math.max(braceWidth, b.width);
|
|
61502
61732
|
}
|
|
@@ -61504,6 +61734,12 @@ class StaffSystem {
|
|
|
61504
61734
|
this.width += this.accoladeWidth;
|
|
61505
61735
|
this.computedWidth += this.accoladeWidth;
|
|
61506
61736
|
}
|
|
61737
|
+
else {
|
|
61738
|
+
for (const b of this._brackets) {
|
|
61739
|
+
b.updateCanPaint();
|
|
61740
|
+
b.finalizeBracket(settings.display.resources.engravingSettings);
|
|
61741
|
+
}
|
|
61742
|
+
}
|
|
61507
61743
|
}
|
|
61508
61744
|
_getStaffTrackGroup(track) {
|
|
61509
61745
|
for (let i = 0, j = this.staves.length; i < j; i++) {
|
|
@@ -61533,12 +61769,12 @@ class StaffSystem {
|
|
|
61533
61769
|
break;
|
|
61534
61770
|
case BracketExtendMode.GroupStaves:
|
|
61535
61771
|
// when grouping staves, we create one bracket for the whole track across all staves
|
|
61536
|
-
bracket = new SingleTrackSystemBracket(track);
|
|
61772
|
+
bracket = new SingleTrackSystemBracket(this, track);
|
|
61537
61773
|
bracket.index = this._brackets.length;
|
|
61538
61774
|
this._brackets.push(bracket);
|
|
61539
61775
|
break;
|
|
61540
61776
|
case BracketExtendMode.GroupSimilarInstruments:
|
|
61541
|
-
bracket = new SimilarInstrumentSystemBracket(track);
|
|
61777
|
+
bracket = new SimilarInstrumentSystemBracket(this, track);
|
|
61542
61778
|
bracket.index = this._brackets.length;
|
|
61543
61779
|
this._brackets.push(bracket);
|
|
61544
61780
|
break;
|
|
@@ -61585,8 +61821,10 @@ class StaffSystem {
|
|
|
61585
61821
|
}
|
|
61586
61822
|
}
|
|
61587
61823
|
paintPartial(cx, cy, canvas, startIndex, count) {
|
|
61588
|
-
for (
|
|
61589
|
-
|
|
61824
|
+
for (const s of this.allStaves) {
|
|
61825
|
+
if (s.isVisible) {
|
|
61826
|
+
s.paint(cx, cy, canvas, startIndex, count);
|
|
61827
|
+
}
|
|
61590
61828
|
}
|
|
61591
61829
|
const res = this.layout.renderer.settings.display.resources;
|
|
61592
61830
|
if (this.staves.length > 0 && startIndex === 0) {
|
|
@@ -61623,9 +61861,9 @@ class StaffSystem {
|
|
|
61623
61861
|
const oldBaseLine = canvas.textBaseline;
|
|
61624
61862
|
const oldTextAlign = canvas.textAlign;
|
|
61625
61863
|
for (const g of this.staves) {
|
|
61626
|
-
if (g.
|
|
61627
|
-
const firstStart = cy + g.
|
|
61628
|
-
const lastEnd = cy + g.
|
|
61864
|
+
if (g.firstVisibleStaff) {
|
|
61865
|
+
const firstStart = cy + g.firstVisibleStaff.contentTop;
|
|
61866
|
+
const lastEnd = cy + g.lastVisibleStaff.contentBottom;
|
|
61629
61867
|
let trackNameText = '';
|
|
61630
61868
|
switch (trackNameMode) {
|
|
61631
61869
|
case TrackNameMode.FullName:
|
|
@@ -61679,6 +61917,9 @@ class StaffSystem {
|
|
|
61679
61917
|
if (this.allStaves.length > 0 && needsSystemBarLine) {
|
|
61680
61918
|
let previousStaffInBracket = null;
|
|
61681
61919
|
for (const s of this.allStaves) {
|
|
61920
|
+
if (!s.isVisible) {
|
|
61921
|
+
continue;
|
|
61922
|
+
}
|
|
61682
61923
|
if (previousStaffInBracket !== null) {
|
|
61683
61924
|
const previousBottom = previousStaffInBracket.contentBottom;
|
|
61684
61925
|
const thisTop = s.contentTop;
|
|
@@ -61705,17 +61946,17 @@ class StaffSystem {
|
|
|
61705
61946
|
const settings = this.layout.renderer.settings;
|
|
61706
61947
|
for (const bracket of this._brackets) {
|
|
61707
61948
|
if (bracket.canPaint) {
|
|
61708
|
-
const barStartX = cx + bracket.
|
|
61949
|
+
const barStartX = cx + bracket.firstVisibleStaffInBracket.x;
|
|
61709
61950
|
const barSize = bracket.width;
|
|
61710
61951
|
const barOffset = settings.display.accoladeBarPaddingRight;
|
|
61711
|
-
const firstStart = cy + bracket.
|
|
61712
|
-
const lastEnd = cy + bracket.
|
|
61952
|
+
const firstStart = cy + bracket.firstVisibleStaffInBracket.contentTop;
|
|
61953
|
+
const lastEnd = cy + bracket.lastVisibleStaffInBracket.contentBottom;
|
|
61713
61954
|
let accoladeStart = firstStart;
|
|
61714
61955
|
let accoladeEnd = lastEnd;
|
|
61715
61956
|
if (bracket.drawAsBrace) {
|
|
61716
61957
|
CanvasHelper.fillMusicFontSymbolSafe(canvas, barStartX - barOffset - barSize, accoladeEnd, bracket.braceScale, MusicFontSymbol.Brace);
|
|
61717
61958
|
}
|
|
61718
|
-
else if (bracket.
|
|
61959
|
+
else if (bracket.firstVisibleStaffInBracket !== bracket.lastVisibleStaffInBracket) {
|
|
61719
61960
|
// brackets typically overflow by 1/4 staff-space
|
|
61720
61961
|
const smuflMetrics = settings.display.resources.engravingSettings;
|
|
61721
61962
|
const bracketOverflow = smuflMetrics.oneStaffSpace * 0.25;
|
|
@@ -61747,40 +61988,86 @@ class StaffSystem {
|
|
|
61747
61988
|
this.bottomPadding = Math.max(this.bottomPadding, neededHeight);
|
|
61748
61989
|
this._hasSystemSeparator = true;
|
|
61749
61990
|
}
|
|
61991
|
+
const anyStaffVisible = this._finalizeTrackGroups();
|
|
61992
|
+
// for now we always force one staff to be visible.
|
|
61993
|
+
// making also whole systems invisible needs separate attention (also on player cursor handling)
|
|
61994
|
+
if (!anyStaffVisible) {
|
|
61995
|
+
const group = this.staves[0];
|
|
61996
|
+
const firstStaff = group.staves[0];
|
|
61997
|
+
firstStaff.isVisible = true;
|
|
61998
|
+
this._finalizeTrackGroups(true);
|
|
61999
|
+
}
|
|
62000
|
+
for (const b of this._brackets) {
|
|
62001
|
+
b.finalizeBracket(settings.display.resources.engravingSettings);
|
|
62002
|
+
}
|
|
62003
|
+
}
|
|
62004
|
+
_finalizeTrackGroups(onlyFirstGroup = false) {
|
|
61750
62005
|
let currentY = 0;
|
|
62006
|
+
const settings = this.layout.renderer.settings;
|
|
61751
62007
|
const smufl = settings.display.resources.engravingSettings;
|
|
61752
62008
|
const topBracketSpikeHeight = smufl.glyphHeights.get(MusicFontSymbol.BracketTop);
|
|
61753
62009
|
const bottomBracketSpikeHeight = smufl.glyphHeights.get(MusicFontSymbol.BracketBottom);
|
|
61754
62010
|
let previousStaff = undefined;
|
|
61755
|
-
|
|
61756
|
-
|
|
61757
|
-
|
|
61758
|
-
|
|
61759
|
-
|
|
61760
|
-
const
|
|
61761
|
-
|
|
61762
|
-
|
|
61763
|
-
|
|
61764
|
-
|
|
61765
|
-
|
|
62011
|
+
let endSpikeOverflow = 0;
|
|
62012
|
+
let anyStaffVisible = false;
|
|
62013
|
+
for (const group of this.staves) {
|
|
62014
|
+
let firstVisibleStaffInGroup = undefined;
|
|
62015
|
+
let lastVisibleStaffInGroup = undefined;
|
|
62016
|
+
for (const staff of group.staves) {
|
|
62017
|
+
// check if we need "in-between padding"
|
|
62018
|
+
if (previousStaff !== undefined && previousStaff.trackIndex !== staff.trackIndex) {
|
|
62019
|
+
currentY += settings.display.trackStaffPaddingBetween;
|
|
62020
|
+
}
|
|
62021
|
+
const bracket = this._staffToBracket.has(staff) ? this._staffToBracket.get(staff) : undefined;
|
|
62022
|
+
const hasBracket = bracket && !bracket.drawAsBrace && bracket.canPaint;
|
|
62023
|
+
if (hasBracket && bracket.firstStaffInBracket === staff) {
|
|
62024
|
+
const spikeOverflow = topBracketSpikeHeight - staff.topOverflow;
|
|
62025
|
+
if (spikeOverflow > 0) {
|
|
62026
|
+
currentY += spikeOverflow;
|
|
62027
|
+
}
|
|
62028
|
+
}
|
|
62029
|
+
staff.x = this.accoladeWidth;
|
|
62030
|
+
staff.y = currentY;
|
|
62031
|
+
if (!onlyFirstGroup) {
|
|
62032
|
+
staff.finalizeStaff();
|
|
62033
|
+
}
|
|
62034
|
+
if (staff.isVisible) {
|
|
62035
|
+
currentY += staff.height;
|
|
62036
|
+
anyStaffVisible = true;
|
|
62037
|
+
previousStaff = staff;
|
|
62038
|
+
if (!firstVisibleStaffInGroup) {
|
|
62039
|
+
firstVisibleStaffInGroup = staff;
|
|
62040
|
+
}
|
|
62041
|
+
lastVisibleStaffInGroup = staff;
|
|
62042
|
+
}
|
|
62043
|
+
endSpikeOverflow = 0;
|
|
62044
|
+
if (hasBracket && bracket.lastStaffInBracket === staff) {
|
|
62045
|
+
const spikeOverflow = bottomBracketSpikeHeight - staff.bottomOverflow;
|
|
62046
|
+
if (spikeOverflow > 0) {
|
|
62047
|
+
if (staff.isVisible) {
|
|
62048
|
+
currentY += spikeOverflow;
|
|
62049
|
+
}
|
|
62050
|
+
else {
|
|
62051
|
+
endSpikeOverflow = spikeOverflow;
|
|
62052
|
+
}
|
|
62053
|
+
}
|
|
61766
62054
|
}
|
|
61767
62055
|
}
|
|
61768
|
-
|
|
61769
|
-
|
|
61770
|
-
|
|
61771
|
-
|
|
61772
|
-
|
|
61773
|
-
|
|
61774
|
-
|
|
61775
|
-
currentY += spikeOverflow;
|
|
61776
|
-
}
|
|
62056
|
+
group.firstVisibleStaff = firstVisibleStaffInGroup;
|
|
62057
|
+
group.lastVisibleStaff = lastVisibleStaffInGroup;
|
|
62058
|
+
if (!this.firstVisibleStaff) {
|
|
62059
|
+
this.firstVisibleStaff = firstVisibleStaffInGroup;
|
|
62060
|
+
}
|
|
62061
|
+
if (onlyFirstGroup) {
|
|
62062
|
+
break;
|
|
61777
62063
|
}
|
|
61778
|
-
previousStaff = staff;
|
|
61779
62064
|
}
|
|
61780
|
-
|
|
61781
|
-
|
|
61782
|
-
|
|
62065
|
+
// ensure we add overflow if last bracket is hidden
|
|
62066
|
+
if (endSpikeOverflow) {
|
|
62067
|
+
currentY += endSpikeOverflow;
|
|
61783
62068
|
}
|
|
62069
|
+
this._contentHeight = currentY;
|
|
62070
|
+
return anyStaffVisible;
|
|
61784
62071
|
}
|
|
61785
62072
|
buildBoundingsLookup(cx, cy) {
|
|
61786
62073
|
if (this.layout.renderer.boundsLookup.isFinished) {
|
|
@@ -61814,6 +62101,9 @@ class StaffSystem {
|
|
|
61814
62101
|
const masterBarBoundsLookup = new Map();
|
|
61815
62102
|
for (let i = 0; i < this.staves.length; i++) {
|
|
61816
62103
|
for (const staff of this.staves[i].staves) {
|
|
62104
|
+
if (!staff.isVisible) {
|
|
62105
|
+
continue;
|
|
62106
|
+
}
|
|
61817
62107
|
for (const renderer of staff.barRenderers) {
|
|
61818
62108
|
let masterBarBounds;
|
|
61819
62109
|
if (!masterBarBoundsLookup.has(renderer.bar.masterBar.index)) {
|
|
@@ -62124,8 +62414,9 @@ class ScoreLayout {
|
|
|
62124
62414
|
}
|
|
62125
62415
|
firstBarIndex = 0;
|
|
62126
62416
|
lastBarIndex = 0;
|
|
62127
|
-
createEmptyStaffSystem() {
|
|
62417
|
+
createEmptyStaffSystem(index) {
|
|
62128
62418
|
const system = new StaffSystem(this);
|
|
62419
|
+
system.index = index;
|
|
62129
62420
|
const allFactories = Environment.defaultRenderers;
|
|
62130
62421
|
const renderStaves = [];
|
|
62131
62422
|
for (let trackIndex = 0; trackIndex < this.renderer.tracks.length; trackIndex++) {
|
|
@@ -62137,7 +62428,7 @@ class ScoreLayout {
|
|
|
62137
62428
|
let previousStaff = undefined;
|
|
62138
62429
|
for (const factory of allFactories) {
|
|
62139
62430
|
if (this.profile.has(factory.staffId) && factory.canCreate(track, staff)) {
|
|
62140
|
-
const renderStaff = new RenderStaff(trackIndex, staff, factory);
|
|
62431
|
+
const renderStaff = new RenderStaff(system, trackIndex, staff, factory);
|
|
62141
62432
|
// insert shared effect bands at front
|
|
62142
62433
|
renderStaff.topEffectInfos.splice(0, 0, ...sharedTopEffects);
|
|
62143
62434
|
renderStaff.bottomEffectInfos.push(...sharedBottomEffects);
|
|
@@ -65295,7 +65586,7 @@ class HorizontalScreenLayout extends ScoreLayout {
|
|
|
65295
65586
|
}
|
|
65296
65587
|
endBarIndex = startIndex + endBarIndex - 1; // map count to array index
|
|
65297
65588
|
endBarIndex = Math.min(score.masterBars.length - 1, Math.max(0, endBarIndex));
|
|
65298
|
-
this._system = this.createEmptyStaffSystem();
|
|
65589
|
+
this._system = this.createEmptyStaffSystem(0);
|
|
65299
65590
|
this._system.isLast = true;
|
|
65300
65591
|
this._system.x = this.pagePadding[0];
|
|
65301
65592
|
this._system.y = this.pagePadding[1];
|
|
@@ -65568,8 +65859,7 @@ class PageViewLayout extends ScoreLayout {
|
|
|
65568
65859
|
this._systems = [];
|
|
65569
65860
|
let currentIndex = 0;
|
|
65570
65861
|
const maxWidth = this._maxWidth;
|
|
65571
|
-
let system = this.createEmptyStaffSystem();
|
|
65572
|
-
system.index = this._systems.length;
|
|
65862
|
+
let system = this.createEmptyStaffSystem(this._systems.length);
|
|
65573
65863
|
system.x = this.pagePadding[0];
|
|
65574
65864
|
system.y = y;
|
|
65575
65865
|
while (currentIndex < this._allMasterBarRenderers.length) {
|
|
@@ -65600,8 +65890,7 @@ class PageViewLayout extends ScoreLayout {
|
|
|
65600
65890
|
this._fitSystem(system);
|
|
65601
65891
|
y += this._paintSystem(system, oldHeight);
|
|
65602
65892
|
// note: we do not increase currentIndex here to have it added to the next system
|
|
65603
|
-
system = this.createEmptyStaffSystem();
|
|
65604
|
-
system.index = this._systems.length;
|
|
65893
|
+
system = this.createEmptyStaffSystem(this._systems.length);
|
|
65605
65894
|
system.x = this.pagePadding[0];
|
|
65606
65895
|
system.y = y;
|
|
65607
65896
|
}
|
|
@@ -65686,8 +65975,7 @@ class PageViewLayout extends ScoreLayout {
|
|
|
65686
65975
|
return barsPerRow;
|
|
65687
65976
|
}
|
|
65688
65977
|
_createStaffSystem(currentBarIndex, endIndex) {
|
|
65689
|
-
const system = this.createEmptyStaffSystem();
|
|
65690
|
-
system.index = this._systems.length;
|
|
65978
|
+
const system = this.createEmptyStaffSystem(this._systems.length);
|
|
65691
65979
|
const barsPerRow = this._getBarsPerSystem(system.index);
|
|
65692
65980
|
const maxWidth = this._maxWidth;
|
|
65693
65981
|
const end = endIndex + 1;
|
|
@@ -68367,16 +68655,77 @@ class NumberedBarRendererFactory extends BarRendererFactory {
|
|
|
68367
68655
|
class ClefGlyph extends MusicFontGlyph {
|
|
68368
68656
|
_clef;
|
|
68369
68657
|
_clefOttava;
|
|
68658
|
+
_ottavaGlyph;
|
|
68370
68659
|
constructor(x, y, clef, clefOttava) {
|
|
68371
68660
|
super(x, y, 1, ClefGlyph._getSymbol(clef, clefOttava));
|
|
68372
68661
|
this._clef = clef;
|
|
68373
68662
|
this._clefOttava = clefOttava;
|
|
68374
68663
|
}
|
|
68664
|
+
getBoundingBoxTop() {
|
|
68665
|
+
let top = super.getBoundingBoxTop();
|
|
68666
|
+
const ottava = this._ottavaGlyph;
|
|
68667
|
+
if (ottava) {
|
|
68668
|
+
const ottavaTop = this.y + ottava.getBoundingBoxTop();
|
|
68669
|
+
top = ModelUtils.minBoundingBox(top, ottavaTop);
|
|
68670
|
+
}
|
|
68671
|
+
return top;
|
|
68672
|
+
}
|
|
68673
|
+
getBoundingBoxBottom() {
|
|
68674
|
+
let bottom = super.getBoundingBoxBottom();
|
|
68675
|
+
const ottava = this._ottavaGlyph;
|
|
68676
|
+
if (ottava) {
|
|
68677
|
+
const ottavaBottom = this.y + ottava.getBoundingBoxBottom();
|
|
68678
|
+
bottom = ModelUtils.maxBoundingBox(bottom, ottavaBottom);
|
|
68679
|
+
}
|
|
68680
|
+
return bottom;
|
|
68681
|
+
}
|
|
68375
68682
|
doLayout() {
|
|
68376
68683
|
this.center = true;
|
|
68377
68684
|
super.doLayout();
|
|
68378
68685
|
this.width = this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.GClef);
|
|
68379
68686
|
this.offsetX = this.width / 2;
|
|
68687
|
+
this._ottavaGlyph = undefined;
|
|
68688
|
+
switch (this._clef) {
|
|
68689
|
+
case Clef.C3:
|
|
68690
|
+
case Clef.C4:
|
|
68691
|
+
switch (this._clefOttava) {
|
|
68692
|
+
case Ottavia._8vb:
|
|
68693
|
+
return;
|
|
68694
|
+
}
|
|
68695
|
+
break;
|
|
68696
|
+
case Clef.F4:
|
|
68697
|
+
case Clef.G2:
|
|
68698
|
+
return;
|
|
68699
|
+
}
|
|
68700
|
+
let ottavaSymbol;
|
|
68701
|
+
let top = false;
|
|
68702
|
+
switch (this._clefOttava) {
|
|
68703
|
+
case Ottavia._15ma:
|
|
68704
|
+
ottavaSymbol = MusicFontSymbol.Clef15;
|
|
68705
|
+
top = true;
|
|
68706
|
+
break;
|
|
68707
|
+
case Ottavia._8va:
|
|
68708
|
+
ottavaSymbol = MusicFontSymbol.Clef8;
|
|
68709
|
+
top = true;
|
|
68710
|
+
break;
|
|
68711
|
+
case Ottavia._8vb:
|
|
68712
|
+
ottavaSymbol = MusicFontSymbol.Clef8;
|
|
68713
|
+
break;
|
|
68714
|
+
case Ottavia._15mb:
|
|
68715
|
+
ottavaSymbol = MusicFontSymbol.Clef15;
|
|
68716
|
+
break;
|
|
68717
|
+
default:
|
|
68718
|
+
return;
|
|
68719
|
+
}
|
|
68720
|
+
const ottavaX = this.width / 2;
|
|
68721
|
+
const ottavaY = top
|
|
68722
|
+
? this.renderer.smuflMetrics.glyphTop.get(this.symbol)
|
|
68723
|
+
: this.renderer.smuflMetrics.glyphBottom.get(this.symbol) -
|
|
68724
|
+
this.renderer.smuflMetrics.glyphHeights.get(ottavaSymbol);
|
|
68725
|
+
this._ottavaGlyph = new MusicFontGlyph(ottavaX, -ottavaY, 1, ottavaSymbol);
|
|
68726
|
+
this._ottavaGlyph.center = true;
|
|
68727
|
+
this._ottavaGlyph.renderer = this.renderer;
|
|
68728
|
+
this._ottavaGlyph.doLayout();
|
|
68380
68729
|
}
|
|
68381
68730
|
static _getSymbol(clef, clefOttava) {
|
|
68382
68731
|
switch (clef) {
|
|
@@ -68424,44 +68773,10 @@ class ClefGlyph extends MusicFontGlyph {
|
|
|
68424
68773
|
const _ = ElementStyleHelper.bar(canvas, BarSubElement.StandardNotationClef, this.renderer.bar);
|
|
68425
68774
|
try {
|
|
68426
68775
|
super.paint(cx, cy, canvas);
|
|
68427
|
-
|
|
68428
|
-
|
|
68429
|
-
|
|
68430
|
-
switch (this._clefOttava) {
|
|
68431
|
-
case Ottavia._8vb:
|
|
68432
|
-
return;
|
|
68433
|
-
}
|
|
68434
|
-
break;
|
|
68435
|
-
case Clef.F4:
|
|
68436
|
-
case Clef.G2:
|
|
68437
|
-
return;
|
|
68438
|
-
}
|
|
68439
|
-
let ottavaGlyph;
|
|
68440
|
-
let top = false;
|
|
68441
|
-
switch (this._clefOttava) {
|
|
68442
|
-
case Ottavia._15ma:
|
|
68443
|
-
ottavaGlyph = MusicFontSymbol.Clef15;
|
|
68444
|
-
top = true;
|
|
68445
|
-
break;
|
|
68446
|
-
case Ottavia._8va:
|
|
68447
|
-
ottavaGlyph = MusicFontSymbol.Clef8;
|
|
68448
|
-
top = true;
|
|
68449
|
-
break;
|
|
68450
|
-
case Ottavia._8vb:
|
|
68451
|
-
ottavaGlyph = MusicFontSymbol.Clef8;
|
|
68452
|
-
break;
|
|
68453
|
-
case Ottavia._15mb:
|
|
68454
|
-
ottavaGlyph = MusicFontSymbol.Clef15;
|
|
68455
|
-
break;
|
|
68456
|
-
default:
|
|
68457
|
-
return;
|
|
68776
|
+
const ottava = this._ottavaGlyph;
|
|
68777
|
+
if (ottava) {
|
|
68778
|
+
ottava.paint(cx + this.x, cy + this.y, canvas);
|
|
68458
68779
|
}
|
|
68459
|
-
const ottavaX = this.width / 2;
|
|
68460
|
-
const ottavaY = top
|
|
68461
|
-
? this.renderer.smuflMetrics.glyphTop.get(this.symbol)
|
|
68462
|
-
: this.renderer.smuflMetrics.glyphBottom.get(this.symbol) -
|
|
68463
|
-
this.renderer.smuflMetrics.glyphHeights.get(ottavaGlyph);
|
|
68464
|
-
CanvasHelper.fillMusicFontSymbolSafe(canvas, cx + this.x + ottavaX, cy + this.y - ottavaY, 1, ottavaGlyph, true);
|
|
68465
68780
|
}
|
|
68466
68781
|
finally {
|
|
68467
68782
|
_?.[Symbol.dispose]?.();
|