示例#1
0
        /// <summary>
        /// Adds the staff name to the first barline of each visible staff in the score.
        /// </summary>
        private void SetStaffNames()
        {
            foreach (SvgSystem system in Systems)
            {
                for (int staffIndex = 0; staffIndex < system.Staves.Count; staffIndex++)
                {
                    Staff staff = system.Staves[staffIndex];
                    if (!(staff is InvisibleOutputStaff))
                    {
                        foreach (NoteObject noteObject in staff.Voices[0].NoteObjects)
                        {
                            Barline firstBarline = noteObject as Barline;
                            if (firstBarline != null)
                            {
                                float fontHeight = _pageFormat.StaffNameFontHeight;

                                if (staff is InputStaff)
                                {
                                    fontHeight *= _pageFormat.InputStavesSizeFactor;
                                }
                                StaffNameText staffNameText = new StaffNameText(firstBarline, staff.Staffname, fontHeight);
                                firstBarline.DrawObjects.Add(staffNameText);
                                break;
                            }
                        }
                    }
                }
            }
        }
示例#2
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);
        }
示例#3
0
        /// <summary>
        /// There is currently one bar per System.
        /// All Duration Symbols have been constructed in voice.NoteObjects.
        /// There are no barlines in the score yet.
        /// Add a barline to each Voice in the staff, adding a double bar to the final system
        /// </summary>
        /// <param name="barlineType"></param>
        /// <param name="systemNumbers"></param>
        private void SetBarlines()
        {
            for (int systemIndex = 0; systemIndex < Systems.Count; ++systemIndex)
            {
                foreach (Staff staff in Systems[systemIndex].Staves)
                {
                    if (!(staff is InvisibleOutputStaff))
                    {
                        foreach (Voice voice in staff.Voices)
                        {
                            Debug.Assert(voice.NoteObjects.Count > 0 &&
                                         !(voice.NoteObjects[voice.NoteObjects.Count - 1] is Barline));

                            Barline barline = new Barline(voice);
                            if (systemIndex == Systems.Count - 1)
                            {
                                barline.BarlineType = BarlineType.end;
                            }
                            else
                            {
                                barline.BarlineType = BarlineType.single;
                            }

                            voice.NoteObjects.Add(barline);
                        }
                    }
                }
            }
        }
示例#4
0
        /// <summary>
        /// Adds a bar number to the first Barline in the top visible voice of each system except the first.
        /// </summary>
        private void AddBarNumbers()
        {
            int barNumber = 1;

            foreach (SvgSystem system in Systems)
            {
                Voice topVisibleVoice = system.TopVisibleVoice();
                bool  isFirstBarline  = true;
                for (int i = 0; i < topVisibleVoice.NoteObjects.Count - 1; i++)
                {
                    Barline barline = topVisibleVoice.NoteObjects[i] as Barline;
                    if (barline != null)
                    {
                        if (isFirstBarline && system != Systems[0])
                        {
                            FramedBarNumberText framedBarNumber = new FramedBarNumberText(this, barNumber.ToString(), _pageFormat.Gap, _pageFormat.StafflineStemStrokeWidth);

                            barline.DrawObjects.Add(framedBarNumber);
                            isFirstBarline = false;
                        }
                        barNumber++;
                    }
                }
            }
        }
示例#5
0
        /// <summary>
        /// Aligns barline glyphs in this moment, moving an immediately preceding clef, but
        /// without moving the following duration symbol (which is aligned at this.AlignmentX).
        /// </summary>
        public void AlignBarlineGlyphs()
        {
            float minBarlineOriginX = float.MaxValue;

            foreach (NoteObject noteObject in _noteObjects)
            {
                Barline b = noteObject as Barline;
                if (b != null && b.Metrics != null && b.Metrics.OriginX < minBarlineOriginX)
                {
                    minBarlineOriginX = b.Metrics.OriginX;
                }
            }
            for (int index = 0; index < _noteObjects.Count; index++)
            {
                Barline barline = _noteObjects[index] as Barline;
                if (barline != null && barline.Metrics != null)
                {
                    Debug.Assert(AlignmentX == 0F);
                    if (index > 0)
                    {
                        ClefSymbol clef = _noteObjects[index - 1] as ClefSymbol;
                        if (clef != null)
                        {
                            clef.Metrics.Move(minBarlineOriginX - barline.Metrics.OriginX, 0);
                        }
                    }
                    barline.Metrics.Move(minBarlineOriginX - barline.Metrics.OriginX, 0);
                }
            }
        }
