/// <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; } } }
public void PerformOnStaff(Staff staff, ScoreRendererBase renderer) { var staffLinePen = renderer.CreatePenFromDefaults(staff, "staffLineThickness", s => s.DefaultStaffLineThickness); staffLinePen.ZIndex = -1; var staffLineWidth = renderer.Settings.IsMusicPaperMode && scoreService.Systems.Any() ? (double?)scoreService.Systems.Max(s => CalculateStaffLineWidth(staff, s, renderer.Settings)) : null; foreach (var system in scoreService.Systems) { if (system.LinePositions == null) { continue; } var staffFragment = system.Staves[scoreService.CurrentStaffNo - 1]; Draw(staff, renderer, staffFragment, system, staffLinePen, staffLineWidth); } }