Пример #1
0
        /// <summary>
        /// Forces naturals to be displayed when there are two synchronous chordSymbols in thisStaffMoment,
        /// and they share diatonic pitches having different accidentals.
        /// </summary>
        private void ForceNaturals(NoteObjectMoment thisStaffMoment)
        {
            List <ChordSymbol> momentChordSymbols = new List <ChordSymbol>(2);

            foreach (ChordSymbol chordSymbol in thisStaffMoment.ChordSymbols)
            {
                momentChordSymbols.Add(chordSymbol);
            }
            if (momentChordSymbols.Count == 2)
            {
                foreach (Head head1 in momentChordSymbols[0].HeadsTopDown)
                {
                    foreach (Head head2 in momentChordSymbols[1].HeadsTopDown)
                    {
                        if (head1.Pitch == head2.Pitch)
                        {
                            if (head1.Alteration != 0 && head2.DisplayAccidental != DisplayAccidental.force)
                            {
                                head2.DisplayAccidental = DisplayAccidental.force;
                            }
                            if (head2.Alteration != 0 && head1.DisplayAccidental != DisplayAccidental.force)
                            {
                                head1.DisplayAccidental = DisplayAccidental.force;
                            }
                        }
                    }
                }
            }
        }
Пример #2
0
 /// <summary>
 /// Forces naturals to be displayed when the most recent staff moment containing chords shares
 /// diatonic pitches with thisStaffMoment, and those pitches have different accidentals.
 /// </summary>
 private void ForceNaturals(NoteObjectMoment previousStaffMoment, NoteObjectMoment thisStaffMoment)
 {
     foreach (ChordSymbol chordSymbol in thisStaffMoment.ChordSymbols)
     {
         foreach (Head head in chordSymbol.HeadsTopDown)
         {
             if (head.Alteration == 0)
             {
                 bool found = false;
                 head.DisplayAccidental = DisplayAccidental.suppress; // naturals are suppressed by default
                 foreach (ChordSymbol previousChordSymbol in previousStaffMoment.ChordSymbols)
                 {
                     foreach (Head previousHead in previousChordSymbol.HeadsTopDown)
                     {
                         if ((head.Pitch == previousHead.Pitch) && previousHead.Alteration != 0)
                         {
                             head.DisplayAccidental = DisplayAccidental.force;
                             found = true;
                             break;
                         }
                     }
                     if (found)
                     {
                         break;
                     }
                 }
             }
         }
     }
 }
Пример #3
0
        /// <summary>
        /// Returns the (positive) horizontal distance by which this anchorage symbol overlaps
        /// (any characters in) the previous noteObjectMoment (which contains symbols from both voices
        /// in a 2-voice staff). The result can be 0. If there is no overlap, the result is float.Minval.
        /// </summary>
        /// <param name="previousAS"></param>
        public virtual float OverlapWidth(NoteObjectMoment previousNOM)
        {
            float overlap      = float.MinValue;
            float localOverlap = float.MinValue;

            foreach (AnchorageSymbol previousAS in previousNOM.AnchorageSymbols)
            {
                localOverlap = this.Metrics.OverlapWidth(previousAS);
                overlap      = overlap > localOverlap ? overlap : localOverlap;
            }
            return(overlap);
        }
Пример #4
0
 /// <summary>
 /// Returns the (positive) horizontal distance by which this noteObject overlaps
 /// (any characters in) the previous noteObjectMoment (which contains symbols from both voices
 /// in a 2-voice staff). The result can be 0. If there is no overlap, the result is float.Minval.
 /// </summary>
 /// <param name="previousAS"></param>
 public virtual float OverlapWidth(NoteObjectMoment previousNOM)
 {
     float overlap = float.MinValue;
     float localOverlap = float.MinValue;
     foreach(NoteObject noteObject in previousNOM.NoteObjects)
     {
         if(this.Metrics != null)
         {
             localOverlap = this.Metrics.OverlapWidth(noteObject.Metrics);
             overlap = overlap > localOverlap ? overlap : localOverlap;
         }
     }
     return overlap;
 }
