@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.
package/dist/alphaTab.js CHANGED
@@ -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
  *
@@ -209,9 +209,9 @@
209
209
  * @internal
210
210
  */
211
211
  class VersionInfo {
212
- static version = '1.8.0-alpha.1669';
213
- static date = '2026-01-08T02:24:31.439Z';
214
- static commit = 'f7c00b0b8db32011293f475bf5e930d21c1903ac';
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
+ }
25551
25697
  }
25552
- else if (element.getAttribute('new-page', 'no') === 'yes') {
25553
- track.addLineBreaks(masterBar.index);
25698
+ if (isMeasurePrint) {
25699
+ this._currentBarNumberDisplayBar = newDisplay;
25700
+ }
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}
42171
+ */
42172
+ get copyrightFont() {
42173
+ return this.elementFonts.get(exports.NotationElement.ScoreCopyright);
42174
+ }
42175
+ /**
42176
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreCopyright}
42006
42177
  */
42007
- copyrightFont = new Font(RenderingResources._sansFont, 12, FontStyle.Plain, FontWeight.Bold);
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}
42186
+ */
42187
+ get titleFont() {
42188
+ return this.elementFonts.get(exports.NotationElement.ScoreTitle);
42189
+ }
42190
+ /**
42191
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreTitle}
42012
42192
  */
42013
- titleFont = new Font(RenderingResources._serifFont, 32, FontStyle.Plain);
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}
42201
+ */
42202
+ get subTitleFont() {
42203
+ return this.elementFonts.get(exports.NotationElement.ScoreSubTitle);
42204
+ }
42205
+ /**
42206
+ * @deprecated use {@link elementFonts} with {@link NotationElement.ScoreSubTitle}
42018
42207
  */
42019
- subTitleFont = new Font(RenderingResources._serifFont, 20, FontStyle.Plain);
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}
42231
+ */
42232
+ get timerFont() {
42233
+ return this.elementFonts.get(exports.NotationElement.EffectBeatTimer);
42234
+ }
42235
+ /**
42236
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectBeatTimer}
42036
42237
  */
42037
- timerFont = new Font(RenderingResources._serifFont, 12, FontStyle.Plain);
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}
42246
+ */
42247
+ get directionsFont() {
42248
+ return this.elementFonts.get(exports.NotationElement.EffectDirections);
42249
+ }
42250
+ /**
42251
+ * @deprecated use {@link elementFonts} with {@link NotationElement.EffectDirections}
42042
42252
  */
42043
- directionsFont = new Font(RenderingResources._serifFont, 14, FontStyle.Plain);
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}
42267
+ */
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
42048
42277
  */
42049
- fretboardNumberFont = new Font(RenderingResources._sansFont, 11, FontStyle.Plain);
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(', '))) {
@@ -57216,7 +57502,9 @@
57216
57502
  }
