private void DrawLedgerLines(ScoreRendererBase renderer, Note element, double notePositionY) { var ledgerLinePen = renderer.CreatePenFromDefaults(element, "legerLineThickness", s => s.DefaultStaffLineThickness); double startPositionX = scoreService.CursorPositionX - (renderer.IsSMuFLFont ? element.GetNoteheadWidthPx(renderer) * 0.5 : 0); double endPositionX = scoreService.CursorPositionX + (renderer.IsSMuFLFont ? element.GetNoteheadWidthPx(renderer) * 1.5 : renderer.LinespacesToPixels(element.GetNoteheadWidthLs(renderer) * 2.2)); if (notePositionY > scoreService.CurrentLinePositions[4] + renderer.Settings.LineSpacing / 2.0f) { for (double i = scoreService.CurrentLinePositions[4]; i < notePositionY - renderer.Settings.LineSpacing / 2.0f; i += renderer.Settings.LineSpacing) { renderer.DrawLine( new Point(startPositionX, i + renderer.Settings.LineSpacing), new Point(endPositionX, i + renderer.Settings.LineSpacing), ledgerLinePen, element); } } if (notePositionY < scoreService.CurrentLinePositions[0] - renderer.Settings.LineSpacing / 2) { for (double i = scoreService.CurrentLinePositions[0]; i > notePositionY + renderer.Settings.LineSpacing / 2.0f; i -= renderer.Settings.LineSpacing) { renderer.DrawLine( new Point(startPositionX, i - renderer.Settings.LineSpacing), new Point(endPositionX, i - renderer.Settings.LineSpacing), ledgerLinePen, element); } } }
public override void Render(Barline element, ScoreRendererBase renderer, FontProfile fontProfile) { var partGroup = element.Staff?.Part?.Group; var doNotDraw = partGroup != null && partGroup.GroupBarline == GroupBarlineType.Mensurstrich; var lightPen = new Pen(element.CoalesceColor(renderer), 1); var thickPen = new Pen(element.CoalesceColor(renderer), 3); var barlinePen = renderer.CreatePenFromDefaults(element, "thinBarlineThickness", s => s.DefaultBarlineThickness); if (measurementService.LastNoteInMeasureEndXPosition > scoreService.CursorPositionX) { scoreService.CursorPositionX = measurementService.LastNoteInMeasureEndXPosition; } double?measureWidth = GetCursorPositionForCurrentBarline(renderer); if (!renderer.Settings.IgnoreCustomElementPositions && measureWidth.HasValue && element.Location == HorizontalPlacement.Right) { scoreService.CursorPositionX = measureWidth.Value; } else if (element.RepeatSign == RepeatSignType.None) { //If measure width is not set, get barline location from the first staff: if (scoreService.CurrentStaff != scoreService.CurrentScore.FirstStaff) { var correspondingMeasure = scoreService.GetCorrespondingMeasure(scoreService.CurrentMeasure, scoreService.CurrentScore.FirstStaff); if (correspondingMeasure != null) { scoreService.CursorPositionX = correspondingMeasure.BarlineLocationX - 16; } } } if (element.RepeatSign == RepeatSignType.None) { if (renderer.Settings.IgnoreCustomElementPositions || !measureWidth.HasValue) { scoreService.CursorPositionX += 16; } if (element.Location == HorizontalPlacement.Right) { measurementService.LastMeasurePositionX = scoreService.CursorPositionX; } if (!doNotDraw) { if (element.Style == BarlineStyle.LightHeavy) { renderer.DrawLine(new Point(scoreService.CursorPositionX - 6, scoreService.CurrentLinePositions[4]), new Point(scoreService.CursorPositionX - 6, scoreService.CurrentLinePositions[0]), lightPen, element); renderer.DrawLine(new Point(scoreService.CursorPositionX - 1.5, scoreService.CurrentLinePositions[4]), new Point(scoreService.CursorPositionX - 1.5, scoreService.CurrentLinePositions[0]), thickPen, element); } else if (element.Style == BarlineStyle.Dashed) { var barlineHeight = Math.Abs(scoreService.CurrentLinePositions[4] - scoreService.CurrentLinePositions[0]); var currentPositionY = scoreService.CurrentLinePositions[0]; var numberOfSegments = 6; var dy = barlineHeight / numberOfSegments; for (int i = 0; i < numberOfSegments; i++) { if (i % 2 == 0) { renderer.DrawLine(new Point(scoreService.CursorPositionX, currentPositionY), new Point(scoreService.CursorPositionX, currentPositionY + dy), barlinePen, element); } currentPositionY += dy; } } else if (element.Style != BarlineStyle.None) { renderer.DrawLine(new Point(scoreService.CursorPositionX, scoreService.CurrentLinePositions[4]), new Point(scoreService.CursorPositionX, scoreService.CurrentLinePositions[0]), lightPen, element); } element.ActualRenderedBounds = new Quadrangle( new Point(scoreService.CursorPositionX, scoreService.CurrentLinePositions[0]), new Point(scoreService.CursorPositionX, scoreService.CurrentLinePositions[0]), new Point(scoreService.CursorPositionX, scoreService.CurrentLinePositions[4]), new Point(scoreService.CursorPositionX, scoreService.CurrentLinePositions[4])); } scoreService.CurrentMeasure.BarlineLocationX = scoreService.CursorPositionX; scoreService.CurrentMeasure.Barline = element; if (!IsLastBarline(element) && (renderer.Settings.IgnoreCustomElementPositions || !measureWidth.HasValue)) { scoreService.CursorPositionX += 6; } } else if (element.RepeatSign == RepeatSignType.Forward) { BeforeDrawRepeatSign(renderer, element, measureWidth); //TODO: Usunąć warunek na HtmlScoreRendererSettings jak zaimplementuję w SVG DrawCharacterInBounds if (renderer.IsSMuFLFont && fontProfile.SMuFLMetadata != null && renderer.CanDrawCharacterInBounds) { DrawRepeatSignSMuFL(renderer, element, measureWidth, fontProfile); } else { DrawRepeatSignAsText(renderer, element, measureWidth, 4, fontProfile); } AfterDrawRepeatSign(renderer, element, measureWidth, 20); } else if (element.RepeatSign == RepeatSignType.Backward) { BeforeDrawRepeatSign(renderer, element, measureWidth); //TODO: Usunąć warunek na HtmlScoreRendererSettings jak zaimplementuję w SVG DrawCharacterInBounds if (renderer.IsSMuFLFont && fontProfile.SMuFLMetadata != null && renderer.CanDrawCharacterInBounds) { DrawRepeatSignSMuFL(renderer, element, measureWidth, fontProfile); } else { DrawRepeatSignAsText(renderer, element, measureWidth, -14.5, fontProfile); } AfterDrawRepeatSign(renderer, element, measureWidth, 6); } if (element.Location == HorizontalPlacement.Right) //Start new measure only if it's right barline { alterationService.Reset(); scoreService.BeginNewMeasure(); } }
private void DrawStems(ScoreRendererBase renderer, Note element, double notePositionY, Note[] chord) { if (element.BaseDuration > RhythmicDuration.Half || element.IsUpperMemberOfChord) { return; } var additionalPlaceForFlag = Math.Log(element.BaseDuration.Denominator, 2) - 2; if (additionalPlaceForFlag < 0) { additionalPlaceForFlag = 0; } if (additionalPlaceForFlag > 1) { additionalPlaceForFlag *= 0.8; } var defaultStemLengthLs = 3 + ((element.BeamList.Any(b => b == NoteBeamType.Single) ? additionalPlaceForFlag : 0)) * (element.IsCueNote || element.IsGraceNote ? 0.66 : 1); var defaultStemLength = renderer.LinespacesToPixels(defaultStemLengthLs); double customStemEndPosition = scoreService.CurrentStaffTop + renderer.TenthsToPixels(element.StemDefaultY); double notePositionForCalculatingStemEnd = GetNotePositionForCalculatingStemEnd(renderer, element, notePositionY, chord); double notePositionForCalculatingStemStart = GetNotePositionForCalculatingStemStart(renderer, element, notePositionY, chord); if (element.StemDirection == VerticalDirection.Down) { if (renderer.Settings.IgnoreCustomElementPositions || !element.HasCustomStemEndPosition) { beamingService.CurrentStemEndPositionY = notePositionForCalculatingStemEnd + defaultStemLength; } else { beamingService.CurrentStemEndPositionY = customStemEndPosition - 4; } } else { if (renderer.Settings.IgnoreCustomElementPositions || !element.HasCustomStemEndPosition) { beamingService.CurrentStemEndPositionY = notePositionForCalculatingStemEnd - defaultStemLength; } else { beamingService.CurrentStemEndPositionY = customStemEndPosition - 6; } } if (renderer.IsSMuFLFont) { var cueNoteShift = element.StemDirection == VerticalDirection.Up ? -3 : 0; beamingService.CurrentStemPositionX = scoreService.CursorPositionX + element.GetNoteheadWidthPx(renderer) * (element.StemDirection == VerticalDirection.Down ? 0 : 1) + (element.IsGraceNote || element.IsCueNote ? cueNoteShift : 0); } else { var polihymniaBadDesignFontFix = element.GetNoteheadWidthPx(renderer) * (element.IsCueNote || element.IsGraceNote ? 2 : 1) + 0.5; beamingService.CurrentStemPositionX = scoreService.CursorPositionX + polihymniaBadDesignFontFix + (element.GetNoteheadWidthPx(renderer) / 2) * (element.StemDirection == VerticalDirection.Down ? -1 : 1) + (element.IsGraceNote || element.IsCueNote ? -2 : 0); } if (element.BeamList.Count > 0 && (element.BeamList[0] != NoteBeamType.Continue || element.HasCustomStemEndPosition)) { var stemPen = renderer.CreatePenFromDefaults(element, "stemThickness", s => s.DefaultStemThickness); renderer.DrawLine( new Point(beamingService.CurrentStemPositionX, notePositionForCalculatingStemStart), new Point(beamingService.CurrentStemPositionX, beamingService.CurrentStemEndPositionY), stemPen, element); } element.StemEndLocation = new Point(beamingService.CurrentStemPositionX, beamingService.CurrentStemEndPositionY); if (element.GraceNoteType == GraceNoteType.Slashed) { renderer.DrawLine(beamingService.CurrentStemPositionX - 5, notePositionY - 5, beamingService.CurrentStemPositionX + 5, notePositionY - 5 - 6, element); } }