Browse Source

merge osmd-public (1.7.6): new EngravingRules, fixes etc. (see changelog)

see public osmd changelog:
https://github.com/opensheetmusicdisplay/opensheetmusicdisplay/blob/develop/CHANGELOG.md
sschmidTU 1 year ago
parent
commit
b6cafb4557

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "osmd-extended",
   "name": "osmd-extended",
-  "version": "1.7.5",
+  "version": "1.7.6",
   "description": "Private / sponsor exclusive OSMD mirror/audio player.",
   "description": "Private / sponsor exclusive OSMD mirror/audio player.",
   "main": "build/opensheetmusicdisplay.min.js",
   "main": "build/opensheetmusicdisplay.min.js",
   "types": "build/dist/src/index.d.ts",
   "types": "build/dist/src/index.d.ts",

+ 8 - 2
src/Common/DataObjects/Pitch.ts

@@ -110,16 +110,22 @@ export class Pitch {
         return Pitch.WrapAroundCheck(newHalfTone, 12);
         return Pitch.WrapAroundCheck(newHalfTone, 12);
     }
     }
 
 
+    /** Returns the fundamental note x (0 <= x <= 11, e.g. 0 = C) with octave change/overflow.
+     * The halftone will be one of the values in the enum NoteEnum, converted to number here as we need numbers for calculation.
+     */
     public static WrapAroundCheck(value: number, limit: number): { halftone: number, overflow: number } {
     public static WrapAroundCheck(value: number, limit: number): { halftone: number, overflow: number } {
+        // the following one-line solution produces the same result, but isn't faster for -128 <= value <=, and harder to understand.
+        //   For very large (unrealistic) numbers it's much faster, see PR #1374.
+        // return {overflow: Math.floor(value / limit) || 0 , halftone:(value % limit + limit) % limit || 0 };
         let overflow: number = 0;
         let overflow: number = 0;
 
 
         while (value < 0) {
         while (value < 0) {
             value += limit;
             value += limit;
-            overflow--; // the octave change
+            overflow--; // octave change downwards
         }
         }
         while (value >= limit) {
         while (value >= limit) {
             value -= limit;
             value -= limit;
-            overflow++; // the octave change
+            overflow++; // octave change upwards
         }
         }
         return {overflow: overflow, halftone: value};
         return {overflow: overflow, halftone: value};
     }
     }

+ 24 - 3
src/MusicalScore/Graphical/EngravingRules.ts

