Exemple #1
0
        public void Paint(float cx, float cy, ICanvas canvas)
        {
            for (int i = 0, j = _allStaves.Count; i < j; i++)
            {
                _allStaves[i].Paint(cx + X, cy + Y, canvas);
            }

            var res = Layout.Renderer.RenderingResources;

            if (Staves.Count > 0)
            {
                //
                // Draw start grouping
                //

                if (_firstStaveInAccolade != null && _lastStaveInAccolade != null)
                {
                    //
                    // draw grouping line for all staves
                    //

                    var firstStart = cy + Y + _firstStaveInAccolade.Y + _firstStaveInAccolade.StaveTop + _firstStaveInAccolade.TopSpacing + _firstStaveInAccolade.TopOverflow;
                    var lastEnd = cy + Y + _lastStaveInAccolade.Y + _lastStaveInAccolade.TopSpacing + _lastStaveInAccolade.TopOverflow
                                         + _lastStaveInAccolade.StaveBottom;

                    var acooladeX = cx + X + _firstStaveInAccolade.X;

                    canvas.Color = res.BarSeperatorColor;

                    canvas.BeginPath();
                    canvas.MoveTo(acooladeX, firstStart);
                    canvas.LineTo(acooladeX, lastEnd);
                    canvas.Stroke();
                }

                //
                // Draw accolade for each track group
                //
                canvas.Font = res.EffectFont;
                for (int i = 0, j = Staves.Count; i < j; i++)
                {
                    var g = Staves[i];
                    var firstStart = cy + Y + g.FirstStaveInAccolade.Y + g.FirstStaveInAccolade.StaveTop + g.FirstStaveInAccolade.TopSpacing + g.FirstStaveInAccolade.TopOverflow;
                    var lastEnd = cy + Y + g.LastStaveInAccolade.Y + g.LastStaveInAccolade.TopSpacing + g.LastStaveInAccolade.TopOverflow
                                         + g.LastStaveInAccolade.StaveBottom;

                    var acooladeX = cx + X + g.FirstStaveInAccolade.X;

                    var barSize = (3 * Layout.Renderer.Settings.Scale);
                    var barOffset = barSize;

                    var accoladeStart = firstStart - (barSize * 4);
                    var accoladeEnd = lastEnd + (barSize * 4);

                    // text
                    if (Index == 0)
                    {
                        canvas.FillText(g.Track.ShortName, cx + X + (AccoladeLabelSpacing * Layout.Scale), firstStart);
                    }

                    // rect
                    canvas.FillRect(acooladeX - barOffset - barSize, accoladeStart, barSize, accoladeEnd - accoladeStart);

                    var spikeStartX = acooladeX - barOffset - barSize;
                    var spikeEndX = acooladeX + barSize * 2;

                    // top spike
                    canvas.BeginPath();
                    canvas.MoveTo(spikeStartX, accoladeStart);
                    canvas.BezierCurveTo(spikeStartX, accoladeStart, spikeStartX, accoladeStart, spikeEndX, accoladeStart - barSize);
                    canvas.BezierCurveTo(acooladeX, accoladeStart + barSize, spikeStartX, accoladeStart + barSize, spikeStartX, accoladeStart + barSize);
                    canvas.ClosePath();
                    canvas.Fill();

                    // bottom spike
                    canvas.BeginPath();
                    canvas.MoveTo(spikeStartX, accoladeEnd);
                    canvas.BezierCurveTo(spikeStartX, accoladeEnd, acooladeX, accoladeEnd, spikeEndX, accoladeEnd + barSize);
                    canvas.BezierCurveTo(acooladeX, accoladeEnd - barSize, spikeStartX, accoladeEnd - barSize, spikeStartX, accoladeEnd - barSize);
                    canvas.ClosePath();

                    canvas.Fill();
                }
            }
        }
