Browse Source

Implementation of displaying ornaments:
1) added Ornament class (extends Modifier) in vexflow.d.ts with constructor and set-function for Flag "Delayed"
2) added "private createOrnaments(): void {...}" in VexFlowMeasure.ts to provide ornament to switch statement
3) created Vexflow Ornament by the function "public static generateOrnaments(vfnote: Vex.Flow.StaveNote, ornament: OrnamentEnum): void {...}" in VexFlowConverter.ts
Testfile did show correct.

Christoph Uiberacker 7 years ago
parent
commit
9d2104dcde

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

@@ -228,6 +228,13 @@ declare namespace Vex {
         export class Articulation extends Modifier {
             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);

+ 57 - 0
src/MusicalScore/Graphical/VexFlow/VexFlowConverter.ts

@@ -18,6 +18,7 @@ import {OutlineAndFillStyleEnum, OUTLINE_AND_FILL_STYLE_DICT} from "../DrawingEn
 import {Logging} from "../../../Common/Logging";
 import { ArticulationEnum, StemDirectionType } from "../../VoiceData/VoiceEntry";
 import { SystemLinePosition } from "../SystemLinePosition";
+import { OrnamentEnum } from "../../VoiceData/OrnamentContainer";
 
 /**
  * Helper class, which contains static methods which actually convert
@@ -270,6 +271,62 @@ export class VexFlowConverter {
         }
     }
 
+    public static generateOrnaments(vfnote: Vex.Flow.StaveNote, ornament: OrnamentEnum): void {
+        // Ornaments
+        let vfPosition: number = Vex.Flow.Modifier.Position.ABOVE;
+
+        if (vfnote.getStemDirection() === Vex.Flow.Stem.UP) {
+            vfPosition = Vex.Flow.Modifier.Position.BELOW;
+        }
+
+        //for (const ornament of ornaments) {
+            // tslint:disable-next-line:switch-default
+        let vfOrna: Vex.Flow.Ornament = undefined;
+        // tslint:disable-next-line:switch-default
+        switch (ornament) {
+            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) {
+            vfOrna.setPosition(vfPosition);
+            vfnote.addModifier(0, vfOrna);
+        }
+        //}
+    }
+
     /**
      * Convert a ClefInstruction to a string represention of a clef type in VexFlow.
      *

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

@@ -490,8 +490,12 @@ export class VexFlowMeasure extends StaffMeasure {
             }
         }
         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);
@@ -508,6 +512,26 @@ export class VexFlowMeasure extends StaffMeasure {
     }
 
     /**
+     * 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:
+            const gnotes: { [voiceID: number]: GraphicalNote[]; } = graphicalStaffEntry.graphicalNotes;
+            for (const voiceID in gnotes) {
+                if (gnotes.hasOwnProperty(voiceID)) {
+                    const vfnote: StaveNote = (graphicalStaffEntry as VexFlowStaffEntry).vfNotes[voiceID];
+                    if (gnotes[voiceID][0].sourceNote.ParentVoiceEntry.OrnamentContainer !== undefined) {
+                        VexFlowConverter.generateOrnaments(vfnote, gnotes[voiceID][0].sourceNote.ParentVoiceEntry.OrnamentContainer.GetOrnament);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
      * Creates a line from 'top' to this measure, of type 'lineType'
      * @param top
      * @param lineType

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

@@ -323,48 +323,48 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     (graphicalNote.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;
   }