Quellcode durchsuchen

feat(Slurs): take slur placement from XML by default (#827). add EngravingRules.SlurPlacementFromXML

fix #827
sschmid vor 4 Jahren
Ursprung
Commit
4cb3de9183

+ 2 - 0
src/MusicalScore/Graphical/EngravingRules.ts

@@ -142,6 +142,7 @@ export class EngravingRules {
     public MinimumDistanceBetweenDashes: number;
     public MaximumLyricsElongationFactor: number;
 
+    public SlurPlacementFromXML: boolean;
     public BezierCurveStepSize: number;
     public TPower3: number[];
     public OneMinusTPower3: number[];
@@ -404,6 +405,7 @@ export class EngravingRules {
         this.TupletNumbersInTabs = false; // disabled by default, nonstandard in tabs, at least how we show them in non-tabs.
 
         // Slur and Tie variables
+        this.SlurPlacementFromXML = true;
         this.BezierCurveStepSize = 1000;
         this.calculateCurveParametersArrays();
         this.TieGhostObjectWidth = 0.75;

+ 8 - 1
src/MusicalScore/Graphical/GraphicalSlur.ts

@@ -17,9 +17,10 @@ import { StemDirectionType } from "../VoiceData/VoiceEntry";
 export class GraphicalSlur extends GraphicalCurve {
     // private intersection: PointF2D;
 
-    constructor(slur: Slur) {
+    constructor(slur: Slur, rules: EngravingRules) {
         super();
         this.slur = slur;
+        this.rules = rules;
     }
 
     public slur: Slur;
@@ -27,6 +28,7 @@ export class GraphicalSlur extends GraphicalCurve {
     public placement: PlacementEnum;
     public graceStart: boolean;
     public graceEnd: boolean;
+    private rules: EngravingRules;
 
     /**
      * Compares the timespan of two Graphical Slurs
@@ -606,6 +608,11 @@ export class GraphicalSlur extends GraphicalCurve {
         //     return;
         // }
 
+        if (this.rules.SlurPlacementFromXML) {
+            this.placement = this.slur.PlacementXml;
+            return;
+        }
+
         // if any StaffEntry belongs to a Measure with multiple Voices, than
         // if Slur's Start- or End-Note belongs to a LinkedVoice Below else Above
         for (let idx: number = 0, len: number = this.staffEntries.length; idx < len; ++idx) {

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

@@ -1045,7 +1045,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
           const openGraphicalSlurs: GraphicalSlur[] = openSlursDict[staffLine.ParentStaff.idInMusicSheet];
           for (let slurIndex: number = 0; slurIndex < openGraphicalSlurs.length; slurIndex++) {
             const oldGSlur: GraphicalSlur = openGraphicalSlurs[slurIndex];
-            const newGSlur: GraphicalSlur = new GraphicalSlur(oldGSlur.slur); //Graphicalslur.createFromSlur(oldSlur);
+            const newGSlur: GraphicalSlur = new GraphicalSlur(oldGSlur.slur, this.rules); //Graphicalslur.createFromSlur(oldSlur);
             staffLine.addSlurToStaffline(newGSlur); // every VFSlur is added to the array in the VFStaffline!
             openGraphicalSlurs[slurIndex] = newGSlur;
           }
@@ -1083,7 +1083,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
                       }
 
                       // Add a Graphical Slur to the staffline, if the recent note is the Startnote of a slur
-                      const gSlur: GraphicalSlur = new GraphicalSlur(slur);
+                      const gSlur: GraphicalSlur = new GraphicalSlur(slur, this.rules);
                       openGraphicalSlurs.push(gSlur);
                       staffLine.addSlurToStaffline(gSlur);
 

+ 11 - 0
src/MusicalScore/ScoreIO/MusicSymbolModules/SlurReader.ts

@@ -4,6 +4,7 @@ import { Slur } from "../../VoiceData/Expressions/ContinuousExpressions/Slur";
 import { Note } from "../../VoiceData/Note";
 import log from "loglevel";
 import { ITextTranslation } from "../../Interfaces/ITextTranslation";
+import { PlacementEnum } from "../../VoiceData/Expressions";
 
 export class SlurReader {
     private musicSheet: MusicSheet;
@@ -27,6 +28,15 @@ export class SlurReader {
                             log.debug("VoiceGenerator.addSlur number: ", ex);
                         }
 
+                        let slurPlacementXml: PlacementEnum = PlacementEnum.NotYetDefined;
+                        const placementAttr: Attr = slurNode.attribute("placement");
+                        if (placementAttr && placementAttr.value) {
+                            if (placementAttr.value === "above") {
+                                slurPlacementXml = PlacementEnum.Above;
+                            } else if (placementAttr.value === "below") {
+                                slurPlacementXml = PlacementEnum.Below;
+                            }
+                        }
                         if (type === "start") {
                             let slur: Slur = this.openSlurDict[slurNumber];
                             if (!slur) {
@@ -34,6 +44,7 @@ export class SlurReader {
                                 this.openSlurDict[slurNumber] = slur;
                             }
                             slur.StartNote = currentNote;
+                            slur.PlacementXml = slurPlacementXml;
                         } else if (type === "stop") {
                             const slur: Slur = this.openSlurDict[slurNumber];
                             if (slur) {

+ 3 - 1
src/MusicalScore/VoiceData/Expressions/ContinuousExpressions/Slur.ts

@@ -1,5 +1,6 @@
 import {Note} from "../../Note";
-import {Fraction} from "../../../../Common/DataObjects/Fraction";
+import { Fraction } from "../../../../Common/DataObjects/Fraction";
+import { PlacementEnum } from "../AbstractExpression";
 
 export class Slur {
     constructor() {
@@ -8,6 +9,7 @@ export class Slur {
 
     private startNote: Note;
     private endNote: Note;
+    public PlacementXml: PlacementEnum; // how the slur is placed in the XML
 
     public get StartNote(): Note {
         return this.startNote;