57217
57503
  doLayout() {
57218
57504
  super.doLayout();
57219
- 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;
57220
57508
  let endingsStrings = '';
57221
57509
  for (let i = 0, j = this._endings.length; i < j; i++) {
57222
57510
  endingsStrings += this._endings[i] + 1;
@@ -57252,7 +57540,7 @@
57252
57540
  const baseline = canvas.textBaseline;
57253
57541
  canvas.textBaseline = TextBaseline.Top;
57254
57542
  const res = this.renderer.resources;
57255
- canvas.font = res.wordsFont;
57543
+ canvas.font = res.elementFonts.get(exports.NotationElement.EffectAlternateEndings);
57256
57544
  canvas.fillText(this._endingsString, cx + this.x + this.renderer.smuflMetrics.alternateEndingsPadding, cy + this.y + this.renderer.smuflMetrics.alternateEndingsPadding);
57257
57545
  canvas.textBaseline = baseline;
57258
57546
  }
@@ -57394,10 +57682,12 @@
57394
57682
  _label;
57395
57683
  _dashed;
57396
57684
  _labelWidth = 0;
57397
- constructor(label, dashed = true) {
57685
+ _fontElement;
57686
+ constructor(label, fontElement, dashed = true) {
57398
57687
  super(BeatXPosition.OnNotes);
57399
57688
  this._label = label;
57400
57689
  this._dashed = dashed;
57690
+ this._fontElement = fontElement;
57401
57691
  }
57402
57692
  doLayout() {
57403
57693
  if (this.renderer.settings.notation.extendLineEffectsToBeatEnd) {
@@ -57405,14 +57695,14 @@
57405
57695
  this.forceGroupedRendering = true;
57406
57696
  }
57407
57697
  super.doLayout();
57408
- this.renderer.scoreRenderer.canvas.font = this.renderer.resources.effectFont;
57698
+ this.renderer.scoreRenderer.canvas.font = this.renderer.resources.elementFonts.get(this._fontElement);
57409
57699
  const size = this.renderer.scoreRenderer.canvas.measureText(this._label);
57410
57700
  this.height = size.height;
57411
57701
  this._labelWidth = size.width;
57412
57702
  }
57413
57703
  paintNonGrouped(cx, cy, canvas) {
57414
57704
  const res = this.renderer.resources;
57415
- canvas.font = res.effectFont;
57705
+ canvas.font = res.elementFonts.get(this._fontElement);
57416
57706
  const b = canvas.textBaseline;
57417
57707
  canvas.textBaseline = TextBaseline.Middle;
57418
57708
  canvas.fillText(this._label, cx + this.x - this._labelWidth / 2, cy + this.y + this.height / 2);
@@ -57473,7 +57763,7 @@
57473
57763
  break;
57474
57764
  }
57475
57765
  barre += `B ${BeatBarreEffectInfo.toRoman(beat.barreFret)}`;
57476
- return new LineRangedGlyph(barre, false);
57766
+ return new LineRangedGlyph(barre, exports.NotationElement.EffectBeatBarre, false);
57477
57767
  }
57478
57768
  static _romanLetters = new Map([
57479
57769
  // ['M', 1000],
@@ -57523,7 +57813,7 @@
57523
57813
  const seconds = ((this._timer - minutes * 60000) / 1000) | 0;
57524
57814
  this._text = `${minutes}:${seconds.toString().padStart(2, '0')}`;
57525
57815
  const c = this.renderer.scoreRenderer.canvas;
57526
- c.font = this.renderer.resources.timerFont;
57816
+ c.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectBeatTimer);
57527
57817
  const size = c.measureText(this._text);
57528
57818
  this._textHeight = c.font.size + this.renderer.smuflMetrics.beatTimerPadding * 2;
57529
57819
  this._textWidth = size.width + this.renderer.smuflMetrics.beatTimerPadding * 2;
@@ -57535,7 +57825,7 @@
57535
57825
  const f = canvas.font;
57536
57826
  const b = canvas.textBaseline;
57537
57827
  const a = canvas.textAlign;
57538
- canvas.font = this.renderer.resources.timerFont;
57828
+ canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectBeatTimer);
57539
57829
  canvas.textBaseline = TextBaseline.Middle;
57540
57830
  canvas.textAlign = TextAlign.Center;
57541
57831
  canvas.fillText(this._text, cx + this.x, cy + this.y + this.height / 2);
@@ -57644,7 +57934,7 @@
57644
57934
  return beat.index === 0 && beat.voice.bar.index === 0 && beat.voice.bar.staff.capo !== 0;
57645
57935
  }
57646
57936
  createNewGlyph(renderer, beat) {
57647
- 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);
57648
57938
  }
