瀏覽代碼

Added shift of start- and endpoint of slurs in x direction (timestamp) from the center of the bounding box to the stem position for better graphical appearance. TODO: There are still some wrong placings to be corrected!

Christoph Uiberacker 6 年之前
父節點
當前提交
876cfdd0f5

+ 40 - 0
src/MusicalScore/Graphical/GraphicalSlur.ts

@@ -11,6 +11,8 @@ import { Matrix2D } from "../../Common/DataObjects/Matrix2D";
 import { LinkedVoice } from "../VoiceData/LinkedVoice";
 import { GraphicalVoiceEntry } from "./GraphicalVoiceEntry";
 import { GraphicalStaffEntry } from "./GraphicalStaffEntry";
+import { Fraction } from "../../Common/DataObjects/Fraction";
+import { StemDirectionType } from "../VoiceData/VoiceEntry";
 
 export class GraphicalSlur extends GraphicalCurve {
     // private intersection: PointF2D;
@@ -27,6 +29,28 @@ export class GraphicalSlur extends GraphicalCurve {
     public graceEnd: boolean;
 
     /**
+     * Compares the timespan of two Graphical Slurs
+     * @param x
+     * @param y
+     */
+    public static Compare (x: GraphicalSlur, y: GraphicalSlur ): number {
+        const xTimestampSpan: Fraction = Fraction.minus(x.staffEntries[x.staffEntries.length - 1].getAbsoluteTimestamp(),
+                                                        x.staffEntries[0].getAbsoluteTimestamp());
+        const yTimestampSpan: Fraction = Fraction.minus(y.staffEntries[y.staffEntries.length - 1].getAbsoluteTimestamp(),
+                                                        y.staffEntries[0].getAbsoluteTimestamp());
+
+        if (xTimestampSpan > yTimestampSpan) {
+            return 1;
+        }
+
+        if (yTimestampSpan > xTimestampSpan) {
+            return -1;
+        }
+
+        return 0;
+    }
+
+    /**
      *
      * @param rules
      */
@@ -396,6 +420,14 @@ export class GraphicalSlur extends GraphicalCurve {
                 startY = slurStartVE.PositionAndShape.RelativePosition.y + slurStartVE.PositionAndShape.BorderBottom;
             }
 
+            // If the stem points towards the starting point of the slur, shift the slur by a small amount to start (approximately) at the x-position
+            // of the notehead. Note: an exact calculation using the position of the note is too complicate for the payoff
+            if ( slurStartVE.parentVoiceEntry.StemDirection === StemDirectionType.Down && this.placement === PlacementEnum.Below ) {
+                startX -= 0.5;
+            }
+            if (slurStartVE.parentVoiceEntry.StemDirection === StemDirectionType.Up && this.placement === PlacementEnum.Above) {
+                startX += 0.5;
+            }
             // if (first.NoteStem !== undefined && first.NoteStem.Direction === StemEnum.StemUp && this.placement === PlacementEnum.Above) {
             //     startX += first.NoteStem.PositionAndShape.RelativePosition.x;
             //     startY = skyBottomLineCalculator.getSkyLineMinAtPoint(staffLine, startX);
@@ -427,6 +459,14 @@ export class GraphicalSlur extends GraphicalCurve {
                 endY = slurEndVE.PositionAndShape.RelativePosition.y + slurEndVE.PositionAndShape.BorderBottom;
             }
 
+            // If the stem points towards the endpoint of the slur, shift the slur by a small amount to start (approximately) at the x-position
+            // of the notehead. Note: an exact calculation using the position of the note is too complicate for the payoff
+            if ( slurEndVE.parentVoiceEntry.StemDirection === StemDirectionType.Down && this.placement === PlacementEnum.Below ) {
+                endX -= 0.5;
+            }
+            if (slurEndVE.parentVoiceEntry.StemDirection === StemDirectionType.Up && this.placement === PlacementEnum.Above) {
+                endX += 0.5;
+            }
             // const first: GraphicalNote = <GraphicalNote>slurEndNote.parentVoiceEntry.notes[0];
             // if (first.NoteStem !== undefined && first.NoteStem.Direction === StemEnum.StemUp && this.placement === PlacementEnum.Above) {
             //     endX += first.NoteStem.PositionAndShape.RelativePosition.x;

+ 0 - 21
src/MusicalScore/Graphical/GraphicalSlurSorter.ts

@@ -1,21 +0,0 @@
-import { Fraction } from "../../Common/DataObjects/Fraction";
-import { GraphicalSlur } from "./GraphicalSlur";
-
-export interface GraphicalSlurSorterKeyValuePair {
-    key: Fraction;
-    value: GraphicalSlur;
-}
-
-export class GraphicalSlurSorter {
-    public Compare (x: GraphicalSlurSorterKeyValuePair, y: GraphicalSlurSorterKeyValuePair ): number {
-        if (x.key > y.key) {
-            return 1;
-        }
-
-        if (y.key > x.key) {
-            return -1;
-        }
-
-        return 0;
-    }
-}

+ 3 - 1
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator.ts

@@ -949,7 +949,9 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     for (const graphicalMusicPage of this.graphicalMusicSheet.MusicPages) {
         for (const musicSystem of graphicalMusicPage.MusicSystems) {
             for (const staffLine of musicSystem.StaffLines) {
-                for (const gSlur of staffLine.GraphicalSlurs) {
+                // Sort all gSlurs in the staffline using the Compare function in class GraphicalSlurSorter
+                const sortedGSlurs: GraphicalSlur[] = staffLine.GraphicalSlurs.sort(GraphicalSlur.Compare);
+                for (const gSlur of sortedGSlurs) {
                     // crossed slurs will be handled later:
                     if (gSlur.slur.isCrossed()) {
                         continue;