Browse Source

Merge branch 'develop' into fix/octava

Benjamin Giesinger 6 years ago
parent
commit
72df08eac1

+ 15 - 2
demo/index.js

@@ -22,9 +22,10 @@ import { OpenSheetMusicDisplay } from '../src/OpenSheetMusicDisplay/OpenSheetMus
         "Mozart, W.A.- Clarinet Quintet (Excerpt)": "Mozart_Clarinet_Quintet_Excerpt.mxl",
         "Mozart/Holzer - Land der Berge (national anthem of Austria)": "Land_der_Berge.musicxml",
         "OSMD Function Test - All": "OSMD_function_test_all.xml",
-        "OSMD Function Test - Autobeam": "OSMD_function_test_autobeam.musicxml",
         "OSMD Function Test - Accidentals": "OSMD_function_test_accidentals.musicxml",
-        "OSMD Function Test - Color": "OSMD_function_test_color.musicxml",
+        "OSMD Function Test - Autobeam": "OSMD_function_test_autobeam.musicxml",
+        "OSMD Function Test - Auto-/Custom-Coloring": "OSMD_function_test_auto-custom-coloring-entchen.musicxml",
+        "OSMD Function Test - Color (from XML)": "OSMD_function_test_color.musicxml",
         "OSMD Function Test - Drumset": "OSMD_function_test_drumset.musicxml",
         "OSMD Function Test - Expressions": "OSMD_function_test_expressions.musicxml",
         "OSMD Function Test - Expressions Overlap": "OSMD_function_test_expressions_overlap.musicxml",
@@ -230,6 +231,18 @@ import { OpenSheetMusicDisplay } from '../src/OpenSheetMusicDisplay/OpenSheetMus
             str = sampleFolder + selectSample.value;
         }
         zoom = 1.0;
