Пример #1
0
        private float GetLeftMarginPos(SvgSystem system, Graphics graphics, PageFormat pageFormat)
        {
            float leftMarginPos = pageFormat.LeftMarginPos;
            float maxNameWidth  = 0;

            foreach (Staff staff in system.Staves)
            {
                foreach (NoteObject noteObject in staff.Voices[0].NoteObjects)
                {
                    Barline firstBarline = noteObject as Barline;
                    if (firstBarline != null)
                    {
                        foreach (DrawObject drawObject in firstBarline.DrawObjects)
                        {
                            StaffNameText staffName = drawObject as StaffNameText;
                            if (staffName != null)
                            {
                                Debug.Assert(staffName.TextInfo != null);

                                TextMetrics staffNameMetrics = new TextMetrics(graphics, null, staffName.TextInfo);
                                float       nameWidth        = staffNameMetrics.Right - staffNameMetrics.Left;
                                maxNameWidth = (maxNameWidth > nameWidth) ? maxNameWidth : nameWidth;
                            }
                        }
                        break;
                    }
                }
            }
            leftMarginPos = maxNameWidth + (pageFormat.Gap * 2.0F);
            leftMarginPos = (leftMarginPos > pageFormat.LeftMarginPos) ? leftMarginPos : pageFormat.LeftMarginPos;

            return(leftMarginPos);
        }
Пример #2
0
        private void CreateEmptyInputStaves(List <List <VoiceDef> > barDefsInOneSystem)
        {
            int nPrintedOutputStaves = _pageFormat.VisibleOutputVoiceIndicesPerStaff.Count;
            int nPrintedInputStaves  = _pageFormat.VisibleInputVoiceIndicesPerStaff.Count;
            int nStaffNames          = _pageFormat.ShortStaffNames.Count;

            for (int i = 0; i < Systems.Count; i++)
            {
                SvgSystem       system = Systems[i];
                List <VoiceDef> barDef = barDefsInOneSystem[i];

                for (int staffIndex = 0; staffIndex < nPrintedInputStaves; staffIndex++)
                {
                    int    staffNameIndex = nPrintedOutputStaves + staffIndex;
                    string staffname      = StaffName(i, staffNameIndex);

                    float      gap = _pageFormat.Gap * _pageFormat.InputStavesSizeFactor;
                    float      stafflineStemStrokeWidth = _pageFormat.StafflineStemStrokeWidth * _pageFormat.InputStavesSizeFactor;
                    InputStaff inputStaff = new InputStaff(system, staffname, _pageFormat.StafflinesPerStaff[staffIndex], gap, stafflineStemStrokeWidth);

                    List <byte> inputVoiceIndices = _pageFormat.VisibleInputVoiceIndicesPerStaff[staffIndex];
                    for (int ivIndex = 0; ivIndex < inputVoiceIndices.Count; ++ivIndex)
                    {
                        InputVoiceDef inputVoiceDef = barDef[inputVoiceIndices[ivIndex] + _algorithm.MidiChannelIndexPerOutputVoice.Count] as InputVoiceDef;
                        Debug.Assert(inputVoiceDef != null);
                        InputVoice inputVoice = new InputVoice(inputStaff);
                        inputVoice.VoiceDef = inputVoiceDef;
                        inputStaff.Voices.Add(inputVoice);
                    }
                    SetStemDirections(inputStaff);
                    system.Staves.Add(inputStaff);
                }
            }
        }
