@coderline/alphatab 1.8.0-alpha.1668 → 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.
package/dist/alphaTab.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * alphaTab v1.8.0-alpha.1668 (develop, build 1668)
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
  *
@@ -209,9 +209,9 @@
209
209
  * @internal
210
210
  */
211
211
  class VersionInfo {
212
- static version = '1.8.0-alpha.1668';
213
- static date = '2026-01-07T02:24:14.986Z';
214
- static commit = 'd04d3bea64ae690eb26684fa027594057bb043b6';
212
+ static version = '1.8.0-alpha.1670';
213
+ static date = '2026-01-09T02:24:51.076Z';
214
+ static commit = 'c4cd0c6435ec1bed778365efd389cb1b52df7ff3';
215
215
  static print(print) {
216
216
  print(`alphaTab ${VersionInfo.version}`);
217
217
  print(`commit: ${VersionInfo.commit}`);
@@ -1321,6 +1321,23 @@
1321
1321
  * The key signature for numbered notation staff.
1322
1322
  */
1323
1323
  NotationElement[NotationElement["EffectNumberedNotationKeySignature"] = 51] = "EffectNumberedNotationKeySignature";
1324
+ /**
1325
+ * The fretboard numbers shown in chord diagrams.
1326
+ */
1327
+ NotationElement[NotationElement["ChordDiagramFretboardNumbers"] = 52] = "ChordDiagramFretboardNumbers";
1328
+ /**
1329
+ * The bar numbers.
1330
+ */
1331
+ NotationElement[NotationElement["BarNumber"] = 53] = "BarNumber";
1332
+ /**
1333
+ * The repeat count indicator shown above the thick bar line to describe
1334
+ * how many repeats should be played.
1335
+ */
1336
+ NotationElement[NotationElement["RepeatCount"] = 54] = "RepeatCount";
1337
+ /**
1338
+ * The slurs shown on bend effects within the score staff.
1339
+ */
1340
+ NotationElement[NotationElement["ScoreBendSlur"] = 55] = "ScoreBendSlur";
1324
1341
  })(exports.NotationElement || (exports.NotationElement = {}));
1325
1342
  /**
1326
1343
  * The notation settings control how various music notation elements are shown and behaving
@@ -2180,6 +2197,11 @@
2180
2197
  * Gets or sets the type of key signature (major/minor)
2181
2198
  */
2182
2199
  keySignatureType = KeySignatureType.Major;
2200
+ /**
2201
+ * How bar numbers should be displayed.
2202
+ * If specified, overrides the value from the stylesheet on score level.
2203
+ */
2204
+ barNumberDisplay;
2183
2205
  /**
2184
2206
  * The bar line to draw on the left side of the bar with an "automatic" type resolved to the actual one.
2185
2207
  * @param isFirstOfSystem Whether the bar is the first one in the system.
@@ -2674,6 +2696,25 @@
2674
2696
  */
2675
2697
  TrackNameOrientation[TrackNameOrientation["Vertical"] = 1] = "Vertical";
2676
2698
  })(TrackNameOrientation || (TrackNameOrientation = {}));
2699
+ /**
2700
+ * How bar numbers are displayed
2701
+ * @public
2702
+ */
2703
+ var BarNumberDisplay;
2704
+ (function (BarNumberDisplay) {
2705
+ /**
2706
+ * Show bar numbers on all bars.
2707
+ */
2708
+ BarNumberDisplay[BarNumberDisplay["AllBars"] = 0] = "AllBars";
2709
+ /**
2710
+ * Show bar numbers on the first bar of every system.
2711
+ */
2712
+ BarNumberDisplay[BarNumberDisplay["FirstOfSystem"] = 1] = "FirstOfSystem";
2713
+ /**
2714
+ * Hide all bar numbers
2715
+ */
2716
+ BarNumberDisplay[BarNumberDisplay["Hide"] = 2] = "Hide";
2717
+ })(BarNumberDisplay || (BarNumberDisplay = {}));
2677
2718
  /**
2678
2719
  * This class represents the rendering stylesheet.
2679
2720
  * It contains settings which control the display of the score when rendered.
@@ -2767,6 +2808,10 @@
2767
2808
  * {@link hideEmptyStaves}
2768
2809
  */
2769
2810
  showSingleStaffBrackets = false;
2811
+ /**
2812
+ * How bar numbers should be displayed.
2813
+ */
2814
+ barNumberDisplay = BarNumberDisplay.AllBars;
2770
2815
  }
2771
2816
 
2772
2817
  /**
@@ -8438,6 +8483,12 @@
8438
8483
  ['buzzroll', 1]
8439
8484
  ]);
8440
8485
  static tremoloPickingStyleReversed = AlphaTex1EnumMappings._reverse(AlphaTex1EnumMappings.tremoloPickingStyle);
8486
+ static barNumberDisplay = new Map([
8487
+ ['allbars', 0],
8488
+ ['firstofsystem', 1],
8489
+ ['hide', 2]
8490
+ ]);
8491
+ static barNumberDisplayReversed = AlphaTex1EnumMappings._reverse(AlphaTex1EnumMappings.barNumberDisplay);
8441
8492
  static keySignaturesMinorReversed = new Map([
8442
8493
  [-7, 'abminor'],
8443
8494
  [-6, 'ebminor'],
@@ -8632,7 +8683,8 @@
8632
8683
  ['chorddiagramsinscore', [[[[10], 1, ['true', 'false']]]]],
8633
8684
  ['hideemptystaves', null],
8634
8685
  ['hideemptystavesinfirstsystem', null],
8635
- ['showsinglestaffbrackets', null]
8686
+ ['showsinglestaffbrackets', null],
8687
+ ['defaultbarnumberdisplay', [[[[10, 17], 0, ['allbars', 'firstofsystem', 'hide']]]]]
8636
8688
  ]);
8637
8689
  static staffMetaDataSignatures = AlphaTex1LanguageDefinitions._signatures([
8638
8690
  ['tuning', [[[[10, 17], 0, ['piano', 'none', 'voice']]], [[[10, 17], 5]]]],
@@ -8917,7 +8969,8 @@
8917
8969
  ['sph', [[[[16], 2]]]],
8918
8970
  ['spu', [[[[16], 2]]]],
8919
8971
  ['db', null],
8920
- ['voicemode', [[[[10, 17], 0, ['staffwise', 'barwise']]]]]
8972
+ ['voicemode', [[[[10, 17], 0, ['staffwise', 'barwise']]]]],
8973
+ ['barnumberdisplay', [[[[10, 17], 0, ['allbars', 'firstofsystem', 'hide']]]]]
8921
8974
  ]);
8922
8975
  static metaDataProperties = AlphaTex1LanguageDefinitions._metaProps([
8923
8976
  [
@@ -8975,6 +9028,7 @@
8975
9028
  ['hideemptystaves', null],
8976
9029
  ['hideemptystavesinfirstsystem', null],
8977
9030
  ['showsinglestaffbrackets', null],
9031
+ ['defaultbarnumberdisplay', null],
8978
9032
  [
8979
9033
  'tuning',
8980
9034
  [
@@ -9031,7 +9085,8 @@
9031
9085
  ['sph', null],
9032
9086
  ['spu', null],
9033
9087
  ['db', null],
9034
- ['voicemode', null]
9088
+ ['voicemode', null],
9089
+ ['barnumberdisplay', null]
9035
9090
  ]);
9036
9091
  static metaDataSignatures = [
9037
9092
  AlphaTex1LanguageDefinitions.scoreMetaDataSignatures,
@@ -12882,6 +12937,13 @@
12882
12937
  case 'showsinglestaffbrackets':
12883
12938
  score.stylesheet.showSingleStaffBrackets = true;
12884
12939
  return ApplyNodeResult.Applied;
12940
+ case 'defaultbarnumberdisplay':
12941
+ const barNumberDisplay = AlphaTex1LanguageHandler._parseEnumValue(importer, metaData.arguments, 'bar number display', AlphaTex1EnumMappings.barNumberDisplay);
12942
+ if (barNumberDisplay === undefined) {
12943
+ return ApplyNodeResult.NotAppliedSemanticError;
12944
+ }
12945
+ score.stylesheet.barNumberDisplay = barNumberDisplay;
12946
+ return ApplyNodeResult.Applied;
12885
12947
  default:
12886
12948
  return ApplyNodeResult.NotAppliedUnrecognizedMarker;
12887
12949
  }
@@ -13373,6 +13435,13 @@
13373
13435
  bar.masterBar.isDoubleBar = true;
13374
13436
  bar.barLineRight = BarLineStyle.LightLight;
13375
13437
  return ApplyNodeResult.Applied;
13438
+ case 'barnumberdisplay':
13439
+ const barNumberDisplay = AlphaTex1LanguageHandler._parseEnumValue(importer, metaData.arguments, 'bar number display', AlphaTex1EnumMappings.barNumberDisplay);
13440
+ if (barNumberDisplay === undefined) {
13441
+ return ApplyNodeResult.NotAppliedSemanticError;
13442
+ }
13443
+ bar.barNumberDisplay = barNumberDisplay;
13444
+ return ApplyNodeResult.Applied;
13376
13445
  default:
13377
13446
  return ApplyNodeResult.NotAppliedUnrecognizedMarker;
13378
13447
  }
@@ -14740,6 +14809,9 @@
14740
14809
  if (stylesheet.showSingleStaffBrackets) {
14741
14810
  nodes.push(Atnf.meta('showSingleStaffBrackets'));
14742
14811
  }
14812
+ if (stylesheet.barNumberDisplay !== BarNumberDisplay.AllBars) {
14813
+ nodes.push(Atnf.identMeta('defaultBarNumberDisplay', BarNumberDisplay[stylesheet.barNumberDisplay]));
14814
+ }
14743
14815
  // Unsupported:
14744
14816
  // 'globaldisplaychorddiagramsontop',
14745
14817
  // 'pertrackchorddiagramsontop',
@@ -14873,6 +14945,9 @@
14873
14945
  }
14874
14946
  ];
14875
14947
  }
14948
+ if (bar.barNumberDisplay !== undefined) {
14949
+ nodes.push(Atnf.identMeta('barNumberDisplay', BarNumberDisplay[bar.barNumberDisplay]));
14950
+ }
14876
14951
  return nodes;
14877
14952
  }
14878
14953
  static _buildStaffMetaDataNodes(nodes, staff) {
@@ -19541,6 +19616,10 @@
19541
19616
  this.readTrack();
19542
19617
  }
19543
19618
  }
19619
+ /**
19620
+ * Guitar Pro 3-6 changes to a bass clef if any string tuning is below B2;
19621
+ */
19622
+ static _bassClefTuningThreshold = ModelUtils.parseTuning('B2').realValue;
19544
19623
  readTrack() {
19545
19624
  const newTrack = new Track();
19546
19625
  newTrack.ensureStaveCount(1);
@@ -19621,11 +19700,11 @@
19621
19700
  this.data.readByte();
19622
19701
  // `12` for all tunings which have bass clefs
19623
19702
  const clefMode = IOHelper.readInt32LE(this.data);
19624
- if (clefMode === 12) {
19625
- this._clefsPerTrack.set(index, Clef.F4);
19703
+ if (clefMode === 12 || tuning[tuning.length - 1] < Gp3To5Importer._bassClefTuningThreshold) {
19704
+ this._clefsPerTrack.set(newTrack.index, Clef.F4);
19626
19705
  }
19627
19706
  else {
19628
- this._clefsPerTrack.set(index, Clef.G2);
19707
+ this._clefsPerTrack.set(newTrack.index, Clef.G2);
19629
19708
  }
19630
19709
  // Unknown, no UI setting seem to affect this
19631
19710
  IOHelper.readInt32LE(this.data);
@@ -19657,11 +19736,11 @@
19657
19736
  }
19658
19737
  }