Exemple #2
0
        public void Paint(float cx, float cy, ICanvas canvas)
        {
            for (int i = 0, j = _allStaves.Count; i < j; i++)
            {
                _allStaves[i].Paint(cx + X, cy + Y, canvas);
            }

            var res = Layout.Renderer.RenderingResources;

            if (Staves.Count > 0)
            {
                //
                // Draw start grouping
                //

                if (_firstStaveInAccolade != null && _lastStaveInAccolade != null)
                {
                    //
                    // draw grouping line for all staves
                    //

                    var firstStart = cy + Y + _firstStaveInAccolade.Y + _firstStaveInAccolade.StaveTop + _firstStaveInAccolade.TopSpacing + _firstStaveInAccolade.TopOverflow;
                    var lastEnd    = cy + Y + _lastStaveInAccolade.Y + _lastStaveInAccolade.TopSpacing + _lastStaveInAccolade.TopOverflow
                                     + _lastStaveInAccolade.StaveBottom;

                    var acooladeX = cx + X + _firstStaveInAccolade.X;

                    canvas.Color = res.BarSeperatorColor;

                    canvas.BeginPath();
                    canvas.MoveTo(acooladeX, firstStart);
                    canvas.LineTo(acooladeX, lastEnd);
                    canvas.Stroke();
                }

                //
                // Draw accolade for each track group
                //
                canvas.Font = res.EffectFont;
                for (int i = 0, j = Staves.Count; i < j; i++)
                {
                    var g          = Staves[i];
                    var firstStart = cy + Y + g.FirstStaveInAccolade.Y + g.FirstStaveInAccolade.StaveTop + g.FirstStaveInAccolade.TopSpacing + g.FirstStaveInAccolade.TopOverflow;
                    var lastEnd    = cy + Y + g.LastStaveInAccolade.Y + g.LastStaveInAccolade.TopSpacing + g.LastStaveInAccolade.TopOverflow
                                     + g.LastStaveInAccolade.StaveBottom;

                    var acooladeX = cx + X + g.FirstStaveInAccolade.X;

                    var barSize   = (3 * Layout.Renderer.Settings.Scale);
                    var barOffset = barSize;

                    var accoladeStart = firstStart - (barSize * 4);
                    var accoladeEnd   = lastEnd + (barSize * 4);

                    // text
                    if (Index == 0)
                    {
                        canvas.FillText(g.Track.ShortName, cx + X + (AccoladeLabelSpacing * Layout.Scale), firstStart);
                    }

                    // rect
                    canvas.FillRect(acooladeX - barOffset - barSize, accoladeStart, barSize, accoladeEnd - accoladeStart);

                    var spikeStartX = acooladeX - barOffset - barSize;
                    var spikeEndX   = acooladeX + barSize * 2;

                    // top spike
                    canvas.BeginPath();
                    canvas.MoveTo(spikeStartX, accoladeStart);
                    canvas.BezierCurveTo(spikeStartX, accoladeStart, spikeStartX, accoladeStart, spikeEndX, accoladeStart - barSize);
                    canvas.BezierCurveTo(acooladeX, accoladeStart + barSize, spikeStartX, accoladeStart + barSize, spikeStartX, accoladeStart + barSize);
                    canvas.ClosePath();
                    canvas.Fill();

                    // bottom spike
                    canvas.BeginPath();
                    canvas.MoveTo(spikeStartX, accoladeEnd);
                    canvas.BezierCurveTo(spikeStartX, accoladeEnd, acooladeX, accoladeEnd, spikeEndX, accoladeEnd + barSize);
                    canvas.BezierCurveTo(acooladeX, accoladeEnd - barSize, spikeStartX, accoladeEnd - barSize, spikeStartX, accoladeEnd - barSize);
                    canvas.ClosePath();

                    canvas.Fill();
                }
            }
        }