+        // Enable Boomwhacker coloring for this song
+        if (str.includes("coloring-entchen")) {
+            //openSheetMusicDisplay.setOptions({coloringMode: 1}); // Auto-Coloring with pre-defined colors
+            openSheetMusicDisplay.setOptions({
+                coloringMode: 2,
+                coloringSetCustom: ["#d82c6b", "#F89D15", "#FFE21A", "#4dbd5c", "#009D96", "#43469d", "#76429c", "#ff0000"]
+                // last color value of coloringSetCustom is for rest notes
+            });
+        } else {
+            openSheetMusicDisplay.setOptions({coloringMode: 0});
+        }
+        openSheetMusicDisplay.setOptions({autoBeam: str.includes("autobeam")});
         openSheetMusicDisplay.load(str).then(
             function() {
                 // This gives you access to the osmd object in the console. Do not use in productive code

+ 1 - 1
package.json

@@ -53,7 +53,7 @@
     "loglevel": "^1.5.0",
     "typescript-collections": "^1.1.2",
     "@types/vexflow": "^1.2.33",
-    "vexflow": "^1.2.87"
+    "vexflow": "^1.2.88"
   },
   "devDependencies": {
     "@types/chai": "^4.0.3",

+ 21 - 0
src/MusicalScore/Graphical/DrawingEnums.ts

@@ -106,3 +106,24 @@ export enum NoteState {
     Debug2,
     Debug3
 }
+
+export enum AutoColorSet {
+    /* different (boomwhacker-like) color set*/
+    C = "#d82c6b",
+    D = "#F89D15",
+    E = "#FFE21A",
+    F = "#4dbd5c",
+    G = "#009D96",
+    A = "#43469d",
+    B = "#76429c",
+    Rest = "#000000"
+
+    // color set from MuseScore Color notehead plugin version 1.1 by Werner Schweer and others
+    /*C = "#eeee00",
+    D = "#9b30ff",
+    E = "#ee9a00",
+    F = "#8b4513",
+    G = "#ff0000",
+    A = "#1e90ff",
+    B = "#00ff00"*/
+}

+ 8 - 1
src/MusicalScore/Graphical/DrawingParameters.ts

@@ -1,6 +1,12 @@
 import { EngravingRules } from "./EngravingRules";
 import { PlacementEnum } from "../VoiceData/Expressions/AbstractExpression";
 
+export enum ColoringModes {
+    XML = 0,
+    AutoColoring = 1,
+    CustomColorSet = 2
+}
+
 export enum DrawingParametersEnum {
     allon = "allon",
     compact = "compact",
@@ -28,6 +34,7 @@ export class DrawingParameters {
     public drawComposer: boolean = true;
     public drawCredits: boolean = true;
     public drawPartNames: boolean = true;
+    public coloringMode: ColoringModes;
     public fingeringPosition: PlacementEnum = PlacementEnum.Left;
     /** Draw notes set to be invisible (print-object="no" in XML). */
     public drawHiddenNotes: boolean = false;
@@ -175,7 +182,7 @@ export class DrawingParameters {
 
     public set DrawPartNames(value: boolean) {
         this.drawPartNames = value;
-        EngravingRules.Rules.RenderInstrumentNames = value;
+        EngravingRules.Rules.RenderPartNames = value;
     }
 
     public get FingeringPosition(): PlacementEnum {

+ 32 - 6
src/MusicalScore/Graphical/EngravingRules.ts

@@ -4,6 +4,9 @@ import * as log from "loglevel";
 import { TextAlignmentEnum } from "../../Common/Enums/TextAlignment";
 import { PlacementEnum } from "../VoiceData/Expressions/AbstractExpression";
 import { AutoBeamOptions } from "../../OpenSheetMusicDisplay/OSMDOptions";
+import { ColoringModes as ColoringMode } from "./DrawingParameters";
+import { Dictionary } from "typescript-collections";
+import { NoteEnum } from "../..";
 
 export class EngravingRules {
     private static rules: EngravingRules;
@@ -176,9 +179,11 @@ export class EngravingRules {
     private durationDistanceDict: {[_: number]: number; } = {};
     private durationScalingDistanceDict: {[_: number]: number; } = {};
 
+    private coloringMode: ColoringMode;
     private coloringEnabled: boolean;
     private colorFlags: boolean;
     private colorBeams: boolean;
+    private coloringSetCustom: Dictionary<NoteEnum|number, string>;
     private defaultColorNotehead: string;
     private defaultColorRest: string;
     private defaultColorStem: string;
@@ -190,7 +195,8 @@ export class EngravingRules {
     private renderTitle: boolean;
     private renderSubtitle: boolean;
     private renderLyricist: boolean;
-    private renderInstrumentNames: boolean;
+    private renderPartNames: boolean;
+    private renderPartAbbreviations: boolean;
     private renderFingerings: boolean;
     private dynamicExpressionMaxDistance: number;
     private dynamicExpressionSpacer: number;
@@ -390,6 +396,7 @@ export class EngravingRules {
         this.metronomeMarkYShift = -0.5;
 
         // Render options (whether to render specific or invisible elements)
+        this.coloringMode = ColoringMode.XML;
         this.coloringEnabled = true;
         this.colorBeams = true;
         this.colorFlags = true;
@@ -403,7 +410,8 @@ export class EngravingRules {
         this.renderTitle = true;
         this.renderSubtitle = true;
         this.renderLyricist = true;
-        this.renderInstrumentNames = true;
+        this.renderPartNames = true;
+        this.renderPartAbbreviations = true;
         this.renderFingerings = true;
         this.fingeringPosition = PlacementEnum.Left; // easier to get bounding box, and safer for vertical layout
         this.fingeringInsideStafflines = false;
@@ -1330,6 +1338,12 @@ export class EngravingRules {
     public get DurationScalingDistanceDict(): {[_: number]: number; } {
         return this.durationScalingDistanceDict;
     }
+    public get ColoringMode(): ColoringMode {
+        return this.coloringMode;
+    }
+    public set ColoringMode(value: ColoringMode) {
+        this.coloringMode = value;
+    }
     public get ColoringEnabled(): boolean {
         return this.coloringEnabled;
     }
@@ -1348,6 +1362,12 @@ export class EngravingRules {
     public set ColorBeams(value: boolean) {
         this.colorBeams = value;
     }
+    public get ColoringSetCurrent(): Dictionary<NoteEnum|number, string> {
+        return this.coloringSetCustom;
+    }
+    public set ColoringSetCurrent(value: Dictionary<NoteEnum|number, string>) {
+        this.coloringSetCustom = value;
+    }
     public get DefaultColorNotehead(): string {
         return this.defaultColorNotehead;
     }
@@ -1408,11 +1428,17 @@ export class EngravingRules {
     public set RenderLyricist(value: boolean) {
         this.renderLyricist = value;
     }
-    public get RenderInstrumentNames(): boolean {
-        return this.renderInstrumentNames;
+    public get RenderPartNames(): boolean {
+        return this.renderPartNames;
+    }
+    public set RenderPartNames(value: boolean) {
+        this.renderPartNames = value;
+    }
+    public get RenderPartAbbreviations(): boolean {
+        return this.renderPartAbbreviations;
     }
-    public set RenderInstrumentNames(value: boolean) {
-        this.renderInstrumentNames = value;
+    public set RenderPartAbbreviations(value: boolean) {
+        this.renderPartAbbreviations = value;
     }
     public get RenderFingerings(): boolean {
         return this.renderFingerings;

+ 7 - 7
src/MusicalScore/Graphical/GraphicalLabel.ts

@@ -1,9 +1,9 @@
-import {Label} from "../Label";
-import {TextAlignmentEnum} from "../../Common/Enums/TextAlignment";
-import {Clickable} from "./Clickable";
-import {BoundingBox} from "./BoundingBox";
-import {EngravingRules} from "./EngravingRules";
-import {MusicSheetCalculator} from "./MusicSheetCalculator";
+import { TextAlignmentEnum } from "../../Common/Enums/TextAlignment";
+import { Label } from "../Label";
+import { BoundingBox } from "./BoundingBox";
+import { Clickable } from "./Clickable";
+import { EngravingRules } from "./EngravingRules";
+import { MusicSheetCalculator } from "./MusicSheetCalculator";
 
 /**
  * The graphical counterpart of a Label
@@ -31,7 +31,7 @@ export class GraphicalLabel extends Clickable {
     }
 
     public toString(): string {
-        return this.label.text;
+        return `${this.label.text} (${this.boundingBox.RelativePosition.x},${this.boundingBox.RelativePosition.y})`;
     }
 
     /**

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

@@ -6,6 +6,8 @@ import { GraphicalStaffEntry } from "./GraphicalStaffEntry";
 import { OctaveEnum } from "../VoiceData/Expressions/ContinuousExpressions/OctaveShift";
 import { VexFlowVoiceEntry } from "./VexFlow/VexFlowVoiceEntry";
 import { EngravingRules } from "./EngravingRules";
+import { ColoringModes } from "./DrawingParameters";
+import { NoteEnum } from "../../Common/DataObjects/Pitch";
 
 /**
  * The graphical counterpart of a [[VoiceEntry]].
@@ -49,6 +51,16 @@ export class GraphicalVoiceEntry extends GraphicalObject {
             const note: GraphicalNote = this.notes[i];
 
             let noteheadColor: string = note.sourceNote.NoteheadColor;
+            // Switch between XML colors and automatic coloring
+            if (EngravingRules.Rules.ColoringMode === ColoringModes.AutoColoring ||
+                    EngravingRules.Rules.ColoringMode === ColoringModes.CustomColorSet) {
+                if (note.sourceNote.isRest()) {
+                    noteheadColor = EngravingRules.Rules.ColoringSetCurrent.getValue(-1);
+                } else {
+                    const fundamentalNote: NoteEnum = note.sourceNote.Pitch.FundamentalNote;
+                    noteheadColor = EngravingRules.Rules.ColoringSetCurrent.getValue(fundamentalNote);
+                }
+            }
 
             // DEBUG runtime coloring test
             /*const testColor: string = "#FF0000";

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

@@ -1591,7 +1591,7 @@ export abstract class MusicSheetCalculator {
     }
 
     protected maxInstrNameLabelLength(): number {
-        if (!EngravingRules.Rules.RenderInstrumentNames) {
+        if (!EngravingRules.Rules.RenderPartNames) {
             return 0;
         }
         let maxLabelLength: number = 0.0;
@@ -1845,6 +1845,9 @@ export abstract class MusicSheetCalculator {
         for (let i: number = 1; i < tie.Notes.length; i++) {
             startNote = startGse.findEndTieGraphicalNoteFromNote(tie.Notes[i - 1]);
             endGse = this.graphicalMusicSheet.GetGraphicalFromSourceStaffEntry(tie.Notes[i].ParentStaffEntry);
+            if (!endGse) {
+                continue;
+            }
             endNote = endGse.findEndTieGraphicalNoteFromNote(tie.Notes[i]);
             if (startNote !== undefined && endNote !== undefined && endGse !== undefined) {
                 if (!startNote.sourceNote.PrintObject || !endNote.sourceNote.PrintObject) {

+ 1 - 1
src/MusicalScore/Graphical/MusicSheetDrawer.ts

@@ -308,7 +308,7 @@ export abstract class MusicSheetDrawer {
         for (const systemLine of musicSystem.SystemLines) {
             this.drawSystemLineObject(systemLine);
         }
-        if (musicSystem === musicSystem.Parent.MusicSystems[0] && musicSystem.Parent === musicSystem.Parent.Parent.MusicPages[0]) {
+        if (musicSystem.Parent === musicSystem.Parent.Parent.MusicPages[0]) {
             for (const label of musicSystem.Labels) {
                 this.drawLabel(label, <number>GraphicalLayers.Notes);
             }

+ 31 - 11
src/MusicalScore/Graphical/MusicSystem.ts

@@ -19,6 +19,7 @@ import {GraphicalMarkedArea} from "./GraphicalMarkedArea";
 import {SystemLine} from "./SystemLine";
 import {SystemLinePosition} from "./SystemLinePosition";
 import {Staff} from "../VoiceData/Staff";
+import { Label } from "../Label";
 
 /**
  * A MusicSystem contains the [[StaffLine]]s for all instruments, until a line break
@@ -29,7 +30,11 @@ export abstract class MusicSystem extends GraphicalObject {
     protected id: number;
     protected staffLines: StaffLine[] = [];
     protected graphicalMeasures: GraphicalMeasure[][] = [];
-    protected labels: Dictionary<GraphicalLabel, Instrument> = new Dictionary<GraphicalLabel, Instrument>();
+    /** Dictionary of (Instruments and) labels.
+     * note that the key needs to be unique, GraphicalLabel is not unique yet.
+     * That is why the labels are labels.values() and not labels.keys().
+     */
+    protected labels: Dictionary<Instrument, GraphicalLabel> = new Dictionary<Instrument, GraphicalLabel>();
     protected measureNumberLabels: GraphicalLabel[] = [];
     protected maxLabelLength: number;
     protected objectsToRedraw: [Object[], Object][] = [];
@@ -75,7 +80,7 @@ export abstract class MusicSystem extends GraphicalObject {
     }
 
     public get Labels(): GraphicalLabel[] {
-        return this.labels.keys();
+        return this.labels.values();
     }
 
     public get ObjectsToRedraw(): [Object[], Object][] {
@@ -274,15 +279,30 @@ export abstract class MusicSystem extends GraphicalObject {
      * @param labelMarginBorderFactor
      */
     public createMusicSystemLabel(instrumentLabelTextHeight: number, systemLabelsRightMargin: number, labelMarginBorderFactor: number): void {
-        if (this.parent === this.parent.Parent.MusicPages[0] && this === this.parent.MusicSystems[0]) {
+        if (this.parent === this.parent.Parent.MusicPages[0]) {
             const instruments: Instrument[] = this.parent.Parent.ParentMusicSheet.getVisibleInstruments();
             for (let idx: number = 0, len: number = instruments.length; idx < len; ++idx) {
                 const instrument: Instrument = instruments[idx];
+                let instrNameLabel: Label;
+                if (this !== this.parent.MusicSystems[0]) {
+                    if (!EngravingRules.Rules.RenderPartAbbreviations
+                        // don't render part abbreviations if there's only one instrument/part (could be an option in the future)
+                        || this.Parent.Parent.ParentMusicSheet.Instruments.length === 1
+                        || !instrument.PartAbbreviation
+                        || instrument.PartAbbreviation === "") {
+                        return;
+                    }
+                    const labelText: string = instrument.PartAbbreviation;
+                    // const labelText: string = instrument.NameLabel.text[0] + ".";
+                    instrNameLabel = new Label(labelText, instrument.NameLabel.textAlignment, instrument.NameLabel.font);
+                } else {
+                    instrNameLabel = instrument.NameLabel;
+                }
                 const graphicalLabel: GraphicalLabel = new GraphicalLabel(
-                    instrument.NameLabel, instrumentLabelTextHeight, TextAlignmentEnum.LeftCenter, this.boundingBox
+                    instrNameLabel, instrumentLabelTextHeight, TextAlignmentEnum.LeftCenter, this.boundingBox
                 );
                 graphicalLabel.setLabelPositionAndShapeBorders();
-                this.labels.setValue(graphicalLabel, instrument);
+                this.labels.setValue(instrument, graphicalLabel);
                 // X-Position will be 0 (Label starts at the same PointF_2D with MusicSystem)
                 // Y-Position will be calculated after the y-Spacing
                 // graphicalLabel.PositionAndShape.RelativePosition = new PointF2D(0.0, 0.0);
@@ -290,7 +310,7 @@ export abstract class MusicSystem extends GraphicalObject {
 
             // calculate maxLabelLength (needed for X-Spacing)
             this.maxLabelLength = 0.0;
-            const labels: GraphicalLabel[] = this.labels.keys();
+            const labels: GraphicalLabel[] = this.labels.values();
             for (let idx: number = 0, len: number = labels.length; idx < len; ++idx) {
                 const label: GraphicalLabel = labels[idx];
                 if (label.PositionAndShape.Size.width > this.maxLabelLength) {
@@ -305,15 +325,15 @@ export abstract class MusicSystem extends GraphicalObject {
      * Set the Y-Positions for the MusicSystem's Labels.
      */
     public setMusicSystemLabelsYPosition(): void {
-        if (this.parent === this.parent.Parent.MusicPages[0] && this === this.parent.MusicSystems[0]) {
-            this.labels.forEach((key: GraphicalLabel, value: Instrument): void => {
+        if (this.parent === this.parent.Parent.MusicPages[0]) {
+            this.labels.forEach((key: Instrument, value: GraphicalLabel): void => {
                 let ypositionSum: number = 0;
                 let staffCounter: number = 0;
                 for (let i: number = 0; i < this.staffLines.length; i++) {
-                    if (this.staffLines[i].ParentStaff.ParentInstrument === value) {
+                    if (this.staffLines[i].ParentStaff.ParentInstrument === key) {
                         for (let j: number = i; j < this.staffLines.length; j++) {
                             const staffLine: StaffLine = this.staffLines[j];
-                            if (staffLine.ParentStaff.ParentInstrument !== value) {
+                            if (staffLine.ParentStaff.ParentInstrument !== key) {
                                 break;
                             }
                             ypositionSum += staffLine.PositionAndShape.RelativePosition.y;
@@ -323,7 +343,7 @@ export abstract class MusicSystem extends GraphicalObject {
                     }
                 }
                 if (staffCounter > 0) {
-                    key.PositionAndShape.RelativePosition = new PointF2D(0.0, ypositionSum / staffCounter + 2.0);
+                    value.PositionAndShape.RelativePosition = new PointF2D(0.0, ypositionSum / staffCounter + 2.0);
                 }
             });
         }

+ 12 - 7
src/MusicalScore/Graphical/MusicSystemBuilder.ts

@@ -65,13 +65,7 @@ export class MusicSystemBuilder {
         // the first System - create also its Labels
         this.currentSystemParams.currentSystem = this.initMusicSystem();
         this.layoutSystemStaves();
-        if (EngravingRules.Rules.RenderInstrumentNames) {
-            this.currentSystemParams.currentSystem.createMusicSystemLabel(
-                this.rules.InstrumentLabelTextHeight,
-                this.rules.SystemLabelsRightMargin,
-                this.rules.LabelMarginBorderFactor
-            );
-        }
+        this.addSystemLabels();
         this.currentPageHeight += this.currentSystemParams.currentSystem.PositionAndShape.RelativePosition.y;
 
         let numberOfMeasures: number = 0;
@@ -191,6 +185,7 @@ export class MusicSystemBuilder {
         if (this.measureListIndex < this.measureList.length) {
             this.currentSystemParams.currentSystem = this.initMusicSystem();
             this.layoutSystemStaves();
+            this.addSystemLabels();
         }
     }
 
@@ -234,6 +229,16 @@ export class MusicSystemBuilder {
         this.currentSystemParams.systemMeasureIndex++;
     }
 
+    private addSystemLabels(): void {
+        if (EngravingRules.Rules.RenderPartNames) {
+            this.currentSystemParams.currentSystem.createMusicSystemLabel(
+                this.rules.InstrumentLabelTextHeight,
+                this.rules.SystemLabelsRightMargin,
+                this.rules.LabelMarginBorderFactor
+            );
+        }
+    }
+
     /**
      * Create a new [[GraphicalMusicPage]]
      * (for now only one long page is used per music sheet, as we scroll down and have no page flips)

+ 12 - 0
src/MusicalScore/Instrument.ts

@@ -29,6 +29,7 @@ export class Instrument extends InstrumentalGroup {
 
     private lyricVersesNumbers: number[] = [];
     private subInstruments: SubInstrument[] = [];
+    private partAbbreviation: string;
 
     public get Voices(): Voice[] {
         return this.voices;
@@ -103,6 +104,13 @@ export class Instrument extends InstrumentalGroup {
         }
         return undefined;
     }
+    public get PartAbbreviation(): string {
+        return this.partAbbreviation;
+    }
+    public set PartAbbreviation(value: string) {
+        this.partAbbreviation = value;
+    }
+
     public get Visible(): boolean {
         if (this.voices.length > 0) {
             return this.Voices[0].Visible;
@@ -242,4 +250,8 @@ export class Instrument extends InstrumentalGroup {
         }
     }
 
+    // necessary to be unique for MusicSystem.labels Dictionary
+    public toString(): string {
+        return `${this.Name} , id: ${this.id}, idstring: ${this.idString}`;
+    }
 }

+ 2 - 0
src/MusicalScore/ScoreIO/MusicSheetReader.ts

@@ -719,6 +719,8 @@ export class MusicSheetReader /*implements IMusicSheetReader*/ {
                         try {
                             if (partElement.name === "part-name") {
                                 instrument.Name = partElement.value;
+                            } else if (partElement.name === "part-abbreviation") {
+                                instrument.PartAbbreviation = partElement.value;
                             } else if (partElement.name === "score-instrument") {
                                 const subInstrument: SubInstrument = new SubInstrument(instrument);
                                 subInstrument.idString = partElement.firstAttribute.value;

+ 10 - 2
src/OpenSheetMusicDisplay/OSMDOptions.ts

@@ -1,4 +1,4 @@
-import { DrawingParametersEnum } from "../MusicalScore/Graphical/DrawingParameters";
+import { DrawingParametersEnum, ColoringModes } from "../MusicalScore/Graphical/DrawingParameters";
 
 /** Possible options for the OpenSheetMusicDisplay constructor, none are mandatory. */
 export interface IOSMDOptions {
@@ -10,6 +10,12 @@ export interface IOSMDOptions {
     autoResize?: boolean;
     /** Render Backend, will be SVG if given undefined, SVG or svg, otherwise Canvas. */
     backend?: string;
+    /** Defines the mode that is used for coloring: XML, Boomwhacker. Default XML (0).
+     *  If coloringMode.CustomColorSet (2) is chosen, a coloringSetCustom parameter must be added.
+     */
+    coloringMode?: ColoringModes;
+    /** Set of 7 colors for automatic coloring of notes from C to B in HTML form (e.g. #00ff00).  */
+    coloringSetCustom?: string[];
     /** Whether to enable coloring noteheads and stems by their XML color attribute. */
     coloringEnabled?: boolean;
     /** Default color for a note head (without stem). Default black (undefined). */
@@ -36,7 +42,9 @@ export interface IOSMDOptions {
     drawLyricist?: boolean;
     /** Whether to draw part (instrument) names. */
     drawPartNames?: boolean;
-    /** Whether to draw fingerings (only left to the note for now). Default true. */
+    /** Whether to draw part (instrument) name abbreviations each system after the first. Only draws if drawPartNames. Default true. */
+    drawPartAbbreviations?: 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, auto).
      * Default left. Auto, above, below experimental (potential collisions because bounding box not correct)

+ 53 - 3
src/OpenSheetMusicDisplay/OpenSheetMusicDisplay.ts

@@ -13,10 +13,13 @@ import {MXLHelper} from "../Common/FileIO/Mxl";
 import {Promise} from "es6-promise";
 import {AJAX} from "./AJAX";
 import * as log from "loglevel";
-import {DrawingParametersEnum, DrawingParameters} from "../MusicalScore/Graphical/DrawingParameters";
+import {DrawingParametersEnum, DrawingParameters, ColoringModes} from "../MusicalScore/Graphical/DrawingParameters";
 import {IOSMDOptions, OSMDOptions, AutoBeamOptions} from "./OSMDOptions";
 import {EngravingRules} from "../MusicalScore/Graphical/EngravingRules";
 import {AbstractExpression} from "../MusicalScore/VoiceData/Expressions/AbstractExpression";
+import {Dictionary} from "typescript-collections";
+import {NoteEnum} from "..";
+import {AutoColorSet} from "../MusicalScore";
 
 /**
  * The main class and control point of OpenSheetMusicDisplay.<br>
@@ -193,7 +196,9 @@ export class OpenSheetMusicDisplay {
      *  For example, setOptions({autoResize: false}) will disable autoResize even during runtime.
      */
     public setOptions(options: IOSMDOptions): void {
-        this.drawingParameters = new DrawingParameters();
+        if (!this.drawingParameters) {
+            this.drawingParameters = new DrawingParameters();
+        }
         if (options.drawingParameters) {
             this.drawingParameters.DrawingParametersEnum =
                 (<any>DrawingParametersEnum)[options.drawingParameters.toLowerCase()];
@@ -240,6 +245,10 @@ export class OpenSheetMusicDisplay {
                 }
             }
         }
+
+        if (options.coloringMode !== undefined) {
+            this.setColoringMode(options);
+        }
         if (options.coloringEnabled !== undefined) {
             EngravingRules.Rules.ColoringEnabled = options.coloringEnabled;
         }
@@ -268,7 +277,10 @@ export class OpenSheetMusicDisplay {
             this.drawingParameters.drawCredits = options.drawCredits;
         }
         if (options.drawPartNames !== undefined) {
-            this.drawingParameters.DrawPartNames = options.drawPartNames;
+            this.drawingParameters.DrawPartNames = options.drawPartNames; // indirectly writes to EngravingRules
+        }
+        if (options.drawPartAbbreviations !== undefined) {
+            EngravingRules.Rules.RenderPartAbbreviations = options.drawPartAbbreviations;
         }
         if (options.drawFingerings === false) {
             EngravingRules.Rules.RenderFingerings = false;
@@ -320,6 +332,44 @@ export class OpenSheetMusicDisplay {
         }
     }
 
+    public setColoringMode(options: IOSMDOptions): void {
+        if (options.coloringMode === ColoringModes.XML) {
+            EngravingRules.Rules.ColoringMode = ColoringModes.XML;
+            return;
+        }
+        const noteIndices: NoteEnum[] = [NoteEnum.C, NoteEnum.D, NoteEnum.E, NoteEnum.F, NoteEnum.G, NoteEnum.A, NoteEnum.B, -1];
+        let colorSetString: string[];
+        if (options.coloringMode === ColoringModes.CustomColorSet) {
+            if (!options.coloringSetCustom || options.coloringSetCustom.length !== 8) {
+                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).");
+            }
+            // validate strings input
+            for (const colorString of options.coloringSetCustom) {
+                const regExp: RegExp = /^\#[0-9a-fA-F]{6}$/;
+                if (!regExp.test(colorString)) {
+                    throw new Error(
+                        "One of the color strings in options.coloringSetCustom was not a valid HTML Hex color:\n" + colorString);
+                }
+            }
+            colorSetString = options.coloringSetCustom;
+        } else if (options.coloringMode === ColoringModes.AutoColoring) {
+            colorSetString = [];
+            const keys: string[] = Object.keys(AutoColorSet);
+            for (let i: number = 0; i < keys.length; i++) {
+                colorSetString.push(AutoColorSet[keys[i]]);
+            }
+        } // for both cases:
+        const coloringSetCurrent: Dictionary<NoteEnum|number, string> = new Dictionary<NoteEnum|number, string>();
+        for (let i: number = 0; i < noteIndices.length; i++) {
+            coloringSetCurrent.setValue(noteIndices[i], colorSetString[i]);
+        }
+        coloringSetCurrent.setValue(-1, colorSetString[7]);
+        EngravingRules.Rules.ColoringSetCurrent = coloringSetCurrent;
+
+        EngravingRules.Rules.ColoringMode = options.coloringMode;
+    }
+
     /**
      * Sets the logging level for this OSMD instance. By default, this is set to `warn`.
      *

+ 728 - 0
test/data/OSMD_function_test_auto-custom-coloring-entchen.musicxml

@@ -0,0 +1,728 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise>
+  <work>
+    <work-title>OSMD Function Test - Auto-Coloring</work-title>
+    </work>
+  <identification>
+    <creator type="composer">Kinderlied</creator>
+    <encoding>
+      <software>MuseScore 2.0.3</software>
+      <encoding-date>2017-01-02</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>7.056</millimeters>
+      <tenths>40</tenths>
+      </scaling>
+    <page-layout>
+      <page-height>1683.27</page-height>
+      <page-width>1190.81</page-width>
+      <page-margins type="even">
+        <left-margin>56.6893</left-margin>
+        <right-margin>56.6893</right-margin>
+        <top-margin>56.6893</top-margin>
+        <bottom-margin>113.379</bottom-margin>
+        </page-margins>
+      <page-margins type="odd">
+        <left-margin>56.6893</left-margin>
+        <right-margin>56.6893</right-margin>
+        <top-margin>56.6893</top-margin>
+        <bottom-margin>113.379</bottom-margin>
+        </page-margins>
+      </page-layout>
+    <word-font font-family="FreeSerif" font-size="10"/>
+    <lyric-font font-family="FreeSerif" font-size="11"/>
+    </defaults>
+  <credit page="1">
+    <credit-words default-x="595.407" default-y="1626.58" justify="center" valign="top" font-size="24">Alle meine Entchen</credit-words>
+    </credit>
+  <part-list>
+    <score-part id="P1">
+      <part-name>Stimme</part-name>
+      <part-abbreviation>St.</part-abbreviation>
+      <score-instrument id="P1-I1">
+        <instrument-name>Stimme</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="547.56">
+      <print>
+        <system-layout>
+          <system-margins>
+            <left-margin>0.00</left-margin>
+            <right-margin>-0.00</right-margin>
+            </system-margins>
+          <top-system-distance>170.00</top-system-distance>
+          </system-layout>
+        </print>
+      <attributes>
+        <divisions>2</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>
+      <harmony print-frame="no">
+        <root>
+          <root-step>C</root-step>
+          </root>
+        <kind>major</kind>
+        </harmony>
+      <note default-x="79.59" default-y="-50.00">
+        <pitch>
+          <step>C</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <lyric number="1">
+          <syllabic>begin</syllabic>
+          <text>Al</text>
+          </lyric>
+        </note>
+      <note default-x="144.36" default-y="-45.00">
+        <pitch>
+          <step>D</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <lyric number="1">
+          <syllabic>end</syllabic>
+          <text>le</text>
+          </lyric>
+        </note>
+      <note default-x="209.14" default-y="-40.00">
+        <pitch>
+          <step>E</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <lyric number="1">
+          <syllabic>begin</syllabic>
+          <text>mei</text>
+          </lyric>
+        </note>
+      <note default-x="273.91" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <lyric number="1">
+          <syllabic>end</syllabic>
+          <text>ne</text>
+          </lyric>
+        </note>
+      <note default-x="338.68" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>up</stem>
+        <lyric number="1">
+          <syllabic>begin</syllabic>
+          <text>Ent</text>
+          </lyric>
+        </note>
+      <note default-x="442.32" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>up</stem>
+        <lyric number="1">
+          <syllabic>end</syllabic>
+          <text>chen</text>
+          </lyric>
+        </note>
+      </measure>
+    <measure number="2" width="529.88">
+      <harmony print-frame="no">
+        <root>
+          <root-step>F</root-step>
+          </root>
+        <kind>major</kind>
+        </harmony>
+      <note default-x="39.42" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <lyric number="1">
+          <syllabic>begin</syllabic>
+          <text>schwim</text>
+          </lyric>
+        </note>
+      <note default-x="118.26" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <lyric number="1">
+          <syllabic>end</syllabic>
+          <text>men</text>
+          </lyric>
+        </note>
+      <note default-x="197.11" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <lyric number="1">
+          <syllabic>single</syllabic>
+          <text>auf</text>
+          </lyric>
+        </note>
+      <note default-x="275.96" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <lyric number="1">
+          <syllabic>single</syllabic>
+          <text>dem</text>
+          </lyric>
+        </note>
+      <harmony print-frame="no">
+        <root>
+          <root-step>C</root-step>
+          </root>
+        <kind>major</kind>
+        </harmony>
+      <note default-x="354.45" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>up</stem>
+        <lyric number="1">
+          <syllabic>single</syllabic>
+          <text>See,</text>
+          </lyric>
+        </note>
+	  <note default-x="430">
+        <rest/>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+      </note>
+      </measure>
+    <measure number="3" width="546.01">
+      <print new-system="yes">
+        <system-layout>
+          <system-margins>
+            <left-margin>0.00</left-margin>
+            <right-margin>-0.00</right-margin>
+            </system-margins>
+          <system-distance>150.00</system-distance>
+          </system-layout>
+        </print>
+      <harmony print-frame="no">
+        <root>
+          <root-step>G</root-step>
+          </root>
+        <kind text="7">dominant</kind>
+        </harmony>
+      <note default-x="61.49" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <lyric number="1">
+          <syllabic>begin</syllabic>
+          <text>Köpf</text>
+          </lyric>
+        </note>
+      <note default-x="128.56" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <lyric number="1">
+          <syllabic>end</syllabic>
+          <text>chen</text>
+          </lyric>
+        </note>
+      <note default-x="195.63" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <lyric number="1">
+          <syllabic>single</syllabic>
+          <text>in</text>
+          </lyric>
+        </note>
+      <note default-x="262.71" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <lyric number="1">
+          <syllabic>single</syllabic>
+          <text>das</text>
+          </lyric>
+        </note>
+      <harmony print-frame="no">
+        <root>
+          <root-step>C</root-step>
+          </root>
+        <kind>major</kind>
+        </harmony>
+      <note default-x="329.78" default-y="-40.00">
+        <pitch>
+          <step>E</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>up</stem>
+        <lyric number="1">
+          <syllabic>begin</syllabic>
+          <text>Was</text>
+          </lyric>
+        </note>
+      <note default-x="437.09" default-y="-40.00">
+        <pitch>
+          <step>E</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>up</stem>
+        <lyric number="1">
+          <syllabic>end</syllabic>
+          <text>ser,</text>
+          </lyric>
+        </note>
+      </measure>
+    <measure number="4" width="531.43">
+      <harmony print-frame="no">
+        <root>
+          <root-step>G</root-step>
+          </root>
+        <kind text="7">dominant</kind>
+        </harmony>
+      <note default-x="44.41" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <lyric number="1">
+          <syllabic>begin</syllabic>
+          <text>Schwänz</text>
+          </lyric>
+        </note>
+      <note default-x="121.26" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <lyric number="1">
+          <syllabic>end</syllabic>
+          <text>chen</text>
+          </lyric>
+        </note>
+      <note default-x="198.10" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        <lyric number="1">
+          <syllabic>single</syllabic>
+          <text>in</text>
+          </lyric>
+        </note>
+      <note default-x="274.94" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        <lyric number="1">
+          <syllabic>single</syllabic>
+          <text>die</text>
+          </lyric>
+        </note>
+      <harmony print-frame="no">
+        <root>
+          <root-step>C</root-step>
+          </root>
+        <kind>major</kind>
+        </harmony>
+      <note default-x="351.42" default-y="-50.00">
+        <pitch>
+          <step>C</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>4</duration>
+        <voice>1</voice>
+        <type>half</type>
+        <stem>up</stem>
+        <lyric number="1">
+          <syllabic>single</syllabic>
+          <text>Höh´.</text>
+          </lyric>
+        </note>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+	  <measure number="5" width="208.81">
+      <note default-x="12.00" default-y="-50.00">
+        <pitch>
+          <step>C</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        </note>
+      <note default-x="36.40" default-y="-45.00">
+        <pitch>
+          <step>D</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        </note>
+      <note default-x="60.80" default-y="-40.00">
+        <pitch>
+          <step>E</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        </note>
+      <note default-x="85.20" default-y="-35.00">
+        <pitch>
+          <step>F</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        </note>
+      <note default-x="109.60" default-y="-30.00">
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">begin</beam>
+        </note>
+      <note default-x="134.01" default-y="-25.00">
+        <pitch>
+          <step>A</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        </note>
+      <note default-x="158.41" default-y="-20.00">
+        <pitch>
+          <step>B</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">continue</beam>
+        </note>
+      <note default-x="182.81" default-y="-15.00">
+        <pitch>
+          <step>C</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>up</stem>
+        <beam number="1">end</beam>
+        </note>
+      </measure>
+    <measure number="6" width="241.81">
+      <note default-x="12.00" default-y="-10.00">
+        <pitch>
+          <step>D</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        </note>
+      <note default-x="39.40" default-y="-5.00">
+        <pitch>
+          <step>E</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        </note>
+      <note default-x="66.80" default-y="0.00">
+        <pitch>
+          <step>F</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        </note>
+      <note default-x="94.20" default-y="5.00">
+        <pitch>
+          <step>G</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        </note>
+      <note default-x="121.60" default-y="10.00">
+        <pitch>
+          <step>A</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <beam number="1">begin</beam>
+        </note>
+      <note default-x="149.01" default-y="15.00">
+        <pitch>
+          <step>B</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        </note>
+      <note default-x="176.41" default-y="20.00">
+        <pitch>
+          <step>C</step>
+          <octave>6</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <beam number="1">continue</beam>
+        </note>
+      <note default-x="203.81" default-y="-50.00">
+        <pitch>
+          <step>C</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        <beam number="1">end</beam>
+        </note>
+      <note default-x="203.81" default-y="-40.00">
+        <chord/>
+        <pitch>
+          <step>E</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        </note>
+      <note default-x="203.81" default-y="-30.00">
+        <chord/>
+        <pitch>
+          <step>G</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        </note>
+      <note default-x="203.81" default-y="-15.00">
+        <chord/>
+        <pitch>
+          <step>C</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        </note>
+      <note default-x="203.81" default-y="-5.00">
+        <chord/>
+        <pitch>
+          <step>E</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        </note>
+      <note default-x="203.81" default-y="5.00">
+        <chord/>
+        <pitch>
+          <step>G</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        </note>
+      <note default-x="203.81" default-y="20.00">
+        <chord/>
+        <pitch>
+          <step>C</step>
+          <octave>6</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>eighth</type>
+        <stem>down</stem>
+        </note>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+    </part>
+  </score-partwise>

+ 1 - 2
test/data/OSMD_function_test_color.musicxml

@@ -2,10 +2,9 @@
 <!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>OSMD Function Test - Color</work-title>
+    <work-title>OSMD Function Test - Color (from XML)</work-title>
     </work>
   <identification>
-    <rights>Copyright © 2002 Recordare LLC</rights>
     <encoding>
       <software>MuseScore 2.3.2</software>
       <encoding-date>2018-10-23</encoding-date>