19659
19738
  else {
19660
- if (GeneralMidi.isBass(newTrack.playbackInfo.program)) {
19661
- this._clefsPerTrack.set(index, Clef.F4);
19739
+ if (tuning[tuning.length - 1] < Gp3To5Importer._bassClefTuningThreshold) {
19740
+ this._clefsPerTrack.set(newTrack.index, Clef.F4);
19662
19741
  }
19663
19742
  else {
19664
- this._clefsPerTrack.set(index, Clef.G2);
19743
+ this._clefsPerTrack.set(newTrack.index, Clef.G2);
19665
19744
  }
19666
19745
  }
19667
19746
  }
@@ -20935,6 +21014,19 @@
20935
21014
  ModelUtils.getOrCreateHeaderFooterStyle(score, ScoreSubElement.CopyrightSecondLine).isVisible =
20936
21015
  value;
20937
21016
  break;
21017
+ case 'System/barIndexDrawType':
21018
+ switch (value) {
21019
+ case 0:
21020
+ score.stylesheet.barNumberDisplay = BarNumberDisplay.AllBars;
21021
+ break;
21022
+ case 1:
21023
+ score.stylesheet.barNumberDisplay = BarNumberDisplay.FirstOfSystem;
21024
+ break;
21025
+ case 2:
21026
+ score.stylesheet.barNumberDisplay = BarNumberDisplay.Hide;
21027
+ break;
21028
+ }
21029
+ break;
20938
21030
  }
20939
21031
  }
20940
21032
  }
@@ -21124,6 +21216,17 @@
21124
21216
  }
21125
21217
  }
21126
21218
  }
21219
+ switch (score.stylesheet.barNumberDisplay) {
21220
+ case BarNumberDisplay.AllBars:
21221
+ binaryStylesheet.addValue('System/barIndexDrawType', 0, DataType.Integer);
21222
+ break;
21223
+ case BarNumberDisplay.FirstOfSystem:
21224
+ binaryStylesheet.addValue('System/barIndexDrawType', 1, DataType.Integer);
21225
+ break;
21226
+ case BarNumberDisplay.Hide:
21227
+ binaryStylesheet.addValue('System/barIndexDrawType', 2, DataType.Integer);
21228
+ break;
21229
+ }
21127
21230
  const writer = ByteBuffer.withCapacity(128);
21128
21231
  binaryStylesheet.writeTo(writer);
21129
21232
  return writer.toArray();
@@ -24830,6 +24933,8 @@
24830
24933
  _idToTrackInfo = new Map();
24831
24934
  _indexToTrackInfo = new Map();
24832
24935
  _staffToContext = new Map();
24936
+ _currentBarNumberDisplayPart;
24937
+ _currentBarNumberDisplayBar;
24833
24938
  _divisionsPerQuarterNote = 1;
24834
24939
  _currentDynamics = DynamicValue.F;
24835
24940
  get name() {
@@ -25443,20 +25548,29 @@
25443
25548
  break;
25444
25549
  }
25445
25550
  }
25551
+ this._currentBarNumberDisplayPart = undefined;
25446
25552
  }
25447
25553
  _parsePartwiseMeasure(element, track, index) {
25448
25554
  const masterBar = this._getOrCreateMasterBar(element, index);
25449
- this._parsePartMeasure(element, masterBar, track);
25555
+ const implicit = element.attributes.get('implicit') === 'yes';
25556
+ this._parsePartMeasure(element, masterBar, track, implicit, true);
25557
+ this._currentBarNumberDisplayBar = undefined;
25450
25558
  }
25451
25559
  _parseTimewiseMeasure(element, index) {
25452
25560
  const masterBar = this._getOrCreateMasterBar(element, index);
25561
+ const implicit = element.attributes.get('implicit') === 'yes';
25453
25562
  for (const c of element.childElements()) {
25454
25563
  switch (c.localName) {
25455
25564
  case 'part':
25456
- this._parseTimewisePart(c, masterBar);
25565
+ this._parseTimewisePart(c, masterBar, implicit);
25566
+ this._currentBarNumberDisplayPart = undefined;
25567
+ break;
25568
+ case 'print':
25569
+ this._parsePrint(c, masterBar, undefined, true);
25457
25570
  break;
25458
25571
  }
25459
25572
  }
25573
+ this._currentBarNumberDisplayBar = undefined;
25460
25574
  }
25461
25575
  _getOrCreateMasterBar(element, index) {
25462
25576
  const implicit = element.attributes.get('implicit') === 'yes';
@@ -25475,13 +25589,13 @@
25475
25589
  const masterBar = this._score.masterBars[index];
25476
25590
  return masterBar;
25477
25591
  }
