示例#1
0
        public override void Paint(float cx, float cy, ICanvas canvas)
        {
            // only render slur once per staff
            var slurId         = "score.slur." + _startBeat.SlurOrigin.Id;
            var renderer       = Renderer;
            var isSlurRendered = renderer.Staff.GetSharedLayoutData(slurId, false);

            if (!isSlurRendered)
            {
                renderer.Staff.SetSharedLayoutData(slurId, true);

                var startNoteRenderer = Renderer.ScoreRenderer.Layout.GetRendererForBar <BarRendererBase>(Renderer.Staff.StaveId, _startBeat.Voice.Bar);
                var direction         = GetBeamDirection(_startBeat, startNoteRenderer);

                var startX = cx + startNoteRenderer.X;
                var startY = cy + startNoteRenderer.Y;
                if (_startBeat.SlurOrigin.Id == _startBeat.Id)
                {
                    startX += startNoteRenderer.GetBeatX(_startBeat, BeatXPosition.MiddleNotes);
                    var note = direction == BeamDirection.Down ? _startBeat.MinNote : _startBeat.MaxNote;
                    startY += startNoteRenderer.GetNoteY(note);
                }
                else
                {
                    startY += startNoteRenderer.Height;
                }
                var endBeat = _startBeat.SlurOrigin.SlurDestination;

                var   endNoteRenderer = Renderer.ScoreRenderer.Layout.GetRendererForBar <ScoreBarRenderer>(Renderer.Staff.StaveId, endBeat.Voice.Bar);
                float endX;
                float endY;
                if (endNoteRenderer == null || startNoteRenderer.Staff != endNoteRenderer.Staff)
                {
                    endNoteRenderer = (ScoreBarRenderer)startNoteRenderer.Staff.BarRenderers[startNoteRenderer.Staff.BarRenderers.Count - 1];
                    endX            = cx + endNoteRenderer.X + endNoteRenderer.Width;
                    endY            = cy + endNoteRenderer.Y + endNoteRenderer.Height;
                }
                else
                {
                    endX = cx + endNoteRenderer.X + endNoteRenderer.GetBeatX(endBeat, BeatXPosition.MiddleNotes);

                    // if the note stem is pointing towards the slur, we need to let it end on top of the stem.
                    var endBeatHelper = endNoteRenderer.Helpers.GetBeamingHelperForBeat(endBeat);
                    if (endBeatHelper.Direction == direction)
                    {
                        endY = cy + endNoteRenderer.Y + endNoteRenderer.CalculateBeamY(endBeatHelper, endX);
                    }
                    else
                    {
                        var note = direction == BeamDirection.Down ? endBeat.MinNote : endBeat.MaxNote;
                        endY = cy + endNoteRenderer.Y + endNoteRenderer.GetNoteY(note);
                    }
                }

                var height = (endX - startX) * Renderer.Settings.SlurHeightFactor;

                TieGlyph.PaintTie(canvas, Scale, startX, startY, endX, endY, direction == BeamDirection.Down, height);
                canvas.Fill();
            }
        }