Exemple #3
0
        private void PaintBend(BendPoint firstPt, BendPoint secondPt, float cx, float cy, float dX, ICanvas canvas)
        {
            var r   = (TabBarRenderer)Renderer;
            var res = Renderer.Resources;

            var overflowOffset = r.LineOffset / 2;

            var x1 = cx + (dX * firstPt.Offset);
            var y1 = cy - (_bendValueHeight * firstPt.Value);

            if (firstPt.Value == 0)
            {
                y1 += r.GetNoteY(_note);
            }
            else
            {
                y1 += overflowOffset;
            }
            var x2 = cx + (dX * secondPt.Offset);
            var y2 = cy - (_bendValueHeight * secondPt.Value);

            if (secondPt.Value == 0)
            {
                y2 += r.GetNoteY(_note);
            }
            else
            {
                y2 += overflowOffset;
            }

            // what type of arrow? (up/down)
            var arrowOffset = 0f;
            var arrowSize   = 6 * Scale;

            if (secondPt.Value > firstPt.Value)
            {
                canvas.BeginPath();
                canvas.MoveTo(x2, y2);
                canvas.LineTo(x2 - arrowSize * 0.5f, y2 + arrowSize);
                canvas.LineTo(x2 + arrowSize * 0.5f, y2 + arrowSize);
                canvas.ClosePath();
                canvas.Fill();
                arrowOffset = arrowSize;
            }
            else if (secondPt.Value != firstPt.Value)
            {
                canvas.BeginPath();
                canvas.MoveTo(x2, y2);
                canvas.LineTo(x2 - arrowSize * 0.5f, y2 - arrowSize);
                canvas.LineTo(x2 + arrowSize * 0.5f, y2 - arrowSize);
                canvas.ClosePath();
                canvas.Fill();
                arrowOffset = -arrowSize;
            }
            canvas.Stroke();

            if (firstPt.Value == secondPt.Value)
            {
                // draw horizontal line
                canvas.MoveTo(x1, y1);
                canvas.LineTo(x2, y2);
                canvas.Stroke();
            }
            else
            {
                if (x2 > x1)
                {
                    // draw bezier lien from first to second point
                    canvas.MoveTo(x1, y1);
                    canvas.BezierCurveTo(x2, y1, x2, y2 + arrowOffset, x2, y2 + arrowOffset);
                    canvas.Stroke();
                }
                else
                {
                    canvas.MoveTo(x1, y1);
                    canvas.LineTo(x2, y2);
                    canvas.Stroke();
                }
            }



            if (secondPt.Value != 0)
            {
                var dV = secondPt.Value;
                var up = secondPt.Value > firstPt.Value;
                dV = Math.Abs(dV);

                // calculate label
                var s = "";
                // Full Steps
                if (dV == 4 && up)
                {
                    s   = "full";
                    dV -= 4;
                }
                else if (dV >= 4)
                {
                    int steps = dV / 4;
                    s += steps;
                    // Quaters
                    dV -= steps * 4;
                }

                if (dV > 0)
                {
                    s += GetFractionSign(dV);
                }

                if (s != "")
                {
                    if (!up)
                    {
                        s = "-" + s;
                    }

                    // draw label
                    canvas.Font = res.TablatureFont;
                    var size = canvas.MeasureText(s);
                    var y    = up ? y2 - res.TablatureFont.Size - (2 * Scale) : y2 + (2 * Scale);
                    var x    = x2 - size / 2;

                    canvas.FillText(s, x, y);
                }
            }
        }