25478
- _parseTimewisePart(element, masterBar) {
25592
+ _parseTimewisePart(element, masterBar, implicit) {
25479
25593
  const id = element.attributes.get('id');
25480
25594
  if (!id || !this._idToTrackInfo.has(id)) {
25481
25595
  return;
25482
25596
  }
25483
25597
  const track = this._idToTrackInfo.get(id).track;
25484
- this._parsePartMeasure(element, masterBar, track);
25598
+ this._parsePartMeasure(element, masterBar, track, implicit, false);
25485
25599
  }
25486
25600
  // current measure state
25487
25601
  /**
@@ -25493,7 +25607,7 @@
25493
25607
  * to access the current voice/staff (e.g. on rests when we don't have notes)
25494
25608
  */
25495
25609
  _lastBeat = null;
25496
- _parsePartMeasure(element, masterBar, track) {
25610
+ _parsePartMeasure(element, masterBar, track, implicit, isPartwise) {
25497
25611
  this._musicalPosition = 0;
25498
25612
  this._lastBeat = null;
25499
25613
  masterBar.alternateEndings = this._nextMasterBarRepeatEnding;
@@ -25520,7 +25634,7 @@
25520
25634
  break;
25521
25635
  // case 'figured-bass': Not supported
25522
25636
  case 'print':
25523
- this._parsePrint(c, masterBar, track);
25637
+ this._parsePrint(c, masterBar, track, true);
25524
25638
  break;
25525
25639
  case 'sound':
25526
25640
  this._parseSound(c, masterBar, track);
@@ -25541,16 +25655,51 @@
25541
25655
  this._applySimileMarks(masterBar, track);
25542
25656
  // initial empty staff and voice (if no other elements created something already)
25543
25657
  const staff = this._getOrCreateStaff(track, 0);
25544
- this._getOrCreateBar(staff, masterBar);
25658
+ const bar = this._getOrCreateBar(staff, masterBar);
25659
+ if (implicit) {
25660
+ bar.barNumberDisplay = BarNumberDisplay.Hide;
25661
+ }
25662
+ else if (isPartwise) {
25663
+ bar.barNumberDisplay = this._currentBarNumberDisplayBar ?? this._currentBarNumberDisplayPart;
25664
+ }
25665
+ else {
25666
+ bar.barNumberDisplay = this._currentBarNumberDisplayPart ?? this._currentBarNumberDisplayBar;
25667
+ }
25545
25668
  // clear measure attribute
25546
25669
  this._keyAllStaves = null;
25547
25670
  }
25548
- _parsePrint(element, masterBar, track) {
25549
- if (element.getAttribute('new-system', 'no') === 'yes') {
25550
- track.addLineBreaks(masterBar.index);
25671
+ _parsePrint(element, masterBar, track, isMeasurePrint) {
25672
+ if (track !== undefined) {
25673
+ if (element.getAttribute('new-system', 'no') === 'yes') {
25674
+ track.addLineBreaks(masterBar.index);
25675
+ }
25676
+ else if (element.getAttribute('new-page', 'no') === 'yes') {
25677
+ track.addLineBreaks(masterBar.index);
25678
+ }
25679
+ }
25680
+ let newDisplay = undefined;
25681
+ for (const c of element.childElements()) {
25682
+ switch (c.localName) {
25683
+ case 'measure-numbering':
25684
+ switch (c.innerText) {
25685
+ case 'none':
25686
+ newDisplay = BarNumberDisplay.Hide;
25687
+ break;
25688
+ case 'measure':
25689
+ newDisplay = BarNumberDisplay.AllBars;
25690
+ break;
25691
+ case 'system':
25692
+ newDisplay = BarNumberDisplay.FirstOfSystem;
25693
+ break;
25694
+ }
25695
+ break;
25696
+ }
25697
+ }
25698
+ if (isMeasurePrint) {
25699
+ this._currentBarNumberDisplayBar = newDisplay;
25551
25700
  }
25552
- else if (element.getAttribute('new-page', 'no') === 'yes') {
25553
- track.addLineBreaks(masterBar.index);
25701
+ else {
25702
+ this._currentBarNumberDisplayPart = newDisplay;
25554
25703
  }
25555
25704
  }
25556
25705
  _applySimileMarks(masterBar, track) {
@@ -26660,7 +26809,7 @@
26660
26809
  if (unit !== null && perMinute > 0) {
26661
26810
  const tempoAutomation = new Automation();
26662
26811
  tempoAutomation.type = AutomationType.Tempo;
26663
- tempoAutomation.value = (perMinute * (unit / 4)) | 0;
26812
+ tempoAutomation.value = perMinute * (unit / 4);
26664
26813
  tempoAutomation.ratioPosition = ratioPosition;
26665
26814
  if (!this._hasSameTempo(masterBar, tempoAutomation)) {
26666
26815
  masterBar.tempoAutomations.push(tempoAutomation);
@@ -29589,7 +29738,7 @@
29589
29738
  }
29590
29739
  if (mEvent.type === MidiEventType.TempoChange) {
29591
29740
  const meta = mEvent;
29592
- bpm = meta.beatsPerMinute;
29741
+ bpm = MidiFileSequencer._sanitizeBpm(meta.beatsPerMinute);
29593
29742
  state.tempoChanges.push(new MidiFileSequencerTempoChange(bpm, absTick, absTime));
29594
29743
  metronomeLengthInMillis = metronomeLengthInTicks * (60000.0 / (bpm * midiFile.division));
29595
29744
  }
@@ -29707,7 +29856,7 @@
29707
29856
  }
29708
29857
  else {
29709
29858
  const previousSyncPoint = syncPoints[i - 1];
29710
- previousModifiedTempo = previousSyncPoint.syncBpm;
29859
+ previousModifiedTempo = MidiFileSequencer._sanitizeBpm(previousSyncPoint.syncBpm);
29711
29860
  previousMillisecondOffset = previousSyncPoint.syncTime;
29712
29861
  previousTick = previousSyncPoint.synthTick;
29713
29862
  }
@@ -29731,7 +29880,7 @@
29731
29880
  syncPoint.syncTime = interpolatedMillisecondOffset;
29732
29881
  syncPoint.syncBpm = previousModifiedTempo;
29733
29882
  }
29734
- bpm = state.tempoChanges[tempoChangeIndex].bpm;
29883
+ bpm = MidiFileSequencer._sanitizeBpm(state.tempoChanges[tempoChangeIndex].bpm);
29735
29884
  tempoChangeIndex++;
29736
29885
  }
29737
29886
  deltaTick = p.synthTick - absTick;
@@ -29752,10 +29901,13 @@
29752
29901
  this._updateCurrentTempo(state, timePosition);
29753
29902
  const lastTempoChange = state.tempoChanges[state.tempoChangeIndex];
29754
29903
  const timeDiff = timePosition - lastTempoChange.time;
29755
- const ticks = (timeDiff / (60000.0 / (lastTempoChange.bpm * state.division))) | 0;
29904
+ const ticks = (timeDiff / (60000.0 / (MidiFileSequencer._sanitizeBpm(lastTempoChange.bpm) * state.division))) | 0;
29756
29905
  // we add 1 for possible rounding errors.(floating point issuses)
29757
29906
  return lastTempoChange.ticks + ticks + 1;
29758
29907
  }
29908
+ static _sanitizeBpm(bpm) {
29909
+ return Math.max(bpm, 1); // prevent <0 bpms. Doesn't make sense and can cause endless loops
29910
+ }
29759
29911
  currentUpdateCurrentTempo(timePosition) {
29760
29912
  this._updateCurrentTempo(this._mainState, timePosition * this.playbackSpeed);
29761
29913
  }
@@ -37487,6 +37639,7 @@
37487
37639
  o.set("barlineright", obj.barLineRight);
37488
37640
  o.set("keysignature", obj.keySignature);
37489
37641
  o.set("keysignaturetype", obj.keySignatureType);
37642
+ o.set("barnumberdisplay", obj.barNumberDisplay);
37490
37643
  if (obj.style) {
37491
37644
  o.set("style", BarStyleSerializer.toJson(obj.style));
37492
37645
  }
@@ -37540,6 +37693,9 @@
37540
37693
  case "keysignaturetype":
37541
37694
  obj.keySignatureType = JsonHelper.parseEnum(v, KeySignatureType);
37542
37695
  return true;
37696
+ case "barnumberdisplay":
37697
+ obj.barNumberDisplay = JsonHelper.parseEnum(v, BarNumberDisplay);
37698
+ return true;
37543
37699
  case "style":
37544
37700
  if (v) {
37545
37701
  obj.style = new BarStyle();
@@ -38034,6 +38190,7 @@
38034
38190
  o.set("hideemptystaves", obj.hideEmptyStaves);
38035
38191
  o.set("hideemptystavesinfirstsystem", obj.hideEmptyStavesInFirstSystem);
38036
38192
  o.set("showsinglestaffbrackets", obj.showSingleStaffBrackets);
38193
+ o.set("barnumberdisplay", obj.barNumberDisplay);
38037
38194
  return o;
38038
38195
  }
38039
38196
  static setProperty(obj, property, v) {
@@ -38104,6 +38261,9 @@
38104
38261
  case "showsinglestaffbrackets":
38105
38262
  obj.showSingleStaffBrackets = v;
38106
38263
  return true;
38264
+ case "barnumberdisplay":
38265
+ obj.barNumberDisplay = JsonHelper.parseEnum(v, BarNumberDisplay);
38266
+ return true;
38107
38267
  }
38108
38268
  return false;
38109
38269
  }
@@ -41835,25 +41995,20 @@
41835
41995
  const o = new Map();
41836
41996
  o.set("smuflfontfamilyname", obj.smuflFontFamilyName);
41837
41997
  o.set("engravingsettings", EngravingSettingsSerializer.toJson(obj.engravingSettings));
41838
- o.set("copyrightfont", Font.toJson(obj.copyrightFont));
41839
- o.set("titlefont", Font.toJson(obj.titleFont));
41840
- o.set("subtitlefont", Font.toJson(obj.subTitleFont));
41841
- o.set("wordsfont", Font.toJson(obj.wordsFont));
41842
- o.set("effectfont", Font.toJson(obj.effectFont));
41843
- o.set("timerfont", Font.toJson(obj.timerFont));
41844
- o.set("directionsfont", Font.toJson(obj.directionsFont));
41845
- o.set("fretboardnumberfont", Font.toJson(obj.fretboardNumberFont));
41998
+ {
41999
+ const m = new Map();
42000
+ o.set("elementfonts", m);
42001
+ for (const [k, v] of obj.elementFonts) {
42002
+ m.set(k.toString(), Font.toJson(v));
42003
+ }
42004
+ }
41846
42005
  o.set("numberednotationfont", Font.toJson(obj.numberedNotationFont));
41847
42006
  o.set("numberednotationgracefont", Font.toJson(obj.numberedNotationGraceFont));
41848
42007
  o.set("tablaturefont", Font.toJson(obj.tablatureFont));
41849
42008
  o.set("gracefont", Font.toJson(obj.graceFont));
41850
42009
  o.set("stafflinecolor", Color.toJson(obj.staffLineColor));
41851
42010
  o.set("barseparatorcolor", Color.toJson(obj.barSeparatorColor));
41852
- o.set("barnumberfont", Font.toJson(obj.barNumberFont));
41853
42011
  o.set("barnumbercolor", Color.toJson(obj.barNumberColor));
41854
- o.set("fingeringfont", Font.toJson(obj.fingeringFont));
41855
- o.set("inlinefingeringfont", Font.toJson(obj.inlineFingeringFont));
41856
- o.set("markerfont", Font.toJson(obj.markerFont));
41857
42012
  o.set("mainglyphcolor", Color.toJson(obj.mainGlyphColor));
41858
42013
  o.set("secondaryglyphcolor", Color.toJson(obj.secondaryGlyphColor));
41859
42014
  o.set("scoreinfocolor", Color.toJson(obj.scoreInfoColor));
@@ -41864,29 +42019,10 @@
41864
42019
  case "smuflfontfamilyname":
41865
42020
  obj.smuflFontFamilyName = v;
41866
42021
  return true;
41867
- case "copyrightfont":
41868
- obj.copyrightFont = Font.fromJson(v);
41869
- return true;
41870
- case "titlefont":
41871
- obj.titleFont = Font.fromJson(v);
41872
- return true;
41873
- case "subtitlefont":
41874
- obj.subTitleFont = Font.fromJson(v);
41875
- return true;
41876
- case "wordsfont":
41877
- obj.wordsFont = Font.fromJson(v);
41878
- return true;
41879
- case "effectfont":
41880
- obj.effectFont = Font.fromJson(v);
41881
- return true;
41882
- case "timerfont":
41883
- obj.timerFont = Font.fromJson(v);
41884
- return true;
41885
- case "directionsfont":
41886
- obj.directionsFont = Font.fromJson(v);
41887
- return true;
41888
- case "fretboardnumberfont":
41889
- obj.fretboardNumberFont = Font.fromJson(v);
42022
+ case "elementfonts":
42023
+ JsonHelper.forEach(v, (v, k) => {
42024
+ obj.elementFonts.set(JsonHelper.parseEnum(k, exports.NotationElement), Font.fromJson(v));
42025
+ });
41890
42026
  return true;
41891
42027
  case "numberednotationfont":
41892
42028
  obj.numberedNotationFont = Font.fromJson(v);
@@ -41906,21 +42042,9 @@
41906
42042
  case "barseparatorcolor":
41907
42043
  obj.barSeparatorColor = Color.fromJson(v);
41908
42044
  return true;
41909
- case "barnumberfont":
41910
- obj.barNumberFont = Font.fromJson(v);
41911
- return true;
41912
42045
  case "barnumbercolor":
41913
42046
  obj.barNumberColor = Color.fromJson(v);
41914
42047
  return true;
41915
- case "fingeringfont":
41916
- obj.fingeringFont = Font.fromJson(v);
41917
- return true;
41918
- case "inlinefingeringfont":
41919
- obj.inlineFingeringFont = Font.fromJson(v);
41920
- return true;
41921
- case "markerfont":
41922
- obj.markerFont = Font.fromJson(v);
41923
- return true;
41924
42048
  case "mainglyphcolor":
41925
42049
  obj.mainGlyphColor = Color.fromJson(v);
41926
42050
  return true;
@@ -41977,6 +42101,46 @@
41977
42101
  class RenderingResources {
41978
42102
  static _sansFont = 'Arial, sans-serif';
41979
42103
  static _serifFont = 'Georgia, serif';
42104
+ static _effectFont = new Font(RenderingResources._serifFont, 12, FontStyle.Italic);
42105
+ /**
42106
+ * The default fonts for notation elements if not specified by the user.
42107
+ */
42108
+ static defaultFonts = new Map([
42109
+ [exports.NotationElement.ScoreTitle, new Font(RenderingResources._serifFont, 32, FontStyle.Plain)],
42110
+ [exports.NotationElement.ScoreSubTitle, new Font(RenderingResources._serifFont, 20, FontStyle.Plain)],
42111
+ [exports.NotationElement.ScoreArtist, new Font(RenderingResources._serifFont, 20, FontStyle.Plain)],
42112
+ [exports.NotationElement.ScoreAlbum, new Font(RenderingResources._serifFont, 20, FontStyle.Plain)],
42113
+ [exports.NotationElement.ScoreWords, new Font(RenderingResources._serifFont, 15, FontStyle.Plain)],
42114
+ [exports.NotationElement.ScoreMusic, new Font(RenderingResources._serifFont, 15, FontStyle.Plain)],
42115
+ [exports.NotationElement.ScoreWordsAndMusic, new Font(RenderingResources._serifFont, 15, FontStyle.Plain)],
42116
+ [exports.NotationElement.ScoreCopyright, new Font(RenderingResources._sansFont, 12, FontStyle.Plain, FontWeight.Bold)],
42117
+ [exports.NotationElement.EffectBeatTimer, new Font(RenderingResources._serifFont, 12, FontStyle.Plain)],
42118
+ [exports.NotationElement.EffectDirections, new Font(RenderingResources._serifFont, 14, FontStyle.Plain)],
42119
+ [exports.NotationElement.ChordDiagramFretboardNumbers, new Font(RenderingResources._sansFont, 11, FontStyle.Plain)],
42120
+ [exports.NotationElement.EffectFingering, new Font(RenderingResources._serifFont, 14, FontStyle.Plain)],
42121
+ [exports.NotationElement.EffectMarker, new Font(RenderingResources._serifFont, 14, FontStyle.Plain, FontWeight.Bold)],
42122
+ [exports.NotationElement.EffectCapo, RenderingResources._effectFont],
42123
+ [exports.NotationElement.EffectFreeTime, RenderingResources._effectFont],
42124
+ [exports.NotationElement.EffectLyrics, RenderingResources._effectFont],
42125
+ [exports.NotationElement.EffectTap, RenderingResources._effectFont],
42126
+ [exports.NotationElement.ChordDiagrams, RenderingResources._effectFont],
42127
+ [exports.NotationElement.EffectChordNames, RenderingResources._effectFont],
42128
+ [exports.NotationElement.EffectText, RenderingResources._effectFont],
42129
+ [exports.NotationElement.EffectPalmMute, RenderingResources._effectFont],
42130
+ [exports.NotationElement.EffectLetRing, RenderingResources._effectFont],
42131
+ [exports.NotationElement.EffectBeatBarre, RenderingResources._effectFont],
42132
+ [exports.NotationElement.EffectTripletFeel, RenderingResources._effectFont],
42133
+ [exports.NotationElement.EffectHarmonics, RenderingResources._effectFont],
42134
+ [exports.NotationElement.EffectPickSlide, RenderingResources._effectFont],
42135
+ [exports.NotationElement.GuitarTuning, RenderingResources._effectFont],
42136
+ [exports.NotationElement.EffectRasgueado, RenderingResources._effectFont],
42137
+ [exports.NotationElement.EffectWhammyBar, RenderingResources._effectFont],
42138
+ [exports.NotationElement.TrackNames, RenderingResources._effectFont],
42139
+ [exports.NotationElement.RepeatCount, new Font(RenderingResources._sansFont, 11, FontStyle.Plain)],
42140
+ [exports.NotationElement.BarNumber, new Font(RenderingResources._sansFont, 11, FontStyle.Plain)],
42141
+ [exports.NotationElement.ScoreBendSlur, new Font(RenderingResources._sansFont, 11, FontStyle.Plain)],
42142
+ [exports.NotationElement.EffectAlternateEndings, new Font(RenderingResources._serifFont, 15, FontStyle.Plain)]
42143
+ ]);
41980
42144
  /**
41981
42145
  * The name of the SMuFL Font to use for rendering music symbols.
41982
42146
  *
@@ -42003,50 +42167,168 @@
42003
42167
  * The font to use for displaying the songs copyright information in the header of the music sheet.
42004
42168
  * @defaultValue `bold 12px Arial, sans-serif`
42005
42169
  * @since 0.9.6
42170
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreCopyright}
42006
42171
  */
42007
- copyrightFont = new Font(RenderingResources._sansFont, 12, FontStyle.Plain, FontWeight.Bold);
42172
+ get copyrightFont() {
42173
+ return this.elementFonts.get(exports.NotationElement.ScoreCopyright);
42174
+ }
42175
+ /**
42176
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreCopyright}
42177
+ */
42178
+ set copyrightFont(value) {
42179
+ this.elementFonts.set(exports.NotationElement.ScoreCopyright, value);
42180
+ }
42008
42181
  /**
42009
42182
  * The font to use for displaying the songs title in the header of the music sheet.
42010
42183
  * @defaultValue `32px Georgia, serif`
42011
42184
  * @since 0.9.6
42185
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreTitle}
42012
42186
  */
42013
- titleFont = new Font(RenderingResources._serifFont, 32, FontStyle.Plain);
42187
+ get titleFont() {
42188
+ return this.elementFonts.get(exports.NotationElement.ScoreTitle);
42189
+ }
42190
+ /**
42191
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreTitle}
42192
+ */
42193
+ set titleFont(value) {
42194
+ this.elementFonts.set(exports.NotationElement.ScoreTitle, value);
42195
+ }
42014
42196
  /**
42015
42197
  * The font to use for displaying the songs subtitle in the header of the music sheet.
42016
42198
  * @defaultValue `20px Georgia, serif`
42017
42199
  * @since 0.9.6
42200
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreSubTitle}
42018
42201
  */
42019
- subTitleFont = new Font(RenderingResources._serifFont, 20, FontStyle.Plain);
42202
+ get subTitleFont() {
42203
+ return this.elementFonts.get(exports.NotationElement.ScoreSubTitle);
42204
+ }
42205
+ /**
42206
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreSubTitle}
42207
+ */
42208
+ set subTitleFont(value) {
42209
+ this.elementFonts.set(exports.NotationElement.ScoreSubTitle, value);
42210
+ }
42020
42211
  /**
42021
42212
  * The font to use for displaying the lyrics information in the header of the music sheet.
42022
42213
  * @defaultValue `15px Arial, sans-serif`
42023
42214
  * @since 0.9.6
42215
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreWords}
42024
42216
  */
42025
- wordsFont = new Font(RenderingResources._serifFont, 15, FontStyle.Plain);
42217
+ get wordsFont() {
42218
+ return this.elementFonts.get(exports.NotationElement.ScoreWords);
42219
+ }
42026
42220
  /**
42027
- * The font to use for displaying certain effect related elements in the music sheet.
42028
- * @defaultValue `italic 12px Georgia, serif`
42029
- * @since 0.9.6
42221
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreWords}
42030
42222
  */
42031
- effectFont = new Font(RenderingResources._serifFont, 12, FontStyle.Italic);
42223
+ set wordsFont(value) {
42224
+ this.elementFonts.set(exports.NotationElement.ScoreWords, value);
42225
+ }
42032
42226
  /**
42033
42227
  * The font to use for displaying beat time information in the music sheet.
42034
42228
  * @defaultValue `12px Georgia, serif`
42035
42229
  * @since 1.4.0
42230
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectBeatTimer}
42036
42231
  */
42037
- timerFont = new Font(RenderingResources._serifFont, 12, FontStyle.Plain);
42232
+ get timerFont() {
42233
+ return this.elementFonts.get(exports.NotationElement.EffectBeatTimer);
42234
+ }
42235
+ /**
42236
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectBeatTimer}
42237
+ */
42238
+ set timerFont(value) {
42239
+ this.elementFonts.set(exports.NotationElement.EffectBeatTimer, value);
42240
+ }
42038
42241
  /**
42039
42242
  * The font to use for displaying the directions texts.
42040
42243
  * @defaultValue `14px Georgia, serif`
42041
42244
  * @since 1.4.0
42245
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectDirections}
42042
42246
  */
42043
- directionsFont = new Font(RenderingResources._serifFont, 14, FontStyle.Plain);
42247
+ get directionsFont() {
42248
+ return this.elementFonts.get(exports.NotationElement.EffectDirections);
42249
+ }
42250
+ /**
42251
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectDirections}
42252
+ */
42253
+ set directionsFont(value) {
42254
+ this.elementFonts.set(exports.NotationElement.EffectDirections, value);
42255
+ }
42044
42256
  /**
42045
42257
  * The font to use for displaying the fretboard numbers in chord diagrams.
42046
42258
  * @defaultValue `11px Arial, sans-serif`
42047
42259
  * @since 0.9.6
42260
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ChordDiagramFretboardNumbers}
42261
+ */
42262
+ get fretboardNumberFont() {
42263
+ return this.elementFonts.get(exports.NotationElement.ChordDiagramFretboardNumbers);
42264
+ }
42265
+ /**
42266
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ChordDiagramFretboardNumbers}
42048
42267
  */
42049
- fretboardNumberFont = new Font(RenderingResources._sansFont, 11, FontStyle.Plain);
42268
+ set fretboardNumberFont(value) {
42269
+ this.elementFonts.set(exports.NotationElement.ChordDiagramFretboardNumbers, value);
42270
+ }
42271
+ /**
42272
+ * Unused, see deprecation note.
42273
+ * @defaultValue `14px Georgia, serif`
42274
+ * @since 0.9.6
42275
+ * @deprecated Since 1.7.0 alphaTab uses the glyphs contained in the SMuFL font
42276
+ * @json_ignore
42277
+ */
42278
+ fingeringFont = RenderingResources._effectFont;
42279
+ /**
42280
+ * Unused, see deprecation note.
42281
+ * @defaultValue `12px Georgia, serif`
42282
+ * @since 1.4.0
42283
+ * @deprecated Since 1.7.0 alphaTab uses the glyphs contained in the SMuFL font
42284
+ * @json_ignore
42285
+ */
42286
+ inlineFingeringFont = RenderingResources._effectFont;
42287
+ /**
42288
+ * The font to use for section marker labels shown above the music sheet.
42289
+ * @defaultValue `bold 14px Georgia, serif`
42290
+ * @since 0.9.6
42291
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectMarker}
42292
+ */
42293
+ get markerFont() {
42294
+ return this.elementFonts.get(exports.NotationElement.EffectMarker);
42295
+ }
42296
+ /**
42297
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectMarker}
42298
+ */
42299
+ set markerFont(value) {
42300
+ this.elementFonts.set(exports.NotationElement.EffectMarker, value);
42301
+ }
42302
+ /**
42303
+ * Ununsed, see deprecation note.
42304
+ * @defaultValue `italic 12px Georgia, serif`
42305
+ * @since 0.9.6
42306
+ * @deprecated use {@link elementFonts} with the respective
42307
+ * @json_ignore
42308
+ */
42309
+ effectFont = RenderingResources._effectFont;
42310
+ /**
42311
+ * The font to use for displaying the bar numbers above the music sheet.
42312
+ * @defaultValue `11px Arial, sans-serif`
42313
+ * @since 0.9.6
42314
+ * @deprecated use {@link elementFonts} with {@link NotationElement.BarNumber}
42315
+ */
42316
+ get barNumberFont() {
42317
+ return this.elementFonts.get(exports.NotationElement.BarNumber);
42318
+ }
42319
+ /**
42320
+ * @deprecated use {@link elementFonts} with {@link NotationElement.BarNumber}
42321
+ */
42322
+ set barNumberFont(value) {
42323
+ this.elementFonts.set(exports.NotationElement.BarNumber, value);
42324
+ }
42325
+ // NOTE: the main staff fonts are still own properties.
42326
+ /**
42327
+ * The fonts used by individual elements. Check {@link defaultFonts} for the elements which have custom fonts.
42328
+ * Removing fonts from this map can lead to unexpected side effects and errors. Only update it with new values.
42329
+ * @json_immutable
42330
+ */
42331
+ elementFonts = new Map();
42050
42332
  /**
42051
42333
  * The font to use for displaying the numbered music notation in the music sheet.
42052
42334
  * @defaultValue `14px Arial, sans-serif`
@@ -42083,38 +42365,12 @@
42083
42365
  * @since 0.9.6
42084
42366
  */
42085
42367
  barSeparatorColor = new Color(34, 34, 17, 0xff);
42086
- /**
42087
- * The font to use for displaying the bar numbers above the music sheet.
42088
- * @defaultValue `11px Arial, sans-serif`
42089
- * @since 0.9.6
42090
- */
42091
- barNumberFont = new Font(RenderingResources._sansFont, 11, FontStyle.Plain);
42092
42368
  /**
42093
42369
  * The color to use for displaying the bar numbers above the music sheet.
42094
42370
  * @defaultValue `rgb(200, 0, 0)`
42095
42371
  * @since 0.9.6
42096
42372
  */
42097
42373
  barNumberColor = new Color(200, 0, 0, 0xff);
42098
- /**
42099
- * The font to use for displaying finger information in the music sheet.
42100
- * @defaultValue `14px Georgia, serif`
42101
- * @since 0.9.6
42102
- * @deprecated Since 1.7.0 alphaTab uses the glyphs contained in the SMuFL font
42103
- */
42104
- fingeringFont = new Font(RenderingResources._serifFont, 14, FontStyle.Plain);
42105
- /**
42106
- * The font to use for displaying finger information when inline into the music sheet.
42107
- * @defaultValue `12px Georgia, serif`
42108
- * @since 1.4.0
42109
- * @deprecated Since 1.7.0 alphaTab uses the glyphs contained in the SMuFL font
42110
- */
42111
- inlineFingeringFont = new Font(RenderingResources._serifFont, 12, FontStyle.Plain);
42112
- /**
42113
- * The font to use for section marker labels shown above the music sheet.
42114
- * @defaultValue `bold 14px Georgia, serif`
42115
- * @since 0.9.6
42116
- */
42117
- markerFont = new Font(RenderingResources._serifFont, 14, FontStyle.Plain, FontWeight.Bold);
42118
42374
  /**
42119
42375
  * The color to use for music notation elements of the primary voice.
42120
42376
  * @defaultValue `rgb(0, 0, 0)`
@@ -42133,28 +42389,50 @@
42133
42389
  * @since 0.9.6
42134
42390
  */
42135
42391
  scoreInfoColor = new Color(0, 0, 0, 0xff);
42392
+ constructor() {
42393
+ for (const [k, v] of RenderingResources.defaultFonts) {
42394
+ this.elementFonts.set(k, v.withSize(v.size));
42395
+ }
42396
+ }
42136
42397
  /**
42137
42398
  * @internal
42138
42399
  * @param element
42139
42400
  */
42140
42401
  getFontForElement(element) {
42402
+ let notationElement = exports.NotationElement.ScoreWords;
42141
42403
  switch (element) {
42142
42404
  case ScoreSubElement.Title:
42143
- return this.titleFont;
42405
+ notationElement = exports.NotationElement.ScoreTitle;
42406
+ break;
42144
42407
  case ScoreSubElement.SubTitle:
42408
+ notationElement = exports.NotationElement.ScoreSubTitle;
42409
+ break;
42145
42410
  case ScoreSubElement.Artist:
42411
+ notationElement = exports.NotationElement.ScoreArtist;
42412
+ break;
42146
42413
  case ScoreSubElement.Album:
42147
- return this.subTitleFont;
42414
+ notationElement = exports.NotationElement.ScoreAlbum;
42415
+ break;
42148
42416
  case ScoreSubElement.Words:
42417
+ notationElement = exports.NotationElement.ScoreWords;
42418
+ break;
42149
42419
  case ScoreSubElement.Music:
42420
+ notationElement = exports.NotationElement.ScoreMusic;
42421
+ break;
42150
42422
  case ScoreSubElement.WordsAndMusic:
42151
- case ScoreSubElement.Transcriber:
42152
- return this.wordsFont;
42423
+ notationElement = exports.NotationElement.ScoreWordsAndMusic;
42424
+ break;
42153
42425
  case ScoreSubElement.Copyright:
42154
42426
  case ScoreSubElement.CopyrightSecondLine:
42155
- return this.copyrightFont;
42427
+ notationElement = exports.NotationElement.ScoreCopyright;
42428
+ break;
42429
+ default:
42430
+ notationElement = exports.NotationElement.ScoreWords;
42431
+ break;
42156
42432
  }
42157
- return this.wordsFont;
42433
+ return this.elementFonts.has(notationElement)
42434
+ ? this.elementFonts.get(notationElement)
42435
+ : RenderingResources.defaultFonts.get(exports.NotationElement.ScoreWords);
42158
42436
  }
42159
42437
  }
42160
42438
 
@@ -42459,6 +42737,13 @@
42459
42737
  * @defaultValue `5`
42460
42738
  */
42461
42739
  trackStaffPaddingBetween = 5;
42740
+ /**
42741
+ * The additional padding to apply between multiple lyric lines.
42742
+ * @since 1.8.0
42743
+ * @category Display
42744
+ * @defaultValue `5`
42745
+ */
42746
+ lyricLinesPaddingBetween = 5;
42462
42747
  /**
42463
42748
  * The mode used to arrange staves and systems.
42464
42749
  * @since 1.3.0
@@ -42569,6 +42854,7 @@
42569
42854
  o.set("staffpaddingleft", obj.staffPaddingLeft);
42570
42855
  o.set("effectbandpaddingbottom", obj.effectBandPaddingBottom);
42571
42856
  o.set("trackstaffpaddingbetween", obj.trackStaffPaddingBetween);
42857
+ o.set("lyriclinespaddingbetween", obj.lyricLinesPaddingBetween);
42572
42858
  o.set("systemslayoutmode", obj.systemsLayoutMode);
42573
42859
  return o;
42574
42860
  }
@@ -42655,6 +42941,9 @@
42655
42941
  case "trackstaffpaddingbetween":
42656
42942
  obj.trackStaffPaddingBetween = v;
42657
42943
  return true;
42944
+ case "lyriclinespaddingbetween":
42945
+ obj.lyricLinesPaddingBetween = v;
42946
+ return true;
42658
42947
  case "systemslayoutmode":
42659
42948
  obj.systemsLayoutMode = JsonHelper.parseEnum(v, exports.SystemsLayoutMode);
42660
42949
  return true;
@@ -55363,23 +55652,20 @@
55363
55652
  this._contents = '';
55364
55653
  const element = api.container;
55365
55654
  if (settings.core.tex) {
55366
- this._contents = element.element.innerText;
55655
+ this._contents = element.element.textContent;
55367
55656
  element.element.innerText = '';
55368
55657
  }
55369
55658
  this._createStyleElements(settings);
55370
55659
  this._file = settings.core.file;
55371
55660
  }
55372
55661
  _setupFontCheckers(settings) {
55373
- this._registerFontChecker(settings.display.resources.copyrightFont);
55374
- this._registerFontChecker(settings.display.resources.effectFont);
55662
+ for (const font of settings.display.resources.elementFonts.values()) {
55663
+ this._registerFontChecker(font);
55664
+ }
55375
55665
  this._registerFontChecker(settings.display.resources.graceFont);
55376
- this._registerFontChecker(settings.display.resources.markerFont);
55377
55666
  this._registerFontChecker(settings.display.resources.tablatureFont);
55378
- this._registerFontChecker(settings.display.resources.titleFont);
55379
- this._registerFontChecker(settings.display.resources.wordsFont);
55380
- this._registerFontChecker(settings.display.resources.barNumberFont);
55381
- this._registerFontChecker(settings.display.resources.fretboardNumberFont);
55382
- this._registerFontChecker(settings.display.resources.subTitleFont);
55667
+ this._registerFontChecker(settings.display.resources.numberedNotationFont);
55668
+ this._registerFontChecker(settings.display.resources.numberedNotationGraceFont);
55383
55669
  }
55384
55670
  _registerFontChecker(font) {
55385
55671
  if (!this._fontCheckers.has(font.families.join(', '))) {
@@ -55390,11 +55676,18 @@
55390
55676
  }
55391
55677
  }
55392
55678
  destroy() {
55393
- this.rootContainer.element.innerHTML = '';
55679
+ const element = this.rootContainer.element;
55680
+ element.innerHTML = '';
55394
55681
  const webFont = this._webFont;
55395
- webFont.usages--;
55396
- if (webFont.usages <= 0) {
55397
- webFont.element.remove();
55682
+ const styleElement = webFont.elements.get(element.ownerDocument);
55683
+ if (styleElement) {
55684
+ styleElement.usages--;
55685
+ if (styleElement.usages <= 0) {
55686
+ styleElement.element.remove();
55687
+ webFont.elements.delete(element.ownerDocument);
55688
+ }
55689
+ }
55690
+ if (webFont.elements.size === 0) {
55398
55691
  BrowserUiFacade._registeredWebFonts.delete(webFont.hash);
55399
55692
  }
55400
55693
  }
@@ -55526,8 +55819,8 @@
55526
55819
  const registeredWebFonts = BrowserUiFacade._registeredWebFonts;
55527
55820
  if (registeredWebFonts.has(hash)) {
55528
55821
  const webFont = registeredWebFonts.get(hash);
55529
- webFont.usages++;
55530
55822
  webFont.checker.fontLoaded.on(this._onFontLoaded.bind(this));
55823
+ this._createStyleElement(webFont, root);
55531
55824
  this._webFont = webFont;
55532
55825
  return;
55533
55826
  }
@@ -55558,10 +55851,6 @@
55558
55851
  font-size: ${settings.display.resources.engravingSettings.musicFontSize}px;
55559
55852
  overflow: visible !important;
55560
55853
  }`;
55561
- const styleElement = root.createElement('style');
55562
- styleElement.id = `alphaTabStyle${fontSuffix}`;
55563
- styleElement.innerHTML = css;
55564
- root.getElementsByTagName('head').item(0).appendChild(styleElement);
55565
55854
  const checker = new FontLoadingChecker([familyName]);
55566
55855
  checker.fontLoaded.on(this._onFontLoaded.bind(this));
55567
55856
  this._fontCheckers.set(familyName, checker);
@@ -55569,14 +55858,29 @@
55569
55858
  settings.display.resources.smuflFontFamilyName = familyName;
55570
55859
  const webFont = {
55571
55860
  hash,
55572
- element: styleElement,
55861
+ elements: new Map(),
55573
55862
  fontSuffix,
55574
- usages: 1,
55575
- checker
55863
+ checker,
55864
+ cssSource: css
55576
55865
  };
55866
+ this._createStyleElement(webFont, root);
55577
55867
  registeredWebFonts.set(hash, webFont);
55578
55868
  this._webFont = webFont;
55579
55869
  }
55870
+ _createStyleElement(webFont, root) {
55871
+ if (webFont.elements.has(root)) {
55872
+ webFont.elements.get(root).usages++;
55873
+ return;
55874
+ }
55875
+ const styleElement = root.createElement('style');
55876
+ styleElement.id = `alphaTabStyle${webFont.fontSuffix}`;
55877
+ styleElement.innerHTML = webFont.cssSource;
55878
+ root.getElementsByTagName('head').item(0).appendChild(styleElement);
55879
+ webFont.elements.set(root, {
55880
+ element: styleElement,
55881
+ usages: 1
55882
+ });
55883
+ }
55580
55884
  static _cssFormat(format) {
55581
55885
  switch (format) {
55582
55886
  case exports.FontFileFormat.EmbeddedOpenType:
@@ -57198,7 +57502,9 @@
57198
57502
  }
57199
57503
  doLayout() {
57200
57504
  super.doLayout();
57201
- this.height = this.renderer.resources.wordsFont.size + this.renderer.smuflMetrics.alternateEndingsPadding * 2;
57505
+ this.height =
57506
+ this.renderer.resources.elementFonts.get(exports.NotationElement.EffectAlternateEndings).size +
57507
+ this.renderer.smuflMetrics.alternateEndingsPadding * 2;
57202
57508
  let endingsStrings = '';
57203
57509
  for (let i = 0, j = this._endings.length; i < j; i++) {
57204
57510
  endingsStrings += this._endings[i] + 1;
@@ -57234,7 +57540,7 @@
57234
57540
  const baseline = canvas.textBaseline;
57235
57541
  canvas.textBaseline = TextBaseline.Top;
57236
57542
  const res = this.renderer.resources;
57237
- canvas.font = res.wordsFont;
57543
+ canvas.font = res.elementFonts.get(exports.NotationElement.EffectAlternateEndings);
57238
57544
  canvas.fillText(this._endingsString, cx + this.x + this.renderer.smuflMetrics.alternateEndingsPadding, cy + this.y + this.renderer.smuflMetrics.alternateEndingsPadding);
57239
57545
  canvas.textBaseline = baseline;
57240
57546
  }
@@ -57376,10 +57682,12 @@
57376
57682
  _label;
57377
57683
  _dashed;
57378
57684
  _labelWidth = 0;
57379
- constructor(label, dashed = true) {
57685
+ _fontElement;
57686
+ constructor(label, fontElement, dashed = true) {
57380
57687
  super(BeatXPosition.OnNotes);
57381
57688
  this._label = label;
57382
57689
  this._dashed = dashed;
57690
+ this._fontElement = fontElement;
57383
57691
  }
57384
57692
  doLayout() {
57385
57693
  if (this.renderer.settings.notation.extendLineEffectsToBeatEnd) {
@@ -57387,14 +57695,14 @@
57387
57695
  this.forceGroupedRendering = true;
57388
57696
  }
57389
57697
  super.doLayout();
57390
- this.renderer.scoreRenderer.canvas.font = this.renderer.resources.effectFont;
57698
+ this.renderer.scoreRenderer.canvas.font = this.renderer.resources.elementFonts.get(this._fontElement);
57391
57699
  const size = this.renderer.scoreRenderer.canvas.measureText(this._label);
57392
57700
  this.height = size.height;
57393
57701
  this._labelWidth = size.width;
57394
57702
  }
57395
57703
  paintNonGrouped(cx, cy, canvas) {
57396
57704
  const res = this.renderer.resources;
57397
- canvas.font = res.effectFont;
57705
+ canvas.font = res.elementFonts.get(this._fontElement);
57398
57706
  const b = canvas.textBaseline;
57399
57707
  canvas.textBaseline = TextBaseline.Middle;
57400
57708
  canvas.fillText(this._label, cx + this.x - this._labelWidth / 2, cy + this.y + this.height / 2);
@@ -57455,7 +57763,7 @@
57455
57763
  break;
57456
57764
  }
57457
57765
  barre += `B ${BeatBarreEffectInfo.toRoman(beat.barreFret)}`;
57458
- return new LineRangedGlyph(barre, false);
57766
+ return new LineRangedGlyph(barre, exports.NotationElement.EffectBeatBarre, false);
57459
57767
  }
57460
57768
  static _romanLetters = new Map([
57461
57769
  // ['M', 1000],
@@ -57505,7 +57813,7 @@
57505
57813
  const seconds = ((this._timer - minutes * 60000) / 1000) | 0;
57506
57814
  this._text = `${minutes}:${seconds.toString().padStart(2, '0')}`;
57507
57815
  const c = this.renderer.scoreRenderer.canvas;
57508
- c.font = this.renderer.resources.timerFont;
57816
+ c.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectBeatTimer);
57509
57817
  const size = c.measureText(this._text);
57510
57818
  this._textHeight = c.font.size + this.renderer.smuflMetrics.beatTimerPadding * 2;
57511
57819
  this._textWidth = size.width + this.renderer.smuflMetrics.beatTimerPadding * 2;
@@ -57517,7 +57825,7 @@
57517
57825
  const f = canvas.font;
57518
57826
  const b = canvas.textBaseline;
57519
57827
  const a = canvas.textAlign;
57520
- canvas.font = this.renderer.resources.timerFont;
57828
+ canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectBeatTimer);
57521
57829
  canvas.textBaseline = TextBaseline.Middle;
57522
57830
  canvas.textAlign = TextAlign.Center;
57523
57831
  canvas.fillText(this._text, cx + this.x, cy + this.y + this.height / 2);
@@ -57626,7 +57934,7 @@
57626
57934
  return beat.index === 0 && beat.voice.bar.index === 0 && beat.voice.bar.staff.capo !== 0;
57627
57935
  }
57628
57936
  createNewGlyph(renderer, beat) {
57629
- return new TextGlyph(0, 0, `Capo. fret ${beat.voice.bar.staff.capo}`, renderer.resources.effectFont, TextAlign.Left);
57937
+ return new TextGlyph(0, 0, `Capo. fret ${beat.voice.bar.staff.capo}`, renderer.resources.elementFonts.get(exports.NotationElement.EffectCapo), TextAlign.Left);
57630
57938
  }
57631
57939
  canExpand(_from, _to) {
57632
57940
  return false;
@@ -57643,31 +57951,41 @@
57643
57951
  _fretRow = 0;
57644
57952
  _firstFretSpacing = 0;
57645
57953
  _center;
57646
- constructor(x, y, chord, center = false) {
57954
+ _fontElement;
57955
+ constructor(x, y, chord, fontElement, center = false) {
57647
57956
  super(x, y);
57648
57957
  this._chord = chord;
57649
57958
  this._center = center;
57959
+ this._fontElement = fontElement;
57650
57960
  }
57651
57961
  doLayout() {
57652
57962
  super.doLayout();
57653
57963
  const res = this.renderer.resources;
57654
- this._textRow = res.effectFont.size * 1.5;
57655
- this._fretRow = res.effectFont.size * 1.5;
57656
- if (this._chord.firstFret > 1) {
57657
- this._firstFretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
57658
- }
57659
- else {
57660
- this._firstFretSpacing = 0;
57661
- }
57662
- this.height =
57663
- this._textRow +
57964
+ const font = res.elementFonts.get(this._fontElement);
57965
+ this._textRow = font.size * 1.5;
57966
+ this._fretRow = font.size * 1.5;
57967
+ this.height = this._textRow;
57968
+ this.width = 2 * this.renderer.smuflMetrics.chordDiagramPaddingX;
57969
+ if (this.renderer.settings.notation.isNotationElementVisible(exports.NotationElement.ChordDiagramFretboardNumbers)) {
57970
+ if (this._chord.firstFret > 1) {
57971
+ this._firstFretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
57972
+ }
57973
+ else {
57974
+ this._firstFretSpacing = 0;
57975
+ }
57976
+ this.height +=
57664
57977
  this._fretRow +
57665
- ChordDiagramGlyph._frets * this.renderer.smuflMetrics.chordDiagramFretSpacing +
57666
- 2 * this.renderer.smuflMetrics.chordDiagramPaddingY;
57667
- this.width =
57668
- this._firstFretSpacing +
57669
- (this._chord.strings.length - 1) * this.renderer.smuflMetrics.chordDiagramStringSpacing +
57670
- 2 * this.renderer.smuflMetrics.chordDiagramPaddingX;
57978
+ ChordDiagramGlyph._frets * this.renderer.smuflMetrics.chordDiagramFretSpacing +
57979
+ 2 * this.renderer.smuflMetrics.chordDiagramPaddingY;
57980
+ this.width +=
57981
+ this._firstFretSpacing +
57982
+ (this._chord.strings.length - 1) * this.renderer.smuflMetrics.chordDiagramStringSpacing;
57983
+ }
57984
+ else if (this._chord.showName) {
57985
+ const canvas = this.renderer.scoreRenderer.canvas;
57986
+ canvas.font = font;
57987
+ this.width += canvas.measureText(this._chord.name).width;
57988
+ }
57671
57989
  }
57672
57990
  paint(cx, cy, canvas) {
57673
57991
  cx += this.x + this.renderer.smuflMetrics.chordDiagramPaddingX + this._firstFretSpacing;
@@ -57675,25 +57993,35 @@
57675
57993
  if (this._center) {
57676
57994
  cx -= this.width / 2;
57677
57995
  }
57678
- const stringSpacing = this.renderer.smuflMetrics.chordDiagramStringSpacing;
57679
- const fretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
57680
57996
  const res = this.renderer.resources;
57681
57997
  const lineWidth = res.engravingSettings.chordDiagramLineWidth;
57682
57998
  const w = this.width - 2 * this.renderer.smuflMetrics.chordDiagramPaddingX - this._firstFretSpacing + lineWidth;
57683
- const circleHeight = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardFilledCircle);
57684
- const circleTopOffset = res.engravingSettings.glyphTop.get(MusicFontSymbol.FretboardFilledCircle);
57685
- const xTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardX) / 2;
57686
- const oTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardO) / 2;
57687
57999
  const align = canvas.textAlign;
57688
58000
  const baseline = canvas.textBaseline;
57689
- canvas.font = res.effectFont;
58001
+ const font = res.elementFonts.get(this._fontElement);
58002
+ canvas.font = font;
57690
58003
  canvas.textAlign = TextAlign.Center;
57691
58004
  canvas.textBaseline = TextBaseline.Top;
57692
58005
  if (this._chord.showName) {
57693
- canvas.fillText(this._chord.name, cx + w / 2, cy + res.effectFont.size / 2);
58006
+ canvas.fillText(this._chord.name, cx + w / 2, cy + font.size / 2);
58007
+ }
58008
+ if (this.renderer.settings.notation.isNotationElementVisible(exports.NotationElement.ChordDiagramFretboardNumbers)) {
58009
+ this._paintFretboard(cx, cy, canvas, w);
57694
58010
  }
58011
+ canvas.textAlign = align;
58012
+ canvas.textBaseline = baseline;
58013
+ }
58014
+ _paintFretboard(cx, cy, canvas, w) {
57695
58015
  cy += this._textRow;
57696
- canvas.font = res.fretboardNumberFont;
58016
+ const res = this.renderer.resources;
58017
+ const stringSpacing = this.renderer.smuflMetrics.chordDiagramStringSpacing;
58018
+ const fretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
58019
+ const circleHeight = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardFilledCircle);
58020
+ const circleTopOffset = res.engravingSettings.glyphTop.get(MusicFontSymbol.FretboardFilledCircle);
58021
+ const xTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardX) / 2;
58022
+ const oTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardO) / 2;
58023
+ const lineWidth = res.engravingSettings.chordDiagramLineWidth;
58024
+ canvas.font = res.elementFonts.get(exports.NotationElement.ChordDiagramFretboardNumbers);
57697
58025
  canvas.textBaseline = TextBaseline.Middle;
57698
58026
  for (let i = 0; i < this._chord.strings.length; i++) {
57699
58027
  const x = cx + i * stringSpacing;
@@ -57756,8 +58084,6 @@
57756
58084
  const xRight = cx + (this._chord.strings.length - strings[0] - 1) * stringSpacing;
57757
58085
  canvas.fillRect(xLeft, y - circleHeight / 2, xRight - xLeft, circleHeight);
57758
58086
  }
57759
- canvas.textAlign = align;
57760
- canvas.textBaseline = baseline;
57761
58087
  }
57762
58088
  }
57763
58089
 
@@ -57783,8 +58109,8 @@
57783
58109
  createNewGlyph(renderer, beat) {
57784
58110
  const showDiagram = beat.voice.bar.staff.track.score.stylesheet.globalDisplayChordDiagramsInScore;
57785
58111
  return showDiagram
57786
- ? new ChordDiagramGlyph(0, 0, beat.chord, true)
57787
- : new TextGlyph(0, 0, beat.chord.name, renderer.resources.effectFont, TextAlign.Center);
58112
+ ? new ChordDiagramGlyph(0, 0, beat.chord, exports.NotationElement.EffectChordNames, true)
58113
+ : new TextGlyph(0, 0, beat.chord.name, renderer.resources.elementFonts.get(exports.NotationElement.EffectChordNames), TextAlign.Center);
57788
58114
  }
57789
58115
  canExpand(_from, _to) {
57790
58116
  return false;
@@ -57895,14 +58221,14 @@
57895
58221
  }
57896
58222
  doLayout() {
57897
58223
  const c = this.renderer.scoreRenderer.canvas;
57898
- c.font = this.renderer.resources.directionsFont;
58224
+ c.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectDirections);
57899
58225
  this.height = c.measureText(this._text).height;
57900
58226
  }
57901
58227
  paint(cx, cy, canvas) {
57902
58228
  const font = canvas.font;
57903
58229
  const baseline = canvas.textBaseline;
57904
58230
  const align = canvas.textAlign;
57905
- canvas.font = this.renderer.resources.directionsFont;
58231
+ canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectDirections);
57906
58232
  canvas.textBaseline = TextBaseline.Middle;
57907
58233
  canvas.textAlign = TextAlign.Right;
57908
58234
  canvas.fillText(this._text, cx + this.x, cy + this.y + this.height / 2);
@@ -58798,7 +59124,7 @@
58798
59124
  (masterBar.index === 0 || masterBar.isFreeTime !== masterBar.previousMasterBar.isFreeTime));
58799
59125
  }
58800
59126
  createNewGlyph(renderer, _beat) {
58801
- return new TextGlyph(0, 0, 'Free time', renderer.resources.effectFont, TextAlign.Left);
59127
+ return new TextGlyph(0, 0, 'Free time', renderer.resources.elementFonts.get(exports.NotationElement.EffectFreeTime), TextAlign.Left);
58802
59128
  }
58803
59129
  canExpand(_from, _to) {
58804
59130
  return true;
@@ -58936,7 +59262,7 @@
58936
59262
  return EffectBarGlyphSizing.GroupedOnBeat;
58937
59263
  }
58938
59264
  createNewGlyph(_renderer, _beat) {
58939
- return new LineRangedGlyph(HarmonicsEffectInfo.harmonicToString(this._harmonicType));
59265
+ return new LineRangedGlyph(HarmonicsEffectInfo.harmonicToString(this._harmonicType), exports.NotationElement.EffectHarmonics);
58940
59266
  }
58941
59267
  static harmonicToString(type) {
58942
59268
  switch (type) {
@@ -59009,7 +59335,7 @@
59009
59335
  return EffectBarGlyphSizing.GroupedOnBeat;
59010
59336
  }
59011
59337
  createNewGlyph(_renderer, _beat) {
59012
- return new LineRangedGlyph('LetRing');
59338
+ return new LineRangedGlyph('LetRing', exports.NotationElement.EffectLetRing);
59013
59339
  }
59014
59340
  canExpand(_from, _to) {
59015
59341
  return true;
@@ -59021,6 +59347,7 @@
59021
59347
  */
59022
59348
  class LyricsGlyph extends EffectGlyph {
59023
59349
  _lines;
59350
+ _linePositions = [];
59024
59351
  font;
59025
59352
  textAlign;
59026
59353
  constructor(x, y, lines, font, textAlign = TextAlign.Center) {
@@ -59031,7 +59358,17 @@
59031
59358
  }
59032
59359
  doLayout() {
59033
59360
  super.doLayout();
59034
- this.height = this.font.size * this._lines.length;
59361
+ const lineSpacing = this.renderer.settings.display.lyricLinesPaddingBetween;
59362
+ const canvas = this.renderer.scoreRenderer.canvas;
59363
+ canvas.font = this.font;
59364
+ let y = 0;
59365
+ for (const line of this._lines) {
59366
+ this._linePositions.push(y);
59367
+ const size = canvas.measureText(line.length > 0 ? line : ' ');
59368
+ y += size.height + lineSpacing;
59369
+ }
59370
+ y -= lineSpacing;
59371
+ this.height = y;
59035
59372
  }
59036
59373
  paint(cx, cy, canvas) {
59037
59374
  canvas.font = this.font;
@@ -59039,7 +59376,7 @@
59039
59376
  canvas.textAlign = this.textAlign;
59040
59377
  for (let i = 0; i < this._lines.length; i++) {
59041
59378
  if (this._lines[i]) {
59042
- canvas.fillText(this._lines[i], cx + this.x, cy + this.y + i * this.font.size);
59379
+ canvas.fillText(this._lines[i], cx + this.x, cy + this.y + this._linePositions[i]);
59043
59380
  }
59044
59381
  }
59045
59382
  canvas.textAlign = old;
@@ -59066,7 +59403,7 @@
59066
59403
  return !!beat.lyrics;
59067
59404
  }
59068
59405
  createNewGlyph(renderer, beat) {
59069
- return new LyricsGlyph(0, 0, beat.lyrics, renderer.resources.effectFont, TextAlign.Center);
59406
+ return new LyricsGlyph(0, 0, beat.lyrics, renderer.resources.elementFonts.get(exports.NotationElement.EffectLyrics), TextAlign.Center);
59070
59407
  }
59071
59408
  canExpand(_from, _to) {
59072
59409
  return true;
@@ -59098,7 +59435,7 @@
59098
59435
  createNewGlyph(renderer, beat) {
59099
59436
  return new TextGlyph(0, 0, !beat.voice.bar.masterBar.section.marker
59100
59437
  ? beat.voice.bar.masterBar.section.text
59101
- : `[${beat.voice.bar.masterBar.section.marker}] ${beat.voice.bar.masterBar.section.text}`, renderer.resources.markerFont, TextAlign.Left);
59438
+ : `[${beat.voice.bar.masterBar.section.marker}] ${beat.voice.bar.masterBar.section.text}`, renderer.resources.elementFonts.get(exports.NotationElement.EffectMarker), TextAlign.Left);
59102
59439
  }
59103
59440
  canExpand(_from, _to) {
59104
59441
  return true;
@@ -59537,7 +59874,7 @@
59537
59874
  return EffectBarGlyphSizing.GroupedOnBeat;
59538
59875
  }
59539
59876
  createNewGlyph(_renderer, _beat) {
59540
- return new LineRangedGlyph('P.M.');
59877
+ return new LineRangedGlyph('P.M.', exports.NotationElement.EffectPalmMute);
59541
59878
  }
59542
59879
  }
59543
59880
 
@@ -59555,7 +59892,7 @@
59555
59892
  return EffectBarGlyphSizing.GroupedOnBeat;
59556
59893
  }
59557
59894
  createNewGlyph(_renderer, _beat) {
59558
- return new LineRangedGlyph('P.S.');
59895
+ return new LineRangedGlyph('P.S.', exports.NotationElement.EffectPickSlide);
59559
59896
  }
59560
59897
  }