Пример #3
0
 /// <summary>
 /// The score contains the correct number of bars per system.
 /// Now, if a barline comes before any chords in a staff, it is moved to the end of the corresponding
 /// staff in the previous system -- or deleted altogether if it is in the first System.
 /// </summary>
 private void MoveInitialBarlinesToPreviousSystem()
 {
     for (int systemIndex = 0; systemIndex < Systems.Count; systemIndex++)
     {
         SvgSystem system = Systems[systemIndex];
         for (int staffIndex = 0; staffIndex < system.Staves.Count; staffIndex++)
         {
             Staff staff = system.Staves[staffIndex];
             for (int voiceIndex = 0; voiceIndex < staff.Voices.Count; voiceIndex++)
             {
                 Voice   voice   = staff.Voices[voiceIndex];
                 Barline barline = voice.InitialBarline;
                 if (barline != null)
                 {
                     if (systemIndex > 0)
                     {
                         Voice voiceInPreviousSystem = Systems[systemIndex - 1].Staves[staffIndex].Voices[voiceIndex];
                         voiceInPreviousSystem.NoteObjects.Add(new Barline(voiceInPreviousSystem, barline.BarlineType));
                     }
                     voice.NoteObjects.Remove(barline);
                 }
             }
         }
     }
 }
Пример #4
0
 public Staff(SvgSystem svgSystem, string staffName, int numberOfStafflines, float gap, float stafflineStemStrokeWidth)
 {
     SVGSystem = svgSystem;
     Staffname = staffName;
     Debug.Assert(numberOfStafflines > 0);
     NumberOfStafflines = numberOfStafflines;
     Gap = gap;
     StafflineStemStrokeWidth = stafflineStemStrokeWidth;
 }
Пример #5
0
        /// <summary>
        /// Creates one System per bar (=list of VoiceDefs) in the argument.
        /// The Systems are complete with staves and voices of the correct type:
        /// Each InputStaff is allocated parallel (empty) InputVoice fields.
        /// Each OutputStaff is allocated parallel (empty) OutputVoice fields.
        /// Each Voice has a VoiceDef field that is allocated to the corresponding
        /// VoiceDef from the argument.
        /// The OutputVoices are arranged according to _pageFormat.OutputVoiceIndicesPerStaff.
        /// The InputVoices are arranged according to _pageFormat.InputVoiceIndicesPerStaff.
        /// OutputVoices are given a midi channel allocated from top to bottom in the printed score.
        /// </summary>
        public void CreateEmptySystems(List <List <VoiceDef> > barDefsInOneSystem, int numberOfVisibleInputStaves)
        {
            foreach (List <VoiceDef> barVoiceDefs in barDefsInOneSystem)
            {
                SvgSystem system = new SvgSystem(this);
                this.Systems.Add(system);
            }

            CreateEmptyOutputStaves(barDefsInOneSystem, numberOfVisibleInputStaves);
            CreateEmptyInputStaves(barDefsInOneSystem);
        }
