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 năm trước cách đây
mục cha
commit
ce761f330c

+ 1 - 1
package.json

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

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

@@ -122,10 +122,21 @@ export class DrawingParameters {
     }
 
     public setForCompactTightMode(): void {
-        this.rules.CompactMode = true;
-        this.DrawCredits = false;
+        this.setForCompactMode(); // also sets CompactMode = true
         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.StaffDistance = 3.5
         // this.MinimumDistanceBetweenSystems = 1

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

@@ -169,12 +169,14 @@ export class EngravingRules {
     private octaveShiftVerticalLineLength: number;
     private graceLineWidth: number;
     private minimumStaffLineDistance: number;
+    private minimumSkyBottomLineDistance: number;
     private minimumCrossedBeamDifferenceMargin: number;
     private displacedNoteMargin: number;
     private minNoteDistance: number;
     private subMeasureXSpacingThreshold: number;
     private measureDynamicsMaxScalingFactor: number;
     private wholeRestXShiftVexflow: number;
+    private metronomeMarksDrawn: boolean;
     private metronomeMarkXShift: number;
     private metronomeMarkYShift: number;
     private maxInstructionsConstValue: number;
@@ -409,7 +411,8 @@ export class EngravingRules {
         this.graceLineWidth = this.staffLineWidth * this.GraceNoteScalingFactor;
 
         // 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;
 
         // xSpacing Variables
@@ -418,6 +421,7 @@ export class EngravingRules {
         this.subMeasureXSpacingThreshold = 35;
         this.measureDynamicsMaxScalingFactor = 2.5;
         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.metronomeMarkYShift = -0.5;
 
@@ -1334,6 +1338,12 @@ export class EngravingRules {
     public set MinimumStaffLineDistance(value: number) {
         this.minimumStaffLineDistance = value;
     }
+    public get MinimumSkyBottomLineDistance(): number {
+        return this.minimumSkyBottomLineDistance;
+    }
+    public set MinimumSkyBottomLineDistance(value: number) {
+        this.minimumSkyBottomLineDistance = value;
+    }
     public get MinimumCrossedBeamDifferenceMargin(): number {
         return this.minimumCrossedBeamDifferenceMargin;
     }
@@ -1370,6 +1380,12 @@ export class EngravingRules {
     public set WholeRestXShiftVexflow(value: number) {
         this.wholeRestXShiftVexflow = value;
     }
+    public get MetronomeMarksDrawn(): boolean {
+        return this.metronomeMarksDrawn;
+    }
+    public set MetronomeMarksDrawn(value: boolean) {
+        this.metronomeMarksDrawn = value;
+    }
     public get MetronomeMarkXShift(): number {
         return this.metronomeMarkXShift;
     }

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

@@ -1375,9 +1375,11 @@ export abstract class MusicSheetCalculator {
                         // in their constructor
                     }
                     // 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) {
                     // 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)
         if (!musicSystem.checkStaffEntriesForStaffEntryLink()) {
             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];
@@ -944,7 +951,7 @@ export class MusicSystemBuilder {
      */
     protected updateStaffLinesRelativePosition(musicSystem: MusicSystem, index: number, value: number): void {
         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;

+ 6 - 1
src/OpenSheetMusicDisplay/OSMDOptions.ts

@@ -69,6 +69,8 @@ export interface IOSMDOptions {
     drawComposer?: boolean;
     /** Whether to draw the lyricist's name, if given (top left of the score). */
     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,
      *  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).
      */
     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;
     /** 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

+ 4 - 11
src/OpenSheetMusicDisplay/OpenSheetMusicDisplay.ts

@@ -335,17 +335,7 @@ export class OpenSheetMusicDisplay {
         if (options.drawingParameters) {
             this.drawingParameters.DrawingParametersEnum =
                 (<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;
@@ -415,6 +405,9 @@ export class OpenSheetMusicDisplay {
         if (options.drawLyricist !== undefined) {
             this.drawingParameters.DrawLyricist = options.drawLyricist;
         }
+        if (options.drawMetronomeMarks !== undefined) {
+            this.rules.MetronomeMarksDrawn = options.drawMetronomeMarks;
+        }
         if (options.drawPartNames !== undefined) {
             this.drawingParameters.DrawPartNames = options.drawPartNames; // indirectly writes to EngravingRules