57649
57939
  canExpand(_from, _to) {
57650
57940
  return false;
@@ -57661,31 +57951,41 @@
57661
57951
  _fretRow = 0;
57662
57952
  _firstFretSpacing = 0;
57663
57953
  _center;
57664
- constructor(x, y, chord, center = false) {
57954
+ _fontElement;
57955
+ constructor(x, y, chord, fontElement, center = false) {
57665
57956
  super(x, y);
57666
57957
  this._chord = chord;
57667
57958
  this._center = center;
57959
+ this._fontElement = fontElement;
57668
57960
  }
57669
57961
  doLayout() {
57670
57962
  super.doLayout();
57671
57963
  const res = this.renderer.resources;
57672
- this._textRow = res.effectFont.size * 1.5;
57673
- this._fretRow = res.effectFont.size * 1.5;
57674
- if (this._chord.firstFret > 1) {
57675
- this._firstFretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
57676
- }
57677
- else {
57678
- this._firstFretSpacing = 0;
57679
- }
57680
- this.height =
57681
- 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 +=
57682
57977
  this._fretRow +
57683
- ChordDiagramGlyph._frets * this.renderer.smuflMetrics.chordDiagramFretSpacing +
57684
- 2 * this.renderer.smuflMetrics.chordDiagramPaddingY;
57685
- this.width =
57686
- this._firstFretSpacing +
57687
- (this._chord.strings.length - 1) * this.renderer.smuflMetrics.chordDiagramStringSpacing +
57688
- 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
+ }
57689
57989
  }
57690
57990
  paint(cx, cy, canvas) {
57691
57991
  cx += this.x + this.renderer.smuflMetrics.chordDiagramPaddingX + this._firstFretSpacing;
@@ -57693,25 +57993,35 @@
57693
57993
  if (this._center) {
57694
57994
  cx -= this.width / 2;
57695
57995
  }
57696
- const stringSpacing = this.renderer.smuflMetrics.chordDiagramStringSpacing;
57697
- const fretSpacing = this.renderer.smuflMetrics.chordDiagramFretSpacing;
57698
57996
  const res = this.renderer.resources;
57699
57997
  const lineWidth = res.engravingSettings.chordDiagramLineWidth;
57700
57998
  const w = this.width - 2 * this.renderer.smuflMetrics.chordDiagramPaddingX - this._firstFretSpacing + lineWidth;
57701
- const circleHeight = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardFilledCircle);
57702
- const circleTopOffset = res.engravingSettings.glyphTop.get(MusicFontSymbol.FretboardFilledCircle);
57703
- const xTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardX) / 2;
57704
- const oTopOffset = res.engravingSettings.glyphHeights.get(MusicFontSymbol.FretboardO) / 2;
57705
57999
  const align = canvas.textAlign;
57706
58000
  const baseline = canvas.textBaseline;
57707
- canvas.font = res.effectFont;
58001
+ const font = res.elementFonts.get(this._fontElement);
58002
+ canvas.font = font;
57708
58003
  canvas.textAlign = TextAlign.Center;
57709
58004
  canvas.textBaseline = TextBaseline.Top;
57710
58005
  if (this._chord.showName) {
57711
- 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);
57712
58010
  }
58011
+ canvas.textAlign = align;
58012
+ canvas.textBaseline = baseline;
58013
+ }
58014
+ _paintFretboard(cx, cy, canvas, w) {
57713
58015
  cy += this._textRow;
57714
- 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);
57715
58025
  canvas.textBaseline = TextBaseline.Middle;
57716
58026
  for (let i = 0; i < this._chord.strings.length; i++) {
57717
58027
  const x = cx + i * stringSpacing;
@@ -57774,8 +58084,6 @@
57774
58084
  const xRight = cx + (this._chord.strings.length - strings[0] - 1) * stringSpacing;
57775
58085
  canvas.fillRect(xLeft, y - circleHeight / 2, xRight - xLeft, circleHeight);
57776
58086
  }
57777
- canvas.textAlign = align;
57778
- canvas.textBaseline = baseline;
57779
58087
  }
57780
58088
  }
57781
58089
 
@@ -57801,8 +58109,8 @@
57801
58109
  createNewGlyph(renderer, beat) {
57802
58110
  const showDiagram = beat.voice.bar.staff.track.score.stylesheet.globalDisplayChordDiagramsInScore;
57803
58111
  return showDiagram
57804
- ? new ChordDiagramGlyph(0, 0, beat.chord, true)
57805
- : 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);
57806
58114
  }
57807
58115
  canExpand(_from, _to) {
57808
58116
  return false;
@@ -57913,14 +58221,14 @@
57913
58221
  }
57914
58222
  doLayout() {
57915
58223
  const c = this.renderer.scoreRenderer.canvas;
57916
- c.font = this.renderer.resources.directionsFont;
58224
+ c.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectDirections);
57917
58225
  this.height = c.measureText(this._text).height;
57918
58226
  }
57919
58227
  paint(cx, cy, canvas) {
57920
58228
  const font = canvas.font;
57921
58229
  const baseline = canvas.textBaseline;
57922
58230
  const align = canvas.textAlign;
57923
- canvas.font = this.renderer.resources.directionsFont;
58231
+ canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectDirections);
57924
58232
  canvas.textBaseline = TextBaseline.Middle;
57925
58233
  canvas.textAlign = TextAlign.Right;
57926
58234
  canvas.fillText(this._text, cx + this.x, cy + this.y + this.height / 2);
@@ -58816,7 +59124,7 @@
58816
59124
  (masterBar.index === 0 || masterBar.isFreeTime !== masterBar.previousMasterBar.isFreeTime));