Пример #6
0
        /// <summary>
        /// There is still one system per bar.
        /// Each VoiceDef begins with an MNXCommon.Clef (taking small clefs into account).
        /// An Exception will be thrown if a SmallClefDef is found on the lower voiceDef in a staff in the systems input.
        /// Small clefs (if there are any) are copied from the top to the bottom voice (if there is one) on each staff.
        /// Small clefs on lower voices on a staff have IsVisible set to false.
        /// </summary>
        /// <param name="systems"></param>
        public void ConvertVoiceDefsToNoteObjects(List <SvgSystem> systems)
        {
            byte[] currentChannelVelocities = new byte[systems[0].Staves.Count];
            var    topVoiceSmallClefs       = new List <SmallClef>();

            int systemAbsMsPos = 0;

            for (int systemIndex = 0; systemIndex < systems.Count; ++systemIndex)
            {
                SvgSystem system = systems[systemIndex];
                system.AbsStartMsPosition = systemAbsMsPos;
                int msPositionReVoiceDef = 0;
                for (int staffIndex = 0; staffIndex < system.Staves.Count; ++staffIndex)
                {
                    Staff staff = system.Staves[staffIndex];
                    msPositionReVoiceDef = 0;
                    topVoiceSmallClefs.Clear();
                    for (int voiceIndex = 0; voiceIndex < staff.Voices.Count; ++voiceIndex)
                    {
                        Voice voice = staff.Voices[voiceIndex];
                        voice.VoiceDef.AgglomerateRests();

                        msPositionReVoiceDef = 0;
                        List <IUniqueDef> iuds = voice.VoiceDef.UniqueDefs;
                        M.Assert(iuds[0] is ClefDef || iuds[0] is MNX.Common.Clef); /** <-------------- **/

                        for (int iudIndex = 0; iudIndex < iuds.Count; ++iudIndex)
                        {
                            IUniqueDef iud           = voice.VoiceDef.UniqueDefs[iudIndex];
                            int        absMsPosition = systemAbsMsPos + msPositionReVoiceDef;

                            NoteObject noteObject =
                                SymbolSet.GetNoteObject(voice, absMsPosition, iud, iudIndex, ref currentChannelVelocities[staffIndex]);

                            if (noteObject is SmallClef smallClef)
                            {
                                if (voiceIndex == 0)
                                {
                                    if (staff.Voices.Count > 1)
                                    {
                                        topVoiceSmallClefs.Add(smallClef);
                                    }
                                }
                                else
                                {
                                    throw new Exception("SmallClefs may not be defined for a lower voice. They will be copied from the top voice");
                                }
                            }

                            if (iud is IUniqueSplittableChordDef iscd && iscd.MsDurationToNextBarline != null)
                            {
                                msPositionReVoiceDef += (int)iscd.MsDurationToNextBarline;
                            }
Пример #7
0
        private void AddExtendersAtTheEndsOfStaves(List <Staff> staves, float rightMarginPos, float gap, float extenderStrokeWidth,
                                                   float hairlinePadding, SvgSystem nextSystem)
        {
            for (int staffIndex = 0; staffIndex < staves.Count; ++staffIndex)
            {
                Staff staff = staves[staffIndex];
                if (!(staff is InvisibleOutputStaff))
                {
                    for (int voiceIndex = 0; voiceIndex < staff.Voices.Count; ++voiceIndex)
                    {
                        Voice                 voice       = staff.Voices[voiceIndex];
                        List <NoteObject>     noteObjects = voice.NoteObjects;
                        ChordSymbol           lastChord   = null;
                        RestSymbol            lastRest    = null;
                        CautionaryChordSymbol cautionary  = null;
                        for (int index = noteObjects.Count - 1; index >= 0; --index)
                        {
                            lastChord  = noteObjects[index] as ChordSymbol;
                            lastRest   = noteObjects[index] as RestSymbol;
                            cautionary = noteObjects[index] as CautionaryChordSymbol;
                            if (cautionary != null)
                            {
                                cautionary.Visible = false;
                                // a CautionaryChordSymbol is a ChordSymbol, but we have not found a real one yet.
                            }
                            else if (lastChord != null || lastRest != null)
                            {
                                break;
                            }
                        }

                        if (lastChord != null && lastChord.MsDurationToNextBarline != null)
                        {
                            List <float> x1s = GetX1sFromChord1(lastChord.ChordMetrics, hairlinePadding);
                            List <float> x2s;
                            List <float> ys = lastChord.ChordMetrics.HeadsOriginYs;
                            if (nextSystem != null && FirstDurationSymbolOnNextSystemIsCautionary(nextSystem.Staves[staffIndex].Voices[voiceIndex]))
                            {
                                x2s = GetEqualFloats(rightMarginPos + gap, x1s.Count);
                            }
                            else
                            {
                                x2s = GetEqualFloats(rightMarginPos, x1s.Count);
                            }
                            lastChord.ChordMetrics.NoteheadExtendersMetrics =
                                CreateExtenders(x1s, x2s, ys, extenderStrokeWidth, gap, true);
                        }
                    }
                }
            }
        }
Пример #8
0
 private void GetNumberOfVoices(SvgSystem svgSystem, ref int nOutputVoices)
 {
     nOutputVoices = 0;
     foreach (Staff staff in svgSystem.Staves)
     {
         foreach (Voice voice in staff.Voices)
         {
             if (voice is OutputVoice)
             {
                 nOutputVoices++;
             }
         }
     }
 }
Пример #9
0
        private void CreateEmptyOutputStaves(List <List <VoiceDef> > barDefsInOneSystem, int numberOfVisibleInputStaves)
        {
            int         nVisibleOutputStaves        = _pageFormat.VisibleOutputVoiceIndicesPerStaff.Count;
            List <byte> invisibleOutputVoiceIndices = new List <byte>();

            if (numberOfVisibleInputStaves > 0)
            {
                invisibleOutputVoiceIndices = InvisibleOutputVoiceIndices(_pageFormat.VisibleOutputVoiceIndicesPerStaff, barDefsInOneSystem[0]);
            }

            for (int i = 0; i < Systems.Count; i++)
            {
                SvgSystem       system = Systems[i];
                List <VoiceDef> barDef = barDefsInOneSystem[i];

                #region create invisible staves
                if (invisibleOutputVoiceIndices.Count > 0)
                {
                    foreach (byte invisibleOutputVoiceIndex in invisibleOutputVoiceIndices)
                    {
                        TrkDef invisibleTrkDef = barDef[invisibleOutputVoiceIndex] as TrkDef;
                        InvisibleOutputStaff invisibleOutputStaff = new InvisibleOutputStaff(system);
                        OutputVoice          outputVoice          = new OutputVoice(invisibleOutputStaff, invisibleTrkDef.MidiChannel, invisibleTrkDef.MasterVolume);
                        outputVoice.VoiceDef = invisibleTrkDef;
                        invisibleOutputStaff.Voices.Add(outputVoice);
                        system.Staves.Add(invisibleOutputStaff);
                    }
                }
                #endregion create invisible staves

                for (int printedStaffIndex = 0; printedStaffIndex < nVisibleOutputStaves; printedStaffIndex++)
                {
                    string      staffname   = StaffName(i, printedStaffIndex);
                    OutputStaff outputStaff = new OutputStaff(system, staffname, _pageFormat.StafflinesPerStaff[printedStaffIndex], _pageFormat.Gap, _pageFormat.StafflineStemStrokeWidth);

                    List <byte> outputVoiceIndices = _pageFormat.VisibleOutputVoiceIndicesPerStaff[printedStaffIndex];
                    for (int ovIndex = 0; ovIndex < outputVoiceIndices.Count; ++ovIndex)
                    {
                        TrkDef trkDef = barDef[outputVoiceIndices[ovIndex]] as TrkDef;
                        Debug.Assert(trkDef != null);
                        OutputVoice outputVoice = new OutputVoice(outputStaff, trkDef.MidiChannel, trkDef.MasterVolume);
                        outputVoice.VoiceDef = trkDef;
                        outputStaff.Voices.Add(outputVoice);
                    }
                    SetStemDirections(outputStaff);
                    system.Staves.Add(outputStaff);
                }
            }
        }
Пример #10
0
        /// <summary>
        /// The current msPosition of a voice will be retrievable as currentMsPositionPerVoicePerStaff[staffIndex][voiceIndex].
        /// </summary>
        /// <param name="system"></param>
        /// <returns></returns>
        private List <List <int> > InitializeCurrentMsPositionPerVoicePerStaff(SvgSystem system)
        {
            List <List <int> > currentMsPositionPerVoicePerStaff = new List <List <int> >();

            foreach (Staff staff in system.Staves)
            {
                List <int> currentVoiceMsPositions = new List <int>();
                currentMsPositionPerVoicePerStaff.Add(currentVoiceMsPositions);
                foreach (Voice voice in staff.Voices)
                {
                    currentVoiceMsPositions.Add(0);
                }
            }
            return(currentMsPositionPerVoicePerStaff);
        }
Пример #11
0
        /// <summary>
        /// Copies Systems[systemIndex]'s content to the end of the previous system (taking account of clefs),
        /// then removes Systems[systemIndex] from the Systems list.
        /// </summary>
        /// <param name="barlineIndex"></param>
        private void JoinToPreviousSystem(int systemIndex)
        {
            Debug.Assert(Systems.Count > 1 && Systems.Count > systemIndex);
            SvgSystem system1 = Systems[systemIndex - 1];
            SvgSystem system2 = Systems[systemIndex];

            Debug.Assert(system1.Staves.Count == system2.Staves.Count);

            for (int staffIndex = 0; staffIndex < system2.Staves.Count; staffIndex++)
            {
                bool   visibleStaff          = !(system1.Staves[staffIndex] is InvisibleOutputStaff);
                string clefTypeAtEndOfStaff1 = null;
                if (visibleStaff)
                {
                    // If a staff has two voices, both contain the same clefTypes (some clefs may be invisible).
                    clefTypeAtEndOfStaff1 = FindClefTypeAtEndOfStaff1(system1.Staves[staffIndex].Voices[0]);
                }

                for (int voiceIndex = 0; voiceIndex < system2.Staves[staffIndex].Voices.Count; voiceIndex++)
                {
                    Voice voice1 = system1.Staves[staffIndex].Voices[voiceIndex];
                    Voice voice2 = system2.Staves[staffIndex].Voices[voiceIndex];
                    if (visibleStaff)
                    {
                        ClefSymbol voice2FirstClef = voice2.NoteObjects[0] as ClefSymbol;
                        Debug.Assert(voice2FirstClef != null && clefTypeAtEndOfStaff1 == voice2FirstClef.ClefType);
                        voice2.NoteObjects.Remove(voice2FirstClef);
                    }

                    try
                    {
                        voice1.AppendNoteObjects(voice2.NoteObjects);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
            Systems.Remove(system2);
            system2 = null;
        }
Пример #12
0
 public override void AddNoteheadExtenderLines(List <Staff> staves, float rightMarginPos, float gap, float extenderStrokeWidth, float hairlinePadding, SvgSystem nextSystem)
 {
     AddExtendersAtTheBeginningsofStaves(staves, rightMarginPos, gap, extenderStrokeWidth, hairlinePadding);
     AddExtendersInStaves(staves, extenderStrokeWidth, gap, hairlinePadding);
     AddExtendersAtTheEndsOfStaves(staves, rightMarginPos, gap, extenderStrokeWidth, hairlinePadding, nextSystem);
 }
Пример #13
0
        /// <summary>
        /// There is still one system per bar.
        /// </summary>
        /// <param name="systems"></param>
        public void ConvertVoiceDefsToNoteObjects(List <SvgSystem> systems)
        {
            byte[] currentChannelVelocities = new byte[systems[0].Staves.Count];

            List <ClefChangeDef> voice0ClefChangeDefs = new List <ClefChangeDef>();
            List <ClefChangeDef> voice1ClefChangeDefs = new List <ClefChangeDef>();

            for (int systemIndex = 0; systemIndex < systems.Count; ++systemIndex)
            {
                SvgSystem system            = systems[systemIndex];
                int       visibleStaffIndex = -1;
                for (int staffIndex = 0; staffIndex < system.Staves.Count; ++staffIndex)
                {
                    Staff staff = system.Staves[staffIndex];
                    if (!(staff is InvisibleOutputStaff))
                    {
                        visibleStaffIndex++;
                    }
                    voice0ClefChangeDefs.Clear();
                    voice1ClefChangeDefs.Clear();
                    for (int voiceIndex = 0; voiceIndex < staff.Voices.Count; ++voiceIndex)
                    {
                        Voice voice           = staff.Voices[voiceIndex];
                        float musicFontHeight = (voice is OutputVoice) ? _pageFormat.MusicFontHeight : _pageFormat.MusicFontHeight * _pageFormat.InputStavesSizeFactor;
                        if (!(staff is InvisibleOutputStaff))
                        {
                            Debug.Assert(_pageFormat.ClefsList[visibleStaffIndex] != null);
                            voice.NoteObjects.Add(new ClefSymbol(voice, _pageFormat.ClefsList[visibleStaffIndex], musicFontHeight));
                        }
                        bool firstLmdd = true;

                        if (staff is InputStaff)
                        {
                            InputVoice inputVoice = staff.Voices[voiceIndex] as InputVoice;
                            if (systemIndex == 0)
                            {
                                InputVoiceDef inputVoiceDef = inputVoice.VoiceDef as InputVoiceDef;
                                inputVoice.SetMidiChannel(inputVoiceDef.MidiChannel, systemIndex);
                            }
                        }
                        foreach (IUniqueDef iud in voice.VoiceDef.UniqueDefs)
                        {
                            NoteObject noteObject =
                                SymbolSet.GetNoteObject(voice, iud, firstLmdd, ref currentChannelVelocities[staffIndex], musicFontHeight);

                            ClefChangeSymbol clefChangeSymbol = noteObject as ClefChangeSymbol;
                            if (clefChangeSymbol != null)
                            {
                                if (voiceIndex == 0)
                                {
                                    voice0ClefChangeDefs.Add(iud as ClefChangeDef);
                                }
                                else
                                {
                                    voice1ClefChangeDefs.Add(iud as ClefChangeDef);
                                }
                            }

                            voice.NoteObjects.Add(noteObject);

                            firstLmdd = false;
                        }
                    }

                    if (voice0ClefChangeDefs.Count > 0 || voice1ClefChangeDefs.Count > 0)
                    {
                        // the main clef on this staff in the next system
                        SetNextSystemClefType(staffIndex, voice0ClefChangeDefs, voice1ClefChangeDefs);
                    }

                    if (staff.Voices.Count == 2)
                    {
                        InsertInvisibleClefChangeSymbols(staff.Voices, voice0ClefChangeDefs, voice1ClefChangeDefs);

                        CheckClefTypes(staff.Voices);

                        StandardSymbolSet standardSymbolSet = SymbolSet as StandardSymbolSet;
                        if (standardSymbolSet != null)
                        {
                            standardSymbolSet.ForceNaturalsInSynchronousChords(staff);
                        }
                    }
                }
            }
        }
Пример #14
0
 /// <summary>
 /// Feb. 2012: Currently only the StandardSymbolSet supports notehead extender lines.
 /// </summary>
 public virtual void AddNoteheadExtenderLines(List <Staff> staves,
                                              float rightMarginPos, float gap, float extenderStrokeWidth, float hairlinePadding, SvgSystem nextSystem)
 {
 }
Пример #15
0
 /// <summary>
 /// Feb. 2012: Currently only the StandardSymbolSet supports notehead extender lines.
 /// </summary>
 public virtual void AddNoteheadExtenderLines(List <Staff> staves,
                                              double rightMarginPos, double gap, double extenderStrokeWidth, double hairlinePadding, SvgSystem nextSystem)
 {
 }
Пример #16
0
 public OutputStaff(SvgSystem svgSystem, string staffName, int numberOfStafflines, double gap, double stafflineStemStrokeWidth)
     : base(svgSystem, staffName, numberOfStafflines, gap, stafflineStemStrokeWidth)
 {
 }
Пример #17
0
 public InputStaff(SvgSystem svgSystem, string staffName, int numberOfStafflines, float gap, float stafflineStemStrokeWidth)
     : base(svgSystem, staffName, numberOfStafflines, gap, stafflineStemStrokeWidth)
 {
 }
Пример #18
0
 public InvisibleOutputStaff(SvgSystem svgSystem)
     : base(svgSystem, "", 1, 1, 1) // These default values will never be used.
 {
 }