示例#6
0
        /// <summary>
        /// Writes out an SVG Voice
        /// </summary>
        /// <param name="w"></param>
        public virtual void WriteSVG(SvgWriter w, bool staffIsVisible)
        {
            for (int i = 0; i < NoteObjects.Count; ++i)
            {
                NoteObject noteObject = NoteObjects[i];
                Barline    barline    = noteObject as Barline;
                if (staffIsVisible && barline != null)
                {
                    bool       isLastNoteObject = (i == (NoteObjects.Count - 1));
                    float      top                  = Staff.Metrics.StafflinesTop;
                    float      bottom               = Staff.Metrics.StafflinesBottom;
                    PageFormat pageFormat           = Staff.SVGSystem.Score.PageFormat;
                    float      barlineStrokeWidth   = pageFormat.BarlineStrokeWidth;
                    float      stafflineStrokeWidth = pageFormat.StafflineStemStrokeWidth;
                    barline.WriteSVG(w, top, bottom, barlineStrokeWidth, stafflineStrokeWidth, isLastNoteObject, false);
                }

                ChordSymbol chordSymbol = noteObject as ChordSymbol;
                if (chordSymbol != null)
                {
                    chordSymbol.WriteSVG(w, staffIsVisible);
                }
                else
                {
                    // if this is the first barline, the staff name and (maybe) barnumber will be written.
                    noteObject.WriteSVG(w, staffIsVisible);
                }
            }
        }
示例#7
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);
                 }
             }
         }
     }
 }
示例#8
0
文件: Voice.cs 项目: notator/MNXtoSVG
        /// <summary>
        /// The system has been justified horizontally, so all objects are at their final horizontal positions.
        /// The outer tips of stems which are inside BeamBlocks have been set to the beamBlock's DefaultStemTipY value.
        /// This function
        ///  1. creates the contained beams, and sets the final coordinates of their corners.
        ///  2. resets the contained Stem.Metrics (by creating and re-allocating new ones)
        ///  3. moves objects which are outside the stem tips vertically by the same amount as the stem tips are moved.
        /// </summary>
        public void FinalizeBeamBlocks()
        {
            HashSet <ChordSymbol> chordSymbolsThatStartBeamBlocks = FindChordSymbolsThatStartBeamBlocks();
            Barline rightBarline = NoteObjects[NoteObjects.Count - 1] as Barline;

            M.Assert(rightBarline != null);

            double rightBarlineX = rightBarline.Metrics.OriginX;

            foreach (var chordSymbol in chordSymbolsThatStartBeamBlocks)
            {
                chordSymbol.FinalizeBeamBlock(rightBarlineX);
            }
        }
示例#9
0
        /// <summary>
        /// Returns the first chordSymbol or restSymbol after the first cautionaryChordSymbol.
        /// If there are cautionaryChordSymbols between the first and the returned chordSymbol or restSymbol, they are rendered invisible.
        /// If there is a barline immediately preceding the durationSymbol that would otherwise be returned, the barline is returned.
        /// Null is returned if no further chordSymbol or RestSymbol is found in the noteObjects.
        /// </summary>
        /// <param name="noteObjects"></param>
        /// <returns></returns>
        private NoteObject GetFollowingChordRestOrBarlineSymbol(List <NoteObject> noteObjects)
        {
            NoteObject noteObjectToReturn = null;
            bool       firstCautionaryChordSymbolFound = false;

            for (int i = 0; i < noteObjects.Count; ++i)
            {
                NoteObject noteObject = noteObjects[i];
                if (firstCautionaryChordSymbolFound == false && noteObject is CautionaryChordSymbol)
                {
                    firstCautionaryChordSymbolFound = true;
                    continue;
                }

                if (firstCautionaryChordSymbolFound)
                {
                    CautionaryChordSymbol followingCautionary = noteObject as CautionaryChordSymbol;
                    if (followingCautionary != null)
                    {
                        followingCautionary.Visible = false;
                        continue;
                    }

                    if (noteObject is ChordSymbol)
                    {
                        noteObjectToReturn = noteObject;
                    }

                    if (noteObject is RestSymbol)
                    {
                        noteObjectToReturn = noteObject;
                    }
                }

                if (noteObjectToReturn != null) // a ChordSymbol or a RestSymbol (not a CautionaryChordSymbol)
                {
                    Barline barline = noteObjects[i - 1] as Barline;
                    if (barline != null)
                    {
                        noteObjectToReturn = barline;
                    }
                    break;
                }
            }
            return(noteObjectToReturn);
        }
