Bladeren bron

Merge branch develop into feature/Ornaments,
adapted createOrnaments() to changes in develop

# Conflicts:
# external/vexflow/vexflow.d.ts
# src/MusicalScore/Graphical/VexFlow/VexFlowConverter.ts

sschmidTU 7 jaren geleden
bovenliggende
commit
fc1c9f2be0

+ 7 - 0
external/vexflow/vexflow.d.ts

@@ -256,6 +256,13 @@ declare namespace Vex {
             constructor(type: string);
         }
 
+        export class Ornament extends Modifier {
+            constructor(type: string);
+            setDelayed(delayed: boolean): void;
+            setUpperAccidental(acc: string): void;
+            setLowerAccidental(acc: string): void;
+        }
+        
         export class Beam {
             constructor(notes: StaveNote[], auto_stem: boolean);
 

+ 61 - 1
src/MusicalScore/Graphical/VexFlow/VexFlowConverter.ts

@@ -19,6 +19,7 @@ import * as log from "loglevel";
 import { ArticulationEnum, StemDirectionType } from "../../VoiceData/VoiceEntry";
 import { SystemLinePosition } from "../SystemLinePosition";
 import { GraphicalVoiceEntry } from "../GraphicalVoiceEntry";
+import { OrnamentEnum, OrnamentContainer } from "../../VoiceData/OrnamentContainer";
 
 /**
  * Helper class, which contains static methods which actually convert
@@ -118,7 +119,7 @@ export class VexFlowConverter {
     public static accidental(accidental: AccidentalEnum): string {
         let acc: string;
         switch (accidental) {
-            case AccidentalEnum.NONE:
+            case AccidentalEnum.NATURAL:
                 acc = "n";
                 break;
             case AccidentalEnum.FLAT:
@@ -306,6 +307,65 @@ export class VexFlowConverter {
         }
     }
 
+    public static generateOrnaments(vfnote: Vex.Flow.StaveNote, oContainer: OrnamentContainer): void {
+        // Ornaments
+        let vfPosition: number = Vex.Flow.Modifier.Position.ABOVE;
+
+        if (vfnote.getStemDirection() === Vex.Flow.Stem.UP) {
+            vfPosition = Vex.Flow.Modifier.Position.BELOW;
+        }
+
+        let vfOrna: Vex.Flow.Ornament = undefined;
+        // tslint:disable-next-line:switch-default
+        switch (oContainer.GetOrnament) {
+            case OrnamentEnum.DelayedInvertedTurn: {
+                vfOrna = new Vex.Flow.Ornament("turn_inverted");
+                vfOrna.setDelayed(true);
+                break;
+            }
+            case OrnamentEnum.DelayedTurn: {
+                vfOrna = new Vex.Flow.Ornament("turn");
+                vfOrna.setDelayed(true);
+                break;
+            }
+            case OrnamentEnum.InvertedMordent: {
+                vfOrna = new Vex.Flow.Ornament("mordent_inverted");
+                vfOrna.setDelayed(false);
+                break;
+            }
+            case OrnamentEnum.InvertedTurn: {
+                vfOrna = new Vex.Flow.Ornament("turn_inverted");
+                vfOrna.setDelayed(false);
+                break;
+            }
+            case OrnamentEnum.Mordent: {
+                vfOrna = new Vex.Flow.Ornament("mordent");
+                vfOrna.setDelayed(false);
+                break;
+            }
+            case OrnamentEnum.Trill: {
+                vfOrna = new Vex.Flow.Ornament("tr");
+                vfOrna.setDelayed(false);
+                break;
+            }
+            case OrnamentEnum.Turn: {
+                vfOrna = new Vex.Flow.Ornament("turn");
+                vfOrna.setDelayed(false);
+                break;
+            }
+        }
+        if (vfOrna !== undefined) {
+            if (oContainer.AccidentalBelow !== AccidentalEnum.NONE) {
+                vfOrna.setLowerAccidental(this.accidental(oContainer.AccidentalBelow));
+            }
+            if (oContainer.AccidentalAbove !== AccidentalEnum.NONE) {
+                vfOrna.setUpperAccidental(this.accidental(oContainer.AccidentalAbove));
+            }
+            vfOrna.setPosition(vfPosition);
+            vfnote.addModifier(0, vfOrna);
+        }
+    }
+
     /**
      * Convert a ClefInstruction to a string represention of a clef type in VexFlow.
      *

+ 28 - 0
src/MusicalScore/Graphical/VexFlow/VexFlowMeasure.ts

@@ -602,8 +602,12 @@ export class VexFlowMeasure extends GraphicalMeasure {
             }
         }
         this.createArticulations();
+        this.createOrnaments();
     }
 
+    /**
+     * Create the articulations for all notes of the current staff entry
+     */
     private createArticulations(): void {
         for (let idx: number = 0, len: number = this.staffEntries.length; idx < len; ++idx) {
             const graphicalStaffEntry: VexFlowStaffEntry = (this.staffEntries[idx] as VexFlowStaffEntry);
@@ -618,6 +622,30 @@ export class VexFlowMeasure extends GraphicalMeasure {
     }
 
     /**
+     * Create the ornaments for all notes of the current staff entry
+     */
+    private createOrnaments(): void {
+        for (let idx: number = 0, len: number = this.staffEntries.length; idx < len; ++idx) {
+            const graphicalStaffEntry: VexFlowStaffEntry = (this.staffEntries[idx] as VexFlowStaffEntry);
+
+            // create vex flow Notes:
+
+            // TODO VexFlowConverter.StaveNote may have something to do with this.
+            // Hint: GraphicalNote[][] is now graphicalVoiceEntries : GraphicalVoiceEntry[]
+            // also, VewFlowVoiceEntry now uses a Vex.Flow.StemmableNote instead of a StaveNote, which generateOrnaments() demands.
+            const gvoices: { [voiceID: number]: GraphicalVoiceEntry; } = graphicalStaffEntry.graphicalVoiceEntries;
+            for (const voiceID in gvoices) {
+                if (gvoices.hasOwnProperty(voiceID)) {
+                    const vfStaveNote: StaveNote = ((gvoices[voiceID] as VexFlowVoiceEntry).vfStaveNote as StaveNote);
+                    if (gvoices[voiceID].notes[0].sourceNote.ParentVoiceEntry.OrnamentContainer !== undefined) {
+                        VexFlowConverter.generateOrnaments(vfStaveNote, gvoices[voiceID].notes[0].sourceNote.ParentVoiceEntry.OrnamentContainer);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
      * Creates a line from 'top' to this measure, of type 'lineType'
      * @param top
      * @param lineType

+ 40 - 40
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator.ts

@@ -330,48 +330,48 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     (graphicalNote.parentVoiceEntry.parentStaffEntry.parentMeasure as VexFlowMeasure).handleBeam(graphicalNote, beam);
   }
 
-    protected handleVoiceEntryLyrics(voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry, lyricWords: LyricWord[]): void {
-        voiceEntry.LyricsEntries.forEach((key: number, lyricsEntry: LyricsEntry) => {
-            const graphicalLyricEntry: GraphicalLyricEntry = new GraphicalLyricEntry(lyricsEntry,
-                                                                                     graphicalStaffEntry,
-                                                                                     this.rules.LyricsHeight,
-                                                                                     this.rules.StaffHeight);
-
-            graphicalStaffEntry.LyricsEntries.push(graphicalLyricEntry);
-
-            // create corresponding GraphicalLabel
-            const graphicalLabel: GraphicalLabel = graphicalLyricEntry.GraphicalLabel;
-            graphicalLabel.setLabelPositionAndShapeBorders();
-
-            if (lyricsEntry.Word !== undefined) {
-                const lyricsEntryIndex: number = lyricsEntry.Word.Syllables.indexOf(lyricsEntry);
-                let index: number = lyricWords.indexOf(lyricsEntry.Word);
-                if (index === -1) {
-                    lyricWords.push(lyricsEntry.Word);
-                    index = lyricWords.indexOf(lyricsEntry.Word);
+  protected handleVoiceEntryLyrics(voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry, lyricWords: LyricWord[]): void {
+      voiceEntry.LyricsEntries.forEach((key: number, lyricsEntry: LyricsEntry) => {
+          const graphicalLyricEntry: GraphicalLyricEntry = new GraphicalLyricEntry(lyricsEntry,
+                                                                                   graphicalStaffEntry,
+                                                                                   this.rules.LyricsHeight,
+                                                                                   this.rules.StaffHeight);
+
+          graphicalStaffEntry.LyricsEntries.push(graphicalLyricEntry);
+
+          // create corresponding GraphicalLabel
+          const graphicalLabel: GraphicalLabel = graphicalLyricEntry.GraphicalLabel;
+          graphicalLabel.setLabelPositionAndShapeBorders();
+
+          if (lyricsEntry.Word !== undefined) {
+              const lyricsEntryIndex: number = lyricsEntry.Word.Syllables.indexOf(lyricsEntry);
+              let index: number = lyricWords.indexOf(lyricsEntry.Word);
+              if (index === -1) {
+                  lyricWords.push(lyricsEntry.Word);
+                  index = lyricWords.indexOf(lyricsEntry.Word);
+              }
+
+              if (this.graphicalLyricWords.length === 0 || index > this.graphicalLyricWords.length - 1) {
+                  const graphicalLyricWord: GraphicalLyricWord = new GraphicalLyricWord(lyricsEntry.Word);
+
+                  graphicalLyricEntry.ParentLyricWord = graphicalLyricWord;
+                  graphicalLyricWord.GraphicalLyricsEntries[lyricsEntryIndex] = graphicalLyricEntry;
+                  this.graphicalLyricWords.push(graphicalLyricWord);
+              } else {
+                  const graphicalLyricWord: GraphicalLyricWord = this.graphicalLyricWords[index];
+
+                  graphicalLyricEntry.ParentLyricWord = graphicalLyricWord;
+                  graphicalLyricWord.GraphicalLyricsEntries[lyricsEntryIndex] = graphicalLyricEntry;
+
+                  if (graphicalLyricWord.isFilled()) {
+                      lyricWords.splice(index, 1);
+                      this.graphicalLyricWords.splice(this.graphicalLyricWords.indexOf(graphicalLyricWord), 1);
+                  }
+              }
+          }
+      });
   }
 
-                if (this.graphicalLyricWords.length === 0 || index > this.graphicalLyricWords.length - 1) {
-                    const graphicalLyricWord: GraphicalLyricWord = new GraphicalLyricWord(lyricsEntry.Word);
-
-                    graphicalLyricEntry.ParentLyricWord = graphicalLyricWord;
-                    graphicalLyricWord.GraphicalLyricsEntries[lyricsEntryIndex] = graphicalLyricEntry;
-                    this.graphicalLyricWords.push(graphicalLyricWord);
-                } else {
-                    const graphicalLyricWord: GraphicalLyricWord = this.graphicalLyricWords[index];
-
-                    graphicalLyricEntry.ParentLyricWord = graphicalLyricWord;
-                    graphicalLyricWord.GraphicalLyricsEntries[lyricsEntryIndex] = graphicalLyricEntry;
-
-                    if (graphicalLyricWord.isFilled()) {
-                        lyricWords.splice(index, 1);
-                        this.graphicalLyricWords.splice(this.graphicalLyricWords.indexOf(graphicalLyricWord), 1);
-                    }
-                }
-            }
-        });
-    }
-
   protected handleVoiceEntryOrnaments(ornamentContainer: OrnamentContainer, voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry): void {
     return;
   }