Exemple #4
0
        public override void Paint(float cx, float cy, ICanvas canvas)
        {
            var r = (TabBarRenderer)Renderer;
            var res = Renderer.Resources;
            // calculate offsets per step
            var dX = Width / BendPoint.MaxPosition;
            var maxValue = 0;
            for (int i = 0, j = _note.BendPoints.Count; i < j; i++)
            {
                if (_note.BendPoints[i].Value > maxValue)
                {
                    maxValue = _note.BendPoints[i].Value;
                }
            }

            var dY = maxValue == 0 ? 0 : _height / maxValue;

            var xx = cx + X;
            var yy = cy + Y + r.GetNoteY(_note);

            canvas.BeginPath();
            for (int i = 0, j = _note.BendPoints.Count - 1; i < j; i++)
            {
                var firstPt = _note.BendPoints[i];
                var secondPt = _note.BendPoints[i + 1];

                // don't draw a line if there's no offset and it's the last point
                if (firstPt.Value == secondPt.Value && i == _note.BendPoints.Count - 2) continue;

                var x1 = xx + (dX * firstPt.Offset);
                var y1 = yy - (dY * firstPt.Value);
                var x2 = xx + (dX * secondPt.Offset);
                var y2 = yy - (dY * secondPt.Value);

                if (firstPt.Value == secondPt.Value)
                {
                    // draw horizontal line
                    canvas.MoveTo(x1, y1);
                    canvas.LineTo(x2, y2);
                    canvas.Stroke();
                }
                else
                {
                    // draw bezier lien from first to second point
                    var hx = x1 + (x2 - x1);
                    var hy = yy - (dY * firstPt.Value);
                    canvas.MoveTo(x1, y1);
                    canvas.BezierCurveTo(hx, hy, x2, y2, x2, y2);
                    canvas.Stroke();
                }

                // what type of arrow? (up/down)
                var arrowSize = 6 * Scale;
                if (secondPt.Value > firstPt.Value)
                {
                    canvas.BeginPath();
                    canvas.MoveTo(x2, y2);
                    canvas.LineTo(x2 - arrowSize * 0.5f, y2 + arrowSize);
                    canvas.LineTo(x2 + arrowSize * 0.5f, y2 + arrowSize);
                    canvas.ClosePath();
                    canvas.Fill();
                }
                else if (secondPt.Value != firstPt.Value)
                {
                    canvas.BeginPath();
                    canvas.MoveTo(x2, y2);
                    canvas.LineTo(x2 - arrowSize * 0.5f, y2 - arrowSize);
                    canvas.LineTo(x2 + arrowSize * 0.5f, y2 - arrowSize);
                    canvas.ClosePath();
                    canvas.Fill();
                }
                canvas.Stroke();

                if (secondPt.Value != 0)
                {
                    var dV = (secondPt.Value - firstPt.Value);
                    var up = dV > 0;
                    dV = Math.Abs(dV);

                    // calculate label
                    var s = "";
                    // Full Steps
                    if (dV == 4)
                    {
                        s = "full";
                        dV -= 4;
                    }
                    else if (dV > 4)
                    {
                        s += dV / 4 + " ";
                        // Quaters
                        dV -= dV / 4;
                    }

                    if (dV > 0)
                    {
                        s += dV + "/4";
                    }

                    if (s != "")
                    {
                        if (!up)
                        {
                            s = "-" + s;
                        }

                        // draw label
                        canvas.Font = res.TablatureFont;
                        var size = canvas.MeasureText(s);
                        var y = up ? y2 - res.TablatureFont.Size - (2 * Scale) : y2 + (2 * Scale);
                        var x = x2 - size / 2;

                        canvas.FillText(s, x, y);
                    }
                }
            }
        }