59561
59898
 
@@ -59630,7 +59967,7 @@
59630
59967
  return EffectBarGlyphSizing.GroupedOnBeat;
59631
59968
  }
59632
59969
  createNewGlyph(_renderer, _beat) {
59633
- return new LineRangedGlyph('rasg.');
59970
+ return new LineRangedGlyph('rasg.', exports.NotationElement.EffectRasgueado);
59634
59971
  }
59635
59972
  canExpand(_from, _to) {
59636
59973
  return true;
@@ -63238,12 +63575,12 @@
63238
63575
  createNewGlyph(renderer, beat) {
63239
63576
  const res = renderer.resources;
63240
63577
  if (beat.slap) {
63241
- return new TextGlyph(0, 0, 'S', res.effectFont, TextAlign.Center);
63578
+ return new TextGlyph(0, 0, 'S', res.elementFonts.get(exports.NotationElement.EffectTap), TextAlign.Center);
63242
63579
  }
63243
63580
  if (beat.pop) {
63244
- return new TextGlyph(0, 0, 'P', res.effectFont, TextAlign.Center);
63581
+ return new TextGlyph(0, 0, 'P', res.elementFonts.get(exports.NotationElement.EffectTap), TextAlign.Center);
63245
63582
  }
63246
- return new TextGlyph(0, 0, 'T', res.effectFont, TextAlign.Center);
63583
+ return new TextGlyph(0, 0, 'T', res.elementFonts.get(exports.NotationElement.EffectTap), TextAlign.Center);
63247
63584
  }
63248
63585
  canExpand(_from, _to) {
63249
63586
  return true;
@@ -63272,7 +63609,7 @@
63272
63609
  for (const automation of this._tempoAutomations) {
63273
63610
  let x = cx + this.renderer.getRatioPositionX(automation.ratioPosition);
63274
63611
  const res = this.renderer.resources;
63275
- canvas.font = res.markerFont;
63612
+ canvas.font = res.elementFonts.get(exports.NotationElement.EffectMarker);
63276
63613
  const notePosY = cy +
63277
63614
  this.y +
63278
63615
  this.height +
@@ -63350,7 +63687,7 @@
63350
63687
  return !!beat.text;
63351
63688
  }
63352
63689
  createNewGlyph(renderer, beat) {
63353
- return new TextGlyph(0, 0, beat.text, renderer.resources.effectFont, TextAlign.Left);
63690
+ return new TextGlyph(0, 0, beat.text, renderer.resources.elementFonts.get(exports.NotationElement.EffectText), TextAlign.Left);
63354
63691
  }
63355
63692
  canExpand(_from, _to) {
63356
63693
  return true;
@@ -63475,7 +63812,7 @@
63475
63812
  const textY = cy + this.height;
63476
63813
  const b = canvas.textBaseline;
63477
63814
  canvas.textBaseline = TextBaseline.Bottom;
63478
- canvas.font = this.renderer.resources.effectFont;
63815
+ canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectTripletFeel);
63479
63816
  canvas.fillText('(', cx, textY);
63480
63817
  cx += canvas.measureText('( ').width;
63481
63818
  cx = this._drawGroup(cx, noteY + this._tupletHeight, canvas, leftNotes);
@@ -63717,7 +64054,7 @@
63717
64054
  return beat.hasWhammyBar;
63718
64055
  }
63719
64056
  createNewGlyph(_renderer, _beat) {
63720
- return new LineRangedGlyph('w/bar');
64057
+ return new LineRangedGlyph('w/bar', exports.NotationElement.EffectWhammyBar);
63721
64058
  }
63722
64059
  canExpand(_from, _to) {
63723
64060
  return true;
@@ -63869,7 +64206,7 @@
63869
64206
  class ChordDiagramContainerGlyph extends RowContainerGlyph {
63870
64207
  addChord(chord) {
63871
64208
  if (chord.strings.length > 0) {
63872
- const chordDiagram = new ChordDiagramGlyph(0, 0, chord);
64209
+ const chordDiagram = new ChordDiagramGlyph(0, 0, chord, exports.NotationElement.ChordDiagrams);
63873
64210
  chordDiagram.renderer = this.renderer;
63874
64211
  chordDiagram.doLayout();
63875
64212
  this.glyphs.push(chordDiagram);
@@ -63933,7 +64270,7 @@
63933
64270
  this.height = 0;
63934
64271
  // Track name
63935
64272
  if (this._trackLabel.length > 0) {
63936
- const trackName = new TextGlyph(0, this.height, this._trackLabel, res.effectFont, TextAlign.Left);
64273
+ const trackName = new TextGlyph(0, this.height, this._trackLabel, res.elementFonts.get(exports.NotationElement.GuitarTuning), TextAlign.Left);
63937
64274
  trackName.renderer = this.renderer;
63938
64275
  trackName.doLayout();
63939
64276
  this.height += trackName.height;
@@ -63941,7 +64278,7 @@
63941
64278
  }
63942
64279
  // Name
63943
64280
  if (tuning.name.length > 0) {
63944
- const tuningName = new TextGlyph(0, this.height, tuning.name, res.effectFont, TextAlign.Left);
64281
+ const tuningName = new TextGlyph(0, this.height, tuning.name, res.elementFonts.get(exports.NotationElement.GuitarTuning), TextAlign.Left);
63945
64282
  tuningName.renderer = this.renderer;
63946
64283
  tuningName.doLayout();
63947
64284
  this.height += tuningName.height;
@@ -63949,7 +64286,7 @@
63949
64286
  }
63950
64287
  const circleScale = this.renderer.smuflMetrics.tuningGlyphCircleNumberScale;
63951
64288
  const circleHeight = this.renderer.smuflMetrics.glyphHeights.get(MusicFontSymbol.GuitarString0) * circleScale;
63952
- this.renderer.scoreRenderer.canvas.font = res.effectFont;
64289
+ this.renderer.scoreRenderer.canvas.font = res.elementFonts.get(exports.NotationElement.GuitarTuning);
63953
64290
  const stringColumnWidth = (circleHeight + this.renderer.scoreRenderer.canvas.measureText(' = Gb').width) *
63954
64291
  res.engravingSettings.tuningGlyphStringColumnScale;
63955
64292
  this.width = Math.max(this.renderer.scoreRenderer.canvas.measureText(this._trackLabel).width, Math.max(this.renderer.scoreRenderer.canvas.measureText(tuning.name).width, 2 * stringColumnWidth));
@@ -63963,7 +64300,7 @@
63963
64300
  const symbol = (MusicFontSymbol.GuitarString0 + (i + 1));
63964
64301
  this.addGlyph(new MusicFontGlyph(currentX, currentY + circleHeight, circleScale, symbol));
63965
64302
  const str = ` = ${Tuning.getTextForTuning(tuning.tunings[i], false)}`;
63966
- this.addGlyph(new TextGlyph(currentX + circleHeight, currentY + circleHeight / 2, str, res.effectFont, TextAlign.Left, TextBaseline.Middle));
64303
+ this.addGlyph(new TextGlyph(currentX + circleHeight, currentY + circleHeight / 2, str, res.elementFonts.get(exports.NotationElement.GuitarTuning), TextAlign.Left, TextBaseline.Middle));
63967
64304
  currentY += circleHeight + this.renderer.smuflMetrics.tuningGlyphStringRowPadding;
63968
64305
  const bottomY = currentY;
63969
64306
  if (this.height < bottomY) {
@@ -65015,7 +65352,7 @@
65015
65352
  let hasAnyTrackName = false;
65016
65353
  if (shouldRender) {
65017
65354
  const canvas = this.layout.renderer.canvas;
65018
- const res = settings.display.resources.effectFont;
65355
+ const res = settings.display.resources.elementFonts.get(exports.NotationElement.TrackNames);
65019
65356
  canvas.font = res;
65020
65357
  for (const t of tracks) {
65021
65358
  let trackNameText = '';
@@ -65169,7 +65506,7 @@
65169
65506
  // Draw track names
65170
65507
  const settings = this.layout.renderer.settings;
65171
65508
  const hasTrackName = this.layout.renderer.settings.notation.isNotationElementVisible(exports.NotationElement.TrackNames);
65172
- canvas.font = res.effectFont;
65509
+ canvas.font = res.elementFonts.get(exports.NotationElement.TrackNames);
65173
65510
  if (hasTrackName) {
65174
65511
  const stylesheet = this.layout.renderer.score.stylesheet;
65175
65512
  const trackNamePolicy = this.layout.renderer.tracks.length === 1
@@ -65859,7 +66196,10 @@
65859
66196
  const msg = 'rendered by alphaTab';
65860
66197
  const resources = this.renderer.settings.display.resources;
65861
66198
  const size = 12;
65862
- const font = Font.withFamilyList(resources.copyrightFont.families, size, FontStyle.Plain, FontWeight.Bold);
66199
+ const fontFamilies = resources.elementFonts.has(exports.NotationElement.ScoreCopyright)
66200
+ ? resources.elementFonts.get(exports.NotationElement.ScoreCopyright).families
66201
+ : resources.tablatureFont.families;
66202
+ const font = Font.withFamilyList(fontFamilies, size, FontStyle.Plain, FontWeight.Bold);
65863
66203
  const fakeBarRenderer = new BarRendererBase(this.renderer, this.renderer.tracks[0].staves[0].bars[0]);
65864
66204
  const glyph = new TextGlyph(0, 0, msg, font, TextAlign.Center, undefined, resources.mainGlyphColor);
65865
66205
  glyph.renderer = fakeBarRenderer;
@@ -66772,13 +67112,7 @@
66772
67112
  this._number = `${num} `;
66773
67113
  }
66774
67114
  doLayout() {
66775
- // TODO: activate this and update paddings accordingly.
66776
- // if (!this.renderer.staff!.isFirstInSystem) {
66777
- // this.width = 0;
66778
- // this.height = 0;
66779
- // return;
66780
- // }
66781
- this.renderer.scoreRenderer.canvas.font = this.renderer.resources.barNumberFont;
67115
+ this.renderer.scoreRenderer.canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.BarNumber);
66782
67116
  const size = this.renderer.scoreRenderer.canvas.measureText(this._number);
66783
67117
  this.width = size.width;
66784
67118
  this.height = size.height;
@@ -66792,7 +67126,7 @@
66792
67126
  try {
66793
67127
  const res = this.renderer.resources;
66794
67128
  const baseline = canvas.textBaseline;
66795
- canvas.font = res.barNumberFont;
67129
+ canvas.font = res.elementFonts.get(exports.NotationElement.BarNumber);
66796
67130
  canvas.textBaseline = TextBaseline.Top;
66797
67131
  canvas.fillText(this._number, cx + this.x, cy + this.y);
66798
67132
  canvas.textBaseline = baseline;
@@ -67891,7 +68225,7 @@
67891
68225
  this._count = count;
67892
68226
  }
67893
68227
  doLayout() {
67894
- this.renderer.scoreRenderer.canvas.font = this.renderer.resources.barNumberFont;
68228
+ this.renderer.scoreRenderer.canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.RepeatCount);
67895
68229
  const size = this.renderer.scoreRenderer.canvas.measureText(`x${this._count}`);
67896
68230
  this.width = 0; // do not account width
67897
68231
  this.height = size.height;
@@ -67902,7 +68236,7 @@
67902
68236
  try {
67903
68237
  const res = this.renderer.resources;
67904
68238
  const oldAlign = canvas.textAlign;
67905
- canvas.font = res.barNumberFont;
68239
+ canvas.font = res.elementFonts.get(exports.NotationElement.RepeatCount);
67906
68240
  canvas.textAlign = TextAlign.Right;
67907
68241
  const s = `x${this._count}`;
67908
68242
  const w = canvas.measureText(s).width / 1.5;
@@ -68027,11 +68361,12 @@
68027
68361
  }
68028
68362
  createStartSpacing() {
68029
68363
  if (this._startSpacing) {
68030
- return;
68364
+ return false;
68031
68365
  }
68032
68366
  const padding = this.index === 0 ? this.settings.display.firstStaffPaddingLeft : this.settings.display.staffPaddingLeft;
68033
68367
  this.addPreBeatGlyph(new SpacingGlyph(0, 0, padding));
68034
68368
  this._startSpacing = true;
68369
+ return true;
68035
68370
  }
68036
68371
  paintTuplets(cx, cy, canvas, beatElement, bracketsAsArcs = false) {
68037
68372
  for (const v of this.voiceContainer.voiceDrawOrder) {
@@ -68373,16 +68708,45 @@
68373
68708
  super.createPreBeatGlyphs();
68374
68709
  this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
68375
68710
  this.createLinePreBeatGlyphs();
68711
+ let hasSpaceAfterStartGlyphs = false;
68376
68712
  if (this.index === 0) {
68377
- this.createStartSpacing();
68713
+ hasSpaceAfterStartGlyphs = this.createStartSpacing();
68714
+ }
68715
+ if (this.shouldCreateBarNumber()) {
68716
+ this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-0.5), this.bar.index + 1));
68378
68717
  }
68379
- this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-0.5), this.bar.index + 1));
68718
+ else if (!hasSpaceAfterStartGlyphs) {
68719
+ this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
68720
+ }
68721
+ }
68722
+ shouldCreateBarNumber() {
68723
+ let display = BarNumberDisplay.AllBars;
68724
+ if (!this.settings.notation.isNotationElementVisible(exports.NotationElement.BarNumber)) {
68725
+ display = BarNumberDisplay.Hide;
68726
+ }
68727
+ else if (this.bar.barNumberDisplay !== undefined) {
68728
+ display = this.bar.barNumberDisplay;
68729
+ }
68730
+ else {
68731
+ display = this.bar.staff.track.score.stylesheet.barNumberDisplay;
68732
+ }
68733
+ switch (display) {
68734
+ case BarNumberDisplay.AllBars:
68735
+ return true;
68736
+ case BarNumberDisplay.FirstOfSystem:
68737
+ return this.isFirstOfStaff;
68738
+ case BarNumberDisplay.Hide:
68739
+ return false;
68740
+ }
68741
+ return true;
68380
68742
  }
68381
68743
  createPostBeatGlyphs() {
68382
68744
  super.createPostBeatGlyphs();
68383
68745
  const lastBar = this.lastBar;
68384
68746
  this.addPostBeatGlyph(new BarLineGlyph(true, this.bar.staff.track.score.stylesheet.extendBarLines));
68385
- if (lastBar.masterBar.isRepeatEnd && lastBar.masterBar.repeatCount > 2) {
68747
+ if (lastBar.masterBar.isRepeatEnd &&
68748
+ lastBar.masterBar.repeatCount > 2 &&
68749
+ this.settings.notation.isNotationElementVisible(exports.NotationElement.RepeatCount)) {
68386
68750
  this.addPostBeatGlyph(new RepeatCountGlyph(0, this.getLineHeight(-0.5), this.bar.masterBar.repeatCount));
68387
68751
  }
68388
68752
  }
@@ -68946,8 +69310,13 @@
68946
69310
  this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
68947
69311
  }
68948
69312
  this.createLinePreBeatGlyphs();
68949
- this.createStartSpacing();
68950
- this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-0.5), this.bar.index + 1));
69313
+ const hasSpaceAfterStartGlyphs = this.createStartSpacing();
69314
+ if (this.shouldCreateBarNumber()) {
69315
+ this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-0.5), this.bar.index + 1));
69316
+ }
69317
+ else if (!hasSpaceAfterStartGlyphs) {
69318
+ this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
69319
+ }
68951
69320
  }