示例#2
0
        public override void Paint(float cx, float cy, ICanvas canvas)
        {
            // only render slur once per staff
            var slurId         = "tab.slur." + _startNote.SlurOrigin.Beat.Id + "." + _startNote.SlurOrigin.SlurDestination.Beat.Id;
            var renderer       = (TabBarRenderer)Renderer;
            var isSlurRendered = renderer.Staff.GetSharedLayoutData(slurId, false);

            if (!isSlurRendered)
            {
                renderer.Staff.SetSharedLayoutData(slurId, true);

                var startNoteRenderer = Renderer.ScoreRenderer.Layout.GetRendererForBar <BarRendererBase>(Renderer.Staff.StaveId, _startNote.Beat.Voice.Bar);
                var direction         = GetBeamDirection(_startNote);

                var startX = cx + startNoteRenderer.X;
                var startY = cy + startNoteRenderer.Y +
                             startNoteRenderer.GetNoteY(_startNote, true);
                if (direction == BeamDirection.Down)
                {
                    startY += renderer.GetTabY(1);
                }


                if (_startNote.SlurOrigin.Id == _startNote.Id)
                {
                    startX += startNoteRenderer.GetBeatX(_startNote.Beat, BeatXPosition.MiddleNotes);
                }

                var   endNote         = _startNote.SlurOrigin.SlurDestination;
                var   endNoteRenderer = Renderer.ScoreRenderer.Layout.GetRendererForBar <BarRendererBase>(Renderer.Staff.StaveId, endNote.Beat.Voice.Bar);
                float endX;
                float endY = startY;
                if (endNoteRenderer == null || startNoteRenderer.Staff != endNoteRenderer.Staff)
                {
                    endNoteRenderer = startNoteRenderer.Staff.BarRenderers[startNoteRenderer.Staff.BarRenderers.Count - 1];
                    endX            = cx + endNoteRenderer.X + endNoteRenderer.Width;
                }
                else
                {
                    endX = cx + endNoteRenderer.X + endNoteRenderer.GetBeatX(endNote.Beat, BeatXPosition.MiddleNotes);
                }

                TieGlyph.PaintTie(canvas, Scale, startX, startY, endX, endY, direction == BeamDirection.Down);
                canvas.Fill();
            }
        }
 public override void Paint(float cx, float cy, ICanvas canvas)
 {
     if (_isOpen)
     {
         TieGlyph.PaintTie(canvas, Scale,
                           cx + X + Width, cy + Y + Height,
                           cx + X + Width, cy + Y,
                           false, Size, 3);
     }
     else
     {
         TieGlyph.PaintTie(canvas, Scale,
                           cx + X, cy + Y,
                           cx + X, cy + Y + Height,
                           false, Size, 3);
     }
     canvas.Fill();
 }