Exemple #5
0
        private void PaintBend(BendPoint firstPt, BendPoint secondPt, float cx, float cy, float dX, ICanvas canvas)
        {
            var r = (TabBarRenderer)Renderer;
            var res = Renderer.Resources;

            var overflowOffset = r.LineOffset / 2;

            var x1 = cx + (dX * firstPt.Offset);
            var y1 = cy - (_bendValueHeight * firstPt.Value);
            if (firstPt.Value == 0)
            {
                y1 += r.GetNoteY(_note);
            }
            else
            {
                y1 += overflowOffset;
            }
            var x2 = cx + (dX * secondPt.Offset);
            var y2 = cy - (_bendValueHeight * secondPt.Value);
            if (secondPt.Value == 0)
            {
                y2 += r.GetNoteY(_note);
            }
            else
            {
                y2 += overflowOffset;
            }

            // what type of arrow? (up/down)
            var arrowOffset = 0f;
            var arrowSize = 6 * Scale;
            if (secondPt.Value > firstPt.Value)
            {
                canvas.BeginPath();
                canvas.MoveTo(x2, y2);
                canvas.LineTo(x2 - arrowSize * 0.5f, y2 + arrowSize);
                canvas.LineTo(x2 + arrowSize * 0.5f, y2 + arrowSize);
                canvas.ClosePath();
                canvas.Fill();
                arrowOffset = arrowSize;
            }
            else if (secondPt.Value != firstPt.Value)
            {
                canvas.BeginPath();
                canvas.MoveTo(x2, y2);
                canvas.LineTo(x2 - arrowSize * 0.5f, y2 - arrowSize);
                canvas.LineTo(x2 + arrowSize * 0.5f, y2 - arrowSize);
                canvas.ClosePath();
                canvas.Fill();
                arrowOffset = -arrowSize;
            }
            canvas.Stroke();

            if (firstPt.Value == secondPt.Value)
            {
                // draw horizontal line
                canvas.MoveTo(x1, y1);
                canvas.LineTo(x2, y2);
                canvas.Stroke();
            }
            else
            {
                if (x2 > x1)
                {
                    // draw bezier lien from first to second point
                    canvas.MoveTo(x1, y1);
                    canvas.BezierCurveTo(x2, y1, x2, y2 + arrowOffset, x2, y2 + arrowOffset);
                    canvas.Stroke();
                }
                else
                {
                    canvas.MoveTo(x1, y1);
                    canvas.LineTo(x2, y2);
                    canvas.Stroke();
                }
            }

            if (secondPt.Value != 0)
            {
                var dV = secondPt.Value;
                var up = secondPt.Value > firstPt.Value;
                dV = Math.Abs(dV);

                // calculate label
                var s = "";
                // Full Steps
                if (dV == 4 && up)
                {
                    s = "full";
                    dV -= 4;
                }
                else if (dV >= 4)
                {
                    int steps = dV / 4;
                    s += steps;
                    // Quaters
                    dV -= steps * 4;
                }

                if (dV > 0)
                {
                    s += GetFractionSign(dV);
                }

                if (s != "")
                {
                    if (!up)
                    {
                        s = "-" + s;
                    }

                    // draw label
                    canvas.Font = res.TablatureFont;
                    var size = canvas.MeasureText(s);
                    var y = up ? y2 - res.TablatureFont.Size - (2 * Scale) : y2 + (2 * Scale);
                    var x = x2 - size / 2;

                    canvas.FillText(s, x, y);
                }
            }
        }