示例#10
0
        public BarlineMetrics(Graphics graphics, Barline barline, float gap)
            : base()
        {
            _objectType = "barline";
            if (barline.BarlineType == BarlineType.end)
            {
                _left = -gap * 1.7F;
            }
            else
            {
                _left = -gap * 0.5F;
            }
            _originX = 0F;
            _right   = gap / 2F;

            if (graphics != null && barline != null)
            {
                foreach (DrawObject drawObject in barline.DrawObjects)
                {
                    Text text = drawObject as Text;
                    if (text != null)
                    {
                        Debug.Assert(text.TextInfo != null &&
                                     (text is StaffNameText || text is FramedBarNumberText));

                        if (text is StaffNameText)
                        {
                            _staffNameMetrics = new TextMetrics(graphics, null, text.TextInfo);
                            // move the staffname vertically to the middle of this staff
                            Staff staff       = barline.Voice.Staff;
                            float staffheight = staff.Gap * (staff.NumberOfStafflines - 1);
                            float dy          = (staffheight * 0.5F) + (gap * 0.8F);
                            _staffNameMetrics.Move(0F, dy);
                        }
                        else if (text is FramedBarNumberText)
                        {
                            _barnumberMetrics = new BarnumberMetrics(graphics, null, text.TextInfo, text.FrameInfo);
                            //_barnumberMetrics = new TextMetrics(graphics, null, text.TextInfo);
                            // move the bar number above this barline
                            float deltaY = (gap * 6F);
                            _barnumberMetrics.Move(0F, -deltaY);
                        }
                    }
                }
            }
        }
示例#11
0
文件: Edge.cs 项目: suvjunmd/Moritz
        /// <summary>
        /// Adds all the staff's metrics, except for the top or bottom staffline.
        /// </summary>
        /// <param name="staff"></param>
        protected void AddStaffMetrics(Staff staff)
        {
            foreach (Voice voice in staff.Voices)
            {
                foreach (NoteObject noteObject in voice.NoteObjects)
                {
                    OutputChordSymbol chordSymbol = noteObject as OutputChordSymbol;
                    ClefSymbol        clef        = noteObject as ClefSymbol;

                    if (chordSymbol != null)
                    {
                        chordSymbol.ChordMetrics.AddToEdge(this);
                    }
                    else if (clef != null && clef.ClefType != "n")
                    {
                        Add(clef.Metrics);
                    }
                    else
                    {
                        Add(noteObject.Metrics);
                    }

                    Barline barline = noteObject as Barline;
                    if (barline != null)
                    {
                        BarlineMetrics barlineMetrics = barline.Metrics as BarlineMetrics;
                        if (barlineMetrics.BarnumberMetrics != null)
                        {
                            Add(barlineMetrics.BarnumberMetrics);
                        }
                        if (barlineMetrics.StaffNameMetrics != null)
                        {
                            Add(barlineMetrics.StaffNameMetrics);
                        }
                    }
                }
            }
        }
