private void Perform(Staff staff, Measure measure, ScoreRendererBase renderer) { //Draw missing stems / Dorysuj brakujące ogonki: Note lastNoteInBeam = null; Note firstNoteInBeam = null; foreach (Note note in staff.Elements.OfType <Note>()) { //Search for the end of the beam / Przeszukaj i znajdź koniec belki: if (note.BeamList.Count == 0) { continue; } if (note.BeamList[0] == NoteBeamType.End) { continue; } if (note.BeamList[0] == NoteBeamType.Start) { firstNoteInBeam = note; continue; } if (note.BeamList[0] != NoteBeamType.Continue) { continue; } if (note.HasCustomStemEndPosition) { continue; } lastNoteInBeam = GetLastNoteInBeam(note, staff); double newStemEndPosition = Math.Abs(note.StemEndLocation.X - firstNoteInBeam.StemEndLocation.X) * ((Math.Abs(lastNoteInBeam.StemEndLocation.Y - firstNoteInBeam.StemEndLocation.Y)) / (Math.Abs(lastNoteInBeam.StemEndLocation.X - firstNoteInBeam.StemEndLocation.X))); //Jeśli ostatnia nuta jest wyżej, to odejmij y zamiast dodać //If the last note is higher, subtract y instead of adding if (lastNoteInBeam.StemEndLocation.Y < firstNoteInBeam.StemEndLocation.Y) { newStemEndPosition *= -1; } Point newStemEndPoint = new Point(note.StemEndLocation.X, firstNoteInBeam.StemEndLocation.Y + newStemEndPosition); if (measure != null && note.Measure != measure) { continue; //Odśwież tylko stemy z wybranego taktu w trybie odświeżania jednego taktu } if (note.StemDirection == VerticalDirection.Down) { var chord = NoteRenderStrategy.GetChord(note, staff); var highestNoteInChord = chord.Last(); renderer.DrawLine(new Point(note.StemEndLocation.X, highestNoteInChord.TextBlockLocation.Y), new Point(newStemEndPoint.X, newStemEndPoint.Y), new Pen(renderer.CoalesceColor(note), renderer.Settings.DefaultStemThickness), note); } else { renderer.DrawLine(new Point(note.StemEndLocation.X, note.TextBlockLocation.Y), new Point(newStemEndPoint.X, newStemEndPoint.Y), new Pen(renderer.CoalesceColor(note), renderer.Settings.DefaultStemThickness), note); } if (lastNoteInBeam == null) { continue; } } }