protected BeamDirection GetBeamDirection(Beat beat, ScoreBarRenderer noteRenderer) { // invert direction (if stems go up, ties go down to not cross them) switch (noteRenderer.GetBeatDirection(beat)) { case BeamDirection.Up: return(BeamDirection.Down); case BeamDirection.Down: default: return(BeamDirection.Up); } }
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; }