Browse Source

Merge branch 'develop' into feat/percussion_stafflines

this is necessary to make visual regression tests comparable to develop.
this shows that there is one little problem with osmd function test drumset,
but other than that very few changes (4 samples), but no negatives and some very positive.
sschmid 5 years ago
parent
commit
ce761f330c

+ 1 - 1
package.json

@@ -71,7 +71,7 @@
   "devDependencies": {
   "devDependencies": {
     "@types/chai": "^4.2.11",
     "@types/chai": "^4.2.11",
     "@types/mocha": "^7.0.2",
     "@types/mocha": "^7.0.2",
-    "@types/node": "^14.0.1",
+    "@types/node": "^14.0.5",
     "canvas": "^2.6.1",
     "canvas": "^2.6.1",
     "chai": "^4.1.0",
     "chai": "^4.1.0",
     "clean-webpack-plugin": "^3.0.0",
     "clean-webpack-plugin": "^3.0.0",

+ 14 - 3
src/MusicalScore/Graphical/DrawingParameters.ts

@@ -122,10 +122,21 @@ export class DrawingParameters {
     }
     }
 
 
     public setForCompactTightMode(): void {
     public setForCompactTightMode(): void {
-        this.rules.CompactMode = true;
-        this.DrawCredits = false;
+        this.setForCompactMode(); // also sets CompactMode = true
         this.DrawPartNames = false;
         this.DrawPartNames = false;
-        this.drawHiddenNotes = false;
+
+        // tight rendering mode, lower margins and safety distances between systems, staffs etc. may cause overlap.
+        // these options can afterwards be finetuned by setting osmd.rules.BetweenStaffDistance for example
+        this.rules.MinimumSkyBottomLineDistance = 1.0; // default 1.0. this can cause collisions with slurs and dynamics sometimes
+        // note that this.rules === osmd.rules, since it's passed as a reference
+
+        this.rules.BetweenStaffDistance = 2.5;
+        this.rules.StaffDistance = 3.5;
+        this.rules.MinimumDistanceBetweenSystems = 1;
+        // this.rules.PageTopMargin = 0.0; // see this.rules.PageTopMarginNarrow used in compact mode
+        this.rules.PageBottomMargin = 1.0;
+        this.rules.PageLeftMargin = 2.0;
+        this.rules.PageRightMargin = 2.0;
         // this.BetweenStaffDistance = 2.5 // etc needs to be set in OSMD.rules
         // this.BetweenStaffDistance = 2.5 // etc needs to be set in OSMD.rules
         // this.StaffDistance = 3.5
         // this.StaffDistance = 3.5
         // this.MinimumDistanceBetweenSystems = 1
         // this.MinimumDistanceBetweenSystems = 1

+ 17 - 1
src/MusicalScore/Graphical/EngravingRules.ts

@@ -169,12 +169,14 @@ export class EngravingRules {
     private octaveShiftVerticalLineLength: number;
     private octaveShiftVerticalLineLength: number;
     private graceLineWidth: number;
     private graceLineWidth: number;
     private minimumStaffLineDistance: number;
     private minimumStaffLineDistance: number;
+    private minimumSkyBottomLineDistance: number;
     private minimumCrossedBeamDifferenceMargin: number;
     private minimumCrossedBeamDifferenceMargin: number;
     private displacedNoteMargin: number;
     private displacedNoteMargin: number;
     private minNoteDistance: number;
     private minNoteDistance: number;
     private subMeasureXSpacingThreshold: number;
     private subMeasureXSpacingThreshold: number;
     private measureDynamicsMaxScalingFactor: number;
     private measureDynamicsMaxScalingFactor: number;
     private wholeRestXShiftVexflow: number;
     private wholeRestXShiftVexflow: number;
+    private metronomeMarksDrawn: boolean;
     private metronomeMarkXShift: number;
     private metronomeMarkXShift: number;
     private metronomeMarkYShift: number;
     private metronomeMarkYShift: number;
     private maxInstructionsConstValue: number;
     private maxInstructionsConstValue: number;
@@ -409,7 +411,8 @@ export class EngravingRules {
         this.graceLineWidth = this.staffLineWidth * this.GraceNoteScalingFactor;
         this.graceLineWidth = this.staffLineWidth * this.GraceNoteScalingFactor;
 
 
         // Line Widths
         // Line Widths
-        this.minimumStaffLineDistance = 1.0;
+        this.minimumStaffLineDistance = 4.0;
+        this.minimumSkyBottomLineDistance = 2.0; // default. 1.0 for compacttight mode (1.0 can cause overlaps)
         this.minimumCrossedBeamDifferenceMargin = 0.0001;
         this.minimumCrossedBeamDifferenceMargin = 0.0001;
 
 
         // xSpacing Variables
         // xSpacing Variables
@@ -418,6 +421,7 @@ export class EngravingRules {
         this.subMeasureXSpacingThreshold = 35;
         this.subMeasureXSpacingThreshold = 35;
         this.measureDynamicsMaxScalingFactor = 2.5;
         this.measureDynamicsMaxScalingFactor = 2.5;
         this.wholeRestXShiftVexflow = -2.5; // VexFlow draws rest notes too far to the right
         this.wholeRestXShiftVexflow = -2.5; // VexFlow draws rest notes too far to the right
+        this.metronomeMarksDrawn = true;
         this.metronomeMarkXShift = -6; // our unit, is taken * unitInPixels
         this.metronomeMarkXShift = -6; // our unit, is taken * unitInPixels
         this.metronomeMarkYShift = -0.5;
         this.metronomeMarkYShift = -0.5;
 
 
@@ -1334,6 +1338,12 @@ export class EngravingRules {
     public set MinimumStaffLineDistance(value: number) {
     public set MinimumStaffLineDistance(value: number) {
         this.minimumStaffLineDistance = value;
         this.minimumStaffLineDistance = value;
     }
     }
+    public get MinimumSkyBottomLineDistance(): number {
+        return this.minimumSkyBottomLineDistance;
+    }
+    public set MinimumSkyBottomLineDistance(value: number) {
+        this.minimumSkyBottomLineDistance = value;
+    }
     public get MinimumCrossedBeamDifferenceMargin(): number {
     public get MinimumCrossedBeamDifferenceMargin(): number {
         return this.minimumCrossedBeamDifferenceMargin;
         return this.minimumCrossedBeamDifferenceMargin;
     }
     }
@@ -1370,6 +1380,12 @@ export class EngravingRules {
     public set WholeRestXShiftVexflow(value: number) {
     public set WholeRestXShiftVexflow(value: number) {
         this.wholeRestXShiftVexflow = value;
         this.wholeRestXShiftVexflow = value;
     }
     }
+    public get MetronomeMarksDrawn(): boolean {
+        return this.metronomeMarksDrawn;
+    }
+    public set MetronomeMarksDrawn(value: boolean) {
+        this.metronomeMarksDrawn = value;
+    }
     public get MetronomeMarkXShift(): number {
     public get MetronomeMarkXShift(): number {
         return this.metronomeMarkXShift;
         return this.metronomeMarkXShift;
     }
     }

+ 5 - 3
src/MusicalScore/Graphical/MusicSheetCalculator.ts

@@ -1375,9 +1375,11 @@ export abstract class MusicSheetCalculator {
                         // in their constructor
                         // in their constructor
                     }
                     }
                     // in case of metronome mark:
                     // in case of metronome mark:
-                    if ((entry.Expression as InstantaneousTempoExpression).Enum === TempoEnum.metronomeMark) {
-                        this.createMetronomeMark((entry.Expression as InstantaneousTempoExpression));
-                        continue;
+                    if (this.rules.MetronomeMarksDrawn) {
+                        if ((entry.Expression as InstantaneousTempoExpression).Enum === TempoEnum.metronomeMark) {
+                            this.createMetronomeMark((entry.Expression as InstantaneousTempoExpression));
+                            continue;
+                        }
                     }
                     }
                 } else if (entry.Expression instanceof ContinuousTempoExpression) {
                 } else if (entry.Expression instanceof ContinuousTempoExpression) {
                     // FIXME: Not yet implemented
                     // FIXME: Not yet implemented

+ 16 - 9
src/MusicalScore/Graphical/MusicSystemBuilder.ts

@@ -919,15 +919,22 @@ export class MusicSystemBuilder {
         // don't perform any y-spacing in case of a StaffEntryLink (in both StaffLines)
         // don't perform any y-spacing in case of a StaffEntryLink (in both StaffLines)
         if (!musicSystem.checkStaffEntriesForStaffEntryLink()) {
         if (!musicSystem.checkStaffEntriesForStaffEntryLink()) {
             for (let i: number = 0; i < musicSystem.StaffLines.length - 1; i++) {
             for (let i: number = 0; i < musicSystem.StaffLines.length - 1; i++) {
-                const upperBottomLine: number = musicSystem.StaffLines[i].SkyBottomLineCalculator.getBottomLineMax();
-                // TODO: Lower skyline should add to offset when there are items above the line. Currently no test
-                // file available
-                // const lowerSkyLine: number = Math.min(...musicSystem.StaffLines[i + 1].SkyLine);
-                if (Math.abs(upperBottomLine) > this.rules.MinimumStaffLineDistance) {
-                    // Remove staffheight from offset. As it results in huge distances
-                    const offset: number = Math.abs(upperBottomLine) + this.rules.MinimumStaffLineDistance - this.rules.StaffHeight;
-                    this.updateStaffLinesRelativePosition(musicSystem, i + 1, offset);
+                const upperBottomLine: number[] = musicSystem.StaffLines[i].BottomLine;
+                const lowerSkyline: number[] = musicSystem.StaffLines[i + 1].SkyLine;
+                // 1. Find maximum required space for sky bottom line touching each other
+                let maxDistance: number = 0;
+                for (let j: number = 0; j < upperBottomLine.length; j++) {
+                    const bottomLineValue: number = upperBottomLine[j];
+                    const skylineValue: number = lowerSkyline[j];
+                    const distance: number = bottomLineValue - skylineValue;
+                    maxDistance = Math.max(distance, maxDistance);
                 }
                 }
+                // 2. Add user defined distance between sky bottom line
+                maxDistance += this.rules.MinimumSkyBottomLineDistance;
+                // 3. Take the maximum between previous value and user defined value for staff line minimum distance
+                maxDistance = Math.max(maxDistance, this.rules.StaffHeight + this.rules.MinimumStaffLineDistance);
+                const lowerStafflineYPos: number = maxDistance + musicSystem.StaffLines[i].PositionAndShape.RelativePosition.y;
+                this.updateStaffLinesRelativePosition(musicSystem, i + 1, lowerStafflineYPos);
             }
             }
         }
         }
         const firstStaffLine: StaffLine = musicSystem.StaffLines[0];
         const firstStaffLine: StaffLine = musicSystem.StaffLines[0];
@@ -944,7 +951,7 @@ export class MusicSystemBuilder {
      */
      */
     protected updateStaffLinesRelativePosition(musicSystem: MusicSystem, index: number, value: number): void {
     protected updateStaffLinesRelativePosition(musicSystem: MusicSystem, index: number, value: number): void {
         for (let i: number = index; i < musicSystem.StaffLines.length; i++) {
         for (let i: number = index; i < musicSystem.StaffLines.length; i++) {
-            musicSystem.StaffLines[i].PositionAndShape.RelativePosition.y += value;
+            musicSystem.StaffLines[i].PositionAndShape.RelativePosition.y = value;
         }
         }
 
 
         musicSystem.PositionAndShape.BorderBottom += value;
         musicSystem.PositionAndShape.BorderBottom += value;

+ 6 - 1
src/OpenSheetMusicDisplay/OSMDOptions.ts

@@ -69,6 +69,8 @@ export interface IOSMDOptions {
     drawComposer?: boolean;
     drawComposer?: boolean;
     /** Whether to draw the lyricist's name, if given (top left of the score). */
     /** Whether to draw the lyricist's name, if given (top left of the score). */
     drawLyricist?: boolean;
     drawLyricist?: boolean;
+    /** Whether to draw metronome marks. Default true. (currently OSMD can only draw one at the beginning) */
+    drawMetronomeMarks?: boolean;
     /** Whether to draw part (instrument) names. Setting this to false also disables drawPartAbbreviations,
     /** Whether to draw part (instrument) names. Setting this to false also disables drawPartAbbreviations,
      *  unless explicitly enabled (drawPartNames: false, drawPartAbbreviations: true).
      *  unless explicitly enabled (drawPartNames: false, drawPartAbbreviations: true).
      */
      */
@@ -126,7 +128,10 @@ export interface IOSMDOptions {
      *  Note: Using a background color will prevent the cursor from being visible for now (will be fixed at some point).
      *  Note: Using a background color will prevent the cursor from being visible for now (will be fixed at some point).
      */
      */
     pageBackgroundColor?: string;
     pageBackgroundColor?: string;
-    /** This makes OSMD render on one single horizontal (staff-)line. */
+    /** This makes OSMD render on one single horizontal (staff-)line.
+     * This option should be set before loading a score. It only starts working after load(),
+     * calling setOptions() after load and then render() doesn't work in this case.
+     */
     renderSingleHorizontalStaffline?: boolean;
     renderSingleHorizontalStaffline?: boolean;
     /** Whether to begin a new system ("line break") when given in XML ('new-system="yes"').
     /** Whether to begin a new system ("line break") when given in XML ('new-system="yes"').
      *  Default false, because OSMD does its own layout that will do line breaks interactively
      *  Default false, because OSMD does its own layout that will do line breaks interactively

+ 4 - 11
src/OpenSheetMusicDisplay/OpenSheetMusicDisplay.ts

@@ -335,17 +335,7 @@ export class OpenSheetMusicDisplay {
         if (options.drawingParameters) {
         if (options.drawingParameters) {
             this.drawingParameters.DrawingParametersEnum =
             this.drawingParameters.DrawingParametersEnum =
                 (<any>DrawingParametersEnum)[options.drawingParameters.toLowerCase()];
                 (<any>DrawingParametersEnum)[options.drawingParameters.toLowerCase()];
-            if (this.drawingParameters.DrawingParametersEnum === DrawingParametersEnum.compacttight) {
-                // tight rendering mode, lower margins and safety distances between systems, staffs etc. may cause overlap.
-                // these options can afterwards be finetuned by setting osmd.rules.BetweenStaffDistance for example
-                this.rules.BetweenStaffDistance = 2.5;
-                this.rules.StaffDistance = 3.5;
-                this.rules.MinimumDistanceBetweenSystems = 1;
-                // this.rules.PageTopMargin = 0.0; // see this.rules.PageTopMarginNarrow used in compact mode
-                this.rules.PageBottomMargin = 1.0;
-                this.rules.PageLeftMargin = 2.0;
-                this.rules.PageRightMargin = 2.0;
-            }
+                // see DrawingParameters.ts: set DrawingParametersEnum, and DrawingParameters.ts:setForCompactTightMode()
         }
         }
 
 
         const backendNotInitialized: boolean = !this.drawer || !this.drawer.Backends || this.drawer.Backends.length < 1;
         const backendNotInitialized: boolean = !this.drawer || !this.drawer.Backends || this.drawer.Backends.length < 1;
@@ -415,6 +405,9 @@ export class OpenSheetMusicDisplay {
         if (options.drawLyricist !== undefined) {
         if (options.drawLyricist !== undefined) {
             this.drawingParameters.DrawLyricist = options.drawLyricist;
             this.drawingParameters.DrawLyricist = options.drawLyricist;
         }
         }
+        if (options.drawMetronomeMarks !== undefined) {
+            this.rules.MetronomeMarksDrawn = options.drawMetronomeMarks;
+        }
         if (options.drawPartNames !== undefined) {
         if (options.drawPartNames !== undefined) {
             this.drawingParameters.DrawPartNames = options.drawPartNames; // indirectly writes to EngravingRules
             this.drawingParameters.DrawPartNames = options.drawPartNames; // indirectly writes to EngravingRules