示例#4
0
        public override void Paint(float cx, float cy, ICanvas canvas)
        {
            var beat = _beat;

            switch (beat.WhammyBarType)
            {
            case WhammyType.None:
            case WhammyType.Custom:
                return;
            }

            var whammyMode        = Renderer.Settings.DisplayMode;
            var startNoteRenderer = Renderer.ScoreRenderer.Layout.GetRendererForBar <ScoreBarRenderer>(Renderer.Staff.StaveId, beat.Voice.Bar);
            var startX            = cx + startNoteRenderer.X + startNoteRenderer.GetBeatX(beat, BeatXPosition.MiddleNotes);
            var beatDirection     = GetBeamDirection(beat, startNoteRenderer);
            var direction         = _beat.Notes.Count == 1 ? beatDirection : BeamDirection.Up;

            var textalign = canvas.TextAlign;

            for (var i = 0; i < beat.Notes.Count; i++)
            {
                var note   = beat.Notes[i];
                var startY = cy + startNoteRenderer.Y + startNoteRenderer.GetNoteY(note, true);
                if (direction == BeamDirection.Down)
                {
                    startY += NoteHeadGlyph.NoteHeadHeight * Scale;
                }

                if (i > 0 && i >= _beat.Notes.Count / 2)
                {
                    direction = BeamDirection.Down;
                }

                var endX = cx + startNoteRenderer.X;
                if (beat.IsLastOfVoice)
                {
                    endX += startNoteRenderer.Width;
                }
                else
                {
                    endX += startNoteRenderer.GetBeatX(beat, BeatXPosition.EndBeat);
                }

                endX -= EndPadding * Scale;

                var slurText = beat.WhammyStyle == BendStyle.Gradual && i == 0 ? "grad." : "";

                ScoreBarRenderer endNoteRenderer = null;
                if (note.IsTieOrigin)
                {
                    endNoteRenderer =
                        Renderer.ScoreRenderer.Layout.GetRendererForBar <ScoreBarRenderer>(Renderer.Staff.StaveId,
                                                                                           note.TieDestination.Beat.Voice.Bar);
                    if (endNoteRenderer != null && endNoteRenderer.Staff == startNoteRenderer.Staff)
                    {
                        endX = cx + endNoteRenderer.X +
                               endNoteRenderer.GetBeatX(note.TieDestination.Beat, BeatXPosition.MiddleNotes);
                    }
                    else
                    {
                        endNoteRenderer = null;
                    }
                }

                var heightOffset = (NoteHeadGlyph.NoteHeadHeight * Scale * NoteHeadGlyph.GraceScale) * 0.5f;
                if (direction == BeamDirection.Up)
                {
                    heightOffset = -heightOffset;
                }
                int   endValue;
                float endY;

                switch (beat.WhammyBarType)
                {
                case WhammyType.Hold:
                    if (note.IsTieOrigin)
                    {
                        if (endNoteRenderer == null)
                        {
                            endY = startY;
                        }
                        else
                        {
                            endY = cy + endNoteRenderer.Y + endNoteRenderer.GetNoteY(note.TieDestination, true);
                        }
                        TieGlyph.PaintTie(canvas, Scale, startX, startY, endX, endY,
                                          beatDirection == BeamDirection.Down);
                        canvas.Fill();
                    }
                    break;

                case WhammyType.Dive:
                    if (i == 0)
                    {
                        _bendNoteHeads[0].X = endX - _bendNoteHeads[0].NoteHeadOffset;
                        _bendNoteHeads[0].Y = cy + startNoteRenderer.Y;
                        _bendNoteHeads[0].Paint(0, 0, canvas);
                    }

                    endValue = GetBendNoteValue(note, beat.WhammyBarPoints[beat.WhammyBarPoints.Count - 1]);
                    if (_bendNoteHeads[0].ContainsNoteValue(endValue))
                    {
                        endY = _bendNoteHeads[0].GetNoteValueY(endValue) + heightOffset;
                        DrawBendSlur(canvas, startX, startY, endX, endY, direction == BeamDirection.Down, Scale, slurText);
                    }
                    else if (endNoteRenderer != null && (note.IsTieOrigin && note.TieDestination.Beat.HasWhammyBar || (note.Beat.IsContinuedWhammy)))
                    {
                        endY = cy + endNoteRenderer.Y + endNoteRenderer.GetNoteY(note.TieDestination, true);
                        DrawBendSlur(canvas, startX, startY, endX, endY, direction == BeamDirection.Down, Scale, slurText);
                    }
                    else if (note.IsTieOrigin)
                    {
                        if (endNoteRenderer == null)
                        {
                            endY = startY;
                        }
                        else
                        {
                            endY = cy + endNoteRenderer.Y + endNoteRenderer.GetNoteY(note.TieDestination, true);
                        }
                        TieGlyph.PaintTie(canvas, Scale, startX, startY, endX, endY,
                                          beatDirection == BeamDirection.Down);
                        canvas.Fill();
                    }
                    break;

                case WhammyType.Dip:
                    if (whammyMode == DisplayMode.SongBook)
                    {
                        if (i == 0)
                        {
                            var simpleStartX = cx + startNoteRenderer.X +
                                               startNoteRenderer.GetBeatX(_beat, BeatXPosition.OnNotes)
                                               - SimpleDipPadding * Scale;
                            var simpleEndX = cx + startNoteRenderer.X +
                                             startNoteRenderer.GetBeatX(_beat, BeatXPosition.PostNotes)
                                             + SimpleDipPadding * Scale;
                            var middleX = (simpleStartX + simpleEndX) / 2;
                            var text    = ((_beat.WhammyBarPoints[1].Value - _beat.WhammyBarPoints[0].Value) / 4)
                                          .ToString();
                            canvas.Font = Renderer.Resources.TablatureFont;
                            canvas.FillText(text, middleX, cy + Y);

                            var simpleStartY = cy + Y + canvas.Font.Size + 2 * Scale;
                            var simpleEndY   = simpleStartY + SimpleDipHeight * Scale;

                            if (_beat.WhammyBarPoints[1].Value > _beat.WhammyBarPoints[0].Value)
                            {
                                canvas.MoveTo(simpleStartX, simpleEndY);
                                canvas.LineTo(middleX, simpleStartY);
                                canvas.LineTo(simpleEndX, simpleEndY);
                            }
                            else
                            {
                                canvas.MoveTo(simpleStartX, simpleStartY);
                                canvas.LineTo(middleX, simpleEndY);
                                canvas.LineTo(simpleEndX, simpleStartY);
                            }
                            canvas.Stroke();
                        }

                        if (note.IsTieOrigin)
                        {
                            if (endNoteRenderer == null)
                            {
                                endY = startY;
                            }
                            else
                            {
                                endY = cy + endNoteRenderer.Y + endNoteRenderer.GetNoteY(note.TieDestination, true);
                            }
                            TieGlyph.PaintTie(canvas, Scale, startX, startY, endX, endY,
                                              beatDirection == BeamDirection.Down);
                            canvas.Fill();
                        }
                    }
                    else
                    {
                        var middleX = (startX + endX) / 2;

                        _bendNoteHeads[0].X = middleX - _bendNoteHeads[0].NoteHeadOffset;
                        _bendNoteHeads[0].Y = cy + startNoteRenderer.Y;
                        _bendNoteHeads[0].Paint(0, 0, canvas);
                        var middleValue = GetBendNoteValue(note, beat.WhammyBarPoints[1]);
                        var middleY     = _bendNoteHeads[0].GetNoteValueY(middleValue) + heightOffset;
                        DrawBendSlur(canvas, startX, startY, middleX, middleY, direction == BeamDirection.Down,
                                     Scale, slurText);

                        _bendNoteHeads[1].X = endX - _bendNoteHeads[1].NoteHeadOffset;
                        _bendNoteHeads[1].Y = cy + startNoteRenderer.Y;
                        _bendNoteHeads[1].Paint(0, 0, canvas);
                        endValue = GetBendNoteValue(note, beat.WhammyBarPoints[beat.WhammyBarPoints.Count - 1]);
                        endY     = _bendNoteHeads[1].GetNoteValueY(endValue) + heightOffset;
                        DrawBendSlur(canvas, middleX, middleY, endX, endY, direction == BeamDirection.Down, Scale, slurText);
                    }

                    break;

                case WhammyType.PrediveDive:
                case WhammyType.Predive:
                    var preX = cx + startNoteRenderer.X +
                               startNoteRenderer.GetBeatX(note.Beat, BeatXPosition.PreNotes);
                    preX += ((ScoreBeatPreNotesGlyph)startNoteRenderer.GetBeatContainer(note.Beat).PreNotes)
                            .PrebendNoteHeadOffset;

                    var preY = cy + startNoteRenderer.Y +
                               startNoteRenderer.GetScoreY(startNoteRenderer.AccidentalHelper.GetNoteLineForValue(note.DisplayValue - note.Beat.WhammyBarPoints[0].Value / 2))
                               + heightOffset;

                    DrawBendSlur(canvas, preX, preY, startX, startY, direction == BeamDirection.Down, Scale, slurText);

                    if (_bendNoteHeads.Count > 0)
                    {
                        _bendNoteHeads[0].X = endX - _bendNoteHeads[0].NoteHeadOffset;
                        _bendNoteHeads[0].Y = cy + startNoteRenderer.Y;
                        _bendNoteHeads[0].Paint(0, 0, canvas);

                        endValue = GetBendNoteValue(note, beat.WhammyBarPoints[beat.WhammyBarPoints.Count - 1]);
                        endY     = _bendNoteHeads[0].GetNoteValueY(endValue) + heightOffset;
                        DrawBendSlur(canvas, startX, startY, endX, endY, direction == BeamDirection.Down, Scale, slurText);
                    }

                    break;
                }
            }

            canvas.TextAlign = textalign;
        }