@@ -147,7 +147,8 @@ export class EngravingRules {
     public MeasureNumberLabelXOffset: number;
     public MeasureNumberLabelXOffset: number;
     /** Whether tuplets should display ratio (3:2 instead of 3 for triplet). Default false. */
     /** Whether tuplets should display ratio (3:2 instead of 3 for triplet). Default false. */
     public TupletsRatioed: boolean;
     public TupletsRatioed: boolean;
-    /** Whether all tuplets should be bracketed (e.g. |--5--| instead of 5). Default false.
+    /** Whether tuplets (except triplets) should be bracketed (e.g. |--5--| instead of 5). Default false.
+     * Note that this doesn't affect triplets (|--3--|), which have their own setting TripletsBracketed.
      * If false, only tuplets given as bracketed in XML (bracket="yes") will be bracketed.
      * If false, only tuplets given as bracketed in XML (bracket="yes") will be bracketed.
      * (If not given in XML, bracketing is implementation-dependent according to standard)
      * (If not given in XML, bracketing is implementation-dependent according to standard)
      */
      */
@@ -244,6 +245,17 @@ export class EngravingRules {
     public SystemDotWidth: number;
     public SystemDotWidth: number;
     public MultipleRestMeasureDefaultWidth: number;
     public MultipleRestMeasureDefaultWidth: number;
     public MultipleRestMeasureAddKeySignature: boolean;
     public MultipleRestMeasureAddKeySignature: boolean;
+    /** Use the same measure width for all measures (experimental).
+     *  Note that this will use the largest width of all measures,
+     *  as Vexflow will mess up the layout with overlays if using less than minimum width.
+     *  See formatter.preCalculateMinTotalWidth()
+     */
+    public FixedMeasureWidth: boolean;
+    /** Use a fixed width for all measures (experimental).
+     *  This is mostly for debugging or for when you already know how big the measures
+     *  in the target score are, because using a too low width will cause overlaps in Vexflow.
+     */
+    public FixedMeasureWidthFixedValue: number;
     public DistanceBetweenVerticalSystemLines: number;
     public DistanceBetweenVerticalSystemLines: number;
     public DistanceBetweenDotAndLine: number;
     public DistanceBetweenDotAndLine: number;
     public RepeatEndStartPadding: number;
     public RepeatEndStartPadding: number;
@@ -333,7 +345,7 @@ export class EngravingRules {
     public RenderLyrics: boolean;
     public RenderLyrics: boolean;
     public RenderChordSymbols: boolean;
     public RenderChordSymbols: boolean;
     public RenderMultipleRestMeasures: boolean;
     public RenderMultipleRestMeasures: boolean;
-    public AutoGenerateMutipleRestMeasuresFromRestMeasures: boolean;
+    public AutoGenerateMultipleRestMeasuresFromRestMeasures: boolean;
     public RenderRehearsalMarks: boolean;
     public RenderRehearsalMarks: boolean;
     public RenderClefsAtBeginningOfStaffline: boolean;
     public RenderClefsAtBeginningOfStaffline: boolean;
     public RenderKeySignatures: boolean;
     public RenderKeySignatures: boolean;
@@ -362,6 +374,11 @@ export class EngravingRules {
     /** This is not for tabs, but for classical scores, especially violin. */
     /** This is not for tabs, but for classical scores, especially violin. */
     public StringNumberOffsetY: number;
     public StringNumberOffsetY: number;
     public NewSystemAtXMLNewSystemAttribute: boolean;
     public NewSystemAtXMLNewSystemAttribute: boolean;
+    /** Whether to begin a new system when a page break is given in XML ('new-page="yes"'), but newPageFromXML is false.
+     *  Default false, because it can lead to nonsensical system breaks after a single measure,
+     *  as OSMD does a different layout than the original music program exported from.
+     * */
+    public NewSystemAtXMLNewPageAttribute: boolean;
     public NewPageAtXMLNewPageAttribute: boolean;
     public NewPageAtXMLNewPageAttribute: boolean;
     public UseJustifiedBuilder: boolean;
     public UseJustifiedBuilder: boolean;
     public PageFormat: PageFormat;
     public PageFormat: PageFormat;
@@ -676,6 +693,9 @@ export class EngravingRules {
         this.MultipleRestMeasureDefaultWidth = 4;
         this.MultipleRestMeasureDefaultWidth = 4;
         this.MultipleRestMeasureAddKeySignature = true;
         this.MultipleRestMeasureAddKeySignature = true;
 
 
+        this.FixedMeasureWidth = false;
+        this.FixedMeasureWidthFixedValue = undefined; // only set to a number x if the width should be always x
+
         // Line Widths
         // Line Widths
         this.MinimumCrossedBeamDifferenceMargin = 0.0001;
         this.MinimumCrossedBeamDifferenceMargin = 0.0001;
 
 
@@ -737,7 +757,7 @@ export class EngravingRules {
         this.RenderLyrics = true;
         this.RenderLyrics = true;
         this.RenderChordSymbols = true;
         this.RenderChordSymbols = true;
         this.RenderMultipleRestMeasures = true;
         this.RenderMultipleRestMeasures = true;
-        this.AutoGenerateMutipleRestMeasuresFromRestMeasures = true;
+        this.AutoGenerateMultipleRestMeasuresFromRestMeasures = true;
         this.RenderRehearsalMarks = true;
         this.RenderRehearsalMarks = true;
         this.RenderClefsAtBeginningOfStaffline = true;
         this.RenderClefsAtBeginningOfStaffline = true;
         this.RenderKeySignatures = true;
         this.RenderKeySignatures = true;
@@ -758,6 +778,7 @@ export class EngravingRules {
         this.StringNumberOffsetY = 0.0;
         this.StringNumberOffsetY = 0.0;
         this.NewSystemAtXMLNewSystemAttribute = false;
         this.NewSystemAtXMLNewSystemAttribute = false;
         this.NewPageAtXMLNewPageAttribute = false;
         this.NewPageAtXMLNewPageAttribute = false;
+        this.NewSystemAtXMLNewPageAttribute = false;
         this.RestoreCursorAfterRerender = true;
         this.RestoreCursorAfterRerender = true;
         this.StretchLastSystemLine = false;
         this.StretchLastSystemLine = false;
         this.IgnoreBracketsWords = true;
         this.IgnoreBracketsWords = true;

+ 5 - 0
src/MusicalScore/Graphical/GraphicalOctaveShift.ts

@@ -4,6 +4,7 @@ import {BoundingBox} from "./BoundingBox";
 import {MusicSymbol} from "./MusicSymbol";
 import {MusicSymbol} from "./MusicSymbol";
 import {ArgumentOutOfRangeException} from "../Exceptions";
 import {ArgumentOutOfRangeException} from "../Exceptions";
 import {PointF2D} from "../../Common/DataObjects/PointF2D";
 import {PointF2D} from "../../Common/DataObjects/PointF2D";
+import { GraphicalMeasure } from "./GraphicalMeasure";
 
 
 /**
 /**
  * The graphical counterpart of an [[OctaveShift]]
  * The graphical counterpart of an [[OctaveShift]]
@@ -24,6 +25,10 @@ export class GraphicalOctaveShift extends GraphicalObject {
     public dashesStart: PointF2D;
     public dashesStart: PointF2D;
     public dashesEnd: PointF2D;
     public dashesEnd: PointF2D;
     public endsOnDifferentStaffLine: boolean;
     public endsOnDifferentStaffLine: boolean;
+    /** Whether the octave shift should be drawn until the end of the measure, instead of the current note. */
+    public graphicalEndAtMeasureEnd: boolean;
+    /** The measure in which this OctaveShift (which can be a part/bracket of a multi-line shift) ends graphically. */
+    public endMeasure: GraphicalMeasure;
     public isFirstPart: boolean;
     public isFirstPart: boolean;
     public isSecondPart: boolean;
     public isSecondPart: boolean;
 
 

+ 39 - 7
src/MusicalScore/Graphical/MusicSheetCalculator.ts

@@ -199,7 +199,7 @@ export abstract class MusicSheetCalculator {
             }
             }
         }
         }
 
 
-        if (this.rules.AutoGenerateMutipleRestMeasuresFromRestMeasures && this.rules.RenderMultipleRestMeasures) {
+        if (this.rules.AutoGenerateMultipleRestMeasuresFromRestMeasures && this.rules.RenderMultipleRestMeasures) {
             //track number of multirests
             //track number of multirests
             let beginMultiRestMeasure: SourceMeasure = undefined;
             let beginMultiRestMeasure: SourceMeasure = undefined;
             let multiRestCount: number = 0;
             let multiRestCount: number = 0;
@@ -316,13 +316,32 @@ export abstract class MusicSheetCalculator {
             minimumStaffEntriesWidth = this.calculateMeasureWidthFromStaffEntries(measures, minimumStaffEntriesWidth);
             minimumStaffEntriesWidth = this.calculateMeasureWidthFromStaffEntries(measures, minimumStaffEntriesWidth);
             MusicSheetCalculator.setMeasuresMinStaffEntriesWidth(measures, minimumStaffEntriesWidth);
             MusicSheetCalculator.setMeasuresMinStaffEntriesWidth(measures, minimumStaffEntriesWidth);
             // minLength = minimumStaffEntriesWidth * 1.2 + maxInstrNameLabelLength + maxInstructionsLength;
             // minLength = minimumStaffEntriesWidth * 1.2 + maxInstrNameLabelLength + maxInstructionsLength;
+            let maxWidth: number = 0;
             for (let i: number = 1; i < this.graphicalMusicSheet.MeasureList.length; i++) {
             for (let i: number = 1; i < this.graphicalMusicSheet.MeasureList.length; i++) {
                 measures = this.graphicalMusicSheet.MeasureList[i];
                 measures = this.graphicalMusicSheet.MeasureList[i];
                 minimumStaffEntriesWidth = this.calculateMeasureXLayout(measures);
                 minimumStaffEntriesWidth = this.calculateMeasureXLayout(measures);
                 minimumStaffEntriesWidth = this.calculateMeasureWidthFromStaffEntries(measures, minimumStaffEntriesWidth);
                 minimumStaffEntriesWidth = this.calculateMeasureWidthFromStaffEntries(measures, minimumStaffEntriesWidth);
+                if (minimumStaffEntriesWidth > maxWidth) {
+                    maxWidth = minimumStaffEntriesWidth;
+                }
+                //console.log(`min width for measure ${measures[0].MeasureNumber}: ${minimumStaffEntriesWidth}`);
                 MusicSheetCalculator.setMeasuresMinStaffEntriesWidth(measures, minimumStaffEntriesWidth);
                 MusicSheetCalculator.setMeasuresMinStaffEntriesWidth(measures, minimumStaffEntriesWidth);
                 // minLength = Math.max(minLength, minimumStaffEntriesWidth * 1.2 + maxInstructionsLength);
                 // minLength = Math.max(minLength, minimumStaffEntriesWidth * 1.2 + maxInstructionsLength);
             }
             }
+            if (this.rules.FixedMeasureWidth) {
+                // experimental: use the same measure width for all measures
+                //   here we take the maximum measure width for now,
+                //   otherwise Vexflow's layout can get completely messed up and place everything on top of each other,
+                //   if it gets less width than it says it needs as a minimum for a measure. (formatter.preCalculateMinTotalWidth)
+                let targetWidth: number = maxWidth;
+                if (this.rules.FixedMeasureWidthFixedValue) {
+                    targetWidth = this.rules.FixedMeasureWidthFixedValue;
+                }
+                for (let i: number = 1; i < this.graphicalMusicSheet.MeasureList.length; i++) {
+                    measures = this.graphicalMusicSheet.MeasureList[i];
+                    MusicSheetCalculator.setMeasuresMinStaffEntriesWidth(measures, targetWidth);
+                }
+            }
         }
         }
         // this.graphicalMusicSheet.MinAllowedSystemWidth = minLength; // currently unused
         // this.graphicalMusicSheet.MinAllowedSystemWidth = minLength; // currently unused
     }
     }
@@ -859,7 +878,6 @@ export abstract class MusicSheetCalculator {
             return;
             return;
         }
         }
 
 
-
         // build the MusicSystems
         // build the MusicSystems
         let musicSystemBuilder: MusicSystemBuilder;
         let musicSystemBuilder: MusicSystemBuilder;
         const measureCount: number = allMeasures.length;
         const measureCount: number = allMeasures.length;
@@ -2522,9 +2540,16 @@ export abstract class MusicSheetCalculator {
         const octaveShifts: MultiExpression[] = [];
         const octaveShifts: MultiExpression[] = [];
         for (let idx: number = 0, len: number = sourceMeasure.StaffLinkedExpressions[staffIndex].length; idx < len; ++idx) {
         for (let idx: number = 0, len: number = sourceMeasure.StaffLinkedExpressions[staffIndex].length; idx < len; ++idx) {
             const multiExpression: MultiExpression = sourceMeasure.StaffLinkedExpressions[staffIndex][idx];
             const multiExpression: MultiExpression = sourceMeasure.StaffLinkedExpressions[staffIndex][idx];
+            let targetOctaveShift: OctaveShift;
             if (multiExpression.OctaveShiftStart) {
             if (multiExpression.OctaveShiftStart) {
+                targetOctaveShift = multiExpression.OctaveShiftStart;
+            } else if (multiExpression.OctaveShiftEnd) {
+                // also check for octave shift that is ending here but starting in earlier measure, see test_octaveshift_notes_shifted_octave_shift_end.musicxml
+                targetOctaveShift = multiExpression.OctaveShiftEnd;
+            }
+            if (targetOctaveShift) {
                 octaveShifts.push(multiExpression);
                 octaveShifts.push(multiExpression);
-                const openOctaveShift: OctaveShift = multiExpression.OctaveShiftStart;
+                const openOctaveShift: OctaveShift = targetOctaveShift;
                 let absoluteEnd: Fraction = openOctaveShift?.ParentEndMultiExpression?.AbsoluteTimestamp;
                 let absoluteEnd: Fraction = openOctaveShift?.ParentEndMultiExpression?.AbsoluteTimestamp;
                 if (!openOctaveShift?.ParentEndMultiExpression) {
                 if (!openOctaveShift?.ParentEndMultiExpression) {
                     const measureEndTimestamp: Fraction = Fraction.plus(sourceMeasure.AbsoluteTimestamp, sourceMeasure.Duration);
                     const measureEndTimestamp: Fraction = Fraction.plus(sourceMeasure.AbsoluteTimestamp, sourceMeasure.Duration);
@@ -2534,7 +2559,8 @@ export abstract class MusicSheetCalculator {
                     // TODO check if octaveshift end exists, otherwise set to last measure end. only necessary if xml was cut manually and is incomplete
                     // TODO check if octaveshift end exists, otherwise set to last measure end. only necessary if xml was cut manually and is incomplete
                 }
                 }
                 openOctaveShifts[staffIndex] = new OctaveShiftParams(
                 openOctaveShifts[staffIndex] = new OctaveShiftParams(
-                    openOctaveShift, multiExpression?.AbsoluteTimestamp,
+                    openOctaveShift, openOctaveShift.ParentStartMultiExpression.AbsoluteTimestamp,
+                    //openOctaveShift, multiExpression?.AbsoluteTimestamp,
                     absoluteEnd
                     absoluteEnd
                 );
                 );
             }
             }
@@ -2577,9 +2603,15 @@ export abstract class MusicSheetCalculator {
                 if (octaveShiftValue === OctaveEnum.NONE) {
                 if (octaveShiftValue === OctaveEnum.NONE) {
                     // check for existing octave shifts outside openOctaveShifts
                     // check for existing octave shifts outside openOctaveShifts
                     for (const octaveShift of octaveShifts) {
                     for (const octaveShift of octaveShifts) {
-                        if (octaveShift.OctaveShiftStart?.ParentStartMultiExpression?.AbsoluteTimestamp.lte(sourceStaffEntry.AbsoluteTimestamp) &&
-                            !octaveShift.OctaveShiftStart?.ParentEndMultiExpression?.AbsoluteTimestamp.lt(sourceStaffEntry.AbsoluteTimestamp)) {
-                                octaveShiftValue = octaveShift.OctaveShiftStart.Type;
+                        let targetOctaveShift: OctaveShift;
+                        if (octaveShift.OctaveShiftStart) {
+                            targetOctaveShift = octaveShift.OctaveShiftStart;
+                        } else if (octaveShift.OctaveShiftEnd) {
+                            targetOctaveShift = octaveShift.OctaveShiftEnd;
+                        }
+                        if (targetOctaveShift?.ParentStartMultiExpression?.AbsoluteTimestamp.lte(sourceStaffEntry.AbsoluteTimestamp) &&
+                            !targetOctaveShift.ParentEndMultiExpression?.AbsoluteTimestamp.lt(sourceStaffEntry.AbsoluteTimestamp)) {
+                                octaveShiftValue = targetOctaveShift.Type;
                                 break;
                                 break;
                             }
                             }
                     }
                     }

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

@@ -134,7 +134,9 @@ export class MusicSystemBuilder {
             }
             }
             const measureFitsInSystem: boolean = this.currentSystemParams.currentWidth + totalMeasureWidth + nextMeasureBeginInstructionWidth < systemMaxWidth;
             const measureFitsInSystem: boolean = this.currentSystemParams.currentWidth + totalMeasureWidth + nextMeasureBeginInstructionWidth < systemMaxWidth;
             const doXmlPageBreak: boolean = this.rules.NewPageAtXMLNewPageAttribute && sourceMeasure.printNewPageXml;
             const doXmlPageBreak: boolean = this.rules.NewPageAtXMLNewPageAttribute && sourceMeasure.printNewPageXml;
-            const doXmlLineBreak: boolean = doXmlPageBreak || // also create new system if doing page break
+            const impliedSystemBreak: boolean = doXmlPageBreak || // also create new system if doing page break
+                (this.rules.NewSystemAtXMLNewPageAttribute && sourceMeasure.printNewPageXml);
+            const doXmlLineBreak: boolean = impliedSystemBreak ||
                 (this.rules.NewSystemAtXMLNewSystemAttribute && sourceMeasure.printNewSystemXml);
                 (this.rules.NewSystemAtXMLNewSystemAttribute && sourceMeasure.printNewSystemXml);
             if (isSystemStartMeasure || (measureFitsInSystem && !doXmlLineBreak)) {
             if (isSystemStartMeasure || (measureFitsInSystem && !doXmlLineBreak)) {
                 this.addMeasureToSystem(
                 this.addMeasureToSystem(
@@ -167,6 +169,7 @@ export class MusicSystemBuilder {
                 this.finalizeCurrentSystem(this.measureList[this.measureList.length - 1], !this.rules.StretchLastSystemLine, false);
                 this.finalizeCurrentSystem(this.measureList[this.measureList.length - 1], !this.rules.StretchLastSystemLine, false);
                 return this.musicSystems;
                 return this.musicSystems;
             }
             }
+            // TODO FixedMeasureWidth: last measure will have a different stretch factor, misaligning measures and widths. use previous stretch factor instead
             this.finalizeCurrentAndCreateNewSystem(this.measureList[this.measureList.length - 1], !this.rules.StretchLastSystemLine, false);
             this.finalizeCurrentAndCreateNewSystem(this.measureList[this.measureList.length - 1], !this.rules.StretchLastSystemLine, false);
         }
         }
         return this.musicSystems;
         return this.musicSystems;

+ 48 - 20
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator.ts

@@ -963,12 +963,14 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
 
 
       if (endStaffLine !== startStaffLine) {
       if (endStaffLine !== startStaffLine) {
         graphicalOctaveShift.endsOnDifferentStaffLine = true;
         graphicalOctaveShift.endsOnDifferentStaffLine = true;
-        let lastMeasureOfFirstShift: GraphicalMeasure = startStaffLine.Measures[startStaffLine.Measures.length - 1];
-        if (lastMeasureOfFirstShift === undefined) { // TODO handle this case correctly (when drawUpToMeasureNumber etc set)
+        let lastMeasureOfFirstShift: GraphicalMeasure = this.findLastStafflineMeasure(startStaffLine);
+        if (lastMeasureOfFirstShift === undefined) { // TODO handle this case correctly (e.g. when no staffentries found above or drawUpToMeasureNumber set)
           lastMeasureOfFirstShift = endMeasure;
           lastMeasureOfFirstShift = endMeasure;
         }
         }
         const lastNoteOfFirstShift: GraphicalStaffEntry = lastMeasureOfFirstShift.staffEntries[lastMeasureOfFirstShift.staffEntries.length - 1];
         const lastNoteOfFirstShift: GraphicalStaffEntry = lastMeasureOfFirstShift.staffEntries[lastMeasureOfFirstShift.staffEntries.length - 1];
         graphicalOctaveShift.setEndNote(lastNoteOfFirstShift);
         graphicalOctaveShift.setEndNote(lastNoteOfFirstShift);
+        graphicalOctaveShift.graphicalEndAtMeasureEnd = true;
+        graphicalOctaveShift.endMeasure = lastMeasureOfFirstShift;
 
 
         const systemsInBetweenCount: number = endStaffLine.ParentMusicSystem.Id - startStaffLine.ParentMusicSystem.Id;
         const systemsInBetweenCount: number = endStaffLine.ParentMusicSystem.Id - startStaffLine.ParentMusicSystem.Id;
         if (systemsInBetweenCount > 0) {
         if (systemsInBetweenCount > 0) {
@@ -980,14 +982,13 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
             const nextShiftFirstMeasure: GraphicalMeasure = nextShiftStaffline.Measures[0];
             const nextShiftFirstMeasure: GraphicalMeasure = nextShiftStaffline.Measures[0];
             // Shift starts on the first measure
             // Shift starts on the first measure
             const nextOctaveShift: VexFlowOctaveShift = new VexFlowOctaveShift(octaveShift, nextShiftFirstMeasure.PositionAndShape);
             const nextOctaveShift: VexFlowOctaveShift = new VexFlowOctaveShift(octaveShift, nextShiftFirstMeasure.PositionAndShape);
+            let nextShiftLastMeasure: GraphicalMeasure = this.findLastStafflineMeasure(nextShiftStaffline);
 
 
-            if (i < systemsInBetweenCount) {
+            if (i < systemsInBetweenCount - 1) {
+              // if not - 1, the last octaveshift will always go to the end of the staffline
               nextOctaveShift.endsOnDifferentStaffLine = true;
               nextOctaveShift.endsOnDifferentStaffLine = true;
-            }
-
-            let nextShiftLastMeasure: GraphicalMeasure = nextShiftStaffline.Measures[nextShiftStaffline.Measures.length - 1];
-            if (nextShiftLastMeasure.IsExtraGraphicalMeasure) { // key/rhythm change measure
-              nextShiftLastMeasure = nextShiftStaffline.Measures[nextShiftStaffline.Measures.length - 2];
+              nextOctaveShift.graphicalEndAtMeasureEnd = true;
+              nextOctaveShift.endMeasure = nextShiftLastMeasure;
             }
             }
             const firstNote: GraphicalStaffEntry = nextShiftFirstMeasure.staffEntries[0];
             const firstNote: GraphicalStaffEntry = nextShiftFirstMeasure.staffEntries[0];
             let lastNote: GraphicalStaffEntry = nextShiftLastMeasure.staffEntries[nextShiftLastMeasure.staffEntries.length - 1];
             let lastNote: GraphicalStaffEntry = nextShiftLastMeasure.staffEntries[nextShiftLastMeasure.staffEntries.length - 1];
@@ -998,6 +999,15 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
               lastNote = endStaffEntry;
               lastNote = endStaffEntry;
             }
             }
 
 
+            if (lastNote.graphicalVoiceEntries.length === 1 &&
+              lastNote.graphicalVoiceEntries[0].notes.length === 1 &&
+              lastNote.graphicalVoiceEntries[0].notes[0].sourceNote.isWholeMeasureNote()
+            ) {
+              // also draw octaveshift until end of measure if we have a whole note that goes over the whole measure
+              nextOctaveShift.graphicalEndAtMeasureEnd = true;
+              nextOctaveShift.endMeasure = nextShiftLastMeasure;
+            }
+
             const logPrefix: string = "VexFlowMusicSheetCalculator.calculateSingleOctaveShift: ";
             const logPrefix: string = "VexFlowMusicSheetCalculator.calculateSingleOctaveShift: ";
             if (!firstNote) {
             if (!firstNote) {
               log.warn(logPrefix + "no firstNote found");
               log.warn(logPrefix + "no firstNote found");
@@ -1023,6 +1033,18 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     }
     }
   }
   }
 
 
+  /** Finds the last staffline measure that has staffentries. (staffentries necessary for octaveshift and pedal) */
+  protected findLastStafflineMeasure(staffline: StaffLine): GraphicalMeasure {
+    for (let i: number = staffline.Measures.length - 1; i >= 0; i--) {
+      const measure: GraphicalMeasure = staffline.Measures[i];
+      if (measure.staffEntries.length > 0) {
+        return measure;
+        // a measure can have no staff entries if e.g. measure.IsExtraGraphicalMeasure, used to show key/rhythm changes.
+      }
+      // else continue with the measure before this one
+    }
+  }
+
   protected calculateSinglePedal(sourceMeasure: SourceMeasure, multiExpression: MultiExpression, measureIndex: number, staffIndex: number): void {
   protected calculateSinglePedal(sourceMeasure: SourceMeasure, multiExpression: MultiExpression, measureIndex: number, staffIndex: number): void {
     // calculate absolute Timestamp and startStaffLine (and EndStaffLine if needed)
     // calculate absolute Timestamp and startStaffLine (and EndStaffLine if needed)
     const pedal: Pedal = multiExpression.PedalStart;
     const pedal: Pedal = multiExpression.PedalStart;
@@ -1123,7 +1145,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
           nextPedal.DepressText = " ";
           nextPedal.DepressText = " ";
           this.calculatePedalSkyBottomLine(nextPedal.startVfVoiceEntry, nextPedal.endVfVoiceEntry, nextPedal, endStaffLine);
           this.calculatePedalSkyBottomLine(nextPedal.startVfVoiceEntry, nextPedal.endVfVoiceEntry, nextPedal, endStaffLine);
         } else {
         } else {
-          let lastMeasureOfFirstShift: GraphicalMeasure = startStaffLine.Measures[startStaffLine.Measures.length - 1];
+          let lastMeasureOfFirstShift: GraphicalMeasure = this.findLastStafflineMeasure(startStaffLine);
           if (lastMeasureOfFirstShift === undefined) { // TODO handle this case correctly (when drawUpToMeasureNumber etc set)
           if (lastMeasureOfFirstShift === undefined) { // TODO handle this case correctly (when drawUpToMeasureNumber etc set)
             lastMeasureOfFirstShift = endMeasure;
             lastMeasureOfFirstShift = endMeasure;
           }
           }
@@ -1157,7 +1179,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
               } else {
               } else {
                 nextPedal.ChangeEnd = false;
                 nextPedal.ChangeEnd = false;
               }
               }
-              let nextPedalLastMeasure: GraphicalMeasure = nextPedalStaffline.Measures[nextPedalStaffline.Measures.length - 1];
+              let nextPedalLastMeasure: GraphicalMeasure = this.findLastStafflineMeasure(nextPedalStaffline);
               const firstNote: GraphicalStaffEntry = nextPedalFirstMeasure.staffEntries[0];
               const firstNote: GraphicalStaffEntry = nextPedalFirstMeasure.staffEntries[0];
               let lastNote: GraphicalStaffEntry = nextPedalLastMeasure.staffEntries[nextPedalLastMeasure.staffEntries.length - 1];
               let lastNote: GraphicalStaffEntry = nextPedalLastMeasure.staffEntries[nextPedalLastMeasure.staffEntries.length - 1];
 
 
@@ -1531,8 +1553,12 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
       log.warn("octaveshift: no endStaffEntry");
       log.warn("octaveshift: no endStaffEntry");
       return;
       return;
     }
     }
+    let endBbox: BoundingBox = endStaffEntry.PositionAndShape;
+    if (vfOctaveShift.graphicalEndAtMeasureEnd) {
+      endBbox = endStaffEntry.parentMeasure.PositionAndShape;
+    }
     let startXOffset: number = startStaffEntry.PositionAndShape.Size.width;
     let startXOffset: number = startStaffEntry.PositionAndShape.Size.width;
-    let endXOffset: number = endStaffEntry.PositionAndShape.Size.width;
+    let endXOffset: number = endBbox.Size.width;
 
 
     //Vexflow renders differently with rests
     //Vexflow renders differently with rests
     if (startStaffEntry.hasOnlyRests()) {
     if (startStaffEntry.hasOnlyRests()) {
@@ -1541,17 +1567,19 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
       startXOffset /= 2;
       startXOffset /= 2;
     }
     }
 
 
-    if (!endStaffEntry.hasOnlyRests()) {
-      endXOffset /= 2;
-    } else {
-      endXOffset *= 2;
+    if (!vfOctaveShift.graphicalEndAtMeasureEnd) {
+      if (!endStaffEntry.hasOnlyRests()) {
+        endXOffset /= 2;
+      } else {
+        endXOffset *= 2;
+      }
+      if (startStaffEntry === endStaffEntry) {
+        endXOffset *= 2;
+      }
     }
     }
 
 
-    if (startStaffEntry === endStaffEntry) {
-      endXOffset *= 2;
-    }
     let startX: number = startStaffEntry.PositionAndShape.AbsolutePosition.x - startXOffset;
     let startX: number = startStaffEntry.PositionAndShape.AbsolutePosition.x - startXOffset;
-    let stopX: number = endStaffEntry.PositionAndShape.AbsolutePosition.x + endXOffset;
+    let stopX: number = endBbox.AbsolutePosition.x + endXOffset;
     if (startX > stopX) {
     if (startX > stopX) {
       // very rare case of the start staffentry being before end staffentry. would lead to error in skybottomline. See #1281
       // very rare case of the start staffentry being before end staffentry. would lead to error in skybottomline. See #1281
       // reverse startX and endX
       // reverse startX and endX
@@ -1560,7 +1588,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
       stopX = oldStartX;
       stopX = oldStartX;
     }
     }
 
 
-    vfOctaveShift.PositionAndShape.Size.width = startX - stopX;
+    vfOctaveShift.PositionAndShape.Size.width = stopX - startX;
     const textBracket: VF.TextBracket = vfOctaveShift.getTextBracket();
     const textBracket: VF.TextBracket = vfOctaveShift.getTextBracket();
     const fontSize: number = (textBracket as any).font.size / 10;
     const fontSize: number = (textBracket as any).font.size / 10;
 
 

+ 31 - 2
src/MusicalScore/Graphical/VexFlow/VexFlowOctaveShift.ts

@@ -92,13 +92,42 @@ export class VexFlowOctaveShift extends GraphicalOctaveShift {
      * Get the actual vexflow text bracket used for drawing
      * Get the actual vexflow text bracket used for drawing
      */
      */
     public getTextBracket(): VF.TextBracket {
     public getTextBracket(): VF.TextBracket {
-        return new VF.TextBracket({
+        let stop: VF.Note = this.endNote;
+        let stopObject: Object;
+        const self: VexFlowOctaveShift = this;
+        if (this.graphicalEndAtMeasureEnd) {
+            // draw until end of measure (measure end barline):
+            //   hack for Vexflow 1.2.93 (will need to be adjusted for Vexflow 4+):
+            //   create a mock object with all the data Vexflow uses for the TextBracket
+            //   (Vexflow theoretically expects a note here, from which it takes position and width)
+            stopObject = {
+                getAbsoluteX(): number {
+                    return (self.endMeasure.PositionAndShape.AbsolutePosition.x + self.endMeasure.PositionAndShape.Size.width) * 10;
+                },
+                getGlyph(): Object {
+                    return {
+                        getWidth(): number {
+                            return 0;
+                        }
+                    };
+                }
+            };
+        }
+        if (stopObject) {
+            stop = stopObject as any;
+        }
+        const vfBracket: VF.TextBracket = new VF.TextBracket({
             position: this.position,
             position: this.position,
             start: this.startNote,
             start: this.startNote,
-            stop: this.endNote,
+            stop: stop,
             superscript: this.supscript,
             superscript: this.supscript,
             text: this.text,
             text: this.text,
         });
         });
+        if (this.endsOnDifferentStaffLine) {
+            // make bracket open-ended (--- instead of ---|) if not ending on current staffline
+            (vfBracket as any).render_options.show_bracket = false;
+        }
+        return vfBracket;
     }
     }
 
 
 }
 }

+ 1 - 1
src/MusicalScore/MusicSheet.ts

@@ -17,10 +17,10 @@ import {NoteState} from "./Graphical/DrawingEnums";
 import {Note} from "./VoiceData/Note";
 import {Note} from "./VoiceData/Note";
 import {VoiceEntry} from "./VoiceData/VoiceEntry";
 import {VoiceEntry} from "./VoiceData/VoiceEntry";
 import log from "loglevel";
 import log from "loglevel";
+import { TextAlignmentEnum } from "../Common/Enums/TextAlignment";
 import { Dictionary } from "typescript-collections";
 import { Dictionary } from "typescript-collections";
 import { PlaybackEntry } from "./Playback/PlaybackEntry";
 import { PlaybackEntry } from "./Playback/PlaybackEntry";
 import { PlaybackSettings } from "../Common/DataObjects/PlaybackSettings";
 import { PlaybackSettings } from "../Common/DataObjects/PlaybackSettings";
-import { TextAlignmentEnum } from "../Common/Enums/TextAlignment";
 
 
 // FIXME Andrea: Commented out some unnecessary/not-ported-yet code, have a look at (*)
 // FIXME Andrea: Commented out some unnecessary/not-ported-yet code, have a look at (*)
 
 

+ 8 - 0
src/MusicalScore/VoiceData/Expressions/InstantaneousTempoExpression.ts

@@ -41,6 +41,14 @@ export class InstantaneousTempoExpression extends AbstractTempoExpression {
         "tempo i",
         "tempo i",
         "rubato",
         "rubato",
         "doppio movimento",
         "doppio movimento",
+        "rallentando",
+        "ritardando",
+        "ritard.",
+        "rit.",
+        "ritard",
+        "rall...",
+        "accelerando",
+        "accel",
     ];
     ];
     private static listInstantaneousTempoAddons: string[] = [
     private static listInstantaneousTempoAddons: string[] = [
         "assai",
         "assai",

+ 5 - 0
src/MusicalScore/VoiceData/Note.ts

@@ -272,6 +272,11 @@ export class Note {
         return this.isRest() && this.Length.RealValue === this.sourceMeasure.ActiveTimeSignature.RealValue;
         return this.isRest() && this.Length.RealValue === this.sourceMeasure.ActiveTimeSignature.RealValue;
     }
     }
 
 
+    /** Whether the note fills the whole measure. */
+    public isWholeMeasureNote(): boolean {
+        return this.Length.RealValue === this.sourceMeasure.ActiveTimeSignature.RealValue;
+    }
+
     public ToString(): string {
     public ToString(): string {
         if (this.pitch) {
         if (this.pitch) {
             return this.Pitch.ToString() + ", length: " + this.length.toString();
             return this.Pitch.ToString() + ", length: " + this.length.toString();

+ 6 - 1
src/OpenSheetMusicDisplay/OSMDOptions.ts

@@ -185,6 +185,11 @@ export interface IOSMDOptions {
      *  at different measures. So this option may result in a system break after a single measure in a system.
      *  at different measures. So this option may result in a system break after a single measure in a system.
      */
      */
     newSystemFromXML?: boolean;
     newSystemFromXML?: boolean;
+    /** Whether to begin a new system ("line break") when given a new page in XML ('new-page="yes"'), but newPageFromXML is false.
+     *  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.
+     */
+    newSystemFromNewPageInXML?: boolean;
     /** Whether to begin a new page ("page break") when given in XML ('new-page="yes"').
     /** Whether to begin a new page ("page break") when given in XML ('new-page="yes"').
      *  Default false, because OSMD does its own layout that will do page breaks interactively
      *  Default false, because OSMD does its own layout that will do page breaks interactively
      * (when given a PageFormat) at different measures.
      * (when given a PageFormat) at different measures.
@@ -257,7 +262,7 @@ export interface IOSMDOptions {
      * Set to true if subsequent measures full of rests should be auto-converted to multi-rest measure. Default is true
      * Set to true if subsequent measures full of rests should be auto-converted to multi-rest measure. Default is true
      * This works across instruments- If all instruments have subsequent measures with nothing but rests, multirest measures are generated
      * This works across instruments- If all instruments have subsequent measures with nothing but rests, multirest measures are generated
      */
      */
-    autoGenerateMutipleRestMeasuresFromRestMeasures?: boolean;
+    autoGenerateMultipleRestMeasuresFromRestMeasures?: boolean;
     /**
     /**
      * Defines multiple simultaneous cursors. If left undefined the standard cursor will be used.
      * Defines multiple simultaneous cursors. If left undefined the standard cursor will be used.
      */
      */

+ 9 - 7
src/OpenSheetMusicDisplay/OpenSheetMusicDisplay.ts

@@ -35,7 +35,7 @@ import { DynamicsCalculator } from "../MusicalScore/ScoreIO/MusicSymbolModules/D
  * After the constructor, use load() and render() to load and render a MusicXML file.
  * After the constructor, use load() and render() to load and render a MusicXML file.
  */
  */
 export class OpenSheetMusicDisplay {
 export class OpenSheetMusicDisplay {
-    private version: string = "1.7.5-audio-extended"; // getter: this.Version
+    private version: string = "1.7.6-audio-extended"; // getter: this.Version
     // at release, bump version and change to -release, afterwards to -dev again
     // at release, bump version and change to -release, afterwards to -dev again
 
 
     /**
     /**
@@ -611,6 +611,9 @@ export class OpenSheetMusicDisplay {
         if (options.newSystemFromXML !== undefined) {
         if (options.newSystemFromXML !== undefined) {
             this.rules.NewSystemAtXMLNewSystemAttribute = options.newSystemFromXML;
             this.rules.NewSystemAtXMLNewSystemAttribute = options.newSystemFromXML;
         }
         }
+        if (options.newSystemFromNewPageInXML !== undefined) {
+            this.rules.NewSystemAtXMLNewPageAttribute = options.newSystemFromNewPageInXML;
+        }
         if (options.newPageFromXML !== undefined) {
         if (options.newPageFromXML !== undefined) {
             this.rules.NewPageAtXMLNewPageAttribute = options.newPageFromXML;
             this.rules.NewPageAtXMLNewPageAttribute = options.newPageFromXML;
         }
         }
@@ -705,8 +708,8 @@ export class OpenSheetMusicDisplay {
         if (options.stretchLastSystemLine !== undefined) {
         if (options.stretchLastSystemLine !== undefined) {
             this.rules.StretchLastSystemLine = options.stretchLastSystemLine;
             this.rules.StretchLastSystemLine = options.stretchLastSystemLine;
         }
         }
-        if (options.autoGenerateMutipleRestMeasuresFromRestMeasures !== undefined) {
-            this.rules.AutoGenerateMutipleRestMeasuresFromRestMeasures = options.autoGenerateMutipleRestMeasuresFromRestMeasures;
+        if (options.autoGenerateMultipleRestMeasuresFromRestMeasures !== undefined) {
+            this.rules.AutoGenerateMultipleRestMeasuresFromRestMeasures = options.autoGenerateMultipleRestMeasuresFromRestMeasures;
         }
         }
         if (options.cursorsOptions !== undefined) {
         if (options.cursorsOptions !== undefined) {
             this.cursorsOptions = options.cursorsOptions;
             this.cursorsOptions = options.cursorsOptions;
@@ -726,12 +729,12 @@ export class OpenSheetMusicDisplay {
             this.rules.ColoringMode = ColoringModes.XML;
             this.rules.ColoringMode = ColoringModes.XML;
             return;
             return;
         }
         }
-        const noteIndices: NoteEnum[] = [NoteEnum.C, NoteEnum.D, NoteEnum.E, NoteEnum.F, NoteEnum.G, NoteEnum.A, NoteEnum.B, -1];
+        const noteIndices: NoteEnum[] = [NoteEnum.C, NoteEnum.D, NoteEnum.E, NoteEnum.F, NoteEnum.G, NoteEnum.A, NoteEnum.B];
         let colorSetString: string[];
         let colorSetString: string[];
         if (options.coloringMode === ColoringModes.CustomColorSet) {
         if (options.coloringMode === ColoringModes.CustomColorSet) {
             if (!options.coloringSetCustom || options.coloringSetCustom.length !== 8) {
             if (!options.coloringSetCustom || options.coloringSetCustom.length !== 8) {
                 throw new Error("Invalid amount of colors: With coloringModes.customColorSet, " +
                 throw new Error("Invalid amount of colors: With coloringModes.customColorSet, " +
-                    "you have to provide a coloringSetCustom parameter with 8 strings (C to B, rest note).");
+                    "you have to provide a coloringSetCustom parameter (array) with 8 strings (C to B, rest note).");
             }
             }
             // validate strings input
             // validate strings input
             for (const colorString of options.coloringSetCustom) {
             for (const colorString of options.coloringSetCustom) {
@@ -753,9 +756,8 @@ export class OpenSheetMusicDisplay {
         for (let i: number = 0; i < noteIndices.length; i++) {
         for (let i: number = 0; i < noteIndices.length; i++) {
             coloringSetCurrent.setValue(noteIndices[i], colorSetString[i]);
             coloringSetCurrent.setValue(noteIndices[i], colorSetString[i]);
         }
         }
-        coloringSetCurrent.setValue(-1, colorSetString[7]);
+        coloringSetCurrent.setValue(-1, colorSetString.last()); // index 7. Unfortunately -1 is not a NoteEnum value, so we can't put it into noteIndices
         this.rules.ColoringSetCurrent = coloringSetCurrent;
         this.rules.ColoringSetCurrent = coloringSetCurrent;
-
         this.rules.ColoringMode = options.coloringMode;
         this.rules.ColoringMode = options.coloringMode;
     }
     }
 
 

+ 6 - 0
test/Util/generateImages_browserless.mjs

@@ -318,7 +318,9 @@ async function generateSampleImage (sampleFilename, directory, osmdInstance, osm
         const defaultOrCompactTightMode = sampleFilename.startsWith("OSMD_Function_Test_Container_height") ? "compacttight" : "default";
         const defaultOrCompactTightMode = sampleFilename.startsWith("OSMD_Function_Test_Container_height") ? "compacttight" : "default";
         const isTestFlatBeams = sampleFilename.startsWith("test_drum_tuplet_beams");
         const isTestFlatBeams = sampleFilename.startsWith("test_drum_tuplet_beams");
         const isTestEndClefStaffEntryBboxes = sampleFilename.startsWith("test_end_measure_clefs_staffentry_bbox");
         const isTestEndClefStaffEntryBboxes = sampleFilename.startsWith("test_end_measure_clefs_staffentry_bbox");
+        const isTestPageBreakImpliesSystemBreak = sampleFilename.startsWith("test_pagebreak_implies_systembreak");
         const isTestPageBottomMargin0 = sampleFilename.includes("PageBottomMargin0");
         const isTestPageBottomMargin0 = sampleFilename.includes("PageBottomMargin0");
+        const enableNewSystemAtSystemBreak = sampleFilename.includes("test_octaveshift_extragraphicalmeasure");
         osmdInstance.EngravingRules.loadDefaultValues(); // note this may also be executed in setOptions below via drawingParameters default
         osmdInstance.EngravingRules.loadDefaultValues(); // note this may also be executed in setOptions below via drawingParameters default
         if (isTestEndClefStaffEntryBboxes) {
         if (isTestEndClefStaffEntryBboxes) {
             drawBoundingBoxString = "VexFlowStaffEntry";
             drawBoundingBoxString = "VexFlowStaffEntry";
@@ -335,6 +337,7 @@ async function generateSampleImage (sampleFilename, directory, osmdInstance, osm
             drawFromMeasureNumber: isFunctionTestDrawingRange ? 9 : 1,
             drawFromMeasureNumber: isFunctionTestDrawingRange ? 9 : 1,
             drawUpToMeasureNumber: isFunctionTestDrawingRange ? 12 : Number.MAX_SAFE_INTEGER,
             drawUpToMeasureNumber: isFunctionTestDrawingRange ? 12 : Number.MAX_SAFE_INTEGER,
             newSystemFromXML: isFunctionTestSystemAndPageBreaks,
             newSystemFromXML: isFunctionTestSystemAndPageBreaks,
+            newSystemFromNewPageInXML: isTestPageBreakImpliesSystemBreak,
             newPageFromXML: isFunctionTestSystemAndPageBreaks,
             newPageFromXML: isFunctionTestSystemAndPageBreaks,
             pageBackgroundColor: "#FFFFFF", // reset by drawingparameters default
             pageBackgroundColor: "#FFFFFF", // reset by drawingparameters default
             pageFormat: pageFormat, // reset by drawingparameters default,
             pageFormat: pageFormat, // reset by drawingparameters default,
@@ -358,6 +361,9 @@ async function generateSampleImage (sampleFilename, directory, osmdInstance, osm
         if (isTestPageBottomMargin0) {
         if (isTestPageBottomMargin0) {
             osmdInstance.EngravingRules.PageBottomMargin = 0;
             osmdInstance.EngravingRules.PageBottomMargin = 0;
         }
         }
+        if (enableNewSystemAtSystemBreak) {
+            osmdInstance.EngravingRules.NewSystemAtXMLNewSystemAttribute = true;
+        }
     }
     }
 
 
     try {
     try {

+ 1 - 1
test/data/test_graceslash_simple.musicxml

@@ -2,7 +2,7 @@
 <!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
 <!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
 <score-partwise version="3.1">
 <score-partwise version="3.1">
   <work>
   <work>
-    <work-title>b</work-title>
+    <work-title>test_graceslash_simple</work-title>
     </work>
     </work>
   <identification>
   <identification>
     <encoding>
     <encoding>

+ 139 - 0
test/data/test_octaveshift_extragraphicalmeasure.musicxml

@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise version="3.1">
+  <work>
+    <work-title>test_octaveshift_extragraphicalmeasure</work-title>
+    </work>
+  <identification>
+    <encoding>
+      <software>MuseScore 3.6.2</software>
+      <encoding-date>2023-05-16</encoding-date>
+      <supports element="accidental" type="yes"/>
+      <supports element="beam" type="yes"/>
+      <supports element="print" attribute="new-page" type="yes" value="yes"/>
+      <supports element="print" attribute="new-system" type="yes" value="yes"/>
+      <supports element="stem" type="yes"/>
+      </encoding>
+    </identification>
+  <defaults>
+    <scaling>
+      <millimeters>6.99911</millimeters>
+      <tenths>40</tenths>
+      </scaling>
+    <page-layout>
+      <page-height>1596.77</page-height>
+      <page-width>1233.87</page-width>
+      <page-margins type="even">
+        <left-margin>85.7252</left-margin>
+        <right-margin>85.7252</right-margin>
+        <top-margin>85.7252</top-margin>
+        <bottom-margin>85.7252</bottom-margin>
+        </page-margins>
+      <page-margins type="odd">
+        <left-margin>85.7252</left-margin>
+        <right-margin>85.7252</right-margin>
+        <top-margin>85.7252</top-margin>
+        <bottom-margin>85.7252</bottom-margin>
+        </page-margins>
+      </page-layout>
+    <word-font font-family="Edwin" font-size="10"/>
+    <lyric-font font-family="Edwin" font-size="10"/>
+    </defaults>
+  <credit page="1">
+    <credit-type>title</credit-type>
+    <credit-words default-x="616.935" default-y="1511.05" justify="center" valign="top" font-size="22">test_octaveshift_extragraphicalmeasure</credit-words>
+    </credit>
+  <part-list>
+    <score-part id="P1">
+      <part-name>Piano</part-name>
+      <part-abbreviation>Pno.</part-abbreviation>
+      <score-instrument id="P1-I1">
+        <instrument-name>Piano</instrument-name>
+        </score-instrument>
+      <midi-device id="P1-I1" port="1"></midi-device>
+      <midi-instrument id="P1-I1">
+        <midi-channel>1</midi-channel>
+        <midi-program>1</midi-program>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      </score-part>
+    </part-list>
+  <part id="P1">
+    <measure number="1" width="978.70">
+      <print>
+        <system-layout>
+          <system-margins>
+            <left-margin>50.00</left-margin>
+            <right-margin>0.00</right-margin>
+            </system-margins>
+          <top-system-distance>170.00</top-system-distance>
+          </system-layout>
+        </print>
+      <attributes>
+        <divisions>1</divisions>
+        <key>
+          <fifths>0</fifths>
+          </key>
+        <time>
+          <beats>4</beats>
+          <beat-type>4</beat-type>
+          </time>
+        <clef>
+          <sign>G</sign>
+          <line>2</line>
+          </clef>
+        </attributes>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="down" size="8" number="1" default-y="25.30"/>
+          </direction-type>
+        </direction>
+      <note default-x="80.72" default-y="5.00">
+        <pitch>
+          <step>G</step>
+          <octave>6</octave>
+          </pitch>
+        <duration>4</duration>
+        <voice>1</voice>
+        <type>whole</type>
+        </note>
+      <barline location="right">
+        <bar-style>light-light</bar-style>
+        </barline>
+      </measure>
+    <measure number="2" width="254.12">
+      <print new-system="yes">
+        <system-layout>
+          <system-margins>
+            <left-margin>0.00</left-margin>
+            <right-margin>774.58</right-margin>
+            </system-margins>
+          <system-distance>235.00</system-distance>
+          </system-layout>
+        </print>
+      <attributes>
+        <key>
+          <fifths>1</fifths>
+          </key>
+        </attributes>
+      <note default-x="81.85" default-y="20.00">
+        <pitch>
+          <step>C</step>
+          <octave>7</octave>
+          </pitch>
+        <duration>4</duration>
+        <voice>1</voice>
+        <type>whole</type>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="stop" size="8" number="1"/>
+          </direction-type>
+        </direction>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+    </part>
+  </score-partwise>

+ 1603 - 0
test/data/test_octaveshift_notes_shifted_octave_shift_end.musicxml

@@ -0,0 +1,1603 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise version="3.1">
+  <work>
+    <work-title>test_octaveshift_notes_shifted_octave_shift_end</work-title>
+    </work>
+  <identification>
+    <creator type="composer">Hanon</creator>
+    <encoding>
+      <software>MuseScore 3.6.2</software>
+      <encoding-date>2023-05-24</encoding-date>
+      <supports element="accidental" type="yes"/>
+      <supports element="beam" type="yes"/>
+      <supports element="print" attribute="new-page" type="yes" value="yes"/>
+      <supports element="print" attribute="new-system" type="yes" value="yes"/>
+      <supports element="stem" type="yes"/>
+      </encoding>
+    </identification>
+  <defaults>
+    <scaling>
+      <millimeters>6.99911</millimeters>
+      <tenths>40</tenths>
+      </scaling>
+    <page-layout>
+      <page-height>1696.94</page-height>
+      <page-width>1200.48</page-width>
+      <page-margins type="even">
+        <left-margin>85.7252</left-margin>
+        <right-margin>85.7252</right-margin>
+        <top-margin>85.7252</top-margin>
+        <bottom-margin>85.7252</bottom-margin>
+        </page-margins>
+      <page-margins type="odd">
+        <left-margin>85.7252</left-margin>
+        <right-margin>85.7252</right-margin>
+        <top-margin>85.7252</top-margin>
+        <bottom-margin>85.7252</bottom-margin>
+        </page-margins>
+      </page-layout>
+    <word-font font-family="Edwin" font-size="10"/>
+    <lyric-font font-family="Edwin" font-size="10"/>
+    </defaults>
+  <credit page="1">
+    <credit-type>title</credit-type>
+    <credit-words default-x="600.24" default-y="1611.63" justify="center" valign="top" font-size="22">Scale</credit-words>
+    </credit>
+  <credit page="1">
+    <credit-type>composer</credit-type>
+    <credit-words default-x="1114.75" default-y="1590.19" justify="right" valign="top">scale test</credit-words>
+    </credit>
+  <part-list>
+    <score-part id="P1">
+      <part-name>R.H.</part-name>
+      <part-abbreviation>R.H</part-abbreviation>
+      <score-instrument id="P1-I1">
+        <instrument-name>Piano</instrument-name>
+        </score-instrument>
+      <midi-device id="P1-I1" port="1"></midi-device>
+      <midi-instrument id="P1-I1">
+        <midi-channel>1</midi-channel>
+        <midi-program>1</midi-program>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      </score-part>
+    <score-part id="P2">
+      <part-name>L.H.</part-name>
+      <part-abbreviation>L.H.</part-abbreviation>
+      <score-instrument id="P2-I1">
+        <instrument-name>Piano</instrument-name>
+        </score-instrument>
+      <midi-device id="P2-I1" port="1"></midi-device>
+      <midi-instrument id="P2-I1">
+        <midi-channel>2</midi-channel>
+        <midi-program>1</midi-program>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      </score-part>
+    </part-list>
+  <part id="P1">
+    <measure number="1" width="256.39">
+      <print>
+        <system-layout>
+          <system-margins>
+            <left-margin>50.73</left-margin>
+            <right-margin>0.00</right-margin>
+            </system-margins>
+          <top-system-distance>170.00</top-system-distance>
+          </system-layout>
+        </print>
+      <attributes>
+        <divisions>4</divisions>
+        <key>
+          <fifths>0</fifths>
+          </key>
+        <time>
+          <beats>2</beats>
+          <beat-type>4</beat-type>
+          </time>
+        <clef>
+          <sign>G</sign>
+          <line>2</line>
+          </clef>
+        </attributes>
+      <direction placement="below">
+        <direction-type>
+          <octave-shift type="up" size="8" number="1" default-y="-70.26"/>
+          </direction-type>
+        </direction>
+      <note default-x="86.99" default-y="-50.00">
+        <pitch>
+          <step>C</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="108.98" default-y="-45.00">
+        <pitch>
+          <step>D</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="130.98" default-y="-40.00">
+        <pitch>
+          <step>E</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="150.10" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="169.23" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="188.35" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="207.47" default-y="-20.00">
+        <pitch>
+          <step>B</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <direction placement="below">
+        <direction-type>
+          <octave-shift type="stop" size="8" number="1"/>
+          </direction-type>
+        </direction>
+      <note default-x="226.59" default-y="-50.00">
+        <pitch>
+          <step>C</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="2" width="163.15">
+      <note default-x="13.00" default-y="-45.00">
+        <pitch>
+          <step>D</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="30.19" default-y="-40.00">
+        <pitch>
+          <step>E</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="47.39" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="64.58" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="81.78" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="98.97" default-y="-20.00">
+        <pitch>
+          <step>B</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="116.16" default-y="-15.00">
+        <pitch>
+          <step>C</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="133.36" default-y="-10.00">
+        <pitch>
+          <step>D</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="3" width="174.70">
+      <note default-x="13.00" default-y="-5.00">
+        <pitch>
+          <step>E</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="31.28" default-y="0.00">
+        <pitch>
+          <step>F</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="49.57" default-y="5.00">
+        <pitch>
+          <step>G</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="68.06" default-y="10.00">
+        <pitch>
+          <step>A</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="90.06" default-y="15.00">
+        <pitch>
+          <step>B</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="108.34" default-y="-15.00">
+        <pitch>
+          <step>C</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="126.62" default-y="-10.00">
+        <pitch>
+          <step>D</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="144.91" default-y="-5.00">
+        <pitch>
+          <step>E</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="4" width="201.65">
+      <note default-x="13.00" default-y="0.00">
+        <pitch>
+          <step>F</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="35.69" default-y="5.00">
+        <pitch>
+          <step>G</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="58.39" default-y="10.00">
+        <pitch>
+          <step>A</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="81.08" default-y="15.00">
+        <pitch>
+          <step>B</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="103.78" default-y="20.00">
+        <pitch>
+          <step>C</step>
+          <octave>6</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="126.47" default-y="15.00">
+        <pitch>
+          <step>B</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="149.16" default-y="10.00">
+        <pitch>
+          <step>A</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="171.86" default-y="5.00">
+        <pitch>
+          <step>G</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="5" width="182.40">
+      <note default-x="13.00" default-y="0.00">
+        <pitch>
+          <step>F</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="32.12" default-y="-5.00">
+        <pitch>
+          <step>E</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="51.25" default-y="-10.00">
+        <pitch>
+          <step>D</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="70.37" default-y="20.00">
+        <pitch>
+          <step>C</step>
+          <octave>6</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="92.36" default-y="15.00">
+        <pitch>
+          <step>B</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="114.36" default-y="10.00">
+        <pitch>
+          <step>A</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="133.48" default-y="5.00">
+        <pitch>
+          <step>G</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="152.61" default-y="0.00">
+        <pitch>
+          <step>F</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="6" width="391.84">
+      <print new-system="yes">
+        <system-layout>
+          <system-margins>
+            <left-margin>49.52</left-margin>
+            <right-margin>0.00</right-margin>
+            </system-margins>
+          <system-distance>150.00</system-distance>
+          </system-layout>
+        </print>
+      <note default-x="61.36" default-y="-5.00">
+        <pitch>
+          <step>E</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="102.44" default-y="-10.00">
+        <pitch>
+          <step>D</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="143.53" default-y="-15.00">
+        <pitch>
+          <step>C</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="184.61" default-y="-20.00">
+        <pitch>
+          <step>B</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="225.70" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="266.78" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="307.87" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="348.95" default-y="-40.00">
+        <pitch>
+          <step>E</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="7" width="351.18">
+      <note default-x="13.00" default-y="-45.00">
+        <pitch>
+          <step>D</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <direction placement="below">
+        <direction-type>
+          <octave-shift type="up" size="8" number="1" default-y="-62.86"/>
+          </direction-type>
+        </direction>
+      <note default-x="55.05" default-y="-15.00">
+        <pitch>
+          <step>C</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="97.09" default-y="-20.00">
+        <pitch>
+          <step>B</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="139.14" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="181.19" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="223.24" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="265.28" default-y="-40.00">
+        <pitch>
+          <step>E</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="307.33" default-y="-45.00">
+        <pitch>
+          <step>D</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="8" width="236.50">
+      <note default-x="16.50" default-y="-50.00">
+        <pitch>
+          <step>C</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>8</duration>
+        <voice>1</voice>
+        <type>half</type>
+        <stem>up</stem>
+        </note>
+      <direction placement="below">
+        <direction-type>
+          <octave-shift type="stop" size="8" number="1"/>
+          </direction-type>
+        </direction>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+    </part>
+  <part id="P2">
+    <measure number="1" width="256.39">
+      <print>
+        <staff-layout number="1">
+          <staff-distance>65.00</staff-distance>
+          </staff-layout>
+        </print>
+      <attributes>
+        <divisions>4</divisions>
+        <key>
+          <fifths>0</fifths>
+          </key>
+        <time>
+          <beats>2</beats>
+          <beat-type>4</beat-type>
+          </time>
+        <clef>
+          <sign>F</sign>
+          <line>4</line>
+          </clef>
+        </attributes>
+      <note default-x="86.99" default-y="-165.00">
+        <pitch>
+          <step>C</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="108.98" default-y="-160.00">
+        <pitch>
+          <step>D</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="130.98" default-y="-155.00">
+        <pitch>
+          <step>E</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="150.10" default-y="-150.00">
+        <pitch>
+          <step>F</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="169.23" default-y="-145.00">
+        <pitch>
+          <step>G</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="188.35" default-y="-140.00">
+        <pitch>
+          <step>A</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="207.47" default-y="-135.00">
+        <pitch>
+          <step>B</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="226.59" default-y="-130.00">
+        <pitch>
+          <step>C</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="2" width="163.15">
+      <note default-x="13.00" default-y="-125.00">
+        <pitch>
+          <step>D</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="30.19" default-y="-120.00">
+        <pitch>
+          <step>E</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="47.39" default-y="-115.00">
+        <pitch>
+          <step>F</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="64.58" default-y="-110.00">
+        <pitch>
+          <step>G</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="81.78" default-y="-105.00">
+        <pitch>
+          <step>A</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="98.97" default-y="-100.00">
+        <pitch>
+          <step>B</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="down" size="8" number="1" default-y="20.00"/>
+          </direction-type>
+        </direction>
+      <note default-x="116.16" default-y="-130.00">
+        <pitch>
+          <step>C</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="133.36" default-y="-125.00">
+        <pitch>
+          <step>D</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="3" width="174.70">
+      <note default-x="13.00" default-y="-120.00">
+        <pitch>
+          <step>E</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="31.28" default-y="-115.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="49.57" default-y="-110.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="68.06" default-y="-105.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="90.06" default-y="-100.00">
+        <pitch>
+          <step>B</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="stop" size="8" number="1"/>
+          </direction-type>
+        </direction>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="down" size="15" number="1" default-y="22.75"/>
+          </direction-type>
+        </direction>
+      <note default-x="108.34" default-y="-130.00">
+        <pitch>
+          <step>C</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="126.62" default-y="-125.00">
+        <pitch>
+          <step>D</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="144.91" default-y="-120.00">
+        <pitch>
+          <step>E</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="4" width="201.65">
+      <note default-x="13.00" default-y="-115.00">
+        <pitch>
+          <step>F</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="35.69" default-y="-110.00">
+        <pitch>
+          <step>G</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="58.39" default-y="-105.00">
+        <pitch>
+          <step>A</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="81.08" default-y="-100.00">
+        <pitch>
+          <step>B</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="103.78" default-y="-95.00">
+        <pitch>
+          <step>C</step>
+          <octave>6</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="126.47" default-y="-100.00">
+        <pitch>
+          <step>B</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="149.16" default-y="-105.00">
+        <pitch>
+          <step>A</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="171.86" default-y="-110.00">
+        <pitch>
+          <step>G</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="stop" size="15" number="1"/>
+          </direction-type>
+        </direction>
+      </measure>
+    <measure number="5" width="182.40">
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="down" size="15" number="1" default-y="32.75"/>
+          </direction-type>
+        </direction>
+      <note default-x="13.00" default-y="-115.00">
+        <pitch>
+          <step>F</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="32.12" default-y="-120.00">
+        <pitch>
+          <step>E</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="51.25" default-y="-125.00">
+        <pitch>
+          <step>D</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="stop" size="15" number="1"/>
+          </direction-type>
+        </direction>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="down" size="8" number="1" default-y="30.06"/>
+          </direction-type>
+        </direction>
+      <note default-x="70.37" default-y="-95.00">
+        <pitch>
+          <step>C</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="92.36" default-y="-100.00">
+        <pitch>
+          <step>B</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="114.36" default-y="-105.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="133.48" default-y="-110.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="152.61" default-y="-115.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="6" width="391.84">
+      <print new-system="yes">
+        <staff-layout number="1">
+          <staff-distance>65.00</staff-distance>
+          </staff-layout>
+        </print>
+      <note default-x="61.36" default-y="-120.00">
+        <pitch>
+          <step>E</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="102.44" default-y="-125.00">
+        <pitch>
+          <step>D</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="stop" size="8" number="1"/>
+          </direction-type>
+        </direction>
+      <note default-x="143.53" default-y="-95.00">
+        <pitch>
+          <step>C</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="184.61" default-y="-100.00">
+        <pitch>
+          <step>B</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="225.70" default-y="-105.00">
+        <pitch>
+          <step>A</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="266.78" default-y="-110.00">
+        <pitch>
+          <step>G</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="307.87" default-y="-115.00">
+        <pitch>
+          <step>F</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="348.95" default-y="-120.00">
+        <pitch>
+          <step>E</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="7" width="351.18">
+      <note default-x="13.00" default-y="-125.00">
+        <pitch>
+          <step>D</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="55.05" default-y="-130.00">
+        <pitch>
+          <step>C</step>
+          <octave>3</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="97.09" default-y="-135.00">
+        <pitch>
+          <step>B</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="139.14" default-y="-140.00">
+        <pitch>
+          <step>A</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      <note default-x="181.19" default-y="-145.00">
+        <pitch>
+          <step>G</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <beam number="2">begin</beam>
+        </note>
+      <note default-x="223.24" default-y="-150.00">
+        <pitch>
+          <step>F</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="265.28" default-y="-155.00">
+        <pitch>
+          <step>E</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        <beam number="2">continue</beam>
+        </note>
+      <note default-x="307.33" default-y="-160.00">
+        <pitch>
+          <step>D</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>16th</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <beam number="2">end</beam>
+        </note>
+      </measure>
+    <measure number="8" width="236.50">
+      <note default-x="16.50" default-y="-165.00">
+        <pitch>
+          <step>C</step>
+          <octave>2</octave>
+          </pitch>
+        <duration>8</duration>
+        <voice>1</voice>
+        <type>half</type>
+        <stem>up</stem>
+        </note>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+    </part>
+  </score-partwise>

BIN
test/data/test_octaveshift_notes_shifted_octave_shift_end_original.mxl


+ 129 - 0
test/data/test_pagebreak_implies_systembreak.musicxml

@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise version="3.1">
+  <work>
+    <work-title>test_pagebreak_implies_systembreak</work-title>
+    </work>
+  <identification>
+    <encoding>
+      <software>MuseScore 3.6.2</software>
+      <encoding-date>2023-03-29</encoding-date>
+      <supports element="accidental" type="yes"/>
+      <supports element="beam" type="yes"/>
+      <supports element="print" attribute="new-page" type="yes" value="yes"/>
+      <supports element="print" attribute="new-system" type="yes" value="yes"/>
+      <supports element="stem" type="yes"/>
+      </encoding>
+    </identification>
+  <defaults>
+    <scaling>
+      <millimeters>6.99911</millimeters>
+      <tenths>40</tenths>
+      </scaling>
+    <page-layout>
+      <page-height>1596.77</page-height>
+      <page-width>1233.87</page-width>
+      <page-margins type="even">
+        <left-margin>85.7252</left-margin>
+        <right-margin>85.7252</right-margin>
+        <top-margin>85.7252</top-margin>
+        <bottom-margin>85.7252</bottom-margin>
+        </page-margins>
+      <page-margins type="odd">
+        <left-margin>85.7252</left-margin>
+        <right-margin>85.7252</right-margin>
+        <top-margin>85.7252</top-margin>
+        <bottom-margin>85.7252</bottom-margin>
+        </page-margins>
+      </page-layout>
+    <word-font font-family="Edwin" font-size="10"/>
+    <lyric-font font-family="Edwin" font-size="10"/>
+    </defaults>
+  <credit page="1">
+    <credit-type>title</credit-type>
+    <credit-words default-x="616.935" default-y="1511.05" justify="center" valign="top" font-size="22">test_pagebreak_implies_systembreak</credit-words>
+    </credit>
+  <part-list>
+    <score-part id="P1">
+      <part-name>Piano</part-name>
+      <part-abbreviation>Pno.</part-abbreviation>
+      <score-instrument id="P1-I1">
+        <instrument-name>Piano</instrument-name>
+        </score-instrument>
+      <midi-device id="P1-I1" port="1"></midi-device>
+      <midi-instrument id="P1-I1">
+        <midi-channel>1</midi-channel>
+        <midi-program>1</midi-program>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      </score-part>
+    </part-list>
+  <part id="P1">
+    <measure number="1" width="978.70">
+      <print>
+        <system-layout>
+          <system-margins>
+            <left-margin>50.00</left-margin>
+            <right-margin>0.00</right-margin>
+            </system-margins>
+          <top-system-distance>170.00</top-system-distance>
+          </system-layout>
+        </print>
+      <attributes>
+        <divisions>1</divisions>
+        <key>
+          <fifths>0</fifths>
+          </key>
+        <time>
+          <beats>4</beats>
+          <beat-type>4</beat-type>
+          </time>
+        <clef>
+          <sign>G</sign>
+          <line>2</line>
+          </clef>
+        </attributes>
+      <note default-x="80.72" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>4</duration>
+        <voice>1</voice>
+        <type>whole</type>
+        <lyric number="1" default-x="11.18" default-y="-40.00" relative-y="-30.00">
+          <syllabic>single</syllabic>
+          <text>Page1</text>
+          </lyric>
+        </note>
+      </measure>
+    <measure number="2" width="275.81">
+      <print new-page="yes">
+        <system-layout>
+          <system-margins>
+            <left-margin>0.00</left-margin>
+            <right-margin>752.89</right-margin>
+            </system-margins>
+          <top-system-distance>70.00</top-system-distance>
+          </system-layout>
+        </print>
+      <note default-x="58.59" default-y="-20.00">
+        <pitch>
+          <step>B</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>4</duration>
+        <voice>1</voice>
+        <type>whole</type>
+        <lyric number="1" default-x="13.31" default-y="-40.00" relative-y="-30.00">
+          <syllabic>single</syllabic>
+          <text>Page2</text>
+          </lyric>
+        </note>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+    </part>
+  </score-partwise>