Exemple #6
0
        public override void Paint(float cx, float cy, ICanvas canvas)
        {
            var r   = (TabBarRenderer)Renderer;
            var res = Renderer.Resources;
            // calculate offsets per step
            var dX       = Width / BendPoint.MaxPosition;
            var maxValue = 0;

            for (int i = 0, j = _note.BendPoints.Count; i < j; i++)
            {
                if (_note.BendPoints[i].Value > maxValue)
                {
                    maxValue = _note.BendPoints[i].Value;
                }
            }

            var dY = maxValue == 0 ? 0 : _height / maxValue;

            var xx = cx + X;
            var yy = cy + Y + r.GetNoteY(_note);

            canvas.BeginPath();
            for (int i = 0, j = _note.BendPoints.Count - 1; i < j; i++)
            {
                var firstPt  = _note.BendPoints[i];
                var secondPt = _note.BendPoints[i + 1];

                // don't draw a line if there's no offset and it's the last point
                if (firstPt.Value == secondPt.Value && i == _note.BendPoints.Count - 2)
                {
                    continue;
                }

                var x1 = xx + (dX * firstPt.Offset);
                var y1 = yy - (dY * firstPt.Value);
                var x2 = xx + (dX * secondPt.Offset);
                var y2 = yy - (dY * secondPt.Value);

                if (firstPt.Value == secondPt.Value)
                {
                    // draw horizontal line
                    canvas.MoveTo(x1, y1);
                    canvas.LineTo(x2, y2);
                    canvas.Stroke();
                }
                else
                {
                    // draw bezier lien from first to second point
                    var hx = x1 + (x2 - x1);
                    var hy = yy - (dY * firstPt.Value);
                    canvas.MoveTo(x1, y1);
                    canvas.BezierCurveTo(hx, hy, x2, y2, x2, y2);
                    canvas.Stroke();
                }



                // what type of arrow? (up/down)
                var arrowSize = 6 * Scale;
                if (secondPt.Value > firstPt.Value)
                {
                    canvas.BeginPath();
                    canvas.MoveTo(x2, y2);
                    canvas.LineTo(x2 - arrowSize * 0.5f, y2 + arrowSize);
                    canvas.LineTo(x2 + arrowSize * 0.5f, y2 + arrowSize);
                    canvas.ClosePath();
                    canvas.Fill();
                }
                else if (secondPt.Value != firstPt.Value)
                {
                    canvas.BeginPath();
                    canvas.MoveTo(x2, y2);
                    canvas.LineTo(x2 - arrowSize * 0.5f, y2 - arrowSize);
                    canvas.LineTo(x2 + arrowSize * 0.5f, y2 - arrowSize);
                    canvas.ClosePath();
                    canvas.Fill();
                }
                canvas.Stroke();

                if (secondPt.Value != 0)
                {
                    var dV = (secondPt.Value - firstPt.Value);
                    var up = dV > 0;
                    dV = Math.Abs(dV);

                    // calculate label
                    var s = "";
                    // Full Steps
                    if (dV == 4)
                    {
                        s   = "full";
                        dV -= 4;
                    }
                    else if (dV > 4)
                    {
                        s += dV / 4 + " ";
                        // Quaters
                        dV -= dV / 4;
                    }

                    if (dV > 0)
                    {
                        s += dV + "/4";
                    }

                    if (s != "")
                    {
                        if (!up)
                        {
                            s = "-" + s;
                        }

                        // draw label
                        canvas.Font = res.TablatureFont;
                        var size = canvas.MeasureText(s);
                        var y    = up ? y2 - res.TablatureFont.Size - (2 * Scale) : y2 + (2 * Scale);
                        var x    = x2 - size / 2;

                        canvas.FillText(s, x, y);
                    }
                }
            }
        }