68952
69321
  createLinePreBeatGlyphs() {
68953
69322
  if (this._isOnlyNumbered &&
@@ -71495,7 +71864,7 @@
71495
71864
  if (note.bendStyle === BendStyle.Gradual) {
71496
71865
  const res = this.renderer.resources;
71497
71866
  const c = this.renderer.scoreRenderer.canvas;
71498
- c.font = res.barNumberFont; // see note in paint()
71867
+ c.font = res.elementFonts.get(exports.NotationElement.ScoreBendSlur);
71499
71868
  slurHeight += c.measureText('grad.').height;
71500
71869
  }
71501
71870
  if (slurHeight > maxSlurHeight) {
@@ -71595,11 +71964,16 @@
71595
71964
  this._notes.sort((a, b) => {
71596
71965
  return b.displayValue - a.displayValue;
71597
71966
  });
71967
+ // draw slurs
71968
+ if (this.renderer.settings.notation.isNotationElementVisible(exports.NotationElement.ScoreBendSlur)) {
71969
+ this._paintSlurs(cx, cy, canvas, startNoteRenderer, startX, middleX, endBeatX);
71970
+ }
71971
+ }
71972
+ _paintSlurs(cx, cy, canvas, startNoteRenderer, startX, middleX, endBeatX) {
71598
71973
  const directionBeat = this._beat.graceType === GraceType.BendGrace ? this._beat.nextBeat : this._beat;
71599
71974
  let direction = this._notes.length === 1 ? this.getTieDirection(directionBeat, startNoteRenderer) : BeamDirection.Up;
71600
71975
  const noteHeadHeight = this.renderer.smuflMetrics.glyphHeights.get(MusicFontSymbol.NoteheadBlack);
71601
- // draw slurs
71602
- canvas.font = this.renderer.resources.barNumberFont; // we have never have set it explicitly, that's the current state
71976
+ canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.ScoreBendSlur);
71603
71977
  for (let i = 0; i < this._notes.length; i++) {
71604
71978
  const note = this._notes[i];
71605
71979
  const _ = ElementStyleHelper.note(canvas, NoteSubElement.StandardNotationEffects, note);
@@ -79728,6 +80102,7 @@
79728
80102
  BackingTrack,
79729
80103
  Bar,
79730
80104
  get BarLineStyle () { return BarLineStyle; },
80105
+ get BarNumberDisplay () { return BarNumberDisplay; },
79731
80106
  BarStyle,
79732
80107
  get BarSubElement () { return BarSubElement; },
79733
80108
  get BarreShape () { return BarreShape; },