58817
59125
  }
58818
59126
  createNewGlyph(renderer, _beat) {
58819
- 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);
58820
59128
  }
58821
59129
  canExpand(_from, _to) {
58822
59130
  return true;
@@ -58954,7 +59262,7 @@
58954
59262
  return EffectBarGlyphSizing.GroupedOnBeat;
58955
59263
  }
58956
59264
  createNewGlyph(_renderer, _beat) {
58957
- return new LineRangedGlyph(HarmonicsEffectInfo.harmonicToString(this._harmonicType));
59265
+ return new LineRangedGlyph(HarmonicsEffectInfo.harmonicToString(this._harmonicType), exports.NotationElement.EffectHarmonics);
58958
59266
  }
58959
59267
  static harmonicToString(type) {
58960
59268
  switch (type) {
@@ -59027,7 +59335,7 @@
59027
59335
  return EffectBarGlyphSizing.GroupedOnBeat;
59028
59336
  }
59029
59337
  createNewGlyph(_renderer, _beat) {
59030
- return new LineRangedGlyph('LetRing');
59338
+ return new LineRangedGlyph('LetRing', exports.NotationElement.EffectLetRing);
59031
59339
  }
59032
59340
  canExpand(_from, _to) {
59033
59341
  return true;
@@ -59039,6 +59347,7 @@
59039
59347
  */
59040
59348
  class LyricsGlyph extends EffectGlyph {
59041
59349
  _lines;
59350
+ _linePositions = [];
59042
59351
  font;
59043
59352
  textAlign;
59044
59353
  constructor(x, y, lines, font, textAlign = TextAlign.Center) {
@@ -59049,7 +59358,17 @@
59049
59358
  }
59050
59359
  doLayout() {
59051
59360
  super.doLayout();
59052
- 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;
59053
59372
  }
59054
59373
  paint(cx, cy, canvas) {
59055
59374
  canvas.font = this.font;
@@ -59057,7 +59376,7 @@
59057
59376
  canvas.textAlign = this.textAlign;
59058
59377
  for (let i = 0; i < this._lines.length; i++) {
59059
59378
  if (this._lines[i]) {
59060
- 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]);
59061
59380
  }
59062
59381
  }
59063
59382
  canvas.textAlign = old;
@@ -59084,7 +59403,7 @@
59084
59403
  return !!beat.lyrics;
59085
59404
  }
59086
59405
  createNewGlyph(renderer, beat) {
59087
- 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);
59088
59407
  }