示例#12
0
        public override Metrics NoteObjectMetrics(Graphics graphics, NoteObject noteObject, VerticalDir voiceStemDirection, float gap, float strokeWidth)
        {
            Metrics               returnMetrics         = null;
            ClefSymbol            clef                  = noteObject as ClefSymbol;
            Barline               barline               = noteObject as Barline;
            CautionaryChordSymbol cautionaryChordSymbol = noteObject as CautionaryChordSymbol;
            ChordSymbol           chord                 = noteObject as ChordSymbol;
            RestSymbol            rest                  = noteObject as RestSymbol;

            if (barline != null)
            {
                returnMetrics = new BarlineMetrics(graphics, barline, gap);
            }
            else if (clef != null)
            {
                if (clef.ClefType != "n")
                {
                    returnMetrics = new ClefMetrics(clef, gap);
                }
            }
            else if (cautionaryChordSymbol != null)
            {
                returnMetrics = new ChordMetrics(graphics, cautionaryChordSymbol, voiceStemDirection, gap, strokeWidth);
            }
            else if (chord != null)
            {
                returnMetrics = new ChordMetrics(graphics, chord, voiceStemDirection, gap, strokeWidth);
            }
            else if (rest != null)
            {
                // All rests are originally created on the centre line.
                // They are moved vertically later, if they are on a 2-Voice staff.
                returnMetrics = new RestMetrics(graphics, rest, gap, noteObject.Voice.Staff.NumberOfStafflines, strokeWidth);
            }

            return(returnMetrics);
        }
示例#13
0
        private List <float> GetCautionaryRightExtenderX2s(CautionaryChordSymbol cautionaryChordSymbol1,
                                                           List <NoteObject> noteObjects, List <float> x1s, List <float> ys, float hairlinePadding)
        {
            List <float> x2s     = new List <float>();
            NoteObject   no2     = GetFollowingChordRestOrBarlineSymbol(noteObjects);
            Barline      barline = no2 as Barline;
            ChordSymbol  chord2  = no2 as ChordSymbol;
            RestSymbol   rest2   = no2 as RestSymbol;

            if (barline != null)
            {
                float x2 = barline.Metrics.OriginX;
                x2s = GetEqualFloats(x2, x1s.Count);
            }
            else if (chord2 != null)
            {
                x2s = GetX2sFromChord2(ys, chord2.ChordMetrics, hairlinePadding);
            }
            else if (rest2 != null)
            {
                float x2 = rest2.Metrics.Left - hairlinePadding;
                x2s = GetEqualFloats(x2, x1s.Count);
            }
            else // no2 == null
            {
                Debug.Assert(no2 == null);
                // This voice has no further chords or rests,
                // so draw extenders to the right margin.
                // extend to the right margin
                PageFormat pageFormat     = cautionaryChordSymbol1.Voice.Staff.SVGSystem.Score.PageFormat;
                float      rightMarginPos = pageFormat.RightMarginPos;
                float      gap            = pageFormat.Gap;
                x2s = GetEqualFloats(rightMarginPos + gap, ys.Count);
            }
            return(x2s);
        }
示例#14
0
        /// <summary>
        /// There is currently one bar per System. 
        /// All Duration Symbols have been constructed in voice.NoteObjects.
        /// There are no barlines in the score yet.
        /// Add a barline to each Voice in the staff, adding a double bar to the final system
        /// </summary>
        /// <param name="barlineType"></param>
        /// <param name="systemNumbers"></param>
        private void SetBarlines()
        {
            for(int systemIndex = 0; systemIndex < Systems.Count; ++systemIndex)
            {
                foreach(Staff staff in Systems[systemIndex].Staves)
                {
                    if(!(staff is HiddenOutputStaff))
                    {
                        foreach(Voice voice in staff.Voices)
                        {
                            Debug.Assert(voice.NoteObjects.Count > 0
                                && !(voice.NoteObjects[voice.NoteObjects.Count - 1] is Barline));

                            Barline barline = new Barline(voice);
                            if(systemIndex == Systems.Count - 1)
                                barline.BarlineType = BarlineType.end;
                            else
                                barline.BarlineType = BarlineType.single;

                            voice.NoteObjects.Add(barline);
                        }
                    }
                }
            }
        }