Exemple #7
0
        private void PaintBend(Note note, TabBendRenderPoint firstPt, TabBendRenderPoint secondPt, float cx, float cy, float dX, string slurText, ICanvas canvas)
        {
            var r   = (TabBarRenderer)Renderer;
            var res = Renderer.Resources;

            var overflowOffset = r.LineOffset / 2;

            var x1 = cx + (dX * firstPt.Offset);
            var bendValueHeight = BendValueHeight * Scale;
            var y1 = cy - (bendValueHeight * firstPt.LineValue);

            if (firstPt.Value == 0)
            {
                if (secondPt.Offset == firstPt.Offset)
                {
                    y1 += r.GetNoteY(note.Beat.MaxStringNote, true);
                }
                else
                {
                    y1 += r.GetNoteY(note);
                }
            }
            else
            {
                y1 += overflowOffset;
            }

            var x2 = cx + (dX * secondPt.Offset);
            var y2 = cy - (bendValueHeight * secondPt.LineValue);

            if (secondPt.LineValue == 0)
            {
                y2 += r.GetNoteY(note);
            }
            else
            {
                y2 += overflowOffset;
            }

            // what type of arrow? (up/down)
            var arrowOffset = 0f;
            var arrowSize   = ArrowSize * Scale;

            if (secondPt.Value > firstPt.Value)
            {
                if (y2 + arrowSize > y1)
                {
                    y2 = y1 - arrowSize;
                }
                canvas.BeginPath();
                canvas.MoveTo(x2, y2);
                canvas.LineTo(x2 - arrowSize * 0.5f, y2 + arrowSize);
                canvas.LineTo(x2 + arrowSize * 0.5f, y2 + arrowSize);
                canvas.ClosePath();
                canvas.Fill();
                arrowOffset = arrowSize;
            }
            else if (secondPt.Value != firstPt.Value)
            {
                if (y2 < y1)
                {
                    y2 = y1 + arrowSize;
                }
                canvas.BeginPath();
                canvas.MoveTo(x2, y2);
                canvas.LineTo(x2 - arrowSize * 0.5f, y2 - arrowSize);
                canvas.LineTo(x2 + arrowSize * 0.5f, y2 - arrowSize);
                canvas.ClosePath();
                canvas.Fill();
                arrowOffset = -arrowSize;
            }
            canvas.Stroke();

            if (firstPt.Value == secondPt.Value)
            {
                // draw horizontal dashed line
                // to really have the line ending at the right position
                // we draw from right to left. it's okay if the space is at the beginning
                if (firstPt.LineValue > 0)
                {
                    var dashX    = x2;
                    var dashSize = DashSize * Scale;
                    var end      = (x1 + dashSize);
                    var dashes   = (dashX - x1) / (dashSize * 2);
                    if (dashes < 1)
                    {
                        canvas.MoveTo(dashX, y1);
                        canvas.LineTo(x1, y1);
                    }
                    else
                    {
                        while (dashX > end)
                        {
                            canvas.MoveTo(dashX, y1);
                            canvas.LineTo(dashX - dashSize, y1);
                            dashX -= dashSize * 2;
                        }
                    }

                    canvas.Stroke();
                }
            }
            else
            {
                if (x2 > x1)
                {
                    // draw bezier lien from first to second point
                    canvas.MoveTo(x1, y1);
                    canvas.BezierCurveTo((x1 + x2) / 2, y1, x2, y1, x2, y2 + arrowOffset);
                    canvas.Stroke();
                }
                else
                {
                    canvas.MoveTo(x1, y1);
                    canvas.LineTo(x2, y2);
                    canvas.Stroke();
                }
            }

            if (!string.IsNullOrEmpty(slurText) && firstPt.Offset < secondPt.Offset)
            {
                canvas.Font = res.GraceFont;
                var   size = canvas.MeasureText(slurText);
                float y;
                float x;
                if (y1 > y2)
                {
                    var h = Math.Abs(y1 - y2);
                    y = h > canvas.Font.Size * 1.3f ? y1 - h / 2 : y1;
                    x = (x1 + x2 - size) / 2;
                }
                else
                {
                    y = y1;
                    x = x2 - size;
                }

                canvas.FillText(slurText, x, y);
            }

            if (secondPt.Value != 0 && firstPt.Value != secondPt.Value)
            {
                var dV = secondPt.Value;
                var up = secondPt.Value > firstPt.Value;
                dV = Math.Abs(dV);

                // calculate label
                var s = "";
                // Full Steps
                if (dV == 4)
                {
                    s   = "full";
                    dV -= 4;
                }
                else if (dV >= 4 || dV <= -4)
                {
                    int steps = dV / 4;
                    s += steps;
                    // Quaters
                    dV -= steps * 4;
                }

                if (dV > 0)
                {
                    s += GetFractionSign(dV);
                }

                if (s != "")
                {
                    y2 = cy - (bendValueHeight * secondPt.Value);
                    var startY = y2;
                    if (!up)
                    {
                        startY = y1 + Math.Abs(y2 - y1) * 1f / 3;
                    }

                    // draw label
                    canvas.Font = res.TablatureFont;
                    var size = canvas.MeasureText(s);
                    var y    = startY - res.TablatureFont.Size * 0.5f - (2 * Scale);
                    var x    = x2 - size / 2;

                    canvas.FillText(s, x, y);
                }
            }
        }