Пример #5
0
        /// <summary>
        /// Sets the visibility of naturals in all the chords on this multi-bar staff.
        /// Force naturals to be displayed if this staff contains simultaneous chords which share the same
        /// diatonic pitches, and one of them is not a sharp or flat.
        /// Naturals are also forced if any of the note heights in the chordSymbol is natural and the same
        /// height as a sharp or flat in the most recent (synchronous) chords on this _staff_.
        /// Returns the final MomentSymbol (which only contains ChordSymbols) on this staff, so that the first
        /// MomentsSymbol in the corresponding staff on the next system can be adjusted too.
        /// If the chordSymbol has no heads (as in Study2b2), nothing happens.
        /// </summary>
        public NoteObjectMoment FinalizeAccidentals(NoteObjectMoment previousStaffMoment)
        {
            foreach (NoteObjectMoment thisStaffMoment in this.ChordSymbolMoments)
            {
                if (previousStaffMoment != null)
                {
                    ForceNaturals(previousStaffMoment, thisStaffMoment);
                }
                previousStaffMoment = thisStaffMoment;

                ForceNaturals(thisStaffMoment);
            }
            return(previousStaffMoment);
        }
Пример #6
0
        /// <summary>
        /// Returns the (positive) horizontal distance by which this noteObject overlaps
        /// (any characters in) the previous noteObjectMoment (which contains symbols from both voices
        /// in a 2-voice staff). The result can be 0. If there is no overlap, the result is double.Minval.
        /// </summary>
        /// <param name="previousAS"></param>
        public virtual double OverlapWidth(NoteObjectMoment previousNOM)
        {
            double overlap      = double.MinValue;
            double localOverlap = double.MinValue;

            foreach (NoteObject noteObject in previousNOM.NoteObjects)
            {
                if (this.Metrics != null)
                {
                    localOverlap = this.Metrics.OverlapWidth(noteObject.Metrics);
                    overlap      = overlap > localOverlap ? overlap : localOverlap;
                }
            }
            return(overlap);
        }
Пример #7
0
        /// <summary>
        /// Returns the maximum (positive) horizontal distance by which this anchorage symbol overlaps
        /// (any characters in) the previous noteObjectMoment (which contains symbols from both voices
        /// in a 2-voice staff).
        /// This function is used by rests and barlines.It is overridden by chords.
        /// </summary>
        /// <param name="previousAS"></param>
        public override double OverlapWidth(NoteObjectMoment previousNOM)
        {
            double overlap      = double.MinValue;
            double localOverlap = 0;

            foreach (Anchor previousAS in previousNOM.Anchors)
            {
                //if(this is Study2b2ChordSymbol)
                //	localOverlap = Metrics.OverlapWidth(previousAS);
                //else
                localOverlap = ChordMetrics.OverlapWidth(previousAS);

                overlap = overlap > localOverlap ? overlap : localOverlap;
            }
            return(overlap);
        }
Пример #8
0
        /// <summary>
        /// Returns the maximum (positive) horizontal distance by which this anchorage symbol overlaps
        /// (any characters in) the previous noteObjectMoment (which contains symbols from both voices
        /// in a 2-voice staff).
        /// This function is used by rests and barlines.It is overridden by chords.
        /// </summary>
        /// <param name="previousAS"></param>
        public override float OverlapWidth(NoteObjectMoment previousNOM)
        {
            float overlap      = float.MinValue;
            float localOverlap = 0F;

            foreach (AnchorageSymbol previousAS in previousNOM.AnchorageSymbols)
            {
                //if(this is Study2b2ChordSymbol)
                //	localOverlap = Metrics.OverlapWidth(previousAS);
                //else
                localOverlap = ChordMetrics.OverlapWidth(previousAS);

                overlap = overlap > localOverlap ? overlap : localOverlap;
            }
            return(overlap);
        }
Пример #9
0
 private void FinalizeAccidentals()
 {
     for (int staffIndex = 0; staffIndex < Systems[0].Staves.Count; staffIndex++)
     {
         if (!(Systems[0].Staves[staffIndex] is InvisibleOutputStaff))
         {
             NoteObjectMoment previousStaffMoment = null;
             foreach (SvgSystem system in Systems)
             {
                 Staff staff = system.Staves[staffIndex];
                 {
                     previousStaffMoment = staff.FinalizeAccidentals(previousStaffMoment);
                 }
             }
         }
     }
 }
