Jelajahi Sumber

feat(Options): start new system ("line break") when given in XML and OSMDOptions.newSystemFromXML set (#702)

part of #702

page break coming next, in a similar fashion
sschmid 5 tahun lalu
induk
melakukan
5284aaa5e0

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

@@ -213,6 +213,7 @@ export class EngravingRules {
     /** Position of fingering label in relation to corresponding note (left, right supported, above, below experimental) */
     private fingeringPosition: PlacementEnum;
     private fingeringInsideStafflines: boolean;
+    private newSystemAtXMLNewSystemAttribute: boolean;
     private pageFormat: PageFormat;
     private pageBackgroundColor: string; // vexflow-color-string (#FFFFFF). Default undefined/transparent.
     private renderSingleHorizontalStaffline: boolean;
@@ -441,6 +442,7 @@ export class EngravingRules {
         this.renderLyrics = true;
         this.fingeringPosition = PlacementEnum.Left; // easier to get bounding box, and safer for vertical layout
         this.fingeringInsideStafflines = false;
+        this.newSystemAtXMLNewSystemAttribute = false;
 
         EngravingRules.FixStafflineBoundingBox = false; // TODO temporary workaround
 
@@ -1561,6 +1563,12 @@ export class EngravingRules {
     public set FingeringInsideStafflines(value: boolean) {
         this.fingeringInsideStafflines = value;
     }
+    public get NewSystemAtXMLNewSystemAttribute(): boolean {
+        return this.newSystemAtXMLNewSystemAttribute;
+    }
+    public set NewSystemAtXMLNewSystemAttribute(value: boolean) {
+        this.newSystemAtXMLNewSystemAttribute = value;
+    }
     public get PageFormat(): PageFormat {
         return this.pageFormat;
     }

+ 2 - 1
src/MusicalScore/Graphical/MusicSystemBuilder.ts

@@ -114,7 +114,8 @@ export class MusicSystemBuilder {
             const totalMeasureWidth: number = currentMeasureBeginInstructionsWidth + currentMeasureEndInstructionsWidth + currentMeasureVarWidth;
             const measureFitsInSystem: boolean = this.currentSystemParams.currentWidth + totalMeasureWidth + nextMeasureBeginInstructionWidth < systemMaxWidth;
             //if (true) // prevent line break at all costs, squeezes measures and breaks lyrics spacing
-            if (isSystemStartMeasure || measureFitsInSystem) {
+            const doXmlLineBreak: boolean = this.rules.NewSystemAtXMLNewSystemAttribute && sourceMeasure.printNewSystemXml;
+            if (isSystemStartMeasure || (measureFitsInSystem && !doXmlLineBreak)) {
                 this.addMeasureToSystem(
                     graphicalMeasures, measureStartLine, measureEndLine, totalMeasureWidth,
                     currentMeasureBeginInstructionsWidth, currentMeasureVarWidth, currentMeasureEndInstructionsWidth

+ 6 - 1
src/MusicalScore/ScoreIO/InstrumentReader.ts

@@ -135,7 +135,12 @@ export class InstrumentReader {
     try {
       const xmlMeasureListArr: IXmlElement[] = this.xmlMeasureList[this.currentXmlMeasureIndex].elements();
       for (const xmlNode of xmlMeasureListArr) {
-        if (xmlNode.name === "note") {
+        if (xmlNode.name === "print") {
+          const newSystemAttr: IXmlAttribute = xmlNode.attribute("new-system");
+          if (newSystemAttr?.value === "yes") {
+            currentMeasure.printNewSystemXml = true;
+          }
+        } else if (xmlNode.name === "note") {
           let printObject: boolean = true;
           if (xmlNode.hasAttributes && xmlNode.attribute("print-object") &&
               xmlNode.attribute("print-object").value === "no") {

+ 2 - 0
src/MusicalScore/VoiceData/SourceMeasure.ts

@@ -54,6 +54,8 @@ export class SourceMeasure {
      */
     public endingBarStyleXml: string;
     public endingBarStyleEnum: SystemLinesEnum;
+    /** Whether the MusicXML says to print a new system (line break). See OSMDOptions.newSystemFromXML */
+    public printNewSystemXml: boolean = false;
 
     private measureNumber: number;
     private absoluteTimestamp: Fraction;

+ 5 - 0
src/OpenSheetMusicDisplay/OSMDOptions.ts

@@ -123,6 +123,11 @@ export interface IOSMDOptions {
     pageBackgroundColor?: string;
     /** This makes OSMD render on one single horizontal (staff-)line. */
     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
+     *  at different measures. So this option may result in a system break after a single measure in a system.
+     */
+    newSystemFromXML?: boolean;
 }
 
 export enum AlignRestOption {

+ 3 - 0
src/OpenSheetMusicDisplay/OpenSheetMusicDisplay.ts

@@ -440,6 +440,9 @@ export class OpenSheetMusicDisplay {
         if (options.fingeringInsideStafflines !== undefined) {
             this.rules.FingeringInsideStafflines = options.fingeringInsideStafflines;
         }
+        if (options.newSystemFromXML !== undefined) {
+            this.rules.NewSystemAtXMLNewSystemAttribute = options.newSystemFromXML;
+        }
         if (options.fillEmptyMeasuresWithWholeRest !== undefined) {
             this.rules.FillEmptyMeasuresWithWholeRest = options.fillEmptyMeasuresWithWholeRest;
         }