@coderline/alphatab 1.8.0-alpha.1669 → 1.8.0-alpha.1670

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * alphaTab v1.8.0-alpha.1669 (develop, build 1669)
2
+ * alphaTab v1.8.0-alpha.1670 (develop, build 1670)
3
3
  *
4
4
  * Copyright © 2026, 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.1669';
207
- static date = '2026-01-08T02:24:31.439Z';
208
- static commit = 'f7c00b0b8db32011293f475bf5e930d21c1903ac';
206
+ static version = '1.8.0-alpha.1670';
207
+ static date = '2026-01-09T02:24:51.076Z';
208
+ static commit = 'c4cd0c6435ec1bed778365efd389cb1b52df7ff3';
209
209
  static print(print) {
210
210
  print(`alphaTab ${VersionInfo.version}`);
211
211
  print(`commit: ${VersionInfo.commit}`);
@@ -1315,6 +1315,23 @@ var NotationElement;
1315
1315
  * The key signature for numbered notation staff.
1316
1316
  */
1317
1317
  NotationElement[NotationElement["EffectNumberedNotationKeySignature"] = 51] = "EffectNumberedNotationKeySignature";
1318
+ /**
1319
+ * The fretboard numbers shown in chord diagrams.
1320
+ */
1321
+ NotationElement[NotationElement["ChordDiagramFretboardNumbers"] = 52] = "ChordDiagramFretboardNumbers";
1322
+ /**
1323
+ * The bar numbers.
1324
+ */
1325
+ NotationElement[NotationElement["BarNumber"] = 53] = "BarNumber";
1326
+ /**
1327
+ * The repeat count indicator shown above the thick bar line to describe
1328
+ * how many repeats should be played.
1329
+ */
1330
+ NotationElement[NotationElement["RepeatCount"] = 54] = "RepeatCount";
1331
+ /**
1332
+ * The slurs shown on bend effects within the score staff.
1333
+ */
1334
+ NotationElement[NotationElement["ScoreBendSlur"] = 55] = "ScoreBendSlur";
1318
1335
  })(NotationElement || (NotationElement = {}));
1319
1336
  /**
1320
1337
  * The notation settings control how various music notation elements are shown and behaving
@@ -2174,6 +2191,11 @@ class Bar {
2174
2191
  * Gets or sets the type of key signature (major/minor)
2175
2192
  */
2176
2193
  keySignatureType = KeySignatureType.Major;
2194
+ /**
2195
+ * How bar numbers should be displayed.
2196
+ * If specified, overrides the value from the stylesheet on score level.
2197
+ */
2198
+ barNumberDisplay;
2177
2199
  /**
2178
2200
  * The bar line to draw on the left side of the bar with an "automatic" type resolved to the actual one.
2179
2201
  * @param isFirstOfSystem Whether the bar is the first one in the system.
@@ -2668,6 +2690,25 @@ var TrackNameOrientation;
2668
2690
  */
2669
2691
  TrackNameOrientation[TrackNameOrientation["Vertical"] = 1] = "Vertical";
2670
2692
  })(TrackNameOrientation || (TrackNameOrientation = {}));
2693
+ /**
2694
+ * How bar numbers are displayed
2695
+ * @public
2696
+ */
2697
+ var BarNumberDisplay;
2698
+ (function (BarNumberDisplay) {
2699
+ /**
2700
+ * Show bar numbers on all bars.
2701
+ */
2702
+ BarNumberDisplay[BarNumberDisplay["AllBars"] = 0] = "AllBars";
2703
+ /**
2704
+ * Show bar numbers on the first bar of every system.
2705
+ */
2706
+ BarNumberDisplay[BarNumberDisplay["FirstOfSystem"] = 1] = "FirstOfSystem";
2707
+ /**
2708
+ * Hide all bar numbers
2709
+ */
2710
+ BarNumberDisplay[BarNumberDisplay["Hide"] = 2] = "Hide";
2711
+ })(BarNumberDisplay || (BarNumberDisplay = {}));
2671
2712
  /**
2672
2713
  * This class represents the rendering stylesheet.
2673
2714
  * It contains settings which control the display of the score when rendered.
@@ -2761,6 +2802,10 @@ class RenderStylesheet {
2761
2802
  * {@link hideEmptyStaves}
2762
2803
  */
2763
2804
  showSingleStaffBrackets = false;
2805
+ /**
2806
+ * How bar numbers should be displayed.
2807
+ */
2808
+ barNumberDisplay = BarNumberDisplay.AllBars;
2764
2809
  }
2765
2810
 
2766
2811
  /**
@@ -8432,6 +8477,12 @@ class AlphaTex1EnumMappings {
8432
8477
  ['buzzroll', 1]
8433
8478
  ]);
8434
8479
  static tremoloPickingStyleReversed = AlphaTex1EnumMappings._reverse(AlphaTex1EnumMappings.tremoloPickingStyle);
8480
+ static barNumberDisplay = new Map([
8481
+ ['allbars', 0],
8482
+ ['firstofsystem', 1],
8483
+ ['hide', 2]
8484
+ ]);
8485
+ static barNumberDisplayReversed = AlphaTex1EnumMappings._reverse(AlphaTex1EnumMappings.barNumberDisplay);
8435
8486
  static keySignaturesMinorReversed = new Map([
8436
8487
  [-7, 'abminor'],
8437
8488
  [-6, 'ebminor'],
@@ -8626,7 +8677,8 @@ class AlphaTex1LanguageDefinitions {
8626
8677
  ['chorddiagramsinscore', [[[[10], 1, ['true', 'false']]]]],
8627
8678
  ['hideemptystaves', null],
8628
8679
  ['hideemptystavesinfirstsystem', null],
8629
- ['showsinglestaffbrackets', null]
8680
+ ['showsinglestaffbrackets', null],
8681
+ ['defaultbarnumberdisplay', [[[[10, 17], 0, ['allbars', 'firstofsystem', 'hide']]]]]
8630
8682
  ]);
8631
8683
  static staffMetaDataSignatures = AlphaTex1LanguageDefinitions._signatures([
8632
8684
  ['tuning', [[[[10, 17], 0, ['piano', 'none', 'voice']]], [[[10, 17], 5]]]],
@@ -8911,7 +8963,8 @@ class AlphaTex1LanguageDefinitions {
8911
8963
  ['sph', [[[[16], 2]]]],
8912
8964
  ['spu', [[[[16], 2]]]],
8913
8965
  ['db', null],
8914
- ['voicemode', [[[[10, 17], 0, ['staffwise', 'barwise']]]]]
8966
+ ['voicemode', [[[[10, 17], 0, ['staffwise', 'barwise']]]]],
8967
+ ['barnumberdisplay', [[[[10, 17], 0, ['allbars', 'firstofsystem', 'hide']]]]]
8915
8968
  ]);
8916
8969
  static metaDataProperties = AlphaTex1LanguageDefinitions._metaProps([
8917
8970
  [
@@ -8969,6 +9022,7 @@ class AlphaTex1LanguageDefinitions {
8969
9022
  ['hideemptystaves', null],
8970
9023
  ['hideemptystavesinfirstsystem', null],
8971
9024
  ['showsinglestaffbrackets', null],
9025
+ ['defaultbarnumberdisplay', null],
8972
9026
  [
8973
9027
  'tuning',
8974
9028
  [
@@ -9025,7 +9079,8 @@ class AlphaTex1LanguageDefinitions {
9025
9079
  ['sph', null],
9026
9080
  ['spu', null],
9027
9081
  ['db', null],
9028
- ['voicemode', null]
9082
+ ['voicemode', null],
9083
+ ['barnumberdisplay', null]
9029
9084
  ]);
9030
9085
  static metaDataSignatures = [
9031
9086
  AlphaTex1LanguageDefinitions.scoreMetaDataSignatures,
@@ -12876,6 +12931,13 @@ class AlphaTex1LanguageHandler {
12876
12931
  case 'showsinglestaffbrackets':
12877
12932
  score.stylesheet.showSingleStaffBrackets = true;
12878
12933
  return ApplyNodeResult.Applied;
12934
+ case 'defaultbarnumberdisplay':
12935
+ const barNumberDisplay = AlphaTex1LanguageHandler._parseEnumValue(importer, metaData.arguments, 'bar number display', AlphaTex1EnumMappings.barNumberDisplay);
12936
+ if (barNumberDisplay === undefined) {
12937
+ return ApplyNodeResult.NotAppliedSemanticError;
12938
+ }
12939
+ score.stylesheet.barNumberDisplay = barNumberDisplay;
12940
+ return ApplyNodeResult.Applied;
12879
12941
  default:
12880
12942
  return ApplyNodeResult.NotAppliedUnrecognizedMarker;
12881
12943
  }
@@ -13367,6 +13429,13 @@ class AlphaTex1LanguageHandler {
13367
13429
  bar.masterBar.isDoubleBar = true;
13368
13430
  bar.barLineRight = BarLineStyle.LightLight;
13369
13431
  return ApplyNodeResult.Applied;
13432
+ case 'barnumberdisplay':
13433
+ const barNumberDisplay = AlphaTex1LanguageHandler._parseEnumValue(importer, metaData.arguments, 'bar number display', AlphaTex1EnumMappings.barNumberDisplay);
13434
+ if (barNumberDisplay === undefined) {
13435
+ return ApplyNodeResult.NotAppliedSemanticError;
13436
+ }
13437
+ bar.barNumberDisplay = barNumberDisplay;
13438
+ return ApplyNodeResult.Applied;
13370
13439
  default:
13371
13440
  return ApplyNodeResult.NotAppliedUnrecognizedMarker;
13372
13441
  }
@@ -14734,6 +14803,9 @@ class AlphaTex1LanguageHandler {
14734
14803
  if (stylesheet.showSingleStaffBrackets) {
14735
14804
  nodes.push(Atnf.meta('showSingleStaffBrackets'));
14736
14805
  }
14806
+ if (stylesheet.barNumberDisplay !== BarNumberDisplay.AllBars) {
14807
+ nodes.push(Atnf.identMeta('defaultBarNumberDisplay', BarNumberDisplay[stylesheet.barNumberDisplay]));
14808
+ }
14737
14809
  // Unsupported:
14738
14810
  // 'globaldisplaychorddiagramsontop',
14739
14811
  // 'pertrackchorddiagramsontop',
@@ -14867,6 +14939,9 @@ class AlphaTex1LanguageHandler {
14867
14939
  }
14868
14940
  ];
14869
14941
  }
14942
+ if (bar.barNumberDisplay !== undefined) {
14943
+ nodes.push(Atnf.identMeta('barNumberDisplay', BarNumberDisplay[bar.barNumberDisplay]));
14944
+ }
14870
14945
  return nodes;
14871
14946
  }
14872
14947
  static _buildStaffMetaDataNodes(nodes, staff) {
@@ -19535,6 +19610,10 @@ class Gp3To5Importer extends ScoreImporter {
19535
19610
  this.readTrack();
19536
19611
  }
19537
19612
  }
19613
+ /**
19614
+ * Guitar Pro 3-6 changes to a bass clef if any string tuning is below B2;
19615
+ */
19616
+ static _bassClefTuningThreshold = ModelUtils.parseTuning('B2').realValue;
19538
19617
  readTrack() {
19539
19618
  const newTrack = new Track();
19540
19619
  newTrack.ensureStaveCount(1);
@@ -19615,11 +19694,11 @@ class Gp3To5Importer extends ScoreImporter {
19615
19694
  this.data.readByte();
19616
19695
  // `12` for all tunings which have bass clefs
19617
19696
  const clefMode = IOHelper.readInt32LE(this.data);
19618
- if (clefMode === 12) {
19619
- this._clefsPerTrack.set(index, Clef.F4);
19697
+ if (clefMode === 12 || tuning[tuning.length - 1] < Gp3To5Importer._bassClefTuningThreshold) {
19698
+ this._clefsPerTrack.set(newTrack.index, Clef.F4);
19620
19699
  }
19621
19700
  else {
19622
- this._clefsPerTrack.set(index, Clef.G2);
19701
+ this._clefsPerTrack.set(newTrack.index, Clef.G2);
19623
19702
  }
19624
19703
  // Unknown, no UI setting seem to affect this
19625
19704
  IOHelper.readInt32LE(this.data);
@@ -19651,11 +19730,11 @@ class Gp3To5Importer extends ScoreImporter {
19651
19730
  }
19652
19731
  }
19653
19732
  else {
19654
- if (GeneralMidi.isBass(newTrack.playbackInfo.program)) {
19655
- this._clefsPerTrack.set(index, Clef.F4);
19733
+ if (tuning[tuning.length - 1] < Gp3To5Importer._bassClefTuningThreshold) {
19734
+ this._clefsPerTrack.set(newTrack.index, Clef.F4);
19656
19735
  }
19657
19736
  else {
19658
- this._clefsPerTrack.set(index, Clef.G2);
19737
+ this._clefsPerTrack.set(newTrack.index, Clef.G2);
19659
19738
  }
19660
19739
  }
19661
19740
  }
@@ -20929,6 +21008,19 @@ class BinaryStylesheet {
20929
21008
  ModelUtils.getOrCreateHeaderFooterStyle(score, ScoreSubElement.CopyrightSecondLine).isVisible =
20930
21009
  value;
20931
21010
  break;
21011
+ case 'System/barIndexDrawType':
21012
+ switch (value) {
21013
+ case 0:
21014
+ score.stylesheet.barNumberDisplay = BarNumberDisplay.AllBars;
21015
+ break;
21016
+ case 1:
21017
+ score.stylesheet.barNumberDisplay = BarNumberDisplay.FirstOfSystem;
21018
+ break;
21019
+ case 2:
21020
+ score.stylesheet.barNumberDisplay = BarNumberDisplay.Hide;
21021
+ break;
21022
+ }
21023
+ break;
20932
21024
  }
20933
21025
  }
20934
21026
  }
