private static void DrawNoteGroupOutline(ScoreRendererBase renderer, Quadrangle noteGroupBounds, NoteOrRest element) { renderer.DrawLine(noteGroupBounds.NW, noteGroupBounds.NE, new Pen(Color.Red), element); renderer.DrawLine(noteGroupBounds.NE, noteGroupBounds.SE, new Pen(Color.Red), element); renderer.DrawLine(noteGroupBounds.SE, noteGroupBounds.SW, new Pen(Color.Red), element); renderer.DrawLine(noteGroupBounds.SW, noteGroupBounds.NW, new Pen(Color.Red), element); }
/// <summary> /// For debug purposes. It will be used in slur edit mode in the future. /// </summary> private void DrawSlurFrame(ScoreRendererBase renderer, Point p1, Point p2, Point p3, Point p4, MusicalSymbol owner) { renderer.DrawLine(p1, p2, owner); renderer.DrawLine(p2, p3, owner); renderer.DrawLine(p3, p4, owner); renderer.DrawLine(p4, p1, owner); }
private void Draw(Staff staff, ScoreRendererBase renderer, StaffFragment staffFragment, StaffSystem system) { renderer.DrawLine(0, staffFragment.LinePositions[0], 0, staffFragment.LinePositions[4], staffFragment); foreach (double position in staffFragment.LinePositions) { Point startPoint = new Point(0, position); Point endPoint = new Point(system.Width, position); renderer.DrawLine(startPoint, endPoint, new Pen(renderer.Settings.DefaultColor, 1, -1), staffFragment); } }
private void Draw(Staff staff, ScoreRendererBase renderer, StaffFragment staffFragment, StaffSystem system, Pen staffLinePen, double?staffLineWidth) { renderer.DrawLine(0, staffFragment.LinePositions[0], 0, staffFragment.LinePositions[4], staffLinePen, staffFragment); var endPositionX = staffLineWidth ?? CalculateStaffLineWidth(staff, system, renderer.Settings); foreach (double linePositionY in staffFragment.LinePositions) { Point startPoint = new Point(0, linePositionY); Point endPoint = new Point(endPositionX, linePositionY); renderer.DrawLine(startPoint, endPoint, staffLinePen, staffFragment); } }
public static void TupletMark(IMeasurementService measurementService, IScoreService scoreService, ScoreRendererBase renderer, NoteOrRest element, int beamLoop) { if (measurementService.TupletState == null) { throw new Exception("DrawTupletMark was called but no tuplet is currently open in staff."); } Staff staff = scoreService.CurrentStaff; NoteOrRest firstElementInTuplet = staff.Peek <NoteOrRest>(element, PeekType.BeginningOfTuplet); int index = staff.Elements.IndexOf(firstElementInTuplet); List <MusicalSymbol> elementsUnderTuplet = staff.Elements.GetRange(index, staff.Elements.IndexOf(element) - index); var elementsUnderTupletForAverageStemLength = elementsUnderTuplet.OfType <Note>().Where(n => MusicalSymbol.DirectionToPlacement(n.StemDirection) == measurementService.TupletState.TupletPlacement).ToList(); double averageStemLength = elementsUnderTupletForAverageStemLength.Count == 0 ? 0 : elementsUnderTupletForAverageStemLength.Average(n => n.ActualStemLength); averageStemLength += 10; //Add space int placementMod = measurementService.TupletState.TupletPlacement == VerticalPlacement.Above ? -1 : 1; double tupletBracketStartXPosition = firstElementInTuplet.TextBlockLocation.X + 6; double tupletBracketStartYPosition = firstElementInTuplet.TextBlockLocation.Y + 25 + averageStemLength * placementMod; double tupletBracketEndXPosition = element.TextBlockLocation.X + 12; double tupletBracketEndYPosition = element.TextBlockLocation.Y + 25 + averageStemLength * placementMod; if (measurementService.TupletState.AreSingleBeamsPresentUnderTuplet) //Draw tuplet bracket { renderer.DrawLine(new Point(tupletBracketStartXPosition, tupletBracketStartYPosition), new Point(tupletBracketEndXPosition, tupletBracketEndYPosition), element); renderer.DrawLine(new Point(tupletBracketStartXPosition, tupletBracketStartYPosition), new Point(tupletBracketStartXPosition, firstElementInTuplet.TextBlockLocation.Y + 25 + (averageStemLength - 4) * placementMod), element); renderer.DrawLine(new Point(tupletBracketEndXPosition, tupletBracketEndYPosition), new Point(tupletBracketEndXPosition, element.TextBlockLocation.Y + 25 + (averageStemLength - 4) * placementMod), element); } double numberOfNotesYTranslation = 0; if (measurementService.TupletState.TupletPlacement == VerticalPlacement.Above) { numberOfNotesYTranslation -= 18; //If text should appear above the tuplet, move a bit to up } //If bracket is not drawn, move up or down to fill space if (!measurementService.TupletState.AreSingleBeamsPresentUnderTuplet) { numberOfNotesYTranslation += 10 * (measurementService.TupletState.TupletPlacement == VerticalPlacement.Above ? 1 : -1); } var allElementsUnderTuplet = elementsUnderTuplet.OfType <NoteOrRest>().ToList(); allElementsUnderTuplet.Add(element); var tupletNumber = CalculateTupletNumber(allElementsUnderTuplet); renderer.DrawString(Convert.ToString(tupletNumber), MusicFontStyles.LyricsFont, new Point(tupletBracketStartXPosition + (tupletBracketEndXPosition - tupletBracketStartXPosition) / 2 - 6, tupletBracketStartYPosition + (tupletBracketEndYPosition - tupletBracketStartYPosition) / 2 + numberOfNotesYTranslation), element); }
/// <summary> /// Draws tuplet mark /// </summary> /// <param name="measurementService"></param> /// <param name="scoreService"></param> /// <param name="renderer"></param> /// <param name="element"></param> public static void TupletMark(IMeasurementService measurementService, IScoreService scoreService, ScoreRendererBase renderer, NoteOrRest element) { if (measurementService.TupletState == null) { throw new Exception("DrawTupletMark was called but no tuplet is currently open in staff."); } var tupletBracketPen = renderer.CreatePenFromDefaults(element, "tupletBracketThickness", s => s.DefaultTupletBracketThickness); Staff staff = scoreService.CurrentStaff; NoteOrRest firstElementInTuplet = staff.Peek <NoteOrRest>(element, PeekType.BeginningOfTuplet); int index = staff.Elements.IndexOf(firstElementInTuplet); List <MusicalSymbol> elementsUnderTuplet = staff.Elements.GetRange(index, staff.Elements.IndexOf(element) - index + 1); var noteGroupBounds = elementsUnderTuplet.OfType <Note>().GetBounds(renderer); if (IsDebugMode) { DrawNoteGroupOutline(renderer, noteGroupBounds, element); } var boundsOnOneSide = measurementService.TupletState.TupletPlacement == VerticalPlacement.Above ? new Tuple <Point, Point>(noteGroupBounds.NW, noteGroupBounds.NE) : new Tuple <Point, Point>(noteGroupBounds.SW, noteGroupBounds.SE); int placementMod = measurementService.TupletState.TupletPlacement == VerticalPlacement.Above ? -1 : 1; var bracketDefinition = new TupletBracketDefinition( boundsOnOneSide.Item1.X, boundsOnOneSide.Item1.Y + renderer.LinespacesToPixels(2) * placementMod, boundsOnOneSide.Item2.X, boundsOnOneSide.Item2.Y + renderer.LinespacesToPixels(2) * placementMod); if (measurementService.TupletState.AreSingleBeamsPresentUnderTuplet) //Draw tuplet bracket { renderer.DrawLine(bracketDefinition.StartPoint, bracketDefinition.Point25, tupletBracketPen, element); renderer.DrawLine(bracketDefinition.Point75, bracketDefinition.EndPoint, tupletBracketPen, element); renderer.DrawLine(bracketDefinition.StartPoint, bracketDefinition.StartPoint.Translate(0, renderer.LinespacesToPixels(-1) * placementMod), tupletBracketPen, element); renderer.DrawLine(bracketDefinition.EndPoint, bracketDefinition.EndPoint.Translate(0, renderer.LinespacesToPixels(-1) * placementMod), tupletBracketPen, element); } var tupletNumber = CalculateTupletNumber(elementsUnderTuplet.OfType <NoteOrRest>()); var textToWrite = renderer.Settings.MusicFontProfile.MusicFont.BuildTupletNumber(tupletNumber); var fontStyle = renderer.IsSMuFLFont ? MusicFontStyles.MusicFont : MusicFontStyles.LyricsFont; var textSize = renderer.CanMeasureString ? renderer.MeasureString(fontStyle, textToWrite) : new Size(); var textPosition = renderer.CanMeasureString ? bracketDefinition.MidPoint.Translate(textSize.Width / -2, textSize.Height / 2) : bracketDefinition.MidPoint.Translate(-3.7, 4.7); renderer.DrawString(textToWrite, fontStyle, textPosition, element); }
/// <summary> /// Applies DrawLinesBetweenStavesFinishingTouch to the score. /// </summary> /// <param name="score">Score</param> /// <param name="renderer">Score renderer</param> public void PerformOnScore(Score score, ScoreRendererBase renderer) { var lightPen = new Pen(renderer.Settings.DefaultColor, 1); var thickPen = new Pen(renderer.Settings.DefaultColor, 3); var defaultPen = new Pen(renderer.Settings.DefaultColor, renderer.Settings.DefaultStaffLineThickness); for (var i = 0; i < scoreService.CurrentScore.Staves.Count - 1; i++) { var staff = scoreService.CurrentScore.Staves[i]; var barlinePen = renderer.CreatePenFromDefaults(staff, "thinBarlineThickness", s => s.DefaultBarlineThickness); foreach (var system in scoreService.CurrentScore.Systems) { if (renderer.Settings.RenderingMode == ScoreRenderingModes.SinglePage) { var page = staff.Score.Pages.FirstOrDefault(p => p.Systems.Contains(system)); var pageNumber = page == null ? -1 : staff.Score.Pages.IndexOf(page) + 1; if (pageNumber != renderer.Settings.CurrentPage) { continue; } } if (system.LinePositions == null) { continue; } var staffFragment = system.Staves[i]; if (!system.LinePositions.ContainsKey(i + 1) || !system.LinePositions.ContainsKey(i + 2)) { continue; } renderer.DrawLine(0, system.LinePositions[i + 1][4], 0, system.LinePositions[i + 2][0], barlinePen, staffFragment); foreach (var measure in staff.Measures.Where(m => m.Barline != null && m.System == system)) { if (measure.Barline?.Style == BarlineStyle.LightHeavy) { renderer.DrawLine(measure.BarlineLocationX - 6, system.LinePositions[i + 1][4], measure.BarlineLocationX - 6, system.LinePositions[i + 2][0], lightPen, measure.Barline); renderer.DrawLine(measure.BarlineLocationX - 1.5, system.LinePositions[i + 1][4], measure.BarlineLocationX - 1.5, system.LinePositions[i + 2][0], thickPen, measure.Barline); } else if (measure.Barline?.Style != BarlineStyle.None) { renderer.DrawLine(measure.BarlineLocationX, system.LinePositions[i + 1][4], measure.BarlineLocationX, system.LinePositions[i + 2][0], barlinePen, measure.Barline); } } } } }
private void PerformOnBeamGroups(IEnumerable <BeamGroup> beamGroups, ScoreRendererBase renderer) { foreach (var beamGroup in beamGroups) { Note previousNote = null; foreach (var member in beamGroup.Members) { var currentNote = member as Note; if (currentNote == null) { continue; } var beamPen = renderer.CreatePenFromDefaults(currentNote, "beamThickness", s => s.DefaultBeamThickness); beamPen.Color = currentNote.CoalesceColor(renderer); var beamSpacing = renderer.GetEngravingDefault("beamSpacing") ?? beamPen.Thickness * 0.6; var beamNumber = 1; foreach (var beamType in currentNote.BeamList) { var beamOffset = (beamPen.Thickness + beamSpacing) * (beamNumber - 1) * (currentNote.StemDirection == VerticalDirection.Up ? 1 : -1); var stemEnd = beamGroup.Start.TranslateHorizontallyAndMaintainAngle(beamGroup.Angle, currentNote.StemEndLocation.X - beamGroup.Start.X); currentNote.StemStartLocation = stemEnd; if (beamType == NoteBeamType.ForwardHook || beamType == NoteBeamType.BackwardHook) { var hookLength = beamType == NoteBeamType.ForwardHook ? 6 : -6; var hookEnd = stemEnd.TranslateByAngleOld(beamGroup.Angle, hookLength); renderer.DrawLine(stemEnd.Translate(0, beamOffset), hookEnd.Translate(0, beamOffset), beamPen, beamGroup); } else if (previousNote != null && beamType != NoteBeamType.Single && previousNote.BeamList.Count >= beamNumber) { var stemEnd1 = beamGroup.Start.TranslateHorizontallyAndMaintainAngle(beamGroup.Angle, previousNote.StemEndLocation.X - beamGroup.Start.X); renderer.DrawLine(stemEnd1.Translate(0, beamOffset), stemEnd.Translate(0, beamOffset), beamPen, beamGroup); } beamNumber++; } previousNote = currentNote; } } }
private void PerformOnBeamGroups(IEnumerable <BeamGroup> beamGroups, ScoreRendererBase renderer) { foreach (var beamGroup in beamGroups) { Note previousNote = null; foreach (var member in beamGroup.Members) { var currentNote = member as Note; if (currentNote == null) { continue; } var beamNumber = 1; foreach (var beamType in currentNote.BeamList) { var beamOffset = 28 + 4 * (beamNumber - 1) * (currentNote.StemDirection == VerticalDirection.Up ? 1 : -1); var stemEnd = beamGroup.Start.TranslateHorizontallyAndMaintainAngle(beamGroup.Angle, currentNote.StemEndLocation.X - beamGroup.Start.X); currentNote.StemStartLocation = stemEnd; if (beamType == NoteBeamType.ForwardHook || beamType == NoteBeamType.BackwardHook) { var hookLength = beamType == NoteBeamType.ForwardHook ? 6 : -6; var hookEnd = stemEnd.TranslateByAngle(beamGroup.Angle, hookLength); renderer.DrawLine(stemEnd.Translate(0, beamOffset), hookEnd.Translate(0, beamOffset), new Pen { Thickness = 2, Color = currentNote.CoalesceColor(renderer) }, beamGroup); } else if (previousNote != null && beamType != NoteBeamType.Single && previousNote.BeamList.Count >= beamNumber) { var stemEnd1 = beamGroup.Start.TranslateHorizontallyAndMaintainAngle(beamGroup.Angle, previousNote.StemEndLocation.X - beamGroup.Start.X); renderer.DrawLine(stemEnd1.Translate(0, beamOffset), stemEnd.Translate(0, beamOffset), new Pen { Thickness = 2, Color = currentNote.CoalesceColor(renderer) }, beamGroup); } beamNumber++; } previousNote = currentNote; } } }
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; } } }
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) { if (note.BeamList[0] == NoteBeamType.End) { continue; } if (note.BeamList[0] == NoteBeamType.Start) { firstNoteInBeam = note; continue; } if (note.BeamList[0] == NoteBeamType.Continue) { if (note.HasCustomStemEndPosition) { continue; } for (int i = staff.Elements.IndexOf(note) + 1; i < staff.Elements.Count; i++) { Note note2 = staff.Elements[i] as Note; if (note2 == null) { continue; } if (note2.BeamList.Count > 0) { if (note2.BeamList[0] == NoteBeamType.End) { lastNoteInBeam = note2; break; } } } 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) { renderer.DrawLine(new Point(note.StemEndLocation.X, note.TextBlockLocation.Y + 25), new Point(newStemEndPoint.X, newStemEndPoint.Y + 23 + 5), note); } else { renderer.DrawLine(new Point(note.StemEndLocation.X, note.TextBlockLocation.Y + 23), new Point(newStemEndPoint.X, newStemEndPoint.Y + 23 + 5), note); } } } if (lastNoteInBeam == null) { continue; } } }