示例#15
0
        /// <summary>
        /// Sets Chord.Stem.Direction for each chord.
        /// Chords are beamed together, duration classes permitting, unless a rest or clef intervenes.
        /// If a barline intervenes, and beamsCrossBarlines is true, the chords are beamed together.
        /// If a barline intervenes, and beamsCrossBarlines is false, the beam is broken.
        /// </summary>
        public void SetChordStemDirectionsAndCreateBeamBlocks(PageFormat pageFormat)
        {
            List <ChordSymbol> chordsBeamedTogether = new List <ChordSymbol>();
            ClefSymbol         currentClef          = null;
            bool        breakGroup = false;
            ChordSymbol lastChord  = null;

            foreach (ChordSymbol cs in ChordSymbols)
            {
                lastChord = cs;
            }

            foreach (NoteObject noteObject in NoteObjects)
            {
                CautionaryChordSymbol cautionaryChord = noteObject as CautionaryChordSymbol;
                ChordSymbol           chord           = noteObject as ChordSymbol;
                RestSymbol            rest            = noteObject as RestSymbol;
                ClefSymbol            clef            = noteObject as ClefSymbol;
                Barline barline = noteObject as Barline;

                if (cautionaryChord != null)
                {
                    continue;
                }

                if (chord != null)
                {
                    if (chord.DurationClass == DurationClass.cautionary ||
                        chord.DurationClass == DurationClass.breve ||
                        chord.DurationClass == DurationClass.semibreve ||
                        chord.DurationClass == DurationClass.minim ||
                        chord.DurationClass == DurationClass.crotchet)
                    {
                        if (currentClef != null)
                        {
                            if (this.StemDirection == VerticalDir.none)
                            {
                                chord.Stem.Direction = chord.DefaultStemDirection(currentClef);
                            }
                            else
                            {
                                chord.Stem.Direction = this.StemDirection;
                            }
                        }
                        breakGroup = true;
                    }
                    else
                    {
                        chordsBeamedTogether.Add(chord);
                        if (chord.Stem.BeamContinues) // this is true by default
                        {
                            breakGroup = false;
                        }
                        else
                        {
                            breakGroup = true;
                        }
                    }
                }

                if (chordsBeamedTogether.Count > 0)
                {
                    if (rest != null)
                    {
                        if (rest.LocalCautionaryChordDef == null)
                        {
                            breakGroup = true;
                        }
                    }

                    if (clef != null)
                    {
                        breakGroup = true;
                    }

                    if (barline != null && !pageFormat.BeamsCrossBarlines)
                    {
                        breakGroup = true;
                    }

                    if (chord == lastChord)
                    {
                        breakGroup = true;
                    }
                }

                if (chordsBeamedTogether.Count > 0 && breakGroup)
                {
                    if (currentClef != null)
                    {
                        if (chordsBeamedTogether.Count == 1)
                        {
                            if (this.StemDirection == VerticalDir.none)
                            {
                                chordsBeamedTogether[0].Stem.Direction = chordsBeamedTogether[0].DefaultStemDirection(currentClef);
                            }
                            else
                            {
                                chordsBeamedTogether[0].Stem.Direction = this.StemDirection;
                            }
                        }
                        else if (chordsBeamedTogether.Count > 1)
                        {
                            float beamThickness       = pageFormat.BeamThickness;
                            float beamStrokeThickness = pageFormat.StafflineStemStrokeWidth;
                            if (this is InputVoice)
                            {
                                beamThickness       *= pageFormat.InputStavesSizeFactor;
                                beamStrokeThickness *= pageFormat.InputStavesSizeFactor;
                            }
                            chordsBeamedTogether[0].BeamBlock =
                                new BeamBlock(currentClef, chordsBeamedTogether, this.StemDirection, beamThickness, beamStrokeThickness);
                        }
                    }
                    chordsBeamedTogether.Clear();
                }

                if (clef != null)
                {
                    currentClef = clef;
                }
            }
        }