@@ -21118,6 +21210,17 @@ class BinaryStylesheet {
21118
21210
  }
21119
21211
  }
21120
21212
  }
21213
+ switch (score.stylesheet.barNumberDisplay) {
21214
+ case BarNumberDisplay.AllBars:
21215
+ binaryStylesheet.addValue('System/barIndexDrawType', 0, DataType.Integer);
21216
+ break;
21217
+ case BarNumberDisplay.FirstOfSystem:
21218
+ binaryStylesheet.addValue('System/barIndexDrawType', 1, DataType.Integer);
21219
+ break;
21220
+ case BarNumberDisplay.Hide:
21221
+ binaryStylesheet.addValue('System/barIndexDrawType', 2, DataType.Integer);
21222
+ break;
21223
+ }
21121
21224
  const writer = ByteBuffer.withCapacity(128);
21122
21225
  binaryStylesheet.writeTo(writer);
21123
21226
  return writer.toArray();
@@ -24824,6 +24927,8 @@ class MusicXmlImporter extends ScoreImporter {
24824
24927
  _idToTrackInfo = new Map();
24825
24928
  _indexToTrackInfo = new Map();
24826
24929
  _staffToContext = new Map();
24930
+ _currentBarNumberDisplayPart;
24931
+ _currentBarNumberDisplayBar;
24827
24932
  _divisionsPerQuarterNote = 1;
24828
24933
  _currentDynamics = DynamicValue.F;
24829
24934
  get name() {
@@ -25437,20 +25542,29 @@ class MusicXmlImporter extends ScoreImporter {
25437
25542
  break;
25438
25543
  }
25439
25544
  }
25545
+ this._currentBarNumberDisplayPart = undefined;
25440
25546
  }
25441
25547
  _parsePartwiseMeasure(element, track, index) {
25442
25548
  const masterBar = this._getOrCreateMasterBar(element, index);
25443
- this._parsePartMeasure(element, masterBar, track);
25549
+ const implicit = element.attributes.get('implicit') === 'yes';
25550
+ this._parsePartMeasure(element, masterBar, track, implicit, true);
25551
+ this._currentBarNumberDisplayBar = undefined;
25444
25552
  }
25445
25553
  _parseTimewiseMeasure(element, index) {
25446
25554
  const masterBar = this._getOrCreateMasterBar(element, index);
25555
+ const implicit = element.attributes.get('implicit') === 'yes';
25447
25556
  for (const c of element.childElements()) {
25448
25557
  switch (c.localName) {
25449
25558
  case 'part':
25450
- this._parseTimewisePart(c, masterBar);
25559
+ this._parseTimewisePart(c, masterBar, implicit);
25560
+ this._currentBarNumberDisplayPart = undefined;
25561
+ break;
25562
+ case 'print':
25563
+ this._parsePrint(c, masterBar, undefined, true);
25451
25564
  break;
25452
25565
  }
25453
25566
  }
25567
+ this._currentBarNumberDisplayBar = undefined;
25454
25568
  }