59089
59408
  canExpand(_from, _to) {
59090
59409
  return true;
@@ -59116,7 +59435,7 @@
59116
59435
  createNewGlyph(renderer, beat) {
59117
59436
  return new TextGlyph(0, 0, !beat.voice.bar.masterBar.section.marker
59118
59437
  ? beat.voice.bar.masterBar.section.text
59119
- : `[${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);
59120
59439
  }
59121
59440
  canExpand(_from, _to) {
59122
59441
  return true;
@@ -59555,7 +59874,7 @@
59555
59874
  return EffectBarGlyphSizing.GroupedOnBeat;
59556
59875
  }
59557
59876
  createNewGlyph(_renderer, _beat) {
59558
- return new LineRangedGlyph('P.M.');
59877
+ return new LineRangedGlyph('P.M.', exports.NotationElement.EffectPalmMute);
59559
59878
  }
59560
59879
  }
59561
59880
 
@@ -59573,7 +59892,7 @@
59573
59892
  return EffectBarGlyphSizing.GroupedOnBeat;
59574
59893
  }
59575
59894
  createNewGlyph(_renderer, _beat) {
59576
- return new LineRangedGlyph('P.S.');
59895
+ return new LineRangedGlyph('P.S.', exports.NotationElement.EffectPickSlide);
59577
59896
  }
59578
59897
  }
59579
59898
 
@@ -59648,7 +59967,7 @@
59648
59967
  return EffectBarGlyphSizing.GroupedOnBeat;
59649
59968
  }
59650
59969
  createNewGlyph(_renderer, _beat) {
59651
- return new LineRangedGlyph('rasg.');
59970
+ return new LineRangedGlyph('rasg.', exports.NotationElement.EffectRasgueado);
59652
59971
  }
59653
59972
  canExpand(_from, _to) {
59654
59973
  return true;
@@ -63256,12 +63575,12 @@
63256
63575
  createNewGlyph(renderer, beat) {
63257
63576
  const res = renderer.resources;
63258
63577
  if (beat.slap) {
63259
- 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);
63260
63579
  }
63261
63580
  if (beat.pop) {
63262
- 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);
63263
63582
  }
63264
- 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);
63265
63584
  }
63266
63585
  canExpand(_from, _to) {
63267
63586
  return true;
@@ -63290,7 +63609,7 @@
63290
63609
  for (const automation of this._tempoAutomations) {
63291
63610
  let x = cx + this.renderer.getRatioPositionX(automation.ratioPosition);
63292
63611
  const res = this.renderer.resources;
63293
- canvas.font = res.markerFont;
63612
+ canvas.font = res.elementFonts.get(exports.NotationElement.EffectMarker);
63294
63613
  const notePosY = cy +
63295
63614
  this.y +
63296
63615
  this.height +
@@ -63368,7 +63687,7 @@
63368
63687
  return !!beat.text;
63369
63688
  }
63370
63689
  createNewGlyph(renderer, beat) {
63371
- 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);
63372
63691
  }
63373
63692
  canExpand(_from, _to) {
63374
63693
  return true;
@@ -63493,7 +63812,7 @@
63493
63812
  const textY = cy + this.height;
63494
63813
  const b = canvas.textBaseline;
63495
63814
  canvas.textBaseline = TextBaseline.Bottom;
63496
- canvas.font = this.renderer.resources.effectFont;
63815
+ canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.EffectTripletFeel);
63497
63816
  canvas.fillText('(', cx, textY);
63498
63817
  cx += canvas.measureText('( ').width;
63499
63818
  cx = this._drawGroup(cx, noteY + this._tupletHeight, canvas, leftNotes);
@@ -63735,7 +64054,7 @@
63735
64054
  return beat.hasWhammyBar;
63736
64055
  }
63737
64056
  createNewGlyph(_renderer, _beat) {
63738
- return new LineRangedGlyph('w/bar');
64057
+ return new LineRangedGlyph('w/bar', exports.NotationElement.EffectWhammyBar);
63739
64058
  }
63740
64059
  canExpand(_from, _to) {
63741
64060
  return true;
@@ -63887,7 +64206,7 @@
63887
64206
  class ChordDiagramContainerGlyph extends RowContainerGlyph {
63888
64207
  addChord(chord) {
63889
64208
  if (chord.strings.length > 0) {
63890
- const chordDiagram = new ChordDiagramGlyph(0, 0, chord);
64209
+ const chordDiagram = new ChordDiagramGlyph(0, 0, chord, exports.NotationElement.ChordDiagrams);
63891
64210
  chordDiagram.renderer = this.renderer;
63892
64211
  chordDiagram.doLayout();
63893
64212
  this.glyphs.push(chordDiagram);
@@ -63951,7 +64270,7 @@
63951
64270
  this.height = 0;
63952
64271
  // Track name
63953
64272
  if (this._trackLabel.length > 0) {
63954
- 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);
63955
64274
  trackName.renderer = this.renderer;
63956
64275
  trackName.doLayout();
63957
64276
  this.height += trackName.height;
@@ -63959,7 +64278,7 @@
63959
64278
  }
63960
64279
  // Name
63961
64280
  if (tuning.name.length > 0) {
63962
- 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);
63963
64282
  tuningName.renderer = this.renderer;
63964
64283
  tuningName.doLayout();
63965
64284
  this.height += tuningName.height;
@@ -63967,7 +64286,7 @@
63967
64286
  }
63968
64287
  const circleScale = this.renderer.smuflMetrics.tuningGlyphCircleNumberScale;
63969
64288
  const circleHeight = this.renderer.smuflMetrics.glyphHeights.get(MusicFontSymbol.GuitarString0) * circleScale;
63970
- this.renderer.scoreRenderer.canvas.font = res.effectFont;
64289
+ this.renderer.scoreRenderer.canvas.font = res.elementFonts.get(exports.NotationElement.GuitarTuning);
63971
64290
  const stringColumnWidth = (circleHeight + this.renderer.scoreRenderer.canvas.measureText(' = Gb').width) *
63972
64291
  res.engravingSettings.tuningGlyphStringColumnScale;
63973
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));
@@ -63981,7 +64300,7 @@
63981
64300
  const symbol = (MusicFontSymbol.GuitarString0 + (i + 1));
63982
64301
  this.addGlyph(new MusicFontGlyph(currentX, currentY + circleHeight, circleScale, symbol));
63983
64302
  const str = ` = ${Tuning.getTextForTuning(tuning.tunings[i], false)}`;
63984
- 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));
63985
64304
  currentY += circleHeight + this.renderer.smuflMetrics.tuningGlyphStringRowPadding;
63986
64305
  const bottomY = currentY;
63987
64306
  if (this.height < bottomY) {
@@ -65033,7 +65352,7 @@
65033
65352
  let hasAnyTrackName = false;
65034
65353
  if (shouldRender) {
65035
65354
  const canvas = this.layout.renderer.canvas;
65036
- const res = settings.display.resources.effectFont;
65355
+ const res = settings.display.resources.elementFonts.get(exports.NotationElement.TrackNames);
65037
65356
  canvas.font = res;
65038
65357
  for (const t of tracks) {
65039
65358
  let trackNameText = '';
@@ -65187,7 +65506,7 @@
65187
65506
  // Draw track names
65188
65507
  const settings = this.layout.renderer.settings;
65189
65508
  const hasTrackName = this.layout.renderer.settings.notation.isNotationElementVisible(exports.NotationElement.TrackNames);
65190
- canvas.font = res.effectFont;
65509
+ canvas.font = res.elementFonts.get(exports.NotationElement.TrackNames);
65191
65510
  if (hasTrackName) {
65192
65511
  const stylesheet = this.layout.renderer.score.stylesheet;
65193
65512
  const trackNamePolicy = this.layout.renderer.tracks.length === 1
@@ -65877,7 +66196,10 @@
65877
66196
  const msg = 'rendered by alphaTab';
65878
66197
  const resources = this.renderer.settings.display.resources;
65879
66198
  const size = 12;
65880
- 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);
65881
66203
  const fakeBarRenderer = new BarRendererBase(this.renderer, this.renderer.tracks[0].staves[0].bars[0]);
65882
66204
  const glyph = new TextGlyph(0, 0, msg, font, TextAlign.Center, undefined, resources.mainGlyphColor);
65883
66205
  glyph.renderer = fakeBarRenderer;
@@ -66790,13 +67112,7 @@
66790
67112
  this._number = `${num} `;
66791
67113
  }
66792
67114
  doLayout() {
66793
- // TODO: activate this and update paddings accordingly.
66794
- // if (!this.renderer.staff!.isFirstInSystem) {
66795
- // this.width = 0;
66796
- // this.height = 0;
66797
- // return;
66798
- // }
66799
- this.renderer.scoreRenderer.canvas.font = this.renderer.resources.barNumberFont;
67115
+ this.renderer.scoreRenderer.canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.BarNumber);
66800
67116
  const size = this.renderer.scoreRenderer.canvas.measureText(this._number);
66801
67117
  this.width = size.width;
66802
67118
  this.height = size.height;
@@ -66810,7 +67126,7 @@
66810
67126
  try {
66811
67127
  const res = this.renderer.resources;
66812
67128
  const baseline = canvas.textBaseline;
66813
- canvas.font = res.barNumberFont;
67129
+ canvas.font = res.elementFonts.get(exports.NotationElement.BarNumber);
66814
67130
  canvas.textBaseline = TextBaseline.Top;
66815
67131
  canvas.fillText(this._number, cx + this.x, cy + this.y);
66816
67132
  canvas.textBaseline = baseline;
@@ -67909,7 +68225,7 @@
67909
68225
  this._count = count;
67910
68226
  }
67911
68227
  doLayout() {
67912
- this.renderer.scoreRenderer.canvas.font = this.renderer.resources.barNumberFont;
68228
+ this.renderer.scoreRenderer.canvas.font = this.renderer.resources.elementFonts.get(exports.NotationElement.RepeatCount);
67913
68229
  const size = this.renderer.scoreRenderer.canvas.measureText(`x${this._count}`);
67914
68230
  this.width = 0; // do not account width
67915
68231
  this.height = size.height;
@@ -67920,7 +68236,7 @@
67920
68236
  try {
67921
68237
  const res = this.renderer.resources;
67922
68238
  const oldAlign = canvas.textAlign;
67923
- canvas.font = res.barNumberFont;
68239
+ canvas.font = res.elementFonts.get(exports.NotationElement.RepeatCount);
67924
68240
  canvas.textAlign = TextAlign.Right;
67925
68241
  const s = `x${this._count}`;
67926
68242
  const w = canvas.measureText(s).width / 1.5;
@@ -68045,11 +68361,12 @@
68045
68361
  }
68046
68362
  createStartSpacing() {
68047
68363
  if (this._startSpacing) {
68048
- return;
68364
+ return false;
68049
68365
  }
68050
68366
  const padding = this.index === 0 ? this.settings.display.firstStaffPaddingLeft : this.settings.display.staffPaddingLeft;
68051
68367
  this.addPreBeatGlyph(new SpacingGlyph(0, 0, padding));
68052
68368
  this._startSpacing = true;
68369
+ return true;
68053
68370
  }
68054
68371
  paintTuplets(cx, cy, canvas, beatElement, bracketsAsArcs = false) {
68055
68372
  for (const v of this.voiceContainer.voiceDrawOrder) {
@@ -68391,16 +68708,45 @@
68391
68708
  super.createPreBeatGlyphs();
68392
68709
  this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
68393
68710
  this.createLinePreBeatGlyphs();
68711
+ let hasSpaceAfterStartGlyphs = false;
68394
68712
  if (this.index === 0) {
68395
- 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));
68717
+ }
68718
+ else if (!hasSpaceAfterStartGlyphs) {
68719
+ this.addPreBeatGlyph(new SpacingGlyph(0, 0, this.smuflMetrics.oneStaffSpace));
68396
68720
  }
68397
- this.addPreBeatGlyph(new BarNumberGlyph(0, this.getLineHeight(-0.5), this.bar.index + 1));
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;
68398
68742
  }
68399
68743
  createPostBeatGlyphs() {
68400
68744
  super.createPostBeatGlyphs();
68401
68745
  const lastBar = this.lastBar;
68402
68746
  this.addPostBeatGlyph(new BarLineGlyph(true, this.bar.staff.track.score.stylesheet.extendBarLines));
68403
- 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)) {
68404
68750
  this.addPostBeatGlyph(new RepeatCountGlyph(0, this.getLineHeight(-0.5), this.bar.masterBar.repeatCount));
68405
68751
  }
68406
68752
  }
@@ -68964,8 +69310,13 @@
68964
69310
  this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
68965
69311
  }
68966
69312
  this.createLinePreBeatGlyphs();
68967
- this.createStartSpacing();
68968
- 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
+ }
68969
69320
  }
68970
69321
  createLinePreBeatGlyphs() {
68971
69322
  if (this._isOnlyNumbered &&
@@ -71513,7 +71864,7 @@
71513
71864
  if (note.bendStyle === BendStyle.Gradual) {
71514
71865
  const res = this.renderer.resources;
71515
71866
  const c = this.renderer.scoreRenderer.canvas;
71516
- c.font = res.barNumberFont; // see note in paint()
71867
+ c.font = res.elementFonts.get(exports.NotationElement.ScoreBendSlur);
71517
71868
  slurHeight += c.measureText('grad.').height;
71518
71869
  }
71519
71870
  if (slurHeight > maxSlurHeight) {
@@ -71613,11 +71964,16 @@
71613
71964
  this._notes.sort((a, b) => {
71614
71965
  return b.displayValue - a.displayValue;
71615
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) {
71616
71973
  const directionBeat = this._beat.graceType === GraceType.BendGrace ? this._beat.nextBeat : this._beat;
71617
71974
  let direction = this._notes.length === 1 ? this.getTieDirection(directionBeat, startNoteRenderer) : BeamDirection.Up;
71618
71975
  const noteHeadHeight = this.renderer.smuflMetrics.glyphHeights.get(MusicFontSymbol.NoteheadBlack);
71619
- // draw slurs
71620
- 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);
71621
71977
  for (let i = 0; i < this._notes.length; i++) {
71622
71978
  const note = this._notes[i];
71623
71979
  const _ = ElementStyleHelper.note(canvas, NoteSubElement.StandardNotationEffects, note);
@@ -79746,6 +80102,7 @@
79746
80102
  BackingTrack,
79747
80103
  Bar,
79748
80104
  get BarLineStyle () { return BarLineStyle; },
80105
+ get BarNumberDisplay () { return BarNumberDisplay; },
79749
80106
  BarStyle,
79750
80107
  get BarSubElement () { return BarSubElement; },
79751
80108
  get BarreShape () { return BarreShape; },