示例#5
0
        public override void Paint(float cx, float cy, ICanvas canvas)
        {
            // Draw note heads
            var startNoteRenderer = Renderer.ScoreRenderer.Layout.GetRendererForBar <ScoreBarRenderer>(Renderer.Staff.StaveId, _beat.Voice.Bar);
            var startX            = cx + startNoteRenderer.X + startNoteRenderer.GetBeatX(_beat, BeatXPosition.MiddleNotes);
            var endBeatX          = cx + startNoteRenderer.X;

            if (_beat.IsLastOfVoice)
            {
                endBeatX += startNoteRenderer.PostBeatGlyphsStart;
            }
            else
            {
                endBeatX += startNoteRenderer.GetBeatX(_beat.NextBeat, BeatXPosition.PreNotes);
            }
            endBeatX -= EndPadding * Scale;

            var middleX = (startX + endBeatX) / 2;

            if (_middleNoteGlyph != null)
            {
                _middleNoteGlyph.X = middleX - _middleNoteGlyph.NoteHeadOffset;
                _middleNoteGlyph.Y = cy + startNoteRenderer.Y;
                _middleNoteGlyph.Paint(0, 0, canvas);
            }

            if (_endNoteGlyph != null)
            {
                _endNoteGlyph.X = endBeatX - _endNoteGlyph.NoteHeadOffset;
                _endNoteGlyph.Y = cy + startNoteRenderer.Y;
                _endNoteGlyph.Paint(0, 0, canvas);
            }

            _notes.Sort((a, b) => b.DisplayValue - a.DisplayValue);

            var directionBeat = _beat.GraceType == GraceType.BendGrace ? _beat.NextBeat : _beat;
            var direction     = _notes.Count == 1 ? GetBeamDirection(directionBeat, startNoteRenderer) : BeamDirection.Up;

            // draw slurs
            for (var i = 0; i < _notes.Count; i++)
            {
                var note = _notes[i];
                if (i > 0 && i >= _notes.Count / 2)
                {
                    direction = BeamDirection.Down;
                }

                var startY       = cy + startNoteRenderer.Y + startNoteRenderer.GetNoteY(note, true);
                var heightOffset = (NoteHeadGlyph.NoteHeadHeight * Scale * NoteHeadGlyph.GraceScale) * 0.5f;
                if (direction == BeamDirection.Down)
                {
                    startY += NoteHeadGlyph.NoteHeadHeight * Scale;
                }

                var slurText = note.BendStyle == BendStyle.Gradual ? "grad." : "";

                if (note.IsTieOrigin)
                {
                    var endNote         = note.TieDestination;
                    var endNoteRenderer = endNote == null
                        ? null
                        : Renderer.ScoreRenderer.Layout.GetRendererForBar <ScoreBarRenderer>(Renderer.Staff.StaveId,
                                                                                             endNote.Beat.Voice.Bar);

                    // if we have a line break we draw only a line until the end
                    if (endNoteRenderer == null || endNoteRenderer.Staff != startNoteRenderer.Staff)
                    {
                        var endX            = cx + startNoteRenderer.X + startNoteRenderer.Width;
                        var noteValueToDraw = note.TieDestination.RealValue;

                        var accidental =
                            startNoteRenderer.AccidentalHelper.ApplyAccidentalForValue(note.Beat, noteValueToDraw, false);
                        var endY = cy + startNoteRenderer.Y +
                                   startNoteRenderer.GetScoreY(
                            startNoteRenderer.AccidentalHelper.GetNoteLineForValue(noteValueToDraw));

                        if (note.BendType == BendType.Hold || note.BendType == BendType.Prebend)
                        {
                            TieGlyph.PaintTie(canvas, Scale, startX, startY, endX, endY,
                                              direction == BeamDirection.Down);
                            canvas.Fill();
                        }
                        else
                        {
                            DrawBendSlur(canvas, startX, startY, endX, endY, direction == BeamDirection.Down, Scale,
                                         slurText);
                        }
                    }
                    // otherwise we draw a line to the target note
                    else
                    {
                        var endX = cx + endNoteRenderer.X +
                                   endNoteRenderer.GetBeatX(endNote.Beat, BeatXPosition.MiddleNotes);
                        var endY = cy + endNoteRenderer.Y + endNoteRenderer.GetNoteY(endNote, true);
                        if (direction == BeamDirection.Down)
                        {
                            endY += NoteHeadGlyph.NoteHeadHeight * Scale;
                        }

                        if (note.BendType == BendType.Hold || note.BendType == BendType.Prebend)
                        {
                            TieGlyph.PaintTie(canvas, Scale, startX, startY, endX, endY,
                                              direction == BeamDirection.Down);
                            canvas.Fill();
                        }
                        else
                        {
                            DrawBendSlur(canvas, startX, startY, endX, endY, direction == BeamDirection.Down, Scale,
                                         slurText);
                        }
                    }

                    switch (note.BendType)
                    {
                    case BendType.Prebend:
                    case BendType.PrebendBend:
                    case BendType.PrebendRelease:
                        var preX = cx + startNoteRenderer.X +
                                   startNoteRenderer.GetBeatX(note.Beat, BeatXPosition.PreNotes);
                        preX += ((ScoreBeatPreNotesGlyph)startNoteRenderer.GetBeatContainer(note.Beat).PreNotes)
                                .PrebendNoteHeadOffset;

                        var preY = cy + startNoteRenderer.Y +
                                   startNoteRenderer.GetScoreY(
                            startNoteRenderer.AccidentalHelper.GetNoteLineForValue(note.DisplayValue - note.BendPoints[0].Value / 2)) +
                                   heightOffset;

                        DrawBendSlur(canvas, preX, preY, startX, startY, direction == BeamDirection.Down, Scale);
                        break;
                    }
                }
                else
                {
                    if (direction == BeamDirection.Up)
                    {
                        heightOffset = -heightOffset;
                    }
                    int   endValue;
                    float endY;

                    switch (note.BendType)
                    {
                    case BendType.Bend:
                        endValue = GetBendNoteValue(note, note.BendPoints[note.BendPoints.Count - 1]);
                        endY     = _endNoteGlyph.GetNoteValueY(endValue) + heightOffset;
                        DrawBendSlur(canvas, startX, startY, endBeatX, endY, direction == BeamDirection.Down, Scale,
                                     slurText);

                        break;

                    case BendType.BendRelease:
                        var middleValue = GetBendNoteValue(note, note.BendPoints[1]);
                        var middleY     = _middleNoteGlyph.GetNoteValueY(middleValue) + heightOffset;
                        DrawBendSlur(canvas, startX, startY, middleX, middleY, direction == BeamDirection.Down,
                                     Scale, slurText);

                        endValue = GetBendNoteValue(note, note.BendPoints[note.BendPoints.Count - 1]);
                        endY     = _endNoteGlyph.GetNoteValueY(endValue) + heightOffset;
                        DrawBendSlur(canvas, middleX, middleY, endBeatX, endY, direction == BeamDirection.Down,
                                     Scale, slurText);

                        break;

                    case BendType.Release:
                        if (_bendNoteHeads.Count > 0)
                        {
                            endValue = GetBendNoteValue(note, note.BendPoints[note.BendPoints.Count - 1]);
                            endY     = _bendNoteHeads[0].GetNoteValueY(endValue) + heightOffset;
                            DrawBendSlur(canvas, startX, startY, endBeatX, endY, direction == BeamDirection.Down,
                                         Scale, slurText);
                        }

                        break;

                    case BendType.Prebend:
                    case BendType.PrebendBend:
                    case BendType.PrebendRelease:

                        var preX = cx + startNoteRenderer.X +
                                   startNoteRenderer.GetBeatX(note.Beat, BeatXPosition.PreNotes);
                        preX += ((ScoreBeatPreNotesGlyph)startNoteRenderer.GetBeatContainer(note.Beat).PreNotes)
                                .PrebendNoteHeadOffset;

                        var preY = cy + startNoteRenderer.Y +
                                   startNoteRenderer.GetScoreY(
                            startNoteRenderer.AccidentalHelper.GetNoteLineForValue(note.DisplayValue - note.BendPoints[0].Value / 2)) +
                                   heightOffset;

                        DrawBendSlur(canvas, preX, preY, startX, startY, direction == BeamDirection.Down, Scale);

                        if (_bendNoteHeads.Count > 0)
                        {
                            endValue = GetBendNoteValue(note, note.BendPoints[note.BendPoints.Count - 1]);
                            endY     = _bendNoteHeads[0].GetNoteValueY(endValue) + heightOffset;
                            DrawBendSlur(canvas, startX, startY, endBeatX, endY, direction == BeamDirection.Down,
                                         Scale, slurText);
                        }

                        break;
                    }
                }
            }
        }