25455
25569
  _getOrCreateMasterBar(element, index) {
25456
25570
  const implicit = element.attributes.get('implicit') === 'yes';
@@ -25469,13 +25583,13 @@ class MusicXmlImporter extends ScoreImporter {
25469
25583
  const masterBar = this._score.masterBars[index];
25470
25584
  return masterBar;
25471
25585
  }
25472
- _parseTimewisePart(element, masterBar) {
25586
+ _parseTimewisePart(element, masterBar, implicit) {
25473
25587
  const id = element.attributes.get('id');
25474
25588
  if (!id || !this._idToTrackInfo.has(id)) {
25475
25589
  return;
25476
25590
  }
25477
25591
  const track = this._idToTrackInfo.get(id).track;
25478
- this._parsePartMeasure(element, masterBar, track);
25592
+ this._parsePartMeasure(element, masterBar, track, implicit, false);
25479
25593
  }
25480
25594
  // current measure state
25481
25595
  /**
@@ -25487,7 +25601,7 @@ class MusicXmlImporter extends ScoreImporter {
25487
25601
  * to access the current voice/staff (e.g. on rests when we don't have notes)
25488
25602
  */
25489
25603
  _lastBeat = null;
25490
- _parsePartMeasure(element, masterBar, track) {
25604
+ _parsePartMeasure(element, masterBar, track, implicit, isPartwise) {
25491
25605
  this._musicalPosition = 0;
25492
25606
  this._lastBeat = null;
25493
25607
  masterBar.alternateEndings = this._nextMasterBarRepeatEnding;
@@ -25514,7 +25628,7 @@ class MusicXmlImporter extends ScoreImporter {
25514
25628
  break;
25515
25629
  // case 'figured-bass': Not supported
25516
25630
  case 'print':
25517
- this._parsePrint(c, masterBar, track);
25631
+ this._parsePrint(c, masterBar, track, true);
25518
25632
  break;
25519
25633
  case 'sound':
25520
25634
  this._parseSound(c, masterBar, track);
@@ -25535,16 +25649,51 @@ class MusicXmlImporter extends ScoreImporter {
25535
25649
  this._applySimileMarks(masterBar, track);
25536
25650
  // initial empty staff and voice (if no other elements created something already)
25537
25651
  const staff = this._getOrCreateStaff(track, 0);
25538
- this._getOrCreateBar(staff, masterBar);
25652
+ const bar = this._getOrCreateBar(staff, masterBar);
25653
+ if (implicit) {
25654
+ bar.barNumberDisplay = BarNumberDisplay.Hide;
25655
+ }
25656
+ else if (isPartwise) {
25657
+ bar.barNumberDisplay = this._currentBarNumberDisplayBar ?? this._currentBarNumberDisplayPart;
25658
+ }
25659
+ else {
25660
+ bar.barNumberDisplay = this._currentBarNumberDisplayPart ?? this._currentBarNumberDisplayBar;
25661
+ }
25539
25662
  // clear measure attribute
25540
25663
  this._keyAllStaves = null;
25541
25664
  }
25542
- _parsePrint(element, masterBar, track) {
25543
- if (element.getAttribute('new-system', 'no') === 'yes') {
25544
- track.addLineBreaks(masterBar.index);
25665
+ _parsePrint(element, masterBar, track, isMeasurePrint) {
25666
+ if (track !== undefined) {
25667
+ if (element.getAttribute('new-system', 'no') === 'yes') {
25668
+ track.addLineBreaks(masterBar.index);
25669
+ }
25670
+ else if (element.getAttribute('new-page', 'no') === 'yes') {
25671
+ track.addLineBreaks(masterBar.index);
25672
+ }
25673
+ }
25674
+ let newDisplay = undefined;
25675
+ for (const c of element.childElements()) {
25676
+ switch (c.localName) {
25677
+ case 'measure-numbering':
25678
+ switch (c.innerText) {
25679
+ case 'none':
25680
+ newDisplay = BarNumberDisplay.Hide;
25681
+ break;
25682
+ case 'measure':
25683
+ newDisplay = BarNumberDisplay.AllBars;
25684
+ break;
25685
+ case 'system':
25686
+ newDisplay = BarNumberDisplay.FirstOfSystem;
25687
+ break;
25688
+ }
25689
+ break;
25690
+ }
25545
25691
  }
25546
- else if (element.getAttribute('new-page', 'no') === 'yes') {
25547
- track.addLineBreaks(masterBar.index);
25692
+ if (isMeasurePrint) {
25693
+ this._currentBarNumberDisplayBar = newDisplay;
25694
+ }
25695
+ else {
25696
+ this._currentBarNumberDisplayPart = newDisplay;
25548
25697
  }
25549
25698
  }
25550
25699
  _applySimileMarks(masterBar, track) {
@@ -26654,7 +26803,7 @@ class MusicXmlImporter extends ScoreImporter {
26654
26803
  if (unit !== null && perMinute > 0) {
26655
26804
  const tempoAutomation = new Automation();
26656
26805
  tempoAutomation.type = AutomationType.Tempo;
26657
- tempoAutomation.value = (perMinute * (unit / 4)) | 0;
26806
+ tempoAutomation.value = perMinute * (unit / 4);
26658
26807
  tempoAutomation.ratioPosition = ratioPosition;
26659
26808
  if (!this._hasSameTempo(masterBar, tempoAutomation)) {
26660
26809
  masterBar.tempoAutomations.push(tempoAutomation);
@@ -29583,7 +29732,7 @@ class MidiFileSequencer {
29583
29732
  }
29584
29733
  if (mEvent.type === MidiEventType.TempoChange) {
29585
29734
  const meta = mEvent;
29586
- bpm = meta.beatsPerMinute;
29735
+ bpm = MidiFileSequencer._sanitizeBpm(meta.beatsPerMinute);
29587
29736
  state.tempoChanges.push(new MidiFileSequencerTempoChange(bpm, absTick, absTime));
29588
29737
  metronomeLengthInMillis = metronomeLengthInTicks * (60000.0 / (bpm * midiFile.division));
29589
29738
  }
@@ -29701,7 +29850,7 @@ class MidiFileSequencer {
29701
29850
  }
29702
29851
  else {
29703
29852
  const previousSyncPoint = syncPoints[i - 1];
29704
- previousModifiedTempo = previousSyncPoint.syncBpm;
29853
+ previousModifiedTempo = MidiFileSequencer._sanitizeBpm(previousSyncPoint.syncBpm);
29705
29854
  previousMillisecondOffset = previousSyncPoint.syncTime;
29706
29855
  previousTick = previousSyncPoint.synthTick;
29707
29856
  }
@@ -29725,7 +29874,7 @@ class MidiFileSequencer {
29725
29874
  syncPoint.syncTime = interpolatedMillisecondOffset;
29726
29875
  syncPoint.syncBpm = previousModifiedTempo;
29727
29876
  }
29728
- bpm = state.tempoChanges[tempoChangeIndex].bpm;
29877
+ bpm = MidiFileSequencer._sanitizeBpm(state.tempoChanges[tempoChangeIndex].bpm);
29729
29878
  tempoChangeIndex++;
29730
29879
  }
29731
29880
  deltaTick = p.synthTick - absTick;
@@ -29746,10 +29895,13 @@ class MidiFileSequencer {
29746
29895
  this._updateCurrentTempo(state, timePosition);
29747
29896
  const lastTempoChange = state.tempoChanges[state.tempoChangeIndex];
29748
29897
  const timeDiff = timePosition - lastTempoChange.time;
29749
- const ticks = (timeDiff / (60000.0 / (lastTempoChange.bpm * state.division))) | 0;
29898
+ const ticks = (timeDiff / (60000.0 / (MidiFileSequencer._sanitizeBpm(lastTempoChange.bpm) * state.division))) | 0;
29750
29899
  // we add 1 for possible rounding errors.(floating point issuses)
29751
29900
  return lastTempoChange.ticks + ticks + 1;
29752
29901
  }
29902
+ static _sanitizeBpm(bpm) {
29903
+ return Math.max(bpm, 1); // prevent <0 bpms. Doesn't make sense and can cause endless loops
29904
+ }
29753
29905
  currentUpdateCurrentTempo(timePosition) {
29754
29906
  this._updateCurrentTempo(this._mainState, timePosition * this.playbackSpeed);
29755
29907
  }
@@ -37481,6 +37633,7 @@ class BarSerializer {
37481
37633
  o.set("barlineright", obj.barLineRight);
37482
37634
  o.set("keysignature", obj.keySignature);
37483
37635
  o.set("keysignaturetype", obj.keySignatureType);
37636
+ o.set("barnumberdisplay", obj.barNumberDisplay);
37484
37637
  if (obj.style) {
37485
37638
  o.set("style", BarStyleSerializer.toJson(obj.style));
37486
37639
  }
@@ -37534,6 +37687,9 @@ class BarSerializer {
37534
37687
  case "keysignaturetype":
37535
37688
  obj.keySignatureType = JsonHelper.parseEnum(v, KeySignatureType);
37536
37689
  return true;
37690
+ case "barnumberdisplay":
37691
+ obj.barNumberDisplay = JsonHelper.parseEnum(v, BarNumberDisplay);
37692
+ return true;
37537
37693
  case "style":
37538
37694
  if (v) {
37539
37695
  obj.style = new BarStyle();
@@ -38028,6 +38184,7 @@ class RenderStylesheetSerializer {
38028
38184
  o.set("hideemptystaves", obj.hideEmptyStaves);
38029
38185
  o.set("hideemptystavesinfirstsystem", obj.hideEmptyStavesInFirstSystem);
38030
38186
  o.set("showsinglestaffbrackets", obj.showSingleStaffBrackets);
38187
+ o.set("barnumberdisplay", obj.barNumberDisplay);
38031
38188
  return o;
38032
38189
  }
38033
38190
  static setProperty(obj, property, v) {
@@ -38098,6 +38255,9 @@ class RenderStylesheetSerializer {
38098
38255
  case "showsinglestaffbrackets":
38099
38256
  obj.showSingleStaffBrackets = v;
38100
38257
  return true;
38258
+ case "barnumberdisplay":
38259
+ obj.barNumberDisplay = JsonHelper.parseEnum(v, BarNumberDisplay);
38260
+ return true;
38101
38261
  }
38102
38262
  return false;
38103
38263
  }
@@ -41829,25 +41989,20 @@ class RenderingResourcesSerializer {
41829
41989
  const o = new Map();
41830
41990
  o.set("smuflfontfamilyname", obj.smuflFontFamilyName);
41831
41991
  o.set("engravingsettings", EngravingSettingsSerializer.toJson(obj.engravingSettings));
41832
- o.set("copyrightfont", Font.toJson(obj.copyrightFont));
41833
- o.set("titlefont", Font.toJson(obj.titleFont));
41834
- o.set("subtitlefont", Font.toJson(obj.subTitleFont));
41835
- o.set("wordsfont", Font.toJson(obj.wordsFont));
41836
- o.set("effectfont", Font.toJson(obj.effectFont));
41837
- o.set("timerfont", Font.toJson(obj.timerFont));
41838
- o.set("directionsfont", Font.toJson(obj.directionsFont));
41839
- o.set("fretboardnumberfont", Font.toJson(obj.fretboardNumberFont));
41992
+ {
41993
+ const m = new Map();
41994
+ o.set("elementfonts", m);
41995
+ for (const [k, v] of obj.elementFonts) {
41996
+ m.set(k.toString(), Font.toJson(v));
41997
+ }
41998
+ }
41840
41999
  o.set("numberednotationfont", Font.toJson(obj.numberedNotationFont));
41841
42000
  o.set("numberednotationgracefont", Font.toJson(obj.numberedNotationGraceFont));
41842
42001
  o.set("tablaturefont", Font.toJson(obj.tablatureFont));
41843
42002
  o.set("gracefont", Font.toJson(obj.graceFont));
41844
42003
  o.set("stafflinecolor", Color.toJson(obj.staffLineColor));
41845
42004
  o.set("barseparatorcolor", Color.toJson(obj.barSeparatorColor));
41846
- o.set("barnumberfont", Font.toJson(obj.barNumberFont));
41847
42005
  o.set("barnumbercolor", Color.toJson(obj.barNumberColor));
41848
- o.set("fingeringfont", Font.toJson(obj.fingeringFont));
41849
- o.set("inlinefingeringfont", Font.toJson(obj.inlineFingeringFont));
41850
- o.set("markerfont", Font.toJson(obj.markerFont));
41851
42006
  o.set("mainglyphcolor", Color.toJson(obj.mainGlyphColor));
41852
42007
  o.set("secondaryglyphcolor", Color.toJson(obj.secondaryGlyphColor));
41853
42008
  o.set("scoreinfocolor", Color.toJson(obj.scoreInfoColor));
@@ -41858,29 +42013,10 @@ class RenderingResourcesSerializer {
41858
42013
  case "smuflfontfamilyname":
41859
42014
  obj.smuflFontFamilyName = v;
41860
42015
  return true;
41861
- case "copyrightfont":
41862
- obj.copyrightFont = Font.fromJson(v);
41863
- return true;
41864
- case "titlefont":
41865
- obj.titleFont = Font.fromJson(v);
41866
- return true;
41867
- case "subtitlefont":
41868
- obj.subTitleFont = Font.fromJson(v);
41869
- return true;
41870
- case "wordsfont":
41871
- obj.wordsFont = Font.fromJson(v);
41872
- return true;
41873
- case "effectfont":
41874
- obj.effectFont = Font.fromJson(v);
41875
- return true;
41876
- case "timerfont":
41877
- obj.timerFont = Font.fromJson(v);
41878
- return true;
41879
- case "directionsfont":
41880
- obj.directionsFont = Font.fromJson(v);
41881
- return true;
41882
- case "fretboardnumberfont":
41883
- obj.fretboardNumberFont = Font.fromJson(v);
42016
+ case "elementfonts":
42017
+ JsonHelper.forEach(v, (v, k) => {
42018
+ obj.elementFonts.set(JsonHelper.parseEnum(k, NotationElement), Font.fromJson(v));
42019
+ });
41884
42020
  return true;
41885
42021
  case "numberednotationfont":
41886
42022
  obj.numberedNotationFont = Font.fromJson(v);
@@ -41900,21 +42036,9 @@ class RenderingResourcesSerializer {
41900
42036
  case "barseparatorcolor":
41901
42037
  obj.barSeparatorColor = Color.fromJson(v);
41902
42038
  return true;
41903
- case "barnumberfont":
41904
- obj.barNumberFont = Font.fromJson(v);
41905
- return true;
41906
42039
  case "barnumbercolor":
41907
42040
  obj.barNumberColor = Color.fromJson(v);
41908
42041
  return true;
41909
- case "fingeringfont":
41910
- obj.fingeringFont = Font.fromJson(v);
41911
- return true;
41912
- case "inlinefingeringfont":
41913
- obj.inlineFingeringFont = Font.fromJson(v);
41914
- return true;
41915
- case "markerfont":
41916
- obj.markerFont = Font.fromJson(v);
41917
- return true;
41918
42042
  case "mainglyphcolor":
41919
42043
  obj.mainGlyphColor = Color.fromJson(v);
41920
42044
  return true;
@@ -41971,6 +42095,46 @@ var StaveProfile;
41971
42095
  class RenderingResources {
41972
42096
  static _sansFont = 'Arial, sans-serif';
41973
42097
  static _serifFont = 'Georgia, serif';
42098
+ static _effectFont = new Font(RenderingResources._serifFont, 12, FontStyle.Italic);
42099
+ /**
42100
+ * The default fonts for notation elements if not specified by the user.
42101
+ */
42102
+ static defaultFonts = new Map([
42103
+ [NotationElement.ScoreTitle, new Font(RenderingResources._serifFont, 32, FontStyle.Plain)],
42104
+ [NotationElement.ScoreSubTitle, new Font(RenderingResources._serifFont, 20, FontStyle.Plain)],
42105
+ [NotationElement.ScoreArtist, new Font(RenderingResources._serifFont, 20, FontStyle.Plain)],
42106
+ [NotationElement.ScoreAlbum, new Font(RenderingResources._serifFont, 20, FontStyle.Plain)],
42107
+ [NotationElement.ScoreWords, new Font(RenderingResources._serifFont, 15, FontStyle.Plain)],
42108
+ [NotationElement.ScoreMusic, new Font(RenderingResources._serifFont, 15, FontStyle.Plain)],
42109
+ [NotationElement.ScoreWordsAndMusic, new Font(RenderingResources._serifFont, 15, FontStyle.Plain)],
42110
+ [NotationElement.ScoreCopyright, new Font(RenderingResources._sansFont, 12, FontStyle.Plain, FontWeight.Bold)],
42111
+ [NotationElement.EffectBeatTimer, new Font(RenderingResources._serifFont, 12, FontStyle.Plain)],
42112
+ [NotationElement.EffectDirections, new Font(RenderingResources._serifFont, 14, FontStyle.Plain)],
42113
+ [NotationElement.ChordDiagramFretboardNumbers, new Font(RenderingResources._sansFont, 11, FontStyle.Plain)],
42114
+ [NotationElement.EffectFingering, new Font(RenderingResources._serifFont, 14, FontStyle.Plain)],
42115
+ [NotationElement.EffectMarker, new Font(RenderingResources._serifFont, 14, FontStyle.Plain, FontWeight.Bold)],
42116
+ [NotationElement.EffectCapo, RenderingResources._effectFont],
42117
+ [NotationElement.EffectFreeTime, RenderingResources._effectFont],
42118
+ [NotationElement.EffectLyrics, RenderingResources._effectFont],
42119
+ [NotationElement.EffectTap, RenderingResources._effectFont],
42120
+ [NotationElement.ChordDiagrams, RenderingResources._effectFont],
42121
+ [NotationElement.EffectChordNames, RenderingResources._effectFont],
42122
+ [NotationElement.EffectText, RenderingResources._effectFont],
42123
+ [NotationElement.EffectPalmMute, RenderingResources._effectFont],
42124
+ [NotationElement.EffectLetRing, RenderingResources._effectFont],
42125
+ [NotationElement.EffectBeatBarre, RenderingResources._effectFont],
42126
+ [NotationElement.EffectTripletFeel, RenderingResources._effectFont],
42127
+ [NotationElement.EffectHarmonics, RenderingResources._effectFont],
42128
+ [NotationElement.EffectPickSlide, RenderingResources._effectFont],
42129
+ [NotationElement.GuitarTuning, RenderingResources._effectFont],
42130
+ [NotationElement.EffectRasgueado, RenderingResources._effectFont],
42131
+ [NotationElement.EffectWhammyBar, RenderingResources._effectFont],
42132
+ [NotationElement.TrackNames, RenderingResources._effectFont],
42133
+ [NotationElement.RepeatCount, new Font(RenderingResources._sansFont, 11, FontStyle.Plain)],
42134
+ [NotationElement.BarNumber, new Font(RenderingResources._sansFont, 11, FontStyle.Plain)],
42135
+ [NotationElement.ScoreBendSlur, new Font(RenderingResources._sansFont, 11, FontStyle.Plain)],
42136
+ [NotationElement.EffectAlternateEndings, new Font(RenderingResources._serifFont, 15, FontStyle.Plain)]
42137
+ ]);
41974
42138
  /**
41975
42139
  * The name of the SMuFL Font to use for rendering music symbols.
41976
42140
  *
@@ -41997,50 +42161,168 @@ class RenderingResources {
41997
42161
  * The font to use for displaying the songs copyright information in the header of the music sheet.
41998
42162
  * @defaultValue `bold 12px Arial, sans-serif`
41999
42163
  * @since 0.9.6
42164
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreCopyright}
42165
+ */
42166
+ get copyrightFont() {
42167
+ return this.elementFonts.get(NotationElement.ScoreCopyright);
42168
+ }
42169
+ /**
42170
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreCopyright}
42000
42171
  */
42001
- copyrightFont = new Font(RenderingResources._sansFont, 12, FontStyle.Plain, FontWeight.Bold);
42172
+ set copyrightFont(value) {
42173
+ this.elementFonts.set(NotationElement.ScoreCopyright, value);
42174
+ }
42002
42175
  /**
42003
42176
  * The font to use for displaying the songs title in the header of the music sheet.
42004
42177
  * @defaultValue `32px Georgia, serif`
42005
42178
  * @since 0.9.6
42179
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreTitle}
42180
+ */
42181
+ get titleFont() {
42182
+ return this.elementFonts.get(NotationElement.ScoreTitle);
42183
+ }
42184
+ /**
42185
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreTitle}
42006
42186
  */
42007
- titleFont = new Font(RenderingResources._serifFont, 32, FontStyle.Plain);
42187
+ set titleFont(value) {
42188
+ this.elementFonts.set(NotationElement.ScoreTitle, value);
42189
+ }
42008
42190
  /**
42009
42191
  * The font to use for displaying the songs subtitle in the header of the music sheet.
42010
42192
  * @defaultValue `20px Georgia, serif`
42011
42193
  * @since 0.9.6
42194
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreSubTitle}
42195
+ */
42196
+ get subTitleFont() {
42197
+ return this.elementFonts.get(NotationElement.ScoreSubTitle);
42198
+ }
42199
+ /**
42200
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreSubTitle}
42012
42201
  */
42013
- subTitleFont = new Font(RenderingResources._serifFont, 20, FontStyle.Plain);
42202
+ set subTitleFont(value) {
42203
+ this.elementFonts.set(NotationElement.ScoreSubTitle, value);
42204
+ }
42014
42205
  /**
42015
42206
  * The font to use for displaying the lyrics information in the header of the music sheet.
42016
42207
  * @defaultValue `15px Arial, sans-serif`
42017
42208
  * @since 0.9.6
42209
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreWords}
42018
42210
  */
42019
- wordsFont = new Font(RenderingResources._serifFont, 15, FontStyle.Plain);
42211
+ get wordsFont() {
42212
+ return this.elementFonts.get(NotationElement.ScoreWords);
42213
+ }
42020
42214
  /**
42021
- * The font to use for displaying certain effect related elements in the music sheet.
42022
- * @defaultValue `italic 12px Georgia, serif`
42023
- * @since 0.9.6
42215
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreWords}
42024
42216
  */
42025
- effectFont = new Font(RenderingResources._serifFont, 12, FontStyle.Italic);
42217
+ set wordsFont(value) {
42218
+ this.elementFonts.set(NotationElement.ScoreWords, value);
42219
+ }
42026
42220
  /**
42027
42221
  * The font to use for displaying beat time information in the music sheet.
42028
42222
  * @defaultValue `12px Georgia, serif`
42029
42223
  * @since 1.4.0
42224
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectBeatTimer}
42225
+ */
42226
+ get timerFont() {
42227
+ return this.elementFonts.get(NotationElement.EffectBeatTimer);
42228
+ }
42229
+ /**
42230
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectBeatTimer}
42030
42231
  */
42031
- timerFont = new Font(RenderingResources._serifFont, 12, FontStyle.Plain);
42232
+ set timerFont(value) {
42233
+ this.elementFonts.set(NotationElement.EffectBeatTimer, value);
42234
+ }
42032
42235
  /**
42033
42236
  * The font to use for displaying the directions texts.
42034
42237
  * @defaultValue `14px Georgia, serif`
42035
42238
  * @since 1.4.0
42239
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectDirections}
42240
+ */
42241
+ get directionsFont() {
42242
+ return this.elementFonts.get(NotationElement.EffectDirections);
42243
+ }
42244
+ /**
42245
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectDirections}
42036
42246
  */
42037
- directionsFont = new Font(RenderingResources._serifFont, 14, FontStyle.Plain);
42247
+ set directionsFont(value) {
42248
+ this.elementFonts.set(NotationElement.EffectDirections, value);
42249
+ }
42038
42250
  /**
42039
42251
  * The font to use for displaying the fretboard numbers in chord diagrams.
42040
42252
  * @defaultValue `11px Arial, sans-serif`
42041
42253
  * @since 0.9.6
42254
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ChordDiagramFretboardNumbers}
42255
+ */
42256
+ get fretboardNumberFont() {
42257
+ return this.elementFonts.get(NotationElement.ChordDiagramFretboardNumbers);
42258
+ }
42259
+ /**
42260
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ChordDiagramFretboardNumbers}
42261
+ */
42262
+ set fretboardNumberFont(value) {
42263
+ this.elementFonts.set(NotationElement.ChordDiagramFretboardNumbers, value);
42264
+ }
42265
+ /**
42266
+ * Unused, see deprecation note.
42267
+ * @defaultValue `14px Georgia, serif`
42268
+ * @since 0.9.6
42269
+ * @deprecated Since 1.7.0 alphaTab uses the glyphs contained in the SMuFL font
42270
+ * @json_ignore
42042
42271
  */
42043
- fretboardNumberFont = new Font(RenderingResources._sansFont, 11, FontStyle.Plain);
42272
+ fingeringFont = RenderingResources._effectFont;
42273
+ /**
42274
+ * Unused, see deprecation note.
42275
+ * @defaultValue `12px Georgia, serif`
42276
+ * @since 1.4.0
42277
+ * @deprecated Since 1.7.0 alphaTab uses the glyphs contained in the SMuFL font
42278
+ * @json_ignore
42279
+ */
42280
+ inlineFingeringFont = RenderingResources._effectFont;
42281
+ /**
42282
+ * The font to use for section marker labels shown above the music sheet.
42283
+ * @defaultValue `bold 14px Georgia, serif`
42284
+ * @since 0.9.6
42285
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectMarker}
42286
+ */
42287
+ get markerFont() {
42288
+ return this.elementFonts.get(NotationElement.EffectMarker);
42289
+ }
42290
+ /**
42291
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectMarker}
42292
+ */
42293
+ set markerFont(value) {
42294
+ this.elementFonts.set(NotationElement.EffectMarker, value);
42295
+ }
42296
+ /**
42297
+ * Ununsed, see deprecation note.
42298
+ * @defaultValue `italic 12px Georgia, serif`
42299
+ * @since 0.9.6
42300
+ * @deprecated use {@link elementFonts} with the respective
42301
+ * @json_ignore
42302
+ */
42303
+ effectFont = RenderingResources._effectFont;
42304
+ /**
42305
+ * The font to use for displaying the bar numbers above the music sheet.
42306
+ * @defaultValue `11px Arial, sans-serif`
42307
+ * @since 0.9.6
42308
+ * @deprecated use {@link elementFonts} with {@link NotationElement.BarNumber}
42309
+ */
42310
+ get barNumberFont() {
42311
+ return this.elementFonts.get(NotationElement.BarNumber);
42312
+ }
42313
+ /**
42314
+ * @deprecated use {@link elementFonts} with {@link NotationElement.BarNumber}
42315
+ */
42316
+ set barNumberFont(value) {
42317
+ this.elementFonts.set(NotationElement.BarNumber, value);
42318
+ }
42319
+ // NOTE: the main staff fonts are still own properties.
42320
+ /**
42321
+ * The fonts used by individual elements. Check {@link defaultFonts} for the elements which have custom fonts.
42322
+ * Removing fonts from this map can lead to unexpected side effects and errors. Only update it with new values.
42323
+ * @json_immutable
42324
+ */
42325
+ elementFonts = new Map();
42044
42326
  /**
42045
42327
  * The font to use for displaying the numbered music notation in the music sheet.
42046
42328
  * @defaultValue `14px Arial, sans-serif`
@@ -42077,38 +42359,12 @@ class RenderingResources {
42077
42359
  * @since 0.9.6
42078
42360
  */
42079
42361
  barSeparatorColor = new Color(34, 34, 17, 0xff);
42080
- /**
42081
- * The font to use for displaying the bar numbers above the music sheet.
42082
- * @defaultValue `11px Arial, sans-serif`
42083
- * @since 0.9.6
42084
- */
42085
- barNumberFont = new Font(RenderingResources._sansFont, 11, FontStyle.Plain);
42086
42362
  /**
42087
42363
  * The color to use for displaying the bar numbers above the music sheet.
42088
42364
  * @defaultValue `rgb(200, 0, 0)`
42089
42365
  * @since 0.9.6
42090
42366
  */
42091
42367
  barNumberColor = new Color(200, 0, 0, 0xff);
42092
- /**
42093
- * The font to use for displaying finger information in the music sheet.
42094
- * @defaultValue `14px Georgia, serif`
42095
- * @since 0.9.6
42096
- * @deprecated Since 1.7.0 alphaTab uses the glyphs contained in the SMuFL font
42097
- */
42098
- fingeringFont = new Font(RenderingResources._serifFont, 14, FontStyle.Plain);
42099
- /**
42100
- * The font to use for displaying finger information when inline into the music sheet.
42101
- * @defaultValue `12px Georgia, serif`
42102
- * @since 1.4.0
42103
- * @deprecated Since 1.7.0 alphaTab uses the glyphs contained in the SMuFL font
42104
- */
42105
- inlineFingeringFont = new Font(RenderingResources._serifFont, 12, FontStyle.Plain);
42106
- /**
42107
- * The font to use for section marker labels shown above the music sheet.
42108
- * @defaultValue `bold 14px Georgia, serif`
42109
- * @since 0.9.6
42110
- */
42111
- markerFont = new Font(RenderingResources._serifFont, 14, FontStyle.Plain, FontWeight.Bold);
42112
42368
  /**
42113
42369
  * The color to use for music notation elements of the primary voice.
42114
42370
  * @defaultValue `rgb(0, 0, 0)`
@@ -42127,28 +42383,50 @@ class RenderingResources {
42127
42383
  * @since 0.9.6
42128
42384
  */
42129
42385
  scoreInfoColor = new Color(0, 0, 0, 0xff);
42386
+ constructor() {
42387
+ for (const [k, v] of RenderingResources.defaultFonts) {
42388
+ this.elementFonts.set(k, v.withSize(v.size));
42389
+ }
42390
+ }
42130
42391
  /**
42131
42392
  * @internal
42132
42393
  * @param element
42133
42394
  */
42134
42395
  getFontForElement(element) {
42396
+ let notationElement = NotationElement.ScoreWords;
42135
42397
  switch (element) {
42136
42398
  case ScoreSubElement.Title:
42137
- return this.titleFont;
42399
+ notationElement = NotationElement.ScoreTitle;
42400
+ break;
42138
42401
  case ScoreSubElement.SubTitle:
42402
+ notationElement = NotationElement.ScoreSubTitle;
42403
+ break;
42139
42404
  case ScoreSubElement.Artist:
42405
+ notationElement = NotationElement.ScoreArtist;
42406
+ break;
42140
42407
  case ScoreSubElement.Album:
42141
- return this.subTitleFont;
42408
+ notationElement = NotationElement.ScoreAlbum;
42409
+ break;
42142
42410
  case ScoreSubElement.Words:
42411
+ notationElement = NotationElement.ScoreWords;
42412
+ break;
42143
42413
  case ScoreSubElement.Music:
42414
+ notationElement = NotationElement.ScoreMusic;
42415
+ break;
42144
42416
  case ScoreSubElement.WordsAndMusic:
42145
- case ScoreSubElement.Transcriber:
42146
- return this.wordsFont;
42417
+ notationElement = NotationElement.ScoreWordsAndMusic;
42418
+ break;
42147
42419
  case ScoreSubElement.Copyright:
42148
42420
  case ScoreSubElement.CopyrightSecondLine:
42149
- return this.copyrightFont;
42421
+ notationElement = NotationElement.ScoreCopyright;
42422
+ break;
42423
+ default:
42424
+ notationElement = NotationElement.ScoreWords;
42425
+ break;
42150
42426
  }
42151
- return this.wordsFont;
42427
+ return this.elementFonts.has(notationElement)
42428
+ ? this.elementFonts.get(notationElement)
42429
+ : RenderingResources.defaultFonts.get(NotationElement.ScoreWords);
42152
42430
  }
42153
42431
  }
42154
42432
 
@@ -42453,6 +42731,13 @@ class DisplaySettings {
42453
42731
  * @defaultValue `5`
42454
42732
  */
42455
42733
  trackStaffPaddingBetween = 5;
42734
+ /**
42735
+ * The additional padding to apply between multiple lyric lines.
42736
+ * @since 1.8.0
42737
+ * @category Display
42738
+ * @defaultValue `5`
42739
+ */
42740
+ lyricLinesPaddingBetween = 5;
42456
42741
  /**
42457
42742
  * The mode used to arrange staves and systems.
42458
42743
  * @since 1.3.0
@@ -42563,6 +42848,7 @@ class DisplaySettingsSerializer {
42563
42848
  o.set("staffpaddingleft", obj.staffPaddingLeft);
42564
42849
  o.set("effectbandpaddingbottom", obj.effectBandPaddingBottom);
42565
42850
  o.set("trackstaffpaddingbetween", obj.trackStaffPaddingBetween);
42851
+ o.set("lyriclinespaddingbetween", obj.lyricLinesPaddingBetween);
42566
42852
  o.set("systemslayoutmode", obj.systemsLayoutMode);
42567
42853
  return o;
42568
42854
  }
@@ -42649,6 +42935,9 @@ class DisplaySettingsSerializer {
42649
42935
  case "trackstaffpaddingbetween":
42650
42936
  obj.trackStaffPaddingBetween = v;
42651
42937
  return true;
42938
+ case "lyriclinespaddingbetween":
42939
+ obj.lyricLinesPaddingBetween = v;
42940
+ return true;
42652
42941
  case "systemslayoutmode":
42653
42942
  obj.systemsLayoutMode = JsonHelper.parseEnum(v, SystemsLayoutMode);
42654
42943
  return true;
@@ -55357,23 +55646,20 @@ class BrowserUiFacade {
55357
55646
  this._contents = '';
55358
55647
  const element = api.container;
55359
55648
  if (settings.core.tex) {
55360
- this._contents = element.element.innerText;
55649
+ this._contents = element.element.textContent;
55361
55650
  element.element.innerText = '';
55362
55651
  }
55363
55652
  this._createStyleElements(settings);
55364
55653
  this._file = settings.core.file;
55365
55654
  }
55366
55655
  _setupFontCheckers(settings) {
55367
- this._registerFontChecker(settings.display.resources.copyrightFont);
55368
- this._registerFontChecker(settings.display.resources.effectFont);
55656
+ for (const font of settings.display.resources.elementFonts.values()) {
55657
+ this._registerFontChecker(font);
55658
+ }
55369
55659
  this._registerFontChecker(settings.display.resources.graceFont);
55370
- this._registerFontChecker(settings.display.resources.markerFont);
55371
55660
  this._registerFontChecker(settings.display.resources.tablatureFont);
55372
- this._registerFontChecker(settings.display.resources.titleFont);
55373
- this._registerFontChecker(settings.display.resources.wordsFont);
55374
- this._registerFontChecker(settings.display.resources.barNumberFont);
55375
- this._registerFontChecker(settings.display.resources.fretboardNumberFont);
55376
- this._registerFontChecker(settings.display.resources.subTitleFont);
55661
+ this._registerFontChecker(settings.display.resources.numberedNotationFont);
55662
+ this._registerFontChecker(settings.display.resources.numberedNotationGraceFont);
55377
55663
  }
55378
55664
  _registerFontChecker(font) {
55379
55665
  if (!this._fontCheckers.has(font.families.join(', '))) {
@@ -57210,7 +57496,9 @@ class AlternateEndingsGlyph extends EffectGlyph {
57210
57496
  }
57211
57497
  doLayout() {
57212
57498
  super.doLayout();
57213
- this.height = this.renderer.resources.wordsFont.size + this.renderer.smuflMetrics.alternateEndingsPadding * 2;
57499
+ this.height =
57500
+ this.renderer.resources.elementFonts.get(NotationElement.EffectAlternateEndings).size +
57501
+ this.renderer.smuflMetrics.alternateEndingsPadding * 2;
57214
57502
  let endingsStrings = '';
57215
57503
  for (let i = 0, j = this._endings.length; i < j; i++) {
57216
57504
  endingsStrings += this._endings[i] + 1;
@@ -57246,7 +57534,7 @@ class AlternateEndingsGlyph extends EffectGlyph {
57246
57534
  const baseline = canvas.textBaseline;
57247
57535
  canvas.textBaseline = TextBaseline.Top;
57248
57536
  const res = this.renderer.resources;
57249
- canvas.font = res.wordsFont;
57537
+ canvas.font = res.elementFonts.get(NotationElement.EffectAlternateEndings);
57250
57538
  canvas.fillText(this._endingsString, cx + this.x + this.renderer.smuflMetrics.alternateEndingsPadding, cy + this.y + this.renderer.smuflMetrics.alternateEndingsPadding);
57251
57539
  canvas.textBaseline = baseline;
57252
57540
  }
@@ -57388,10 +57676,12 @@ class LineRangedGlyph extends GroupedEffectGlyph {
57388
57676
  _label;
57389
57677
  _dashed;
57390
57678
  _labelWidth = 0;
57391
- constructor(label, dashed = true) {
57679
+ _fontElement;
57680
+ constructor(label, fontElement, dashed = true) {
57392
57681
  super(BeatXPosition.OnNotes);
57393
57682
  this._label = label;
57394
57683
  this._dashed = dashed;
57684
+ this._fontElement = fontElement;
57395
57685
  }
57396
57686
  doLayout() {
57397
57687
  if (this.renderer.settings.notation.extendLineEffectsToBeatEnd) {
@@ -57399,14 +57689,14 @@ class LineRangedGlyph extends GroupedEffectGlyph {
57399
57689
  this.forceGroupedRendering = true;
57400
57690
  }
57401
57691
  super.doLayout();
57402
- this.renderer.scoreRenderer.canvas.font = this.renderer.resources.effectFont;
57692
+ this.renderer.scoreRenderer.canvas.font = this.renderer.resources.elementFonts.get(this._fontElement);
57403
57693
  const size = this.renderer.scoreRenderer.canvas.measureText(this._label);
57404
57694
  this.height = size.height;
57405
57695
  this._labelWidth = size.width;
57406
57696
  }
57407
57697
  paintNonGrouped(cx, cy, canvas) {
57408
57698
  const res = this.renderer.resources;
57409
- canvas.font = res.effectFont;
57699
+ canvas.font = res.elementFonts.get(this._fontElement);
57410
57700
  const b = canvas.textBaseline;
57411
57701
  canvas.textBaseline = TextBaseline.Middle;
57412
57702
  canvas.fillText(this._label, cx + this.x - this._labelWidth / 2, cy + this.y + this.height / 2);
@@ -57467,7 +57757,7 @@ class BeatBarreEffectInfo extends EffectInfo {
57467
57757
  break;
57468
57758
  }
57469
57759
  barre += `B ${BeatBarreEffectInfo.toRoman(beat.barreFret)}`;
57470
- return new LineRangedGlyph(barre, false);
57760
+ return new LineRangedGlyph(barre, NotationElement.EffectBeatBarre, false);
57471
57761
  }
57472
57762
  static _romanLetters = new Map([
57473
57763
  // ['M', 1000],
@@ -57517,7 +57807,7 @@ class BeatTimerGlyph extends EffectGlyph {
57517
57807
  const seconds = ((this._timer - minutes * 60000) / 1000) | 0;
57518
57808
  this._text = `${minutes}:${seconds.toString().padStart(2, '0')}`;
57519
57809
  const c = this.renderer.scoreRenderer.canvas;
57520
- c.font = this.renderer.resources.timerFont;
57810
+ c.font = this.renderer.resources.elementFonts.get(NotationElement.EffectBeatTimer);
57521
57811
  const size = c.measureText(this._text);
57522
57812
  this._textHeight = c.font.size + this.renderer.smuflMetrics.beatTimerPadding * 2;
57523
57813
  this._textWidth = size.width + this.renderer.smuflMetrics.beatTimerPadding * 2;
@@ -57529,7 +57819,7 @@ class BeatTimerGlyph extends EffectGlyph {
57529
57819
  const f = canvas.font;
57530
57820
  const b = canvas.textBaseline;
57531
57821
  const a = canvas.textAlign;
57532
- canvas.font = this.renderer.resources.timerFont;
57822
+ canvas.font = this.renderer.resources.elementFonts.get(NotationElement.EffectBeatTimer);
57533
57823
  canvas.textBaseline = TextBaseline.Middle;
57534
57824
  canvas.textAlign = TextAlign.Center;
57535
57825
  canvas.fillText(this._text, cx + this.x, cy + this.y + this.height / 2);
@@ -57638,7 +57928,7 @@ class CapoEffectInfo extends EffectInfo {
57638
57928
  return beat.index === 0 && beat.voice.bar.index === 0 && beat.voice.bar.staff.capo !== 0;
57639
57929
  }
57640
57930
  createNewGlyph(renderer, beat) {
57641
- return new TextGlyph(0, 0, `Capo. fret ${beat.voice.bar.staff.capo}`, renderer.resources.effectFont, TextAlign.Left);
57931
+ return new TextGlyph(0, 0, `Capo. fret ${beat.voice.bar.staff.capo}`, renderer.resources.elementFonts.get(NotationElement.EffectCapo), TextAlign.Left);
57642
57932
  }
57643
57933
  canExpand(_from, _to) {
57644
57934
  return false;
@@ -57655,31 +57945,41 @@ class ChordDiagramGlyph extends EffectGlyph {
57655
57945
  _fretRow = 0;
57656
57946
  _firstFretSpacing = 0;
57657
57947
  _center;
57658
- constructor(x, y, chord, center = false) {
57948
+ _fontElement;
57949
+ constructor(x, y, chord, fontElement, center = false) {
57659
57950
  super(x, y);
57660
57951
  this._chord = chord;
57661
57952
  this._center = center;
57953
+ this._fontElement = fontElement;
57662
57954
  }
57663
57955
  doLayout() {
57664
57956
  super.doLayout();
57665
57957
  const res = this.renderer.resources;
57666
- this._textRow = res.effectFont.size * 1.5;
57667
- this._fretRow = res.effectFont.size * 1.5;
57668
- if (this._chord.firstFret > 1) {
57669
- this._firstFretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
57670
- }
57671
- else {
57672
- this._firstFretSpacing = 0;
57673
- }
57674
- this.height =
57675
- this._textRow +
57958
+ const font = res.elementFonts.get(this._fontElement);
57959
+ this._textRow = font.size * 1.5;
57960
+ this._fretRow = font.size * 1.5;
57961
+ this.height = this._textRow;
57962
+ this.width = 2 * this.renderer.smuflMetrics.chordDiagramPaddingX;
57963
+ if (this.renderer.settings.notation.isNotationElementVisible(NotationElement.ChordDiagramFretboardNumbers)) {
57964
+ if (this._chord.firstFret > 1) {
57965
+ this._firstFretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
57966
+ }
57967
+ else {
57968
+ this._firstFretSpacing = 0;
57969
+ }
57970
+ this.height +=
57676
57971
  this._fretRow +
57677
- ChordDiagramGlyph._frets * this.renderer.smuflMetrics.chordDiagramFretSpacing +
57678
- 2 * this.renderer.smuflMetrics.chordDiagramPaddingY;
57679
- this.width =
57680
- this._firstFretSpacing +
57681
- (this._chord.strings.length - 1) * this.renderer.smuflMetrics.chordDiagramStringSpacing +
57682
- 2 * this.renderer.smuflMetrics.chordDiagramPaddingX;
57972
+ ChordDiagramGlyph._frets * this.renderer.smuflMetrics.chordDiagramFretSpacing +
57973
+ 2 * this.renderer.smuflMetrics.chordDiagramPaddingY;
57974
+ this.width +=
57975
+ this._firstFretSpacing +
57976
+ (this._chord.strings.length - 1) * this.renderer.smuflMetrics.chordDiagramStringSpacing;
57977
+ }
57978
+ else if (this._chord.showName) {
57979
+ const canvas = this.renderer.scoreRenderer.canvas;
57980
+ canvas.font = font;
57981
+ this.width += canvas.measureText(this._chord.name).width;
57982
+ }
57683
57983
  }
57684
57984
  paint(cx, cy, canvas) {
57685
57985
  cx += this.x + this.renderer.smuflMetrics.chordDiagramPaddingX + this._firstFretSpacing;
@@ -57687,25 +57987,35 @@ class ChordDiagramGlyph extends EffectGlyph {
57687
57987
  if (this._center) {
57688
57988
  cx -= this.width / 2;
57689
57989
  }
57690
- const stringSpacing = this.renderer.smuflMetrics.chordDiagramStringSpacing;
57691
- const fretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
57692
57990
  const res = this.renderer.resources;
57693
57991
  const lineWidth = res.engravingSettings.chordDiagramLineWidth;
57694
57992
  const w = this.width - 2 * this.renderer.smuflMetrics.chordDiagramPaddingX - this._firstFretSpacing + lineWidth;
57695
- const circleHeight = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardFilledCircle);
57696
- const circleTopOffset = res.engravingSettings.glyphTop.get(MusicFontSymbol.FretboardFilledCircle);
57697
- const xTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardX) / 2;
57698
- const oTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardO) / 2;
57699
57993
  const align = canvas.textAlign;
57700
57994
  const baseline = canvas.textBaseline;
57701
- canvas.font = res.effectFont;
57995
+ const font = res.elementFonts.get(this._fontElement);
57996
+ canvas.font = font;
57702
57997
  canvas.textAlign = TextAlign.Center;
57703
57998
  canvas.textBaseline = TextBaseline.Top;
57704
57999
  if (this._chord.showName) {
57705
- canvas.fillText(this._chord.name, cx + w / 2, cy + res.effectFont.size / 2);
58000
+ canvas.fillText(this._chord.name, cx + w / 2, cy + font.size / 2);
58001
+ }
58002
+ if (this.renderer.settings.notation.isNotationElementVisible(NotationElement.ChordDiagramFretboardNumbers)) {
58003
+ this._paintFretboard(cx, cy, canvas, w);
57706
58004
  }
58005
+ canvas.textAlign = align;
58006
+ canvas.textBaseline = baseline;
58007
+ }
58008
+ _paintFretboard(cx, cy, canvas, w) {
57707
58009
  cy += this._textRow;
57708
- canvas.font = res.fretboardNumberFont;
58010
+ const res = this.renderer.resources;
58011
+ const stringSpacing = this.renderer.smuflMetrics.chordDiagramStringSpacing;
58012
+ const fretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
58013
+ const circleHeight = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardFilledCircle);
58014
+ const circleTopOffset = res.engravingSettings.glyphTop.get(MusicFontSymbol.FretboardFilledCircle);
58015
+ const xTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardX) / 2;
58016
+ const oTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardO) / 2;
58017
+ const lineWidth = res.engravingSettings.chordDiagramLineWidth;
58018
+ canvas.font = res.elementFonts.get(NotationElement.ChordDiagramFretboardNumbers);
57709
58019
  canvas.textBaseline = TextBaseline.Middle;
57710
58020
  for (let i = 0; i < this._chord.strings.length; i++) {
57711
58021
  const x = cx + i * stringSpacing;
@@ -57768,8 +58078,6 @@ class ChordDiagramGlyph extends EffectGlyph {
57768
58078
  const xRight = cx + (this._chord.strings.length - strings[0] - 1) * stringSpacing;
57769
58079
  canvas.fillRect(xLeft, y - circleHeight / 2, xRight - xLeft, circleHeight);
57770
58080
  }
57771
- canvas.textAlign = align;
57772
- canvas.textBaseline = baseline;
57773
58081
  }
57774
58082
  }
57775
58083
 
@@ -57795,8 +58103,8 @@ class ChordsEffectInfo extends EffectInfo {
57795
58103
  createNewGlyph(renderer, beat) {
57796
58104
  const showDiagram = beat.voice.bar.staff.track.score.stylesheet.globalDisplayChordDiagramsInScore;
57797
58105
  return showDiagram
57798
- ? new ChordDiagramGlyph(0, 0, beat.chord, true)
57799
- : new TextGlyph(0, 0, beat.chord.name, renderer.resources.effectFont, TextAlign.Center);
58106
+ ? new ChordDiagramGlyph(0, 0, beat.chord, NotationElement.EffectChordNames, true)
58107
+ : new TextGlyph(0, 0, beat.chord.name, renderer.resources.elementFonts.get(NotationElement.EffectChordNames), TextAlign.Center);
57800
58108
  }
57801
58109
  canExpand(_from, _to) {
57802
58110
  return false;
@@ -57907,14 +58215,14 @@ class JumpDirectionGlyph extends Glyph {
57907
58215
  }
57908
58216
  doLayout() {
57909
58217
  const c = this.renderer.scoreRenderer.canvas;
57910
- c.font = this.renderer.resources.directionsFont;
58218
+ c.font = this.renderer.resources.elementFonts.get(NotationElement.EffectDirections);
57911
58219
  this.height = c.measureText(this._text).height;
57912
58220
  }
57913
58221
  paint(cx, cy, canvas) {
57914
58222
  const font = canvas.font;
57915
58223
  const baseline = canvas.textBaseline;
57916
58224
  const align = canvas.textAlign;
57917
- canvas.font = this.renderer.resources.directionsFont;
58225
+ canvas.font = this.renderer.resources.elementFonts.get(NotationElement.EffectDirections);
57918
58226
  canvas.textBaseline = TextBaseline.Middle;
57919
58227
  canvas.textAlign = TextAlign.Right;
57920
58228
  canvas.fillText(this._text, cx + this.x, cy + this.y + this.height / 2);
@@ -58810,7 +59118,7 @@ class FreeTimeEffectInfo extends EffectInfo {
58810
59118
  (masterBar.index === 0 || masterBar.isFreeTime !== masterBar.previousMasterBar.isFreeTime));
58811
59119
  }
58812
59120
  createNewGlyph(renderer, _beat) {
58813
- return new TextGlyph(0, 0, 'Free time', renderer.resources.effectFont, TextAlign.Left);
59121
+ return new TextGlyph(0, 0, 'Free time', renderer.resources.elementFonts.get(NotationElement.EffectFreeTime), TextAlign.Left);
58814
59122
  }
58815
59123
  canExpand(_from, _to) {
58816
59124
  return true;
@@ -58948,7 +59256,7 @@ class HarmonicsEffectInfo extends NoteEffectInfoBase {
58948
59256
  return EffectBarGlyphSizing.GroupedOnBeat;
58949
59257
  }
58950
59258
  createNewGlyph(_renderer, _beat) {
58951
- return new LineRangedGlyph(HarmonicsEffectInfo.harmonicToString(this._harmonicType));
59259
+ return new LineRangedGlyph(HarmonicsEffectInfo.harmonicToString(this._harmonicType), NotationElement.EffectHarmonics);
58952
59260
  }
58953
59261
  static harmonicToString(type) {
58954
59262
  switch (type) {
@@ -59021,7 +59329,7 @@ class LetRingEffectInfo extends EffectInfo {
59021
59329
  return EffectBarGlyphSizing.GroupedOnBeat;
59022
59330
  }
59023
59331
  createNewGlyph(_renderer, _beat) {
59024
- return new LineRangedGlyph('LetRing');
59332
+ return new LineRangedGlyph('LetRing', NotationElement.EffectLetRing);
59025
59333
  }
59026
59334
  canExpand(_from, _to) {
59027
59335
  return true;
@@ -59033,6 +59341,7 @@ class LetRingEffectInfo extends EffectInfo {
59033
59341
  */
59034
59342
  class LyricsGlyph extends EffectGlyph {
59035
59343
  _lines;
59344
+ _linePositions = [];
59036
59345
  font;
59037
59346
  textAlign;
59038
59347
  constructor(x, y, lines, font, textAlign = TextAlign.Center) {
@@ -59043,7 +59352,17 @@ class LyricsGlyph extends EffectGlyph {
59043
59352
  }
59044
59353
  doLayout() {
59045
59354
  super.doLayout();
59046
- this.height = this.font.size * this._lines.length;
59355
+ const lineSpacing = this.renderer.settings.display.lyricLinesPaddingBetween;
59356
+ const canvas = this.renderer.scoreRenderer.canvas;
59357
+ canvas.font = this.font;
59358
+ let y = 0;
59359
+ for (const line of this._lines) {
59360
+ this._linePositions.push(y);
59361
+ const size = canvas.measureText(line.length > 0 ? line : ' ');
59362
+ y += size.height + lineSpacing;
59363
+ }
59364
+ y -= lineSpacing;
59365
+ this.height = y;
59047
59366
  }
59048
59367
  paint(cx, cy, canvas) {
59049
59368
  canvas.font = this.font;
@@ -59051,7 +59370,7 @@ class LyricsGlyph extends EffectGlyph {
59051
59370
  canvas.textAlign = this.textAlign;
59052
59371
  for (let i = 0; i < this._lines.length; i++) {
59053
59372
  if (this._lines[i]) {
59054
- canvas.fillText(this._lines[i], cx + this.x, cy + this.y + i * this.font.size);
59373
+ canvas.fillText(this._lines[i], cx + this.x, cy + this.y + this._linePositions[i]);
59055
59374
  }
59056
59375
  }
59057
59376
  canvas.textAlign = old;
@@ -59078,7 +59397,7 @@ class LyricsEffectInfo extends EffectInfo {
59078
59397
  return !!beat.lyrics;
59079
59398
  }
59080
59399
  createNewGlyph(renderer, beat) {
59081
- return new LyricsGlyph(0, 0, beat.lyrics, renderer.resources.effectFont, TextAlign.Center);
59400
+ return new LyricsGlyph(0, 0, beat.lyrics, renderer.resources.elementFonts.get(NotationElement.EffectLyrics), TextAlign.Center);
59082
59401
  }
59083
59402
  canExpand(_from, _to) {
59084
59403
  return true;
@@ -59110,7 +59429,7 @@ class MarkerEffectInfo extends EffectInfo {
59110
59429
  createNewGlyph(renderer, beat) {
59111
59430
  return new TextGlyph(0, 0, !beat.voice.bar.masterBar.section.marker
59112
59431
  ? beat.voice.bar.masterBar.section.text
59113
- : `[${beat.voice.bar.masterBar.section.marker}] ${beat.voice.bar.masterBar.section.text}`, renderer.resources.markerFont, TextAlign.Left);
59432
+ : `[${beat.voice.bar.masterBar.section.marker}] ${beat.voice.bar.masterBar.section.text}`, renderer.resources.elementFonts.get(NotationElement.EffectMarker), TextAlign.Left);
59114
59433
  }
59115
59434
  canExpand(_from, _to) {
59116
59435
  return true;
@@ -59549,7 +59868,7 @@ class PalmMuteEffectInfo extends NoteEffectInfoBase {
59549
59868
  return EffectBarGlyphSizing.GroupedOnBeat;
59550
59869
  }
59551
59870
  createNewGlyph(_renderer, _beat) {
59552
- return new LineRangedGlyph('P.M.');
59871
+ return new LineRangedGlyph('P.M.', NotationElement.EffectPalmMute);
59553
59872
  }
59554
59873
  }
59555
59874
 
@@ -59567,7 +59886,7 @@ class PickSlideEffectInfo extends NoteEffectInfoBase {
59567
59886
  return EffectBarGlyphSizing.GroupedOnBeat;
59568
59887
  }
59569
59888
  createNewGlyph(_renderer, _beat) {
59570
- return new LineRangedGlyph('P.S.');
59889
+ return new LineRangedGlyph('P.S.', NotationElement.EffectPickSlide);
59571
59890
  }
59572
59891
  }
59573
59892
 
@@ -59642,7 +59961,7 @@ class RasgueadoEffectInfo extends EffectInfo {
59642
59961
  return EffectBarGlyphSizing.GroupedOnBeat;
59643
59962
  }
59644
59963
  createNewGlyph(_renderer, _beat) {
59645
- return new LineRangedGlyph('rasg.');
59964
+ return new LineRangedGlyph('rasg.', NotationElement.EffectRasgueado);
59646
59965
  }
59647
59966
  canExpand(_from, _to) {
59648
59967
  return true;
@@ -63250,12 +63569,12 @@ class TapEffectInfo extends EffectInfo {
63250
63569
  createNewGlyph(renderer, beat) {
63251
63570
  const res = renderer.resources;
63252
63571
  if (beat.slap) {
63253
- return new TextGlyph(0, 0, 'S', res.effectFont, TextAlign.Center);
63572
+ return new TextGlyph(0, 0, 'S', res.elementFonts.get(NotationElement.EffectTap), TextAlign.Center);
63254
63573
  }
63255
63574
  if (beat.pop) {
63256
- return new TextGlyph(0, 0, 'P', res.effectFont, TextAlign.Center);
63575
+ return new TextGlyph(0, 0, 'P', res.elementFonts.get(NotationElement.EffectTap), TextAlign.Center);
63257
63576
  }
63258
- return new TextGlyph(0, 0, 'T', res.effectFont, TextAlign.Center);
63577
+ return new TextGlyph(0, 0, 'T', res.elementFonts.get(NotationElement.EffectTap), TextAlign.Center);
63259
63578
  }
63260
63579
  canExpand(_from, _to) {
63261
63580
  return true;
@@ -63284,7 +63603,7 @@ class BarTempoGlyph extends EffectGlyph {
63284
63603
  for (const automation of this._tempoAutomations) {
63285
63604
  let x = cx + this.renderer.getRatioPositionX(automation.ratioPosition);
63286
63605
  const res = this.renderer.resources;
63287
- canvas.font = res.markerFont;
63606
+ canvas.font = res.elementFonts.get(NotationElement.EffectMarker);
63288
63607
  const notePosY = cy +
63289
63608
  this.y +
63290
63609
  this.height +
@@ -63362,7 +63681,7 @@ class TextEffectInfo extends EffectInfo {
63362
63681
  return !!beat.text;
63363
63682
  }
63364
63683
  createNewGlyph(renderer, beat) {
63365
- return new TextGlyph(0, 0, beat.text, renderer.resources.effectFont, TextAlign.Left);
63684
+ return new TextGlyph(0, 0, beat.text, renderer.resources.elementFonts.get(NotationElement.EffectText), TextAlign.Left);
63366
63685
  }
63367
63686
  canExpand(_from, _to) {
63368
63687
  return true;
@@ -63487,7 +63806,7 @@ class TripletFeelGlyph extends EffectGlyph {
63487
63806
  const textY = cy + this.height;
63488
63807
  const b = canvas.textBaseline;
63489
63808
  canvas.textBaseline = TextBaseline.Bottom;
63490
- canvas.font = this.renderer.resources.effectFont;
63809
+ canvas.font = this.renderer.resources.elementFonts.get(NotationElement.EffectTripletFeel);
63491
63810
  canvas.fillText('(', cx, textY);
63492
63811
  cx += canvas.measureText('( ').width;
63493
63812
  cx = this._drawGroup(cx, noteY + this._tupletHeight, canvas, leftNotes);
@@ -63729,7 +64048,7 @@ class WhammyBarEffectInfo extends EffectInfo {
63729
64048
  return beat.hasWhammyBar;
63730
64049
  }
63731
64050
  createNewGlyph(_renderer, _beat) {
63732
- return new LineRangedGlyph('w/bar');
64051
+ return new LineRangedGlyph('w/bar', NotationElement.EffectWhammyBar);
63733
64052
  }
63734
64053
  canExpand(_from, _to) {
63735
64054
  return true;
@@ -63881,7 +64200,7 @@ class RowContainerGlyph extends GlyphGroup {
63881
64200
  class ChordDiagramContainerGlyph extends RowContainerGlyph {
63882
64201
  addChord(chord) {
63883
64202
  if (chord.strings.length > 0) {
63884
- const chordDiagram = new ChordDiagramGlyph(0, 0, chord);
64203
+ const chordDiagram = new ChordDiagramGlyph(0, 0, chord, NotationElement.ChordDiagrams);
63885
64204
  chordDiagram.renderer = this.renderer;
63886
64205
  chordDiagram.doLayout();
63887
64206
  this.glyphs.push(chordDiagram);
@@ -63945,7 +64264,7 @@ class TuningGlyph extends GlyphGroup {
63945
64264
  this.height = 0;
63946
64265
  // Track name
63947
64266
  if (this._trackLabel.length > 0) {
63948
- const trackName = new TextGlyph(0, this.height, this._trackLabel, res.effectFont, TextAlign.Left);
64267
+ const trackName = new TextGlyph(0, this.height, this._trackLabel, res.elementFonts.get(NotationElement.GuitarTuning), TextAlign.Left);
63949
64268
  trackName.renderer = this.renderer;
63950
64269
  trackName.doLayout();
63951
64270
  this.height += trackName.height;
@@ -63953,7 +64272,7 @@ class TuningGlyph extends GlyphGroup {
63953
64272
  }
63954
64273
  // Name
63955
64274
  if (tuning.name.length > 0) {
63956
- const tuningName = new TextGlyph(0, this.height, tuning.name, res.effectFont, TextAlign.Left);
64275
+ const tuningName = new TextGlyph(0, this.height, tuning.name, res.elementFonts.get(NotationElement.GuitarTuning), TextAlign.Left);
63957
64276
  tuningName.renderer = this.renderer;
63958
64277
  tuningName.doLayout();
63959
64278
  this.height += tuningName.height;
@@ -63961,7 +64280,7 @@ class TuningGlyph extends GlyphGroup {
63961
64280
  }
63962
64281
  const circleScale = this.renderer.smuflMetrics.tuningGlyphCircleNumberScale;
63963
64282
  const circleHeight = this.renderer.smuflMetrics.glyphHeights.get(MusicFontSymbol.GuitarString0) * circleScale;
63964
- this.renderer.scoreRenderer.canvas.font = res.effectFont;
64283
+ this.renderer.scoreRenderer.canvas.font = res.elementFonts.get(NotationElement.GuitarTuning);
63965
64284
  const stringColumnWidth = (circleHeight + this.renderer.scoreRenderer.canvas.measureText(' = Gb').width) *
63966
64285
  res.engravingSettings.tuningGlyphStringColumnScale;
63967
64286
  this.width = Math.max(this.renderer.scoreRenderer.canvas.measureText(this._trackLabel).width, Math.max(this.renderer.scoreRenderer.canvas.measureText(tuning.name).width, 2 * stringColumnWidth));
@@ -63975,7 +64294,7 @@ class TuningGlyph extends GlyphGroup {
63975
64294
  const symbol = (MusicFontSymbol.GuitarString0 + (i + 1));
63976
64295
  this.addGlyph(new MusicFontGlyph(currentX, currentY + circleHeight, circleScale, symbol));
63977
64296
  const str = ` = ${Tuning.getTextForTuning(tuning.tunings[i], false)}`;
63978
- this.addGlyph(new TextGlyph(currentX + circleHeight, currentY + circleHeight / 2, str, res.effectFont, TextAlign.Left, TextBaseline.Middle));
64297
+ this.addGlyph(new TextGlyph(currentX + circleHeight, currentY + circleHeight / 2, str, res.elementFonts.get(NotationElement.GuitarTuning), TextAlign.Left, TextBaseline.Middle));
63979
64298
  currentY += circleHeight + this.renderer.smuflMetrics.tuningGlyphStringRowPadding;
63980
64299
  const bottomY = currentY;
63981
64300
  if (this.height < bottomY) {
@@ -65027,7 +65346,7 @@ class StaffSystem {
65027
65346
  let hasAnyTrackName = false;
65028
65347
  if (shouldRender) {
65029
65348
  const canvas = this.layout.renderer.canvas;
65030
- const res = settings.display.resources.effectFont;
65349
+ const res = settings.display.resources.elementFonts.get(NotationElement.TrackNames);
65031
65350
  canvas.font = res;
65032
65351
  for (const t of tracks) {
65033
65352
  let trackNameText = '';
@@ -65181,7 +65500,7 @@ class StaffSystem {
65181
65500
  // Draw track names
65182
65501
  const settings = this.layout.renderer.settings;
65183
65502
  const hasTrackName = this.layout.renderer.settings.notation.isNotationElementVisible(NotationElement.TrackNames);
65184
- canvas.font = res.effectFont;
65503
+ canvas.font = res.elementFonts.get(NotationElement.TrackNames);
65185
65504
  if (hasTrackName) {
65186
65505
  const stylesheet = this.layout.renderer.score.stylesheet;
65187
65506
  const trackNamePolicy = this.layout.renderer.tracks.length === 1
@@ -65871,7 +66190,10 @@ class ScoreLayout {
65871
66190
  const msg = 'rendered by alphaTab';
65872
66191
  const resources = this.renderer.settings.display.resources;
65873
66192
  const size = 12;
65874
- const font = Font.withFamilyList(resources.copyrightFont.families, size, FontStyle.Plain, FontWeight.Bold);
66193
+ const fontFamilies = resources.elementFonts.has(NotationElement.ScoreCopyright)
66194
+ ? resources.elementFonts.get(NotationElement.ScoreCopyright).families
66195
+ : resources.tablatureFont.families;
66196
+ const font = Font.withFamilyList(fontFamilies, size, FontStyle.Plain, FontWeight.Bold);
65875
66197
  const fakeBarRenderer = new BarRendererBase(this.renderer, this.renderer.tracks[0].staves[0].bars[0]);
65876
66198
  const glyph = new TextGlyph(0, 0, msg, font, TextAlign.Center, undefined, resources.mainGlyphColor);
65877
66199
  glyph.renderer = fakeBarRenderer;
@@ -66784,13 +67106,7 @@ class BarNumberGlyph extends Glyph {
66784
67106
  this._number = `${num} `;
66785
67107
  }
66786
67108
  doLayout() {
66787
- // TODO: activate this and update paddings accordingly.
66788
- // if (!this.renderer.staff!.isFirstInSystem) {
66789
- // this.width = 0;
66790
- // this.height = 0;
66791
- // return;
66792
- // }
66793
- this.renderer.scoreRenderer.canvas.font = this.renderer.resources.barNumberFont;
67109
+ this.renderer.scoreRenderer.canvas.font = this.renderer.resources.elementFonts.get(NotationElement.BarNumber);
66794
67110
  const size = this.renderer.scoreRenderer.canvas.measureText(this._number);
66795
67111
  this.width = size.width;
66796
67112
  this.height = size.height;
@@ -66804,7 +67120,7 @@ class BarNumberGlyph extends Glyph {
66804
67120
  try {
66805
67121
  const res = this.renderer.resources;
66806
67122
  const baseline = canvas.textBaseline;
66807
- canvas.font = res.barNumberFont;
67123
+ canvas.font = res.elementFonts.get(NotationElement.BarNumber);
66808
67124
  canvas.textBaseline = TextBaseline.Top;
66809
67125
  canvas.fillText(this._number, cx + this.x, cy + this.y);
66810
67126
  canvas.textBaseline = baseline;
@@ -67903,7 +68219,7 @@ class RepeatCountGlyph extends Glyph {
67903
68219
  this._count = count;
67904
68220
  }
67905
68221
  doLayout() {
67906
- this.renderer.scoreRenderer.canvas.font = this.renderer.resources.barNumberFont;
68222
+ this.renderer.scoreRenderer.canvas.font = this.renderer.resources.elementFonts.get(NotationElement.RepeatCount);
67907
68223
  const size = this.renderer.scoreRenderer.canvas.measureText(`x${this._count}`);
67908
68224
  this.width = 0; // do not account width
67909
68225
  this.height = size.height;
@@ -67914,7 +68230,7 @@ class RepeatCountGlyph extends Glyph {
67914
68230
  try {
67915
68231
  const res = this.renderer.resources;
67916
68232
  const oldAlign = canvas.textAlign;
67917
- canvas.font = res.barNumberFont;
68233
+ canvas.font = res.elementFonts.get(NotationElement.RepeatCount);
67918
68234
  canvas.textAlign = TextAlign.Right;
67919
68235
  const s = `x${this._count}`;
67920
68236
  const w = canvas.measureText(s).width / 1.5;
@@ -68039,11 +68355,12 @@ class LineBarRenderer extends BarRendererBase {
68039
68355
  }
68040
68356
  createStartSpacing() {
68041
68357
  if (this._startSpacing) {
68042
- return;
68358
+ return false;
68043
68359
  }
68044
68360
  const padding = this.index === 0 ? this.settings.display.firstStaffPaddingLeft : this.settings.display.staffPaddingLeft;
68045
68361
  this.addPreBeatGlyph(new SpacingGlyph(0, 0, padding));
68046
68362
  this._startSpacing = true;
68363
+ return true;
68047
68364
  }
68048
68365
  paintTuplets(cx, cy, canvas, beatElement, bracketsAsArcs = false) {
68049
68366
  for (const v of this.voiceContainer.voiceDrawOrder) {
@@ -68385,16 +68702,45 @@ class LineBarRenderer extends BarRendererBase {
68385
68702
  super.createPreBeatGlyphs();
68386
68703
  this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
68387
68704
  this.createLinePreBeatGlyphs();
68705
+ let hasSpaceAfterStartGlyphs = false;
68388
68706
  if (this.index === 0) {
68389
- this.createStartSpacing();
68707
+ hasSpaceAfterStartGlyphs = this.createStartSpacing();
68708
+ }
68709
+ if (this.shouldCreateBarNumber()) {
68710
+ this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-0.5), this.bar.index + 1));
68711
+ }
68712
+ else if (!hasSpaceAfterStartGlyphs) {
68713
+ this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
68390
68714
  }
68391
- this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-0.5), this.bar.index + 1));
68715
+ }
68716
+ shouldCreateBarNumber() {
68717
+ let display = BarNumberDisplay.AllBars;
68718
+ if (!this.settings.notation.isNotationElementVisible(NotationElement.BarNumber)) {
68719
+ display = BarNumberDisplay.Hide;
68720
+ }
68721
+ else if (this.bar.barNumberDisplay !== undefined) {
68722
+ display = this.bar.barNumberDisplay;
68723
+ }
68724
+ else {
68725
+ display = this.bar.staff.track.score.stylesheet.barNumberDisplay;
68726
+ }
68727
+ switch (display) {
68728
+ case BarNumberDisplay.AllBars:
68729
+ return true;
68730
+ case BarNumberDisplay.FirstOfSystem:
68731
+ return this.isFirstOfStaff;
68732
+ case BarNumberDisplay.Hide:
68733
+ return false;
68734
+ }
68735
+ return true;
68392
68736
  }
68393
68737
  createPostBeatGlyphs() {
68394
68738
  super.createPostBeatGlyphs();
68395
68739
  const lastBar = this.lastBar;
68396
68740
  this.addPostBeatGlyph(new BarLineGlyph(true, this.bar.staff.track.score.stylesheet.extendBarLines));
68397
- if (lastBar.masterBar.isRepeatEnd && lastBar.masterBar.repeatCount > 2) {
68741
+ if (lastBar.masterBar.isRepeatEnd &&
68742
+ lastBar.masterBar.repeatCount > 2 &&
68743
+ this.settings.notation.isNotationElementVisible(NotationElement.RepeatCount)) {
68398
68744
  this.addPostBeatGlyph(new RepeatCountGlyph(0, this.getLineHeight(-0.5), this.bar.masterBar.repeatCount));
68399
68745
  }
68400
68746
  }
@@ -68958,8 +69304,13 @@ class NumberedBarRenderer extends LineBarRenderer {
68958
69304
  this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
68959
69305
  }
68960
69306
  this.createLinePreBeatGlyphs();
68961
- this.createStartSpacing();
68962
- this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-0.5), this.bar.index + 1));
69307
+ const hasSpaceAfterStartGlyphs = this.createStartSpacing();
69308
+ if (this.shouldCreateBarNumber()) {
69309
+ this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-0.5), this.bar.index + 1));
69310
+ }
69311
+ else if (!hasSpaceAfterStartGlyphs) {
69312
+ this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
69313
+ }
68963
69314
  }
68964
69315
  createLinePreBeatGlyphs() {
68965
69316
  if (this._isOnlyNumbered &&
@@ -71507,7 +71858,7 @@ class ScoreBendGlyph extends ScoreHelperNotesBaseGlyph {
71507
71858
  if (note.bendStyle === BendStyle.Gradual) {
71508
71859
  const res = this.renderer.resources;
71509
71860
  const c = this.renderer.scoreRenderer.canvas;
71510
- c.font = res.barNumberFont; // see note in paint()
71861
+ c.font = res.elementFonts.get(NotationElement.ScoreBendSlur);
71511
71862
  slurHeight += c.measureText('grad.').height;
71512
71863
  }
71513
71864
  if (slurHeight > maxSlurHeight) {
@@ -71607,11 +71958,16 @@ class ScoreBendGlyph extends ScoreHelperNotesBaseGlyph {
71607
71958
  this._notes.sort((a, b) => {
71608
71959
  return b.displayValue - a.displayValue;
71609
71960
  });
71961
+ // draw slurs
71962
+ if (this.renderer.settings.notation.isNotationElementVisible(NotationElement.ScoreBendSlur)) {
71963
+ this._paintSlurs(cx, cy, canvas, startNoteRenderer, startX, middleX, endBeatX);
71964
+ }
71965
+ }
71966
+ _paintSlurs(cx, cy, canvas, startNoteRenderer, startX, middleX, endBeatX) {
71610
71967
  const directionBeat = this._beat.graceType === GraceType.BendGrace ? this._beat.nextBeat : this._beat;
71611
71968
  let direction = this._notes.length === 1 ? this.getTieDirection(directionBeat, startNoteRenderer) : BeamDirection.Up;
71612
71969
  const noteHeadHeight = this.renderer.smuflMetrics.glyphHeights.get(MusicFontSymbol.NoteheadBlack);
71613
- // draw slurs
71614
- canvas.font = this.renderer.resources.barNumberFont; // we have never have set it explicitly, that's the current state
71970
+ canvas.font = this.renderer.resources.elementFonts.get(NotationElement.ScoreBendSlur);
71615
71971
  for (let i = 0; i < this._notes.length; i++) {
71616
71972
  const note = this._notes[i];
71617
71973
  const _ = ElementStyleHelper.note(canvas, NoteSubElement.StandardNotationEffects, note);
@@ -79740,6 +80096,7 @@ const _barrel$3 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty(
79740
80096
  BackingTrack,
79741
80097
  Bar,
79742
80098
  get BarLineStyle () { return BarLineStyle; },
80099
+ get BarNumberDisplay () { return BarNumberDisplay; },
79743
80100
  BarStyle,
79744
80101
  get BarSubElement () { return BarSubElement; },
79745
80102
  get BarreShape () { return BarreShape; },