Bladeren bron

merge osmd-public: fix octave shift display octave. docs/comments.

sschmid 3 jaren geleden
bovenliggende
commit
86c4b2277b

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

@@ -244,7 +244,9 @@ export class EngravingRules {
     public DurationDistanceDict: {[_: number]: number } = {};
     public DurationScalingDistanceDict: {[_: number]: number } = {};
 
-    public AlignRests: number; // 0 = false, 1 = true, 2 = auto
+    /** Whether to align rests. 0 = Never, 1 = Always, 2 = Auto.
+     * Currently not recommended because rests are now positioned to avoid collisions with notes. */
+    public AlignRests: AlignRestOption; // 0 = false, 1 = true, 2 = auto
     public RestCollisionYPadding: number;
     public FillEmptyMeasuresWithWholeRest: FillEmptyMeasuresWithWholeRests | number;
     public ArpeggiosGoAcrossVoices: boolean;
@@ -293,7 +295,8 @@ export class EngravingRules {
     public MpatMode: boolean;
 
     public ArticulationPlacementFromXML: boolean;
-    /** Position of fingering label in relation to corresponding note (left, right supported, above, below experimental) */
+    /** Where to draw fingerings (Above, Below, AboveOrBelow, Left, Right, or Auto).
+     * Default AboveOrBelow. Auto experimental. */
     public FingeringPosition: PlacementEnum;
     public FingeringPositionFromXML: boolean;
     public FingeringPositionGrace: PlacementEnum;
@@ -675,6 +678,9 @@ export class EngravingRules {
         this.NoteToGraphicalNoteMapObjectCount++;
     }
 
+    /** Returns the GraphicalNote corresponding to (its) note. Also used by Cursor.GNotesUnderCursor().
+     *  We don't want to save a GraphicalNote reference in Note, see Note.NoteToGraphicalNoteObjectId.
+     */
     public GNote(note: Note): GraphicalNote {
         return GraphicalNote.FromNote(note, this);
     }

+ 12 - 0
src/MusicalScore/Graphical/MusicSheetCalculator.ts

@@ -2315,9 +2315,11 @@ export abstract class MusicSheetCalculator {
             }
         }
         // check for octave shifts
+        const octaveShifts: MultiExpression[] = [];
         for (let idx: number = 0, len: number = sourceMeasure.StaffLinkedExpressions[staffIndex].length; idx < len; ++idx) {
             const multiExpression: MultiExpression = sourceMeasure.StaffLinkedExpressions[staffIndex][idx];
             if (multiExpression.OctaveShiftStart) {
+                octaveShifts.push(multiExpression);
                 const openOctaveShift: OctaveShift = multiExpression.OctaveShiftStart;
                 let absoluteEnd: Fraction = openOctaveShift?.ParentEndMultiExpression?.AbsoluteTimestamp;
                 if (!openOctaveShift?.ParentEndMultiExpression) {
@@ -2368,6 +2370,16 @@ export abstract class MusicSheetCalculator {
                         octaveShiftValue = openOctaveShifts[staffIndex].getOpenOctaveShift.Type;
                     }
                 }
+                if (octaveShiftValue === OctaveEnum.NONE) {
+                    // check for existing octave shifts outside openOctaveShifts
+                    for (const octaveShift of octaveShifts) {
+                        if (octaveShift.OctaveShiftStart?.ParentStartMultiExpression?.AbsoluteTimestamp.lte(sourceStaffEntry.AbsoluteTimestamp) &&
+                            !octaveShift.OctaveShiftStart?.ParentEndMultiExpression?.AbsoluteTimestamp.lt(sourceStaffEntry.AbsoluteTimestamp)) {
+                                octaveShiftValue = octaveShift.OctaveShiftStart.Type;
+                                break;
+                            }
+                    }
+                }
                 // for each visible Voice create the corresponding GraphicalNotes
                 for (let idx: number = 0, len: number = sourceStaffEntry.VoiceEntries.length; idx < len; ++idx) {
                     const voiceEntry: VoiceEntry = sourceStaffEntry.VoiceEntries[idx];

+ 1 - 0
src/MusicalScore/VoiceData/Expressions/AbstractExpression.ts

@@ -28,6 +28,7 @@ export class AbstractExpression {
             case "below":
                 return PlacementEnum.Below;
             case "aboveorbelow":
+            case "abovebelow":
                 return PlacementEnum.AboveOrBelow;
             case "left":
                 return PlacementEnum.Left;

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

@@ -102,7 +102,11 @@ export class Note {
     public Fingering: TechnicalInstruction; // this is also stored in VoiceEntry.TechnicalInstructions
     public StringInstruction: TechnicalInstruction; // this is also stored in VoiceEntry.TechnicalInstructions
     // note that there is also TabNote.StringNumber, so we can't use that identifier here
-    /** Used by GraphicalNote.FromNote(note) and osmd.rules.GNote(note) to get a GraphicalNote from a Note. */
+    /** Used by GraphicalNote.FromNote(note) and osmd.rules.GNote(note) to get a GraphicalNote from a Note.
+     *  Note that we don't want the data model (Note) to be dependent on the graphical implementation (GraphicalNote),
+     *    and have (potentially circular) import dependencies of graphical parts, which also applies to other non-graphical classes.
+     *    That's why we don't save a GraphicalNote reference directly in Note.
+     */
     public NoteToGraphicalNoteObjectId: number; // used with EngravingRules.NoteToGraphicalNoteMap
 
     public get ParentVoiceEntry(): VoiceEntry {

+ 4 - 4
src/OpenSheetMusicDisplay/OSMDOptions.ts

@@ -115,8 +115,8 @@ export interface IOSMDOptions {
     useXMLMeasureNumbers?: boolean;
     /** Whether to draw fingerings (only left to the note for now). Default true (unless solo part). */
     drawFingerings?: boolean;
-    /** Where to draw fingerings (left, right, above, below, or auto).
-     * Default left. Auto, above, below experimental (potential collisions because bounding box not correct)
+    /** Where to draw fingerings (above, below, aboveorbelow, left, right, or auto).
+     * Default AboveOrBelow. Auto experimental
      */
     fingeringPosition?: string;
     /** For above/below fingerings, whether to draw them directly above/below notes (default), or above/below staffline. */
@@ -127,13 +127,13 @@ export interface IOSMDOptions {
     drawLyrics?: boolean;
     /** Whether to calculate extra slurs with bezier curves not covered by Vexflow slurs. Default true. */
     drawSlurs?: boolean;
-    /** Only draw measure n to m, where m is the number specified. */
+    /** Only draw measure n to m, where m is the number specified. (for n, see drawFromMeasureNumber) */
     drawUpToMeasureNumber?: number;
     /** Only draw the first n systems, where n is the number specified. */
     drawUpToSystemNumber?: number;
     /** Only draw the first n pages, where n is the number specified. */
     drawUpToPageNumber?: number;
-    /** Only draw measure n to m, where n is the number you specify. */
+    /** Only draw measure n to m, where n is the number you specify. (for m, see drawUpToMeasureNumber) */
     drawFromMeasureNumber?: number;
     /** Whether to fill measures that don't have notes given in the XML with whole rests (visible = 1, invisible = 2, for layouting). Default No (0). */
     fillEmptyMeasuresWithWholeRest?: FillEmptyMeasuresWithWholeRests | number;

+ 243 - 0
test/data/test_octave-shift_simple_piano.musicxml

@@ -0,0 +1,243 @@
+<?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>octave-shift_test_simple_piano</work-title>
+    </work>
+  <identification>
+    <encoding>
+      <software>MuseScore 3.6.2</software>
+      <encoding-date>2021-11-18</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>
+  <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="964.13">
+      <print>
+        <system-layout>
+          <system-margins>
+            <left-margin>64.90</left-margin>
+            <right-margin>0.00</right-margin>
+            </system-margins>
+          <top-system-distance>176.77</top-system-distance>
+          </system-layout>
+        <staff-layout number="2">
+          <staff-distance>65.00</staff-distance>
+          </staff-layout>
+        </print>
+      <attributes>
+        <divisions>2</divisions>
+        <key>
+          <fifths>-5</fifths>
+          </key>
+        <time>
+          <beats>4</beats>
+          <beat-type>4</beat-type>
+          </time>
+        <staves>2</staves>
+        <clef number="1">
+          <sign>G</sign>
+          <line>2</line>
+          </clef>
+        <clef number="2">
+          <sign>F</sign>
+          <line>4</line>
+          </clef>
+        </attributes>
+      <note default-x="150.94" default-y="-10.00">
+        <pitch>
+          <step>D</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <accidental>natural</accidental>
+        <stem>down</stem>
+        <staff>1</staff>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="down" size="8" number="1" default-y="55.36"/>
+          </direction-type>
+        <staff>1</staff>
+        </direction>
+      <note default-x="256.54" default-y="20.00">
+        <pitch>
+          <step>C</step>
+          <octave>7</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>down</stem>
+        <staff>1</staff>
+        <notations>
+          <slur type="start" placement="above" number="1"/>
+          </notations>
+        </note>
+      <note default-x="467.73" default-y="15.00">
+        <pitch>
+          <step>B</step>
+          <octave>6</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <accidental>natural</accidental>
+        <stem>down</stem>
+        <staff>1</staff>
+        <notations>
+          <slur type="stop" number="1"/>
+          </notations>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="stop" size="8" number="1"/>
+          </direction-type>
+        <staff>1</staff>
+        </direction>
+      <note default-x="573.33" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <alter>-1</alter>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <staff>1</staff>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="down" size="8" number="1" default-y="68.90"/>
+          </direction-type>
+        <staff>1</staff>
+        </direction>
+      <note default-x="678.93" default-y="30.00">
+        <pitch>
+          <step>E</step>
+          <alter>-1</alter>
+          <octave>7</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>down</stem>
+        <staff>1</staff>
+        <notations>
+          <slur type="start" placement="above" number="1"/>
+          </notations>
+        </note>
+      <note default-x="847.88" default-y="35.00">
+        <pitch>
+          <step>F</step>
+          <octave>7</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <staff>1</staff>
+        <notations>
+          <slur type="stop" number="1"/>
+          </notations>
+        </note>
+      <direction placement="above">
+        <direction-type>
+          <octave-shift type="stop" size="8" number="1"/>
+          </direction-type>
+        <staff>1</staff>
+        </direction>
+      <backup>
+        <duration>8</duration>
+        </backup>
+      <direction placement="below">
+        <direction-type>
+          <octave-shift type="up" size="8" number="1" default-y="-60.26"/>
+          </direction-type>
+        <staff>2</staff>
+        </direction>
+      <note default-x="150.94" default-y="-145.00">
+        <pitch>
+          <step>G</step>
+          <alter>-1</alter>
+          <octave>1</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>5</voice>
+        <type>quarter</type>
+        <stem>up</stem>
+        <staff>2</staff>
+        </note>
+      <note>
+        <rest/>
+        <duration>2</duration>
+        <voice>5</voice>
+        <type>quarter</type>
+        <staff>2</staff>
+        </note>
+      <note>
+        <rest/>
+        <duration>4</duration>
+        <voice>5</voice>
+        <type>half</type>
+        <staff>2</staff>
+        </note>
+      <direction placement="below">
+        <direction-type>
+          <octave-shift type="stop" size="8" number="1"/>
+          </direction-type>
+        <staff>2</staff>
+        </direction>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+    </part>
+  </score-partwise>