Пример #10
0
        /// <summary>
        /// Returns a list of MomentSymbols containing objects of the type given in the Type argument.
        /// Type can be DurationSymbol or any class which inherits from DurationSymbol.
        /// All DurationSymbol msPositions must be set before calling this function.
        /// The MomentSymbols are in order of msPosition.
        /// The contained symbols are in order of voice (top-bottom of this system).
        /// </summary>
        /// <typeparam name="Type">DurationSymbol, ChordSymbol, RestSymbol</typeparam>
        private List <NoteObjectMoment> MomentSymbols <Type>()
        {
            Dictionary <int, NoteObjectMoment> dict = new Dictionary <int, NoteObjectMoment>();

            foreach (Voice voice in this.Voices)
            {
                foreach (NoteObject noteObject in voice.NoteObjects)
                {
                    if (noteObject is DurationSymbol symbol && symbol is Type)
                    {
                        M.Assert(symbol.AbsMsPosition >= 0,
                                 "Symbol.MsPosition must be set before calling this funcion!");
                        if (!dict.ContainsKey(symbol.AbsMsPosition))
                        {
                            NoteObjectMoment nom = new NoteObjectMoment(symbol.AbsMsPosition);
                            nom.Add(symbol);
                            dict.Add(symbol.AbsMsPosition, nom);
                        }
                        else
                        {
                            dict[symbol.AbsMsPosition].Add(symbol);
                        }
                    }
                }
            }
            List <NoteObjectMoment> momentSymbols = new List <NoteObjectMoment>();

            while (dict.Count > 0)
            {
                int smallestKey = int.MaxValue;
                M.Assert(dict.Count > 0);
                foreach (int key in dict.Keys)
                {
                    smallestKey = key < smallestKey ? key : smallestKey;
                }
                momentSymbols.Add(dict[smallestKey]);
                dict.Remove(smallestKey);
            }
            return(momentSymbols);
        }
Пример #11
0
        /// <summary>
        /// Returns the maximum (positive) horizontal distance by which this anchorage symbol overlaps
        /// (any characters in) the previous noteObjectMoment (which contains symbols from both voices
        /// in a 2-voice staff).
        /// This function is used by rests and barlines.It is overridden by chords.
        /// </summary>
        /// <param name="previousAS"></param>
        public override float OverlapWidth(NoteObjectMoment previousNOM)
        {
            float overlap = float.MinValue;
            float localOverlap = 0F;
            foreach(AnchorageSymbol previousAS in previousNOM.AnchorageSymbols)
            {
                //if(this is Study2b2ChordSymbol)
                //	localOverlap = Metrics.OverlapWidth(previousAS);
                //else
                localOverlap = ChordMetrics.OverlapWidth(previousAS);

                overlap = overlap > localOverlap ? overlap : localOverlap;
            }
            return overlap;
        }
Пример #12
0
        /// <summary>
        /// The MomentSymbols are in order of msPosition.
        /// The contained symbols are in order of voice (top-bottom of this system).
        /// Barlines and ClefSigns have been added to the NoteObjectMomentSymbol containing the following
        /// DurationSymbol.
        /// When this function returns, moments are in order of msPosition,
        /// and aligned internally at AlignmentX = 0;
        /// </summary>
        /// <typeparam name="Type">DurationSymbol, ChordSymbol, RestSymbol</typeparam>
        private List<NoteObjectMoment> MomentSymbols(float gap)
        {
            SortedDictionary<int, NoteObjectMoment> dict = new SortedDictionary<int, NoteObjectMoment>();
            Barline barline = null;
            ClefSymbol clef = null;
            foreach(Staff staff in Staves)
            {
                foreach(Voice voice in staff.Voices)
                {
                    int key = -1;
                    #region foreach noteObject
                    foreach(NoteObject noteObject in voice.NoteObjects)
                    {
                        DurationSymbol durationSymbol = noteObject as DurationSymbol;
                        if(durationSymbol == null)
                        {
                            if(noteObject is ClefSymbol)
                                clef = noteObject as ClefSymbol;
                            if(noteObject is Barline)
                                barline = noteObject as Barline;
                        }
                        else
                        {
                            key = durationSymbol.AbsMsPosition;

                            if(!dict.ContainsKey(key))
                            {
                                dict.Add(key, new NoteObjectMoment(durationSymbol.AbsMsPosition));
                            }

                            if(clef != null)
                            {
                                dict[key].Add(clef);
                                clef = null;
                            }
                            if(barline != null)
                            {
                                dict[key].Add(barline);
                                barline = null;
                            }

                            dict[key].Add(durationSymbol);
                        }
                    }
                    #endregion

                    if(clef != null) // final clef
                    {
                        if(dict.ContainsKey(this.AbsEndMsPosition))
                            dict[this.AbsEndMsPosition].Add(clef);
                        else
                        {
                            NoteObjectMoment nom = new NoteObjectMoment(this.AbsEndMsPosition);
                            nom.Add(clef);
                            dict.Add(this.AbsEndMsPosition, nom);
                        }
                    }
                    if(barline != null) // final barline
                    {
                        if(dict.ContainsKey(this.AbsEndMsPosition))
                            dict[this.AbsEndMsPosition].Add(barline);
                        else
                        {
                            NoteObjectMoment nom = new NoteObjectMoment(this.AbsEndMsPosition);
                            nom.Add(barline);
                            dict.Add(this.AbsEndMsPosition, nom);
                        }
                    }
                }
            }

            List<NoteObjectMoment> momentSymbols = new List<NoteObjectMoment>();
            Debug.Assert(dict.Count > 0);
            foreach(int key in dict.Keys)
                momentSymbols.Add(dict[key]);

            foreach(NoteObjectMoment momentSymbol in momentSymbols)
            {
                momentSymbol.AlignBarlineAndClefGlyphs(gap);
            }

            #region debug
            // moments are currently in order of msPosition.
            float prevMsPos = -1;
            foreach(NoteObjectMoment moment in momentSymbols)
            {
                Debug.Assert(moment.AbsMsPosition > prevMsPos);
                prevMsPos = moment.AbsMsPosition;
            }
            #endregion

            return momentSymbols;
        }
Пример #13
0
 private List<NoteObjectMoment> GetVoiceMoments(Voice voice, List<NoteObjectMoment> systemMoments)
 {
     List<NoteObjectMoment> voiceMoments = new List<NoteObjectMoment>();
     NoteObjectMoment voiceNOM = null;
     foreach(NoteObjectMoment systemNOM in systemMoments)
     {
         voiceNOM = null;
         foreach(NoteObject noteObject in systemNOM.NoteObjects)
         {
             if(noteObject.Voice == voice)
             {
                 if(voiceNOM == null)
                 {
                     // noteObject in voice 1
                     voiceNOM = new NoteObjectMoment(systemNOM.AbsMsPosition);
                     voiceNOM.Add(noteObject);
                     voiceNOM.AlignmentX = systemNOM.AlignmentX;
                 }
                 else // noteObject in voice 2
                 {
                     voiceNOM.Add(noteObject);
                 }
             }
         }
         if(voiceNOM != null)
             voiceMoments.Add(voiceNOM);
     }
     return voiceMoments;
 }
Пример #14
0
 private List<NoteObjectMoment> GetStaffMoments(Staff staff, List<NoteObjectMoment> systemMoments)
 {
     List<NoteObjectMoment> staffMoments = new List<NoteObjectMoment>();
     NoteObjectMoment staffNOM = null;
     foreach(NoteObjectMoment systemNOM in systemMoments)
     {
         staffNOM = null;
         foreach(NoteObject noteObject in systemNOM.NoteObjects)
         {
             if(noteObject.Voice.Staff == staff)
             {
                 if(staffNOM == null)
                 {
                     // noteObject in voice 1
                     staffNOM = new NoteObjectMoment(systemNOM.AbsMsPosition);
                     staffNOM.Add(noteObject);
                     staffNOM.AlignmentX = systemNOM.AlignmentX;
                 }
                 else // noteObject in voice 2
                 {
                     staffNOM.Add(noteObject);
                 }
             }
         }
         if(staffNOM != null)
             staffMoments.Add(staffNOM);
     }
     return staffMoments;
 }
Пример #15
0
 /// <summary>
 /// Returns the (positive) horizontal distance by which this anchorage symbol overlaps
 /// (any characters in) the previous noteObjectMoment (which contains symbols from both voices
 /// in a 2-voice staff). The result can be 0. If there is no overlap, the result is float.Minval.
 /// </summary>
 /// <param name="previousAS"></param>
 public virtual float OverlapWidth(NoteObjectMoment previousNOM)
 {
     float overlap = float.MinValue;
     float localOverlap = float.MinValue;
     foreach(AnchorageSymbol previousAS in previousNOM.AnchorageSymbols)
     {
         localOverlap = this.Metrics.OverlapWidth(previousAS);
         overlap = overlap > localOverlap ? overlap : localOverlap;
     }
     return overlap;
 }