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);
            }
        }