Browse Source

Fix: added missing implementation for uncategorized/unknown expressions to get rendered.

Matthias Uiberacker 5 years ago
parent
commit
fd2c0dfa39

+ 1 - 1
src/MusicalScore/Graphical/AbstractGraphicalExpression.ts

@@ -13,7 +13,7 @@ export abstract class AbstractGraphicalExpression extends GraphicalObject {
     /** EngravingRules for positioning */
     protected rules: EngravingRules;
 
-    constructor(parentStaffline: StaffLine, expression: AbstractExpression) {
+    constructor(parentStaffline: StaffLine, expression: AbstractExpression = undefined) {
         super();
         this.expression = expression;
         this.boundingBox = new BoundingBox(this, parentStaffline.PositionAndShape);

+ 33 - 0
src/MusicalScore/Graphical/GraphicalUnknownExpression.ts

@@ -0,0 +1,33 @@
+
+import { StaffLine } from "./StaffLine";
+import { GraphicalLabel } from "./GraphicalLabel";
+import { AbstractGraphicalExpression } from "./AbstractGraphicalExpression";
+import { PlacementEnum } from "../VoiceData/Expressions";
+import { SkyBottomLineCalculator } from "./SkyBottomLineCalculator";
+import log from "loglevel";
+
+export class GraphicalUnknownExpression extends AbstractGraphicalExpression {
+    constructor(staffLine: StaffLine, label: GraphicalLabel) {
+        super(staffLine);
+        this.label = label;
+    }
+
+    public updateSkyBottomLine(): void {
+        // update Sky-BottomLine
+        const skyBottomLineCalculator: SkyBottomLineCalculator = this.parentStaffLine.SkyBottomLineCalculator;
+        const left: number = this.label.PositionAndShape.RelativePosition.x + this.label.PositionAndShape.BorderMarginLeft;
+        const right: number = this.label.PositionAndShape.RelativePosition.x + this.label.PositionAndShape.BorderMarginRight;
+        switch (this.Placement) {
+            case PlacementEnum.Above:
+                const yValueAbove: number = this.label.PositionAndShape.BorderMarginTop + this.label.PositionAndShape.RelativePosition.y;
+                skyBottomLineCalculator.updateSkyLineInRange(left, right, yValueAbove);
+                break;
+            case PlacementEnum.Below:
+                const yValueBelow: number = this.label.PositionAndShape.BorderMarginBottom + this.label.PositionAndShape.RelativePosition.y;
+                skyBottomLineCalculator.updateBottomLineInRange(left, right, yValueBelow);
+                break;
+            default:
+                log.error("Placement for GraphicalUnknownExpression is unknown");
+        }
+    }
+}

+ 42 - 2
src/MusicalScore/Graphical/MusicSheetCalculator.ts

@@ -21,7 +21,7 @@ import { Tuplet } from "../VoiceData/Tuplet";
 import { MusicSystem } from "./MusicSystem";
 import { GraphicalTie } from "./GraphicalTie";
 import { RepetitionInstruction } from "../VoiceData/Instructions/RepetitionInstruction";
-import { MultiExpression } from "../VoiceData/Expressions/MultiExpression";
+import { MultiExpression, MultiExpressionEntry } from "../VoiceData/Expressions/MultiExpression";
 import { StaffEntryLink } from "../VoiceData/StaffEntryLink";
 import { MusicSystemBuilder } from "./MusicSystemBuilder";
 import { MultiTempoExpression } from "../VoiceData/Expressions/MultiTempoExpression";
@@ -67,6 +67,7 @@ import { GraphicalInstantaneousDynamicExpression } from "./GraphicalInstantaneou
 import { ContDynamicEnum } from "../VoiceData/Expressions/ContinuousExpressions/ContinuousDynamicExpression";
 import { GraphicalContinuousDynamicExpression } from "./GraphicalContinuousDynamicExpression";
 import { FillEmptyMeasuresWithWholeRests } from "../../OpenSheetMusicDisplay/OSMDOptions";
+import { GraphicalUnknownExpression } from "./GraphicalUnknownExpression";
 
 /**
  * Class used to do all the calculations in a MusicSheet, which in the end populates a GraphicalMusicSheet.
@@ -543,7 +544,46 @@ export abstract class MusicSheetCalculator {
      * @param staffIndex
      */
     protected calculateMoodAndUnknownExpression(multiExpression: MultiExpression, measureIndex: number, staffIndex: number): void {
-        throw new Error("abstract, not implemented");
+        // calculate absolute Timestamp
+        const absoluteTimestamp: Fraction = multiExpression.AbsoluteTimestamp;
+        const measures: GraphicalMeasure[] = this.graphicalMusicSheet.MeasureList[measureIndex];
+        let relative: PointF2D = new PointF2D();
+
+        if ((multiExpression.MoodList.length > 0) || (multiExpression.UnknownList.length > 0)) {
+        let combinedExprString: string  = "";
+        for (let idx: number = 0, len: number = multiExpression.EntriesList.length; idx < len; ++idx) {
+            const entry: MultiExpressionEntry = multiExpression.EntriesList[idx];
+            if (entry.prefix !== "") {
+                if (combinedExprString === "") {
+                    combinedExprString += entry.prefix;
+                } else {
+                    combinedExprString += " " + entry.prefix;
+                }
+            }
+            if (combinedExprString === "") {
+                combinedExprString += entry.label;
+            } else {
+                combinedExprString += " " + entry.label;
+            }
+        }
+        const staffLine: StaffLine = measures[staffIndex].ParentStaffLine;
+        relative = this.getRelativePositionInStaffLineFromTimestamp(absoluteTimestamp, staffIndex, staffLine, staffLine.isPartOfMultiStaffInstrument());
+
+        if (Math.abs(relative.x - 0) < 0.0001) {
+            relative.x = measures[staffIndex].beginInstructionsWidth + this.rules.RhythmRightMargin;
+        }
+
+        const fontHeight: number = this.rules.UnknownTextHeight;
+
+        const graphLabel: GraphicalLabel  = this.calculateLabel(staffLine,
+                                                                relative, combinedExprString,
+                                                                multiExpression.getFontstyleOfFirstEntry(),
+                                                                multiExpression.getPlacementOfFirstEntry(),
+                                                                fontHeight);
+
+        const gue: GraphicalUnknownExpression = new GraphicalUnknownExpression(staffLine, graphLabel);
+        staffLine.AbstractExpressions.push(gue);
+        }
     }
 
     /**

+ 9 - 12
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator.ts

@@ -691,26 +691,23 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     }
   }
 
-  protected calculateMoodAndUnknownExpression(multiExpression: MultiExpression, measureIndex: number, staffIndex: number): void {
-    return;
-  }
-
   /**
    * Re-adjust the x positioning of expressions. Update the skyline afterwards
    */
   protected calculateExpressionAlignements(): void {
     for (const musicSystem of this.musicSystems) {
-            for (const staffLine of musicSystem.StaffLines) {
-              try {
-                (<VexFlowStaffLine>staffLine).AlignmentManager.alignDynamicExpressions();
-                staffLine.AbstractExpressions.forEach(ae => ae.updateSkyBottomLine());
-              } catch (e) {
-                // TODO still necessary when calculation of expression fails, see calculateDynamicExpressionsForMultiExpression()
-                //   see calculateGraphicalContinuousDynamic(), also in MusicSheetCalculator.
+      for (const staffLine of musicSystem.StaffLines) {
+        try {
+          (<VexFlowStaffLine>staffLine).AlignmentManager.alignDynamicExpressions();
+          staffLine.AbstractExpressions.forEach(ae => ae.updateSkyBottomLine());
+        } catch (e) {
+          // TODO still necessary when calculation of expression fails, see calculateDynamicExpressionsForMultiExpression()
+          //   see calculateGraphicalContinuousDynamic(), also in MusicSheetCalculator.
         }
+      }
     }
   }
-  }
+
 
   /**
    * Check if the tied graphical note belongs to any beams or tuplets and react accordingly.

+ 5 - 7
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer.ts

@@ -27,6 +27,7 @@ import { VexFlowContinuousDynamicExpression } from "./VexFlowContinuousDynamicEx
 import { DrawingParameters } from "../DrawingParameters";
 import { GraphicalMusicPage } from "../GraphicalMusicPage";
 import { GraphicalMusicSheet } from "../GraphicalMusicSheet";
+import { GraphicalUnknownExpression } from "../GraphicalUnknownExpression";
 
 /**
  * This is a global constant which denotes the height in pixels of the space between two lines of the stave
@@ -356,13 +357,10 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
                 // // Draw Mood
                 // } else if (abstractGraphicalExpression instanceof GraphicalMoodExpression) {
                 //     GraphicalMoodExpression; graphicalMood = (GraphicalMoodExpression); abstractGraphicalExpression;
-                //     drawLabel(graphicalMood.GetGraphicalLabel, (int)GraphicalLayers.Notes);
-                // // Draw Unknown
-                // } else if (abstractGraphicalExpression instanceof GraphicalUnknownExpression) {
-                //     GraphicalUnknownExpression; graphicalUnknown =
-                //         (GraphicalUnknownExpression); abstractGraphicalExpression;
-                //     drawLabel(graphicalUnknown.GetGraphicalLabel, (int)GraphicalLayers.Notes);
-                // }
+                //     drawLabel(graphicalMood.GetGraphicalLabel, <number>GraphicalLayers.Notes);
+            // Draw Unknown
+            } else if (abstractGraphicalExpression instanceof GraphicalUnknownExpression) {
+                this.drawLabel(abstractGraphicalExpression.Label, <number>GraphicalLayers.Notes);
             } else {
                 log.warn("Unkown type of expression!");
             }

+ 15 - 13
src/MusicalScore/VoiceData/Expressions/MultiExpression.ts

@@ -7,6 +7,7 @@ import {MoodExpression} from "./MoodExpression";
 import {UnknownExpression} from "./UnknownExpression";
 import {AbstractExpression} from "./AbstractExpression";
 import {PlacementEnum} from "./AbstractExpression";
+import { FontStyles } from "../../../Common/Enums/FontStyles";
 
 export class MultiExpression {
 
@@ -109,19 +110,20 @@ export class MultiExpression {
         }
         return placement;
     }
-    // (*)
-    //public getFontstyleOfFirstEntry(): PSFontStyles {
-    //    let fontStyle: PSFontStyles = PSFontStyles.Regular;
-    //    if (this.expressions.length > 0) {
-    //        if (this.expressions[0].expression instanceof ContinuousDynamicExpression)
-    //            fontStyle = PSFontStyles.Italic;
-    //        else if (this.expressions[0].expression instanceof MoodExpression)
-    //            fontStyle = PSFontStyles.Italic;
-    //        else if (this.expressions[0].expression instanceof UnknownExpression)
-    //            fontStyle = PSFontStyles.Regular;
-    //    }
-    //    return fontStyle;
-    //}
+
+    public getFontstyleOfFirstEntry(): FontStyles {
+       let fontStyle: FontStyles = FontStyles.Regular;
+       if (this.expressions.length > 0) {
+           if (this.expressions[0].expression instanceof ContinuousDynamicExpression) {
+            fontStyle = FontStyles.Italic;
+           } else if (this.expressions[0].expression instanceof MoodExpression) {
+            fontStyle = FontStyles.Italic;
+           } else if (this.expressions[0].expression instanceof UnknownExpression) {
+            fontStyle = FontStyles.Regular;
+           }
+       }
+       return fontStyle;
+    }
     //public getFirstEntry(staffLine: StaffLine, graphLabel: GraphicalLabel): AbstractGraphicalExpression {
     //    let indexOfFirstNotInstDynExpr: number = 0;
     //    if (this.expressions[0].expression instanceof InstantaneousDynamicExpression)