示例#16
0
文件: Metrics.cs 项目: notator/Moritz
        public BarlineMetrics(Graphics graphics, Barline barline, float gap)
            : base()
        {
            _objectType = "barline";
            if(barline.BarlineType == BarlineType.end)
                _left = -gap * 1.7F;
            else
                _left = -gap * 0.5F;
            _originX = 0F;
            _right = gap / 2F;

            if(graphics != null && barline != null)
            {
                foreach(DrawObject drawObject in barline.DrawObjects)
                {
                    Text text = drawObject as Text;
                    if(text != null)
                    {
                        Debug.Assert(text.TextInfo != null
                        && (text is StaffNameText || text is FramedBarNumberText));

                        if(text is StaffNameText)
                        {
                            _staffNameMetrics = new TextMetrics(graphics, null, text.TextInfo);
                            // move the staffname vertically to the middle of this staff
                            Staff staff = barline.Voice.Staff;
                            float staffheight = staff.Gap * (staff.NumberOfStafflines - 1);
                            float dy = (staffheight * 0.5F) + (gap * 0.8F);
                            _staffNameMetrics.Move(0F, dy);
                        }
                        else if(text is FramedBarNumberText)
                        {
                            _barnumberMetrics = new BarnumberMetrics(graphics, null, text.TextInfo, text.FrameInfo);
                            //_barnumberMetrics = new TextMetrics(graphics, null, text.TextInfo);
                            // move the bar number above this barline
                            float deltaY = (gap * 6F);
                            _barnumberMetrics.Move(0F, -deltaY);
                        }
                    }
                }
            }
        }
示例#17
0
        private void AddExtendersInStaves(List <Staff> staves, float extenderStrokeWidth, float gap, float hairlinePadding)
        {
            foreach (Staff staff in staves)
            {
                if (!(staff is InvisibleOutputStaff))
                {
                    foreach (Voice voice in staff.Voices)
                    {
                        List <NoteObject> noteObjects = voice.NoteObjects;
                        int index = 0;
                        while (index < noteObjects.Count - 1)
                        {
                            // noteObjects.Count - 1 because index is immediately incremented when a continuing
                            // chord or rest is found, and it should always be less than noteObjects.Count.
                            ChordSymbol chord1 = noteObjects[index] as ChordSymbol;
                            if (chord1 != null)
                            {
                                List <float> x1s = GetX1sFromChord1(chord1.ChordMetrics, hairlinePadding);
                                List <float> x2s = null;
                                List <float> ys  = null;
                                ++index;
                                if (chord1.MsDurationToNextBarline != null)
                                {
                                    while (index < noteObjects.Count)
                                    {
                                        CautionaryChordSymbol cautionaryChordSymbol = noteObjects[index] as CautionaryChordSymbol;
                                        ChordSymbol           chord2 = noteObjects[index] as ChordSymbol;
                                        RestSymbol            rest2  = noteObjects[index] as RestSymbol;
                                        if (cautionaryChordSymbol != null)
                                        {
                                            cautionaryChordSymbol.Visible = false;
                                        }
                                        else if (chord2 != null)
                                        {
                                            ys  = chord1.ChordMetrics.HeadsOriginYs;
                                            x2s = GetX2sFromChord2(ys, chord2.ChordMetrics, hairlinePadding);
                                            break;
                                        }
                                        else if (rest2 != null)
                                        {
                                            float x2 = rest2.Metrics.Left - hairlinePadding;
                                            ys  = chord1.ChordMetrics.HeadsOriginYs;
                                            x2s = GetEqualFloats(x2, x1s.Count);
                                            break;
                                        }
                                        ++index;
                                    }

                                    if (x2s != null && ys != null)
                                    {
                                        bool hasContinuingBeamBlock =
                                            ((chord1.BeamBlock != null) && (chord1.BeamBlock.Chords[chord1.BeamBlock.Chords.Count - 1] != chord1));
                                        if (hasContinuingBeamBlock)
                                        {
                                            Debug.Assert(true);
                                        }

                                        Barline barline = noteObjects[index - 1] as Barline;
                                        if (barline != null)
                                        {
                                            float x2 = barline.Metrics.OriginX;
                                            x2s = GetEqualFloats(x2, x1s.Count);
                                        }
                                        bool drawExtender = false;
                                        if (chord1.DurationClass > DurationClass.semiquaver)
                                        {
                                            drawExtender = true;
                                        }
                                        if (chord1.DurationClass < DurationClass.crotchet && hasContinuingBeamBlock)
                                        {
                                            drawExtender = false;
                                        }

                                        chord1.ChordMetrics.NoteheadExtendersMetrics =
                                            CreateExtenders(x1s, x2s, ys, extenderStrokeWidth, gap, drawExtender);
                                    }
                                }
                            }
                            else
                            {
                                ++index;
                            }
                        